From 6d4e2ef24558008634b317c3e2216a85216c7225 Mon Sep 17 00:00:00 2001 From: chenweize1998 Date: Tue, 9 Jul 2024 00:16:59 +0800 Subject: [PATCH] feat: initial commit --- .DS_Store | Bin 6148 -> 6148 bytes .dockerignore | 5 + .gitignore | 171 + LICENSE | 201 + PULL_REQUEST_TEMPLATE.md | 29 + common/config.py | 30 + common/log.py | 303 + common/registry.py | 27 + common/types/__init__.py | 4 + common/types/agent.py | 30 + common/types/communication.py | 127 + common/types/llm.py | 104 + common/types/server.py | 26 + common/types/task.py | 8 + common/utils/__init__.py | 1 + common/utils/database_utils.py | 200 + common/utils/json_utils.py | 636 + common/utils/milvus_utils.py | 304 + common/utils/misc.py | 9 + common/utils/tool_utils.py | 18 + common/utils/type_utils.py | 15 + .../cases/gaia/code_executor.yaml | 30 + .../cases/gaia/web_browser.yaml | 35 + .../client_configs/cases/gaia/wikidata.yaml | 30 + .../client_configs/cases/gaia/youtube.yaml | 30 + .../cases/open_instruction/autogpt.yaml | 24 + .../open_instruction/open_interpreter.yaml | 24 + .../cases/paper_writing/arxiv.yaml | 31 + .../cases/paper_writing/chengyang.yaml | 27 + .../cases/paper_writing/chenqian.yaml | 27 + .../paper_writing/formatCraft_printer.yaml | 75 + .../cases/paper_writing/google_scholar.yaml | 22 + .../cases/paper_writing/weizechen.yaml | 27 + .../client_configs/cases/rocobench/alice.yaml | 21 + .../client_configs/cases/rocobench/bob.yaml | 21 + .../client_configs/cases/rocobench/chad.yaml | 21 + .../client_configs/cases/rocobench/dave.yaml | 21 + configs/client_configs/default_config.yaml | 35 + .../client_configs/vecdb/agent_contact.yaml | 47 + configs/server_configs/agent_registry.yaml | 50 + data/open_instruction.jsonl | 153 + dockerfiles/client.Dockerfile | 19 + dockerfiles/compose/.env_template | 10 + dockerfiles/compose/basic.yaml | 79 + dockerfiles/compose/gaia.yaml | 125 + dockerfiles/compose/milvus.yaml | 77 + dockerfiles/compose/open_instruction.yaml | 93 + dockerfiles/compose/paper_writing.yml | 133 + dockerfiles/compose/rocobench.yaml | 141 + dockerfiles/server.Dockerfile | 18 + dockerfiles/server_frontend.Dockerfile | 30 + dockerfiles/tool_agents/autogpt.Dockerfile | 16 + .../tool_agents/open_interpreter.Dockerfile | 29 + dockerfiles/tool_agents/react.Dockerfile | 33 + im_client/__init__.py | 0 im_client/agents/__init__.py | 7 + im_client/agents/autogpt/__init__.py | 1 + im_client/agents/autogpt/autogpt_adapter.py | 265 + .../autogpt_patch/pyproject_latest_dev.toml | 163 + .../autogpt_patch/web_selenium_latest_dev.py | 357 + im_client/agents/base.py | 136 + im_client/agents/open_interpreter/__init__.py | 1 + .../open_interpreter_agent.py | 149 + .../open_interpreter_agent_adapter.py | 98 + .../agents/open_interpreter/requirements.txt | 5 + im_client/agents/react/__init__.py | 1 + im_client/agents/react/react_agent.py | 275 + im_client/agents/react/react_agent_adapter.py | 74 + im_client/agents/react/requirements.txt | 38 + im_client/agents/react/tools.yaml | 229 + im_client/agents/react/tools_arxiv.yaml | 33 + .../agents/react/tools_code_executor.yaml | 20 + im_client/agents/react/tools_scholarly.yaml | 38 + im_client/agents/react/tools_web_browser.yaml | 114 + im_client/agents/react/tools_wikidata.yaml | 12 + im_client/agents/react/tools_youtube.yaml | 26 + im_client/agents/tools/__init__.py | 30 + im_client/agents/tools/arxiv_tools.py | 55 + im_client/agents/tools/code_executor.py | 144 + im_client/agents/tools/playwright_browser.py | 396 + im_client/agents/tools/rag_tools.py | 48 + im_client/agents/tools/scholarly_tools.py | 53 + im_client/agents/tools/wikidata.py | 186 + im_client/agents/tools/wikipedia_api.py | 89 + im_client/agents/tools/youtube.py | 89 + im_client/communication/__init__.py | 1 + .../communication/communication_layer.py | 1497 ++ im_client/communication/task_management.py | 507 + im_client/communication/websocket_client.py | 74 + im_client/llms/__init__.py | 25 + im_client/llms/base.py | 37 + im_client/llms/openai.py | 403 + im_client/llms/utils/__init__.py | 2 + im_client/llms/utils/jsonrepair.py | 636 + im_client/llms/utils/token_counter.py | 61 + im_client/main.py | 52 + im_client/memory/__init__.py | 6 + im_client/memory/base.py | 23 + im_client/memory/chat_history.py | 181 + im_client/observation_func/__init__.py | 17 + im_client/observation_func/default.py | 0 im_client/observation_func/rocobench.py | 13 + im_client/prompts/__init__.py | 3 + im_client/prompts/communication.py | 270 + im_client/prompts/execution.py | 63 + im_client/prompts/react.py | 18 + im_client/requirements.txt | 17 + im_client/server_helper.py | 122 + im_server/app.py | 255 + im_server/frontend/.gitignore | 23 + im_server/frontend/README.md | 70 + im_server/frontend/package-lock.json | 18309 ++++++++++++++++ im_server/frontend/package.json | 40 + im_server/frontend/public/favicon.ico | Bin 0 -> 3870 bytes im_server/frontend/public/index.html | 43 + im_server/frontend/public/logo192.png | Bin 0 -> 5347 bytes im_server/frontend/public/logo512.png | Bin 0 -> 9664 bytes im_server/frontend/public/manifest.json | 25 + im_server/frontend/public/robots.txt | 3 + im_server/frontend/src/App.css | 5 + im_server/frontend/src/App.js | 181 + .../src/components/ChatWindow/ChatWindow.css | 55 + .../src/components/ChatWindow/ChatWindow.jsx | 81 + .../src/components/GroupList/GroupList.css | 159 + .../src/components/GroupList/GroupList.jsx | 59 + .../src/components/Message/Message.css | 45 + .../src/components/Message/Message.jsx | 50 + im_server/frontend/src/index.css | 13 + im_server/frontend/src/index.js | 17 + im_server/frontend/src/logo.svg | 1 + im_server/frontend/src/reportWebVitals.js | 13 + im_server/frontend/src/setupTests.js | 5 + im_server/frontend/src/utils/avatar.js | 21 + im_server/requirements.txt | 10 + scripts/gaia/gaia_merge.py | 28 + scripts/gaia/gaia_postprocess.py | 96 + scripts/gaia/test_gaia.py | 253 + .../open_instruction/test_open_instruction.py | 109 + scripts/test_paper_writing.py | 25 + 139 files changed, 30956 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 PULL_REQUEST_TEMPLATE.md create mode 100644 common/config.py create mode 100644 common/log.py create mode 100644 common/registry.py create mode 100644 common/types/__init__.py create mode 100644 common/types/agent.py create mode 100644 common/types/communication.py create mode 100644 common/types/llm.py create mode 100644 common/types/server.py create mode 100644 common/types/task.py create mode 100644 common/utils/__init__.py create mode 100644 common/utils/database_utils.py create mode 100644 common/utils/json_utils.py create mode 100644 common/utils/milvus_utils.py create mode 100644 common/utils/misc.py create mode 100644 common/utils/tool_utils.py create mode 100644 common/utils/type_utils.py create mode 100644 configs/client_configs/cases/gaia/code_executor.yaml create mode 100644 configs/client_configs/cases/gaia/web_browser.yaml create mode 100644 configs/client_configs/cases/gaia/wikidata.yaml create mode 100644 configs/client_configs/cases/gaia/youtube.yaml create mode 100644 configs/client_configs/cases/open_instruction/autogpt.yaml create mode 100644 configs/client_configs/cases/open_instruction/open_interpreter.yaml create mode 100644 configs/client_configs/cases/paper_writing/arxiv.yaml create mode 100644 configs/client_configs/cases/paper_writing/chengyang.yaml create mode 100644 configs/client_configs/cases/paper_writing/chenqian.yaml create mode 100644 configs/client_configs/cases/paper_writing/formatCraft_printer.yaml create mode 100644 configs/client_configs/cases/paper_writing/google_scholar.yaml create mode 100644 configs/client_configs/cases/paper_writing/weizechen.yaml create mode 100644 configs/client_configs/cases/rocobench/alice.yaml create mode 100644 configs/client_configs/cases/rocobench/bob.yaml create mode 100644 configs/client_configs/cases/rocobench/chad.yaml create mode 100644 configs/client_configs/cases/rocobench/dave.yaml create mode 100644 configs/client_configs/default_config.yaml create mode 100644 configs/client_configs/vecdb/agent_contact.yaml create mode 100644 configs/server_configs/agent_registry.yaml create mode 100644 data/open_instruction.jsonl create mode 100644 dockerfiles/client.Dockerfile create mode 100644 dockerfiles/compose/.env_template create mode 100644 dockerfiles/compose/basic.yaml create mode 100644 dockerfiles/compose/gaia.yaml create mode 100644 dockerfiles/compose/milvus.yaml create mode 100644 dockerfiles/compose/open_instruction.yaml create mode 100644 dockerfiles/compose/paper_writing.yml create mode 100644 dockerfiles/compose/rocobench.yaml create mode 100644 dockerfiles/server.Dockerfile create mode 100644 dockerfiles/server_frontend.Dockerfile create mode 100644 dockerfiles/tool_agents/autogpt.Dockerfile create mode 100644 dockerfiles/tool_agents/open_interpreter.Dockerfile create mode 100644 dockerfiles/tool_agents/react.Dockerfile create mode 100644 im_client/__init__.py create mode 100644 im_client/agents/__init__.py create mode 100644 im_client/agents/autogpt/__init__.py create mode 100644 im_client/agents/autogpt/autogpt_adapter.py create mode 100644 im_client/agents/autogpt/autogpt_patch/pyproject_latest_dev.toml create mode 100644 im_client/agents/autogpt/autogpt_patch/web_selenium_latest_dev.py create mode 100644 im_client/agents/base.py create mode 100644 im_client/agents/open_interpreter/__init__.py create mode 100644 im_client/agents/open_interpreter/open_interpreter_agent.py create mode 100644 im_client/agents/open_interpreter/open_interpreter_agent_adapter.py create mode 100644 im_client/agents/open_interpreter/requirements.txt create mode 100644 im_client/agents/react/__init__.py create mode 100644 im_client/agents/react/react_agent.py create mode 100644 im_client/agents/react/react_agent_adapter.py create mode 100644 im_client/agents/react/requirements.txt create mode 100644 im_client/agents/react/tools.yaml create mode 100644 im_client/agents/react/tools_arxiv.yaml create mode 100644 im_client/agents/react/tools_code_executor.yaml create mode 100644 im_client/agents/react/tools_scholarly.yaml create mode 100644 im_client/agents/react/tools_web_browser.yaml create mode 100644 im_client/agents/react/tools_wikidata.yaml create mode 100644 im_client/agents/react/tools_youtube.yaml create mode 100644 im_client/agents/tools/__init__.py create mode 100644 im_client/agents/tools/arxiv_tools.py create mode 100644 im_client/agents/tools/code_executor.py create mode 100644 im_client/agents/tools/playwright_browser.py create mode 100644 im_client/agents/tools/rag_tools.py create mode 100644 im_client/agents/tools/scholarly_tools.py create mode 100644 im_client/agents/tools/wikidata.py create mode 100644 im_client/agents/tools/wikipedia_api.py create mode 100644 im_client/agents/tools/youtube.py create mode 100644 im_client/communication/__init__.py create mode 100644 im_client/communication/communication_layer.py create mode 100644 im_client/communication/task_management.py create mode 100644 im_client/communication/websocket_client.py create mode 100644 im_client/llms/__init__.py create mode 100644 im_client/llms/base.py create mode 100644 im_client/llms/openai.py create mode 100644 im_client/llms/utils/__init__.py create mode 100644 im_client/llms/utils/jsonrepair.py create mode 100644 im_client/llms/utils/token_counter.py create mode 100644 im_client/main.py create mode 100644 im_client/memory/__init__.py create mode 100644 im_client/memory/base.py create mode 100644 im_client/memory/chat_history.py create mode 100644 im_client/observation_func/__init__.py create mode 100644 im_client/observation_func/default.py create mode 100644 im_client/observation_func/rocobench.py create mode 100644 im_client/prompts/__init__.py create mode 100644 im_client/prompts/communication.py create mode 100644 im_client/prompts/execution.py create mode 100644 im_client/prompts/react.py create mode 100644 im_client/requirements.txt create mode 100644 im_client/server_helper.py create mode 100644 im_server/app.py create mode 100644 im_server/frontend/.gitignore create mode 100644 im_server/frontend/README.md create mode 100644 im_server/frontend/package-lock.json create mode 100644 im_server/frontend/package.json create mode 100644 im_server/frontend/public/favicon.ico create mode 100644 im_server/frontend/public/index.html create mode 100644 im_server/frontend/public/logo192.png create mode 100644 im_server/frontend/public/logo512.png create mode 100644 im_server/frontend/public/manifest.json create mode 100644 im_server/frontend/public/robots.txt create mode 100644 im_server/frontend/src/App.css create mode 100644 im_server/frontend/src/App.js create mode 100644 im_server/frontend/src/components/ChatWindow/ChatWindow.css create mode 100644 im_server/frontend/src/components/ChatWindow/ChatWindow.jsx create mode 100644 im_server/frontend/src/components/GroupList/GroupList.css create mode 100644 im_server/frontend/src/components/GroupList/GroupList.jsx create mode 100644 im_server/frontend/src/components/Message/Message.css create mode 100644 im_server/frontend/src/components/Message/Message.jsx create mode 100644 im_server/frontend/src/index.css create mode 100644 im_server/frontend/src/index.js create mode 100644 im_server/frontend/src/logo.svg create mode 100644 im_server/frontend/src/reportWebVitals.js create mode 100644 im_server/frontend/src/setupTests.js create mode 100644 im_server/frontend/src/utils/avatar.js create mode 100644 im_server/requirements.txt create mode 100644 scripts/gaia/gaia_merge.py create mode 100644 scripts/gaia/gaia_postprocess.py create mode 100644 scripts/gaia/test_gaia.py create mode 100644 scripts/open_instruction/test_open_instruction.py create mode 100644 scripts/test_paper_writing.py diff --git a/.DS_Store b/.DS_Store index dd190938b97568c0b3f2d73c81f08254a1aa2990..abab72627dcc48e60f31fe4678b11714fb5039a9 100644 GIT binary patch delta 220 zcmZoMXfc=|#>B`mu~2NHo}wrd0|Nsi1A_oVQh9MfQcivnkiTHVY>L^rO z8X4#)m>8SY)^c))D(hPZ#b@W_=H+(-Edl~Ypygn|3#DOH50C-1e={%hFP4oBYK)uN eIruq%Zr`lP{GE9+zlbFVNHx#|rp*B&TbKdl#ViH@ delta 207 zcmZoMXfc=|#>B)qu~2NHo}wr-0|Nsi1A_pAXHI@{QcivnkT0;Ak!d+&7)XkRA%!8I zA(^2VSsEzr2*i5-!2rlYQkPU-TmUs@ds0D8W^svu!8JxEW)@a9b`Ew9ZjQ;8jA8s7 zoE)6-0^-%xre-<{#%7ZjFv>7?PTtEX&)tPEZ1Z!*Uo4y1Iruq%&ILN@JM(0I5larB OYk`P?VRL}U7G?lyPA@(H diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..37319c4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +.git +**/node_modules +logs/ +**/__pycache__ +temp \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d181d0c --- /dev/null +++ b/.gitignore @@ -0,0 +1,171 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +**/dist/* +!**/dist/assets +!**/dist/index.html +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ +.idea/ +.vscode +.DS_Store +figs +# frontend + +logs/ +**/volumes/ +results/ +**/.env \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..14da3a0 --- /dev/null +++ b/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,29 @@ + + + + +### 🤔 What is the nature of this change? + +- [ ] New feature +- [ ] Fix bug / bug +- [ ] Style optimization +- [ ] Code style optimization +- [ ] Performance optimization +- [ ] Build optimization +- [ ] Website, documentation, demo improvements +- [ ] Refactor code or style +- [ ] Test related +- [ ] Solved proposed issues +- [ ] Other + +### 🔗 Related Issue + +(Describe the source of related requirements, such as the related issue discussion link. Example: close #123, close #456.) + +### 💡 Background or solution + +(The specific problem solved.) + + diff --git a/common/config.py b/common/config.py new file mode 100644 index 0000000..d943dc2 --- /dev/null +++ b/common/config.py @@ -0,0 +1,30 @@ +import yaml +import os +from .log import logger + + +def _update_config(default, user): + for key, value in user.items(): + if isinstance(value, dict): + default[key] = _update_config(default.get(key, {}), value) + else: + default[key] = value + return default + + +def update_custom_config(config): + if custom_config_path := os.getenv("CUSTOM_CONFIG", ""): + logger.info("Loading custom config from %s" % custom_config_path) + custom_config: dict = yaml.safe_load(open(custom_config_path)) + + _update_config(config, custom_config) + + +try: + global_config = yaml.safe_load(open(os.path.join("configs", "default_config.yaml"))) +except FileNotFoundError: + logger.warn( + "No default config file found, using empty config as the default config. If you want to use a default config file, please make sure it is in the 'configs' folder and named 'default_config.yaml'" + ) + global_config = {} +update_custom_config(global_config) diff --git a/common/log.py b/common/log.py new file mode 100644 index 0000000..ebc417f --- /dev/null +++ b/common/log.py @@ -0,0 +1,303 @@ +"""Logging module adapted from Auto-GPT.""" + +from __future__ import annotations +import logging +import os +import random +import re +import time +import json +from logging import LogRecord +from typing import Any, List, TYPE_CHECKING + +from colorama import Fore, Style +from common.utils import Singleton + +if TYPE_CHECKING: + from common.types.llm import LLMResult + + +class JsonFileHandler(logging.FileHandler): + def __init__(self, filename, mode="a", encoding=None, delay=False): + super().__init__(filename, mode, encoding, delay) + + def emit(self, record): + json_data = json.loads(self.format(record)) + with open(self.baseFilename, "w", encoding="utf-8") as f: + json.dump(json_data, f, ensure_ascii=False, indent=4) + + +class JsonFormatter(logging.Formatter): + def format(self, record): + return record.msg + + +class Logger(metaclass=Singleton): + """ + Logger that handle titles in different colors. + Outputs logs in console, activity.log, and errors.log + For console handler: simulates typing + """ + + def __init__(self): + # create log directory if it doesn't exist + this_files_dir_path = os.path.dirname(__file__) + log_dir = os.path.join(this_files_dir_path, "../logs") + if not os.path.exists(log_dir): + os.makedirs(log_dir) + + log_file = "activity.log" + error_file = "error.log" + + console_formatter = AutoGptFormatter("%(title_color)s%(message)s") + + # Create a handler for console which simulate typing + self.typing_console_handler = TypingConsoleHandler() + self.typing_console_handler.setLevel(logging.INFO) + self.typing_console_handler.setFormatter(console_formatter) + + # Create a handler for console without typing simulation + self.console_handler = ConsoleHandler() + self.console_handler.setLevel(logging.DEBUG) + self.console_handler.setFormatter(console_formatter) + + # Info handler in activity.log + self.file_handler = logging.FileHandler(os.path.join(log_dir, log_file), "a", "utf-8") + self.file_handler.setLevel(logging.DEBUG) + info_formatter = AutoGptFormatter("%(asctime)s %(levelname)s %(title)s %(message_no_color)s") + self.file_handler.setFormatter(info_formatter) + + # Error handler error.log + error_handler = logging.FileHandler(os.path.join(log_dir, error_file), "a", "utf-8") + error_handler.setLevel(logging.ERROR) + error_formatter = AutoGptFormatter( + "%(asctime)s %(levelname)s %(module)s:%(funcName)s:%(lineno)d %(title)s" " %(message_no_color)s" + ) + error_handler.setFormatter(error_formatter) + + self.typing_logger = logging.getLogger("TYPER") + self.typing_logger.addHandler(self.typing_console_handler) + self.typing_logger.addHandler(self.file_handler) + self.typing_logger.addHandler(error_handler) + self.typing_logger.setLevel(logging.DEBUG) + + self.logger = logging.getLogger("LOGGER") + self.logger.addHandler(self.console_handler) + self.logger.addHandler(self.file_handler) + self.logger.addHandler(error_handler) + self.logger.setLevel(logging.DEBUG) + + self.json_logger = logging.getLogger("JSON_LOGGER") + self.json_logger.addHandler(self.file_handler) + self.json_logger.addHandler(error_handler) + self.json_logger.setLevel(logging.DEBUG) + + self.logger.propagate = False + self.typing_logger.propagate = False + self.json_logger.propagate = False + + self.speak_mode = False + self.chat_plugins = [] + + def typewriter_log(self, title="", title_color="", content="", speak_text=False, level=logging.INFO): + for plugin in self.chat_plugins: + plugin.report(f"{title}. {content}") + + if content: + if isinstance(content, list): + content = "\n".join(content) + else: + content = "" + + self.typing_logger.log(level, content, extra={"title": title, "color": title_color}) + + def debug( + self, + message, + title="", + title_color="", + ): + self._log(title, title_color, message, logging.DEBUG) + + def info( + self, + message, + title="", + title_color="", + ): + self._log(title, title_color, message, logging.INFO) + + def warn( + self, + message, + title="", + title_color="", + ): + self._log(title, title_color, message, logging.WARN) + + def error(self, title, message=""): + self._log(title, Fore.RED, message, logging.ERROR) + + def _log( + self, + title: str = "", + title_color: str = "", + message: str = "", + level=logging.INFO, + ): + if isinstance(message, list): + if len(message) > 0: + message = "\n".join([str(m) for m in message]) + else: + message = "" + self.logger.log(level, message, extra={"title": str(title), "color": str(title_color)}) + + def log(self, level, msg, *args, **kwargs): + self._log("", "", msg, level) + + def set_level(self, level): + self.logger.setLevel(level) + self.typing_logger.setLevel(level) + + def double_check(self, additionalText=None): + if not additionalText: + additionalText = ( + "Please ensure you've setup and configured everything" + " correctly. Read https://github.com/Torantulino/Auto-GPT#readme to " + "double check. You can also create a github issue or join the discord" + " and ask there!" + ) + + self.typewriter_log("DOUBLE CHECK CONFIGURATION", Fore.YELLOW, additionalText) + + def log_json(self, data: Any, file_name: str) -> None: + # Define log directory + this_files_dir_path = os.path.dirname(__file__) + log_dir = os.path.join(this_files_dir_path, "../logs") + + # Create a handler for JSON files + json_file_path = os.path.join(log_dir, file_name) + json_data_handler = JsonFileHandler(json_file_path) + json_data_handler.setFormatter(JsonFormatter()) + + # Log the JSON data using the custom file handler + self.json_logger.addHandler(json_data_handler) + self.json_logger.debug(data) + self.json_logger.removeHandler(json_data_handler) + + def log_prompt(self, prompt: List[dict]) -> None: + self.debug("", "-=-=-=-=-=-=-=-=Prompt Start-=-=-=-=-=-=-=-=", Fore.MAGENTA) + for p in prompt: + content = p["content"] if p["content"] is not None else "" + if "tool_calls" in p: + content += "\nTool Calls:\n" + for tool_call in p["tool_calls"]: + content += tool_call.function.name + "\n" + content += tool_call.function.arguments + "\n" + content = content.strip() + self.debug( + content, + title=f'==={p["role"]}===\n', + title_color=Fore.MAGENTA, + ) + self.debug("", "-=-=-=-=-=-=-=-=Prompt End-=-=-=-=-=-=-=-=", Fore.MAGENTA) + + def log_llm_result(self, response: LLMResult) -> None: + if response.content is None: + content = "" + elif isinstance(response.content, str): + content = response.content + elif isinstance(response.content, dict): + content = json.dumps(response.content, indent=2) + if response.tool_calls is not None: + for tool_call in response.tool_calls: + content += f"\n{tool_call.function.name}\n{tool_call.function.arguments}\n" + logger.info("", f"--------------------------------------\n{content.strip()}", Fore.BLUE) + + def get_log_directory(self): + this_files_dir_path = os.path.dirname(__file__) + log_dir = os.path.join(this_files_dir_path, "../logs") + return os.path.abspath(log_dir) + + +""" +Output stream to console using simulated typing +""" + + +class TypingConsoleHandler(logging.StreamHandler): + def emit(self, record): + min_typing_speed = 0.05 + max_typing_speed = 0.01 + + msg = self.format(record) + try: + words = re.split(r"(\s+)", msg) + for i, word in enumerate(words): + print(word, end="", flush=True) + # if i < len(words) - 1: + # print(" ", end="", flush=True) + typing_speed = random.uniform(min_typing_speed, max_typing_speed) + time.sleep(typing_speed) + # type faster after each word + min_typing_speed = min_typing_speed * 0.95 + max_typing_speed = max_typing_speed * 0.95 + print() + except Exception: + self.handleError(record) + + +class ConsoleHandler(logging.StreamHandler): + def emit(self, record) -> None: + msg = self.format(record) + try: + print(msg) + except Exception: + self.handleError(record) + + +class AutoGptFormatter(logging.Formatter): + """ + Allows to handle custom placeholders 'title_color' and 'message_no_color'. + To use this formatter, make sure to pass 'color', 'title' as log extras. + """ + + def format(self, record: LogRecord) -> str: + if hasattr(record, "color") and getattr(record, "color", ""): + record.title_color = ( + getattr(record, "color") + + getattr(record, "title", "") + # + " " + + Style.RESET_ALL + ) + else: + record.title_color = getattr(record, "title", "") + + # Add this line to set 'title' to an empty string if it doesn't exist + record.title = getattr(record, "title", "") + + if hasattr(record, "msg"): + record.message_no_color = remove_color_codes(getattr(record, "msg")) + else: + record.message_no_color = "" + + # Remove color codes from the message + record.message_no_color = remove_color_codes(getattr(record, "msg", "")) + return super().format(record) + + +def remove_color_codes(s: str) -> str: + ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])") + return ansi_escape.sub("", s) + + +logger = Logger() + + +def get_logger(): + return logger + + +def typewriter_log(content="", color="", level=logging.INFO): + for line in content.split("\n"): + logger.typewriter_log(line, title_color=color, level=level) diff --git a/common/registry.py b/common/registry.py new file mode 100644 index 0000000..b53b571 --- /dev/null +++ b/common/registry.py @@ -0,0 +1,27 @@ +from typing import Dict + +from pydantic import BaseModel + + +class Registry(BaseModel): + """Registry for storing and building classes.""" + + name: str + entries: Dict = {} + + def register(self, key: str): + def decorator(class_builder): + self.entries[key] = class_builder + return class_builder + + return decorator + + def build(self, type: str, **kwargs): + if type not in self.entries: + raise ValueError( + f'{type} is not registered. Please register with the .register("{type}") method provided in {self.name} registry' + ) + return self.entries[type](**kwargs) + + def get_all_entries(self): + return self.entries diff --git a/common/types/__init__.py b/common/types/__init__.py new file mode 100644 index 0000000..90329da --- /dev/null +++ b/common/types/__init__.py @@ -0,0 +1,4 @@ +from .communication import * +from .task import * +from .agent import * +from .server import * diff --git a/common/types/agent.py b/common/types/agent.py new file mode 100644 index 0000000..a5e21c4 --- /dev/null +++ b/common/types/agent.py @@ -0,0 +1,30 @@ +from typing import Literal +from pydantic import BaseModel + + +class AgentInfo(BaseModel): + """Data model for agent info that is sent between server and client""" + + # id: str + name: str + type: Literal["Human Assistant", "Thing Assistant"] + desc: str + + +class AgentEntry(BaseModel): + """Data model for agent info that is stored in the database""" + + # id: str + name: str + type: Literal["Human Assistant", "Thing Assistant"] + desc: str + created_at: str + # online: bool = False + + +class VoteMessage(BaseModel): + """Data model for vote message""" + + voter: str + vote: str + reason: str diff --git a/common/types/communication.py b/common/types/communication.py new file mode 100644 index 0000000..c6964f5 --- /dev/null +++ b/common/types/communication.py @@ -0,0 +1,127 @@ +from pydantic import BaseModel, root_validator, Field +from typing import Any +from enum import Enum +from .llm import LLMResult +from datetime import datetime + + +class ContInput(BaseModel): + sender: str + content: str + + +class LaunchGoalParam(BaseModel): + """The parameters for launching a goal. + goal: The goal to be launched. + team_member_names: The names of the team members. If specified, will skip the automatic teamup process. + team_up_depth: The current depth of nested-teamup. Need not be manually specified. + is_collaborative_planning_enabled: Whether to enable collaborative planning. + comm_id: The communication ID. If specified, will continue the previous conversation. + cont_info: Useful only when `comm_id` is specified. The info to continue the previous conversation.""" + + goal: str + team_member_names: list[str] | None = None + team_up_depth: int | None = None + is_collaborative_planning_enabled: bool = False + comm_id: str | None = None + cont_input: ContInput | None = None + obs_kwargs: dict[str, Any] = {} + max_turns: int | None = None + skip_naming: bool = True + + @root_validator(pre=True) + def handle(cls, values): + cont_input = values.get("cont_input") + comm_id = values.get("comm_id") + if isinstance(cont_input, str): + if cont_input == "": + values["cont_input"] = None + else: + values["cont_input"] = ContInput(sender="user", content=cont_input) + if comm_id == "": + values["comm_id"] = None + return values + + +class CommunicationProtocol(Enum): + DISCUSSION = 0 + VOTE = 1 + + +class CommunicationState(Enum): + TEAMUP = 0 + DISCUSSION = 1 + VOTE = 2 + EXECUTION = 3 + + +class CommunicationType(Enum): + # message type + DEFAULT = 0 + PROPOSAL = 1 + VOTE = 2 + VOTING_RESULT = 3 + DISCUSSION = 4 + SYNC_TASK_ASSIGNMENT = 5 + ASYNC_TASK_ASSIGNMENT = 6 + INFORM_TASK_RESULT = 7 + INFORM_TASK_PROGRESS = 8 + PAUSE = 9 + CONCLUDE_GROUP_DISCUSSION = 10 + CONCLUSION = 11 + + +COMMUNICATION_TYPE_MAP = { + "discussion": CommunicationType.DISCUSSION, + "sync_task_assign": CommunicationType.SYNC_TASK_ASSIGNMENT, + "async_task_assign": CommunicationType.ASYNC_TASK_ASSIGNMENT, + "pause": CommunicationType.PAUSE, + "conclude_group_discussion": CommunicationType.CONCLUDE_GROUP_DISCUSSION, +} + + +class CommunicationInfo(BaseModel): + comm_id: str + goal: str + team_members: list[dict] + memory: Any + state: CommunicationState = CommunicationState.TEAMUP + tool_memory: list[LLMResult] = [] + is_task_assigned: bool = False + conclusion: str | None = None + team_up_depth: int | None = None + is_collaborative_planning_enabled: bool = False + max_turns: int | None = None + curr_turn: int = 0 + + +class AgentMessage(BaseModel): + content: str = "" + sender: str = "" + comm_id: str = "" + next_speaker: str | list[str] = "" + # protocol: str = "" + state: CommunicationState = CommunicationState.TEAMUP + type: CommunicationType = CommunicationType.DEFAULT + proposal_id: str = "" + # Below are for the first message after teaming up + goal: str | None = None + team_members: list[dict] | None = None + team_up_depth: int | None = None + # properties for task manager + task_id: str = "" + task_desc: str = "" + # task_input: str|None=None + task_conclusion: str = "" + task_abstract: str = "" + # pause+trigger + # async task ids as triggers for PAUSE Type AgentMessage + triggers: list[str] = [] + # Dynamic_Collaborative_Planner + updated_plan: str = "" + is_collaborative_planning_enabled: bool = False + # timestamp: str = Field(default_factory=lambda: str(datetime.now())) + max_turns: int | None = None + + def to_llm_result(self): + return LLMResult(content=self.content, role="assistant", name=self.sender) diff --git a/common/types/llm.py b/common/types/llm.py new file mode 100644 index 0000000..4e32b2d --- /dev/null +++ b/common/types/llm.py @@ -0,0 +1,104 @@ +from copy import deepcopy +import json +from pydantic import BaseModel +from openai.types.chat import ChatCompletionMessageToolCall +from common.utils.json_utils import JsonRepair + + +class LLMResult(BaseModel): + content: None | str | dict = "" + role: str = "" + name: str = "" + tool_calls: list[ChatCompletionMessageToolCall] | None = None + parsed_tool_calls: list[ChatCompletionMessageToolCall] | None = None # arguments are parsed into python objects + tool_call_id: str | None = None + send_tokens: int = 0 + recv_tokens: int = 0 + total_tokens: int = 0 + + def __init__(self, **data): + super().__init__(**data) + if self.tool_calls: + parsed_tool_calls = [] + + for tool_call in self.tool_calls: + tool_call_ = deepcopy(tool_call) + tool_call_.function.arguments = json.loads(JsonRepair(tool_call_.function.arguments).repair()) + if tool_call_.function.arguments is None: + tool_call_.function.arguments = {} + parsed_tool_calls.append(tool_call_) + self.parsed_tool_calls = parsed_tool_calls + + def to_openai_message(self, add_name_prefix: bool = False): + def _get_content(): + if add_name_prefix: + return f"[{self.name}]: {self.content}" + else: + return self.content + + match self.role: + # is user of system + case "user" | "system": + return { + "role": self.role, + "content": _get_content(), + } + case "assistant": + result = {"role": self.role, "content": _get_content()} + if self.tool_calls is not None: + result["tool_calls"] = self.tool_calls + # if "type" not in result["tool_calls"]: + # result["tool_calls"]["type"] = "function" + return result + case "tool": + return { + "role": self.role, + "content": _get_content(), + "tool_call_id": self.tool_call_id, + } + case _: + raise ValueError(f"Invalid role: {self.role}") + + def __eq__(self, other): + if not isinstance(other, LLMResult): + return False + result = True + try: + result &= self.content == other.content + except Exception: + try: + result &= str(self.content) == str(self.content) + except Exception: + raise ValueError("The `content` field is not comparable") + result &= self.role == other.role + result &= self.name == other.name + if self.tool_calls is not None or other.tool_calls is not None: + result &= not (self.tool_calls is None or other.tool_calls is None) + if not result: + return False + result &= len(self.tool_calls) == len(other.tool_calls) + for t1, t2 in zip(self.tool_calls, other.tool_calls): + result &= t1.id == t2.id + result &= t1.function.arguments == t2.function.arguments + result &= t1.function.name == t2.function.name + if self.tool_call_id is not None or other.tool_call_id is not None: + result &= not (self.tool_call_id is None or other.tool_call_id is None) + if not result: + return False + result &= self.tool_call_id == other.tool_call_id + return result + + def __hash__(self): + return hash( + ( + self.content, + self.role, + self.name, + ( + ((t.id, t.function.arguments, t.function.name) for t in self.tool_calls) + if self.tool_calls is not None + else tuple() + ), + self.tool_call_id, + ) + ) diff --git a/common/types/server.py b/common/types/server.py new file mode 100644 index 0000000..7701be5 --- /dev/null +++ b/common/types/server.py @@ -0,0 +1,26 @@ +from __future__ import annotations +from pydantic import BaseModel + + +class AgentRegistryRetrivalParam(BaseModel): + sender: str + capabilities: list[str] + + +class AgentRegistryTeamupParam(BaseModel): + sender: str + agent_names: list[str] + team_name: str | None = None + + +class AgentRegistryTeamupOutput(BaseModel): + comm_id: str + agent_names: list[str] + + +class AgentRegistryQueryParam(BaseModel): + name: str | list[str] + + +class ChatRecordFetchParam(BaseModel): + comm_id: str | list[str] | None = None diff --git a/common/types/task.py b/common/types/task.py new file mode 100644 index 0000000..1684bf3 --- /dev/null +++ b/common/types/task.py @@ -0,0 +1,8 @@ +from pydantic import BaseModel + + +class TaskInfo(BaseModel): + comm_id: str + goal: str + teammates: list[str] + created_at: str diff --git a/common/utils/__init__.py b/common/utils/__init__.py new file mode 100644 index 0000000..57e6671 --- /dev/null +++ b/common/utils/__init__.py @@ -0,0 +1 @@ +from .type_utils import Singleton diff --git a/common/utils/database_utils.py b/common/utils/database_utils.py new file mode 100644 index 0000000..566d575 --- /dev/null +++ b/common/utils/database_utils.py @@ -0,0 +1,200 @@ +from __future__ import annotations +from sqlitedict import SqliteDict, decode, encode, identity +import os +from abc import ABC, abstractmethod +from typing import Union, Type +from pydantic import BaseModel + + +class Serializable(ABC): + @abstractmethod + def to_dict(self) -> dict: + raise NotImplementedError("Subclasses must implement this method") + + @classmethod + @abstractmethod + def from_dict(cls, data: dict) -> Serializable: + raise NotImplementedError("Subclasses must implement this method") + + def __eq__(self, other): + if isinstance(other, self.__class__): + return self.to_dict() == other.to_dict() + return False + + +class AutoStoredDict(SqliteDict): + """ + A dictionary-like interface providing an automatic way to store and retrieve + objects that are instances of Serializable or BaseModel directly from a SQLite database. + This class extends SqliteDict to handle complex objects by serializing them before storing + and deserializing them when retrieving. + + The AutoStoredDict is particularly useful for applications that require persistence + of complex data structures that go beyond simple key-value pairs, allowing + efficient storage and retrieval of models and data objects directly from the database. + + Attributes: + object_type (Type[Union[Serializable, BaseModel]] | None): Specifies the type of objects + this dictionary will manage. This type must either be a subclass of Serializable or a + subclass of BaseModel, which are used to perform the correct serialization and + deserialization operations. If None, the dictionary will manage simple data types that + do not require serialization or deserialization (e.g., int, str, float, dict). + + Args: + filename (str): The path to the SQLite database file. + tablename (str): The name of the table within the database to store the dictionary items. + object_type (Type[Union[Serializable, BaseModel]] | None, optional): The class type of the objects + to be stored, which must include serialization and deserialization methods. If set to None, the + dictionary will handle only simple data types directly (such as int, str, float, dict), which do + not require complex serialization or deserialization processes. Defaults to None. + from_dict_hook : Custom hook to define the way of deserialization. Defaults to None. + **kwargs: Additional keyword arguments to be passed to the SqliteDict constructor. + + Examples: + # Importing necessary classes + >>> from pydantic import BaseModel + + # Define a Pydantic model + >>> class MyModel(BaseModel): + >>> name: str + >>> age: int + + # Define a class that implements the Serializable interface + >>> class MySerializable(Serializable): + >>> def __init__(self, data): + >>> self.data = data + >>> def to_dict(self) -> dict: + >>> return {"data": self.data} + >>> @classmethod + >>> def from_dict(cls, data: dict) -> 'MySerializable': + >>> return cls(data['data']) + >>> def __str__(self): + >>> return f"MySerializable(data={self.data})" + + # Create an instance of AutoStoredDict for MyModel + >>> db_model = AutoStoredDict(filename='mydatabase.sqlite', tablename='mymodels', object_type=MyModel) + >>> db_model['alice'] = MyModel(name='Alice', age=30) + >>> print(db_model['alice']) + MyModel(name='Alice', age=30) + + # Create an instance of AutoStoredDict for MySerializable + >>> db_serializable = AutoStoredDict(filename='mydatabase.sqlite', tablename='mydata', object_type=MySerializable) + >>> db_serializable['item1'] = MySerializable("Example data") + >>> print(db_serializable['item1']) + MySerializable(data=Example data) + """ + + def __init__( + self, + filename: str, + tablename: str, + object_type: Type[Union[Serializable, BaseModel]] | None = None, + from_dict_hook=None, + **kwargs, + ): + self.object_type = object_type + self.from_dict_hook = from_dict_hook + os.makedirs(os.path.dirname(filename.rstrip("/")), exist_ok=True) + super().__init__(filename, tablename, flag="c", autocommit=True, **kwargs) + + def keys(self): + return [x for x in self.iterkeys()] + + def values(self): + return [self.__getitem__(key) for key in self.iterkeys()] + + def items(self): + return [(key, self.__getitem__(key)) for key in self.iterkeys()] + + def __setitem__(self, key, value): + # return super().__setitem__(key, value) + if isinstance(value, Serializable): + super().__setitem__(key, value.to_dict()) + elif isinstance(value, BaseModel): + super().__setitem__(key, value.model_dump()) + else: + super().__setitem__(key, value) + + def __getitem__(self, key): + item = super().__getitem__(key) + if isinstance(item, dict) and self.object_type: + if issubclass(self.object_type, BaseModel): + if self.from_dict_hook != None: + return self.from_dict_hook(item) + else: + return self.object_type.model_validate(item) + elif issubclass(self.object_type, Serializable): + if self.from_dict_hook != None: + return self.from_dict_hook(item) + else: + return self.object_type.from_dict(item) + return item + + def todict(self): + return {k: v for k, v in self.iteritems()} + + def __str__(self): + return str(self.todict()) + + def __eq__(self, other): + if isinstance(other, AutoStoredDict): + return self.todict() == other.todict() + return False + + +class AutoStoredSet: + def __init__(self, filename, tablename, set_name="__set") -> None: + self.dbdict = AutoStoredDict(filename, tablename) + self.set_name = set_name + if set_name in self.dbdict: + # print('loading') + self.data = self.dbdict[f"{self.set_name}"] + else: + # print('creating') + self.data = set() + self.dbdict[f"{set_name}"] = set() + + def save_db(self): + self.dbdict[f"{self.set_name}"] = self.data + + def load_db(self): + self.data = self.dbdict[f"{self.set_name}"] + + def add(self, item): + self.load_db() + self.data.add(item) + self.save_db() + + def remove(self, item): + self.load_db() + self.data.remove(item) + self.save_db() + + def clear(self): + self.data.clear() + self.save_db() + + def discard(self, item): + self.load_db() + self.data.discard(item) + self.save_db() + + def __eq__(self, value) -> bool: + self.load_db() + return self.data == value + + def __contains__(self, value): + self.load_db() + return value in self.data + + def __iter__(self): + self.load_db() + return iter(self.data) + + def __str__(self) -> str: + self.load_db() + return str(self.data) + + def replace(self, other): + self.data = set(other) + self.save_db() diff --git a/common/utils/json_utils.py b/common/utils/json_utils.py new file mode 100644 index 0000000..ad63f79 --- /dev/null +++ b/common/utils/json_utils.py @@ -0,0 +1,636 @@ +# jsonrepair.py - Repair invalid JSON documents in Python +# +# Just https://github.com/josdejong/jsonrepair ported from TypeScript to Python. +# +# This port won't get updates, because the goal should be to generate this library instead. +# +# See: https://github.com/josdejong/jsonrepair/issues/84 +# + +import json +import re +from typing import Optional + +CONTROL_CHARACTERS = {"\b": "\\b", "\f": "\\f", "\n": "\\n", "\r": "\\r", "\t": "\\t"} + +ESCAPE_CHARACTERS = { + '"': '"', + "\\": "\\", + "/": "/", + "b": "\b", + "f": "\f", + "n": "\n", + "r": "\r", + "t": "\t", + # note that \u is handled separately in parseString() +} + + +def remove_at_index(text: str, start: int, count: int) -> str: + return text[0:start] + text[start + count :] + + +def is_control_character(char: str) -> bool: + return char in CONTROL_CHARACTERS + + +def is_valid_string_character(char: str) -> bool: + return 0x20 <= ord(char) <= 0x10FFFF + + +def is_quote(char: str) -> bool: + return is_single_quote(char) or is_double_quote(char) + + +def is_single_quote(char: str) -> bool: + """Test whether the given character is a single quote character. + Also tests for special variants of single quotes. + """ + return char in ( + "'", # U+0027 + "‘", # U+2018 + "’", # U+2019 + "`", # U+0060 + "´", # U+00B4 + ) + + +def is_double_quote(char: str) -> bool: + return is_ascii_double_quote(char) or is_double_quote_left(char) or is_double_quote_right(char) + + +def is_ascii_double_quote(char: str) -> bool: + return char == '"' # U+0022 + + +def is_double_quote_left(char: str) -> bool: + return char == "“" # U+201C + + +def is_double_quote_right(char: str) -> bool: + return char == "”" # U+201D + + +def is_start_of_value(char: str) -> bool: + regex_start_of_value = r"^[[{\w-]$" # alpha, number, minus, or opening bracket or brace + return bool(re.search(regex_start_of_value, char)) or is_quote(char) + + +def ends_with_comma_or_newline(text: str) -> bool: + return bool(re.search(r"[,\n][ \t\r]*$", text)) + + +def is_whitespace(char: str) -> bool: + return char.isspace() + + +def is_special_whitespace(char: str) -> bool: + """Check if the given character is a special whitespace character, some unicode variant""" + return ( + char == "\u00a0" # non-breaking space + or ord("\u2000") <= ord(char) <= ord("\u200a") + or char == "\u202f" + or char == "\u205f" + or char == "\u3000" + ) + + +def insert_before_last_whitespace(text: str, text_to_insert: str) -> str: + index = len(text) + + if not is_whitespace(text[index - 1]): + # no trailing whitespaces + return text + text_to_insert + + while is_whitespace(text[index - 1]): + index -= 1 + + return text[:index] + text_to_insert + text[index:] + + +def strip_last_occurrence(text: str, text_to_strip: str, strip_remaining: bool = False) -> str: + index = text.rindex(text_to_strip) + try: + return text[:index] + ("" if strip_remaining else text[index + 1 :]) + except ValueError: + return text + + +def is_hex(char: str) -> bool: + try: + int(char, 16) + return True + except ValueError: + return False + + +def is_delimiter(char: str) -> bool: + return char in ",:[]{}()\n'" or is_quote(char) + + +def at_end_of_block_comment(text: str, i: int) -> bool: + return text[i] == "*" and text[i + 1] == "/" + + +class JsonRepairError(Exception): + def __init__(self, message: str, position: int): + super(JsonRepairError, self).__init__(message + f" at position {position}") + self.position = position + + +class JsonRepair: + """Repairs invalid JSON, i.e. change JavaScript notation into JSON notation. + + Example: + + try: + json = "{name: 'John'}" + repaired = JsonRepair(json).repair() + print(repaired) + # '{"name": "John"}' + except JsonRepairFailed as err: + print(err) + + """ + + def __init__(self, text: str): + self.text = text + self.i = 0 # current index in text + self.output = "" # generated output + + def char(self, pos: int = 0) -> str: + return self.text[self.i + pos] + + def inc(self, by: int = 1) -> None: + self.i += by + + def dec(self, by: int = 1) -> None: + self.i -= by + + def is_start_of_document(self, pos: int = 0) -> bool: + return self.i + pos == 0 + + def is_end_of_document(self, pos: int = 0) -> bool: + return self.i + pos >= len(self.text) + + def repair(self) -> str: + processed = self.parse_value() + if not processed: + raise self.unexpected_end() + + processed_comma = self.parse_character(",") + if processed_comma: + self.parse_whitespace_and_skip_comments() + + if not self.is_end_of_document() and is_start_of_value(self.char()) and ends_with_comma_or_newline(self.output): + # start of a new value after end of the root level object: looks like + # newline delimited JSON -> turn into a root level array + if not processed_comma: + # repair missing comma + self.output = insert_before_last_whitespace(self.output, ",") + + self.parse_newline_delimited_json() + elif processed_comma: + # repair: remove trailing comma + self.output = strip_last_occurrence(self.output, ",") + + if self.is_end_of_document(): + # reached the end of the document properly + return self.output + + raise self.unexpected_character() + + def parse_value(self) -> bool: + self.parse_whitespace_and_skip_comments() + processed = ( + self.parse_object() + or self.parse_array() + or self.parse_string() + or self.parse_number() + or self.parse_keywords() + or self.parse_unquoted_string() + ) + self.parse_whitespace_and_skip_comments() + return processed + + def parse_whitespace_and_skip_comments(self) -> bool: + start = self.i + + changed = self.parse_whitespace() + while True: + changed = self.parse_comment() + if changed: + changed = self.parse_whitespace() + if not changed: + break + + return self.i > start + + def parse_whitespace(self) -> bool: + whitespace = "" + + while not self.is_end_of_document(): + char = self.char() + + normal = is_whitespace(char) + special = is_special_whitespace(char) + + if not normal and not special: + break + + if special: + whitespace += " " # repair special whitespace + else: + whitespace += char + + self.inc() + + if whitespace: + self.output += whitespace + return True + return False + + def parse_comment(self) -> bool: + # find a block comment '/* ... */' + if not self.is_end_of_document() and not self.is_end_of_document(pos=+1): + if self.char() == "/" and self.char(pos=+1) == "*": + # repair block comment by skipping it + while not self.is_end_of_document() and not at_end_of_block_comment(self.text, self.i): + self.inc() + self.inc(by=2) + return True + + # find a line comment '// ...' + if self.char() == "/" and self.char(pos=+1) == "/": + # repair line comment by skipping it + while not self.is_end_of_document() and self.char() != "\n": + self.inc() + return True + + return False + + def parse_character(self, char: str) -> bool: + if not self.is_end_of_document(): + if self.char() == char: + self.output += char + self.inc() + return True + return False + + def skip_character(self, char: str) -> bool: + if not self.is_end_of_document() and self.char() == char: + self.inc() + return True + return False + + def skip_escape_character(self) -> bool: + return self.skip_character("\\") + + def parse_object(self) -> bool: + """Parse an object like '{"key": "value"}'""" + if not self.is_end_of_document() and self.char() == "{": + self.output += "{" + self.inc() + self.parse_whitespace_and_skip_comments() + + initial = True + while not self.is_end_of_document() and self.char() != "}": + if not initial: + processed_comma = self.parse_character(",") + if not processed_comma: + # repair missing comma + self.output = insert_before_last_whitespace(self.output, ",") + self.parse_whitespace_and_skip_comments() + else: + processed_comma = True + initial = False + + processed_key = self.parse_string() or self.parse_unquoted_string() + if not processed_key: + if self.is_end_of_document() or self.char() in "{}[]": + # repair trailing comma + self.output = strip_last_occurrence(self.output, ",") + break + raise self.object_key_expected() + + self.parse_whitespace_and_skip_comments() + processed_colon = self.parse_character(":") + if not processed_colon: + if is_start_of_value(self.char()): + # repair missing colon + self.output = insert_before_last_whitespace(self.output, ":") + else: + raise self.colon_expected() + processed_value = self.parse_value() + if not processed_value: + if processed_colon: + raise self.object_value_expected() + raise self.colon_expected() + + if not self.is_end_of_document() and self.char() == "}": + self.output += "}" + self.inc() + else: + # repair missing end bracket + self.output = insert_before_last_whitespace(self.output, "}") + + return True + + return False + + def parse_array(self) -> bool: + """Parse an array like '["item1", "item2", ...]'""" + if not self.is_end_of_document() and self.char() == "[": + self.output += "[" + self.inc() + self.parse_whitespace_and_skip_comments() + + initial = True + while not self.is_end_of_document() and self.char() != "]": + if not initial: + processed_comma = self.parse_character(",") + if not processed_comma: + # repair missing comma + self.output = insert_before_last_whitespace(self.output, ",") + else: + initial = False + + processed_value = self.parse_value() + if not processed_value: + # repair trailing comma + self.output = strip_last_occurrence(self.output, ",") + break + + if not self.is_end_of_document() and self.char() == "]": + self.output += "]" + self.inc() + else: + # repair missing closing array bracket + self.output = insert_before_last_whitespace(self.output, "]") + + return True + + return False + + def parse_newline_delimited_json(self): + """Parse and repair Newline Delimited JSON (NDJSON): + multiple JSON objects separated by a newline character + """ + # repair NDJSON + initial = True + processed_value = True + while processed_value: + if not initial: + # parse optional comma, insert when missing + processed_comma = self.parse_character(",") + if not processed_comma: + # repair: add missing comma + self.output = insert_before_last_whitespace(self.output, ",") + else: + initial = False + + processed_value = self.parse_value() + + if not processed_value: + # repair: remove trailing comma + self.output = strip_last_occurrence(self.output, ",") + + # repair: wrap the output inside array brackets + self.output = f"[\n{self.output}\n]" + + def parse_string(self) -> bool: + """Parse a string enclosed by double quotes "...". Can contain escaped quotes + Repair strings enclosed in single quotes or special quotes + Repair an escaped string + """ + if not self.is_end_of_document(): + skip_escape_chars = self.char() == "\\" + if skip_escape_chars: + # repair: remove the first escape character + self.inc() + skip_escape_chars = True + + if not self.is_end_of_document() and is_quote(self.char()): + is_end_quote = is_single_quote if is_single_quote(self.char()) else is_double_quote + + if self.char() != '"': + pass # TODO?: repair non-normalized quote + self.output += '"' + self.inc() + + while not self.is_end_of_document() and not is_end_quote(self.char()): + if self.char() == "\\": + char = self.char(pos=+1) + escape_char = ESCAPE_CHARACTERS.get(char) + if escape_char: + self.output += self.text[self.i : self.i + 2] + self.inc(by=2) + elif char == "u": + if ( + not self.is_end_of_document(pos=+5) + and is_hex(self.char(pos=+2)) + and is_hex(self.char(pos=+3)) + and is_hex(self.char(pos=+4)) + and is_hex(self.char(pos=+5)) + ): + self.output += self.text[self.i : self.i + 6] + self.inc(by=6) + else: + raise self.invalid_unicode_character(self.i) + else: + # repair invalid escape character: remove it + self.output += char + self.inc(by=2) + else: + char = self.char() + + if char == '"' and self.char(pos=-1) != "\\": + # repair unescaped double quote + self.output += "\\" + char + self.inc() + elif is_control_character(char): + # unescaped control character + self.output += CONTROL_CHARACTERS[char] + self.inc() + else: + if not is_valid_string_character(char): + raise self.invalid_character(char) + self.output += char + self.inc() + + if skip_escape_chars: + processed = self.skip_escape_character() + if processed: + pass # repair: skipped escape character (nothing to do) + + if not self.is_end_of_document() and is_quote(self.char()): + if self.char() != '"': + pass # TODO:? repair non-normalized quote + + self.output += '"' + self.inc() + else: + # repair missing end quote + self.output += '"' + + self.parse_concatenated_string() + + return True + + return False + + def parse_concatenated_string(self) -> bool: + """Repair concatenated strings like \"hello\" + \"world\", change this into \"helloworld\" """ + processed = False + + self.parse_whitespace_and_skip_comments() + while not self.is_end_of_document() and self.char() == "+": + processed = True + self.inc() + self.parse_whitespace_and_skip_comments() + + # repair: remove the end quote of the first string + self.output = strip_last_occurrence(self.output, '"', True) + start = len(self.output) + self.parse_string() + + # repair: remove the start quote of the second string + self.output = remove_at_index(self.output, start, 1) + + return processed + + def parse_number(self) -> bool: + """Parse a number like 2.4 or 2.4e6""" + if not self.is_end_of_document(): + start = self.i + if self.char() == "-": + self.inc() + err = self.expect_digit(start) + if err: + raise err + + if not self.is_end_of_document() and self.char() == "0": + self.inc() + elif not self.is_end_of_document() and self.char() in "123456789": + self.inc() + while not self.is_end_of_document() and self.char().isdigit(): + self.inc() + + if not self.is_end_of_document() and self.char() == ".": + self.inc() + err = self.expect_digit(start) + if err: + raise err + while not self.is_end_of_document() and self.char().isdigit(): + self.inc() + + if not self.is_end_of_document() and self.char() in "eE": + self.inc() + if not self.is_end_of_document() and self.char() in "+-": + self.inc() + err = self.expect_digit(start) + if err: + raise err + while not self.is_end_of_document() and self.char().isdigit(): + self.inc() + + if self.i > start: + self.output += self.text[start : self.i] + return True + + return False + + def parse_keywords(self) -> bool: + """Parse keywords true, false, null + Repair Python keywords True, False, None + """ + return ( + self.parse_keyword("true", "true") + or self.parse_keyword("false", "false") + or self.parse_keyword("null", "null") + # repair Python keywords True, False, None + or self.parse_keyword("True", "true") + or self.parse_keyword("False", "false") + or self.parse_keyword("None", "null") + ) + + def parse_keyword(self, name: str, value: str) -> bool: + if self.text[self.i : self.i + len(name)] == name: + self.output += value + self.inc(by=len(name)) + return True + + return False + + def parse_unquoted_string(self) -> bool: + """Repair and unquoted string by adding quotes around it + Repair a MongoDB function call like NumberLong("2") + Repair a JSONP function call like callback({...}); + """ + # note that the symbol can end with whitespaces: we stop at the next delimiter + start = self.i + while not self.is_end_of_document() and not is_delimiter(self.char()): + self.inc() + + if self.i > start: + if not self.is_end_of_document() and self.char() == "(": + # repair a MongoDB function call like NumberLong("2") + # repair a JSONP function call like callback({...}); + self.inc() + + self.parse_value() + + if not self.is_end_of_document() and self.char() == ")": + # repair: skip close bracket of function call + self.inc() + if not self.is_end_of_document() and self.char() == ";": + # repair: skip semicolon after JSONP call + self.inc() + + return True + + # else repair unquoted string + + # first, go back to prevent getting trailing whitespaces in the string + while not self.is_start_of_document() and is_whitespace(self.char(pos=-1)): + self.dec() + + symbol = self.text[start : self.i] + self.output += json.dumps(symbol) + + return True + + return False + + def expect_digit(self, start: int) -> Optional[JsonRepairError]: + if self.is_end_of_document() or not self.char().isdigit(): + num_so_far = self.text[start : self.i] + return JsonRepairError(f"Invalid number '{num_so_far}', expecting a digit {self.got()}", 2) + + def invalid_character(self, char: str) -> JsonRepairError: + return JsonRepairError("Invalid character " + json.dumps(char), self.i) + + def unexpected_character(self) -> JsonRepairError: + return JsonRepairError("Unexpected character " + json.dumps(self.text[self.i]), self.i) + + def unexpected_end(self) -> JsonRepairError: + return JsonRepairError("Unexpected end of json string", len(self.text)) + + def object_key_expected(self) -> JsonRepairError: + return JsonRepairError("Object key expected", self.i) + + def object_value_expected(self) -> JsonRepairError: + return JsonRepairError("Object value expected", self.i) + + def colon_expected(self) -> JsonRepairError: + return JsonRepairError("Colon expected", self.i) + + def invalid_unicode_character(self, start: int) -> JsonRepairError: + end = start + 2 + while re.match(r"\w", self.text[end]): + end += 1 + chars = self.text[start:end] + return JsonRepairError(f'Invalid unicode character "{chars}"', self.i) + + def got(self) -> str: + return f"but got '{self.char()}'" if not self.is_end_of_document() else "but reached end of input" diff --git a/common/utils/milvus_utils.py b/common/utils/milvus_utils.py new file mode 100644 index 0000000..12e6e52 --- /dev/null +++ b/common/utils/milvus_utils.py @@ -0,0 +1,304 @@ +from pymilvus import ( + utility, + connections, + CollectionSchema, + FieldSchema, + DataType, + Collection, +) +import yaml + +# import logging +from common.log import logger +import os +from openai import OpenAI +from typing import List +import asyncio, json +from tenacity import retry, stop_after_attempt, wait_exponential + +openai_engine = "text-embedding-ada-002" +VECTOR_DIMENSION = 1536 +client = OpenAI() + +# MilvusConfPath = os.path.join(os.path.dirname(__file__), "..", "config", "vecdb") + +MilvusDType = { + "INT64": DataType.INT64, + "INT32": DataType.INT32, + "INT16": DataType.INT16, + "INT8": DataType.INT8, + "BOOL": DataType.BOOL, + "VARCHAR": DataType.VARCHAR, + "FLOAT": DataType.FLOAT, + "DOUBLE": DataType.DOUBLE, + "JSON": DataType.JSON, + #'ARRAY': DataType.ARRAY, + "FLOAT_VECTOR": DataType.FLOAT_VECTOR, + "BINARY_VECTOR": DataType.BINARY_VECTOR, +} + + +class MilvusWrapper(Collection): + def __init__( + self, + name, + schema, + using="default", + consistence_level="Strong", + shards_num=2, + auto_vectorized_fields=[], + search_config={}, + index_config={}, + create_index=False, + hide_keys=False, + ) -> None: + if utility.has_collection(name): + logger.info(f"Loading from exsisting collection {name}.") + else: + logger.info(f"Creating new collection {name}") + + super().__init__( + name=name, + schema=schema, + using=using, + shards_num=shards_num, + consistency_level=consistence_level, + ) + + self.search_config = search_config + self.index_config = index_config + + if create_index and self.index_config != {}: + self.create_index(**list(self.index_config.values())[0]) + + self.fields = [f.name for f in schema.fields] + self.auto_vectorized_fields = auto_vectorized_fields + + self.show_fields = self.fields[: (len(self.fields) - len(self.auto_vectorized_fields))] + if hide_keys: + self.show_fields.remove(self.primary_field.name) + # print(self.show_fields) + assert len(self.auto_vectorized_fields) <= 1 + self.auto_vec_index = [self.fields.index(field) for field in self.auto_vectorized_fields] + + # data format transfer functions + def _dicts_to_input_list(self, dict_data): + if isinstance(dict_data, list) and all(isinstance(jd, dict) for jd in dict_data): + return [[jd[key] for jd in dict_data] for key in dict_data[0]] + return [[v] for k, v in dict_data.items()] + + def _lists_to_input_list(self, list_data): + if isinstance(list_data, list) and all(isinstance(ld, list) for ld in list_data): + return [[ld[i] for ld in list_data] for i in range(len(list_data[0]))] + return [[v] for v in list_data] + + def _objects_to_dict(self, obj): + if isinstance(obj, list): + return [x.__dict__ for x in obj] + return obj.__dict__ + + def _reformat(self, data): + if isinstance(data, dict): + return self._dicts_to_input_list(data) + elif isinstance(data, list): + if isinstance(data[0], (int, str)): + return self._lists_to_input_list(data) + else: + assert all(isinstance(element, type(data[0])) for element in data) + if isinstance(data[0], dict): + return self._dicts_to_input_list(data) + elif isinstance(data[0], list): + return self._lists_to_input_list(data) + return self._dicts_to_input_list(self._objects_to_dict(data)) + return self._dicts_to_input_list(self._objects_to_dict(data)) + + def _reformat_and_vectorize(self, data): + data = self._reformat(data) + for index, _ in zip(self.auto_vec_index, self.auto_vectorized_fields): + text = data[index] + vector = self._get_embedding_for_text(text) + data.append(vector) + return data + + @retry( + stop=stop_after_attempt(5), + reraise=True, + wait=wait_exponential(multiplier=1, min=1, max=10), + ) + def _get_embedding_for_text(self, text: List[str]): + embeddings = client.embeddings.create(input=text, model=openai_engine, encoding_format="float") + return [x.embedding for x in embeddings.data] + + def _primary_field_query(self, key, output_fields): + self.load() + if self.primary_field.dtype == DataType.VARCHAR: + expr = f'{self.primary_field.name} == "{key}"' + else: + expr = f"{self.primary_field.name} == {key}" + res = self.query(expr=expr, output_fields=output_fields, consistency_level="Strong") + return res + + def __setitem__(self, key, value): + # automatically add key field into data + if isinstance(value, list): + assert len(value) < len(self.fields) + value = [key, *value] + elif isinstance(value, dict): + assert self.primary_field.name not in value + value = {f"{self.primary_field.name}": key, **value} + else: + assert self.primary_field.name not in self._objects_to_dict(value) + value = {f"{self.primary_field.name}": key, **self._objects_to_dict(value)} + return self.upsert_data(value) + + def __getitem__(self, key): + res = self._primary_field_query(key, ["*"]) + return {f: res[0][f] for f in self.show_fields} + + def __contains__(self, key): + res = self._primary_field_query(key, []) + return res != [] + + def keys(self): + self.load() + count = self.__len__() + if count > 0: + res = self.query(expr="", output_fields=[], limit=count, consistency_level="Strong") + return [x[f"{self.primary_field.name}"] for x in res] + return [] + + def items(self): + self.load() + count = self.__len__() + if count > 0: + res = self.query(expr="", output_fields=["*"], limit=count, consistency_level="Strong") + return [{f: x[f] for f in self.show_fields} for x in res] + return [] + + def __len__(self): + res = self.query(expr="", output_fields=["count(*)"], consistency_level="Strong") + return res[0]["count(*)"] + + def remove(self, key): + if self.primary_field.dtype == DataType.VARCHAR: + expr = f"{self.primary_field.name} == '{key}'" + else: + expr = f"{self.primary_field.name} == {key}" + self.delete(expr) + + # input: list, obj, json, list[list], list[obj], list[json] + def insert_data(self, data): + data = self._reformat_and_vectorize(data) + return self.insert(data) + + def upsert_data(self, data): + data = self._reformat_and_vectorize(data) + # dict_data = {f: data[i] for i, f in enumerate(self.fields)} + return self.upsert(data) + + def get_search_config(self, name): + if name in self.search_config: + return self.search_config[name] + raise KeyError(f"Search config named {name} does not exist.") + + def search_via_config(self, data, name=None): + self.load() + if self.search_config == {}: + raise RuntimeError("Search configuration is empty.") + name = name or next(iter(self.search_config)) + if name not in self.search_config: + raise KeyError(f"Search config named {name} does not exist.") + if self.search_config[name].get("auto_vectorize", False): + data = self._get_embedding_for_text(data) + res = self.search(data, **self.search_config[name]["search_params"]) + return [ + [{f: hit.entity.get(f) for f in self.search_config[name]["search_params"]["output_fields"]} for hit in hits] + for hits in res + ] + + def index_via_config(self, name=None): + if self.index_config == {}: + raise RuntimeError("Index configuration is empty.") + name = name or next(iter(self.index_config)) + if name not in self.index_config: + raise KeyError(f"Index config named {name} does not exist.") + return self.create_index(**self.index_config[name]) + + +class ConfigMilvusWrapper(MilvusWrapper): + def __init__(self, config_path, name_modify=None, connection_modify=None) -> None: + # config_path = os.path.join(MilvusConfPath, config_path) + with open(config_path, "r") as f: + self.config = yaml.safe_load(f) + + if name_modify != None: + self.config["name"] = name_modify + + # config for schemas + schema_config = self.config["collectionSchema"] + fields = [] + auto_vectorized_fields = [] + for field_config in schema_config["fields"]: + field_config = self._adapt_field_config(field_config) + if field_config.pop("auto_vectorize", False): + auto_vectorized_fields.append(field_config["name"]) + field_schema = FieldSchema(**field_config) + fields.append(field_schema) + + # adding auto-vectorized fields + for field_name in auto_vectorized_fields: + vec_field_name = field_name + "_vec" + field_schema = FieldSchema( + **{ + "name": vec_field_name, + "dtype": DataType.FLOAT_VECTOR, + "dim": VECTOR_DIMENSION, + } + ) + fields.append(field_schema) + + schema_config["fields"] = fields + schema = CollectionSchema(**schema_config) + + # config for database connection + conn = connection_modify or self.config["using"] + + # config for search + search_config = {} + if "search" in self.config: + search_config = {d.pop("name"): d for d in self.config["search"]} + + # config for index + index_config = {} + if "index" in self.config: + index_config = {d.pop("name"): d for d in self.config["index"]} + + hide_keys = self.config.get("hide_keys", False) + + super().__init__( + name=self.config["name"], + schema=schema, + using=conn, + shards_num=self.config["shards_num"], + consistence_level=self.config.get("consistence_level", "Strong"), + search_config=search_config, + index_config=index_config, + create_index=self.config.get("auto_create_index", True), + auto_vectorized_fields=auto_vectorized_fields, + hide_keys=hide_keys, + ) + + def _adapt_field_config(self, field_dict): + field_dict["dtype"] = MilvusDType[field_dict["dtype"]] + if "element_type" in field_dict: + field_dict["dtype"] = MilvusDType[field_dict["element_type"]] + return field_dict + + +# connections.connect( +# alias="default", +# user='username', +# password='password', +# host='localhost', #'host.docker.internal', +# port='19530' +# ) diff --git a/common/utils/misc.py b/common/utils/misc.py new file mode 100644 index 0000000..8c801b6 --- /dev/null +++ b/common/utils/misc.py @@ -0,0 +1,9 @@ +from common.log import logger +from tenacity import RetryCallState + + +def log_retry(retry_state: RetryCallState): + exception = retry_state.outcome.exception() + logger.warn( + f"Retrying {retry_state.fn}\nAttempt: {retry_state.attempt_number}\nException: {exception.__class__.__name__} {exception}", + ) diff --git a/common/utils/tool_utils.py b/common/utils/tool_utils.py new file mode 100644 index 0000000..b294c34 --- /dev/null +++ b/common/utils/tool_utils.py @@ -0,0 +1,18 @@ +from httpx import Cookies +from pydantic import BaseModel +from common.types.llm import LLMResult + + +class ToolResponse(BaseModel): + observation: str = "" + cookies: Cookies = None + + class Config: + arbitrary_types_allowed = True + + def to_llm_result(self, tool_call_id: str = "0") -> LLMResult: + return LLMResult( + content=self.observation, + role="tool", + tool_call_id=tool_call_id, + ) diff --git a/common/utils/type_utils.py b/common/utils/type_utils.py new file mode 100644 index 0000000..ef96eb5 --- /dev/null +++ b/common/utils/type_utils.py @@ -0,0 +1,15 @@ +import abc + + +class Singleton(abc.ABCMeta, type): + """ + Singleton metaclass for ensuring only one instance of a class. + """ + + _instances = {} + + def __call__(cls, *args, **kwargs): + """Call method for the singleton metaclass.""" + if cls not in cls._instances: + cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) + return cls._instances[cls] diff --git a/configs/client_configs/cases/gaia/code_executor.yaml b/configs/client_configs/cases/gaia/code_executor.yaml new file mode 100644 index 0000000..bf4fae1 --- /dev/null +++ b/configs/client_configs/cases/gaia/code_executor.yaml @@ -0,0 +1,30 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + agent_type: ReAct + agent_name: CodeExecutor + desc: |- + CodeExecutor can write and execute codes to solve given questions. + tools_config: tools_code_executor.yaml + image_name: react-agent + container_name: code_executor_react_agent + port: 7071 + model: gpt-4-1106-preview + max_num_steps: 8 + +comm: + name: CodeExecutor + desc: |- + The CodeExecutor agent possesses the capability to access and interact with a terminal, enabling it to execute written code directly. It is designed to assist with tasks that involve coding, calculations, data analysis, etc. Whether you need to run a complex algorithm or perform detailed computations, the CodeExecutor agent is here to help, ensuring accuracy and speed in handling your coding needs. + type: Thing Assistant + support_nested_teams: false + max_team_up_attempts: 10 + tools: + team_up_tools: configs/tools/tools_team_up.yaml + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + temperature: 0.1 diff --git a/configs/client_configs/cases/gaia/web_browser.yaml b/configs/client_configs/cases/gaia/web_browser.yaml new file mode 100644 index 0000000..49403b6 --- /dev/null +++ b/configs/client_configs/cases/gaia/web_browser.yaml @@ -0,0 +1,35 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + agent_type: ReAct + agent_name: WebBrowserAgent + desc: |- + WebBrowserAgent can access the interenet. Its key functionalities include: + + - Web Searching: Conducts comprehensive searches using various search engines to find the most relevant and recent information. + - Page Navigation: Visits and navigates through multiple webpages, capable of scrolling up and down to access content located at different parts of a webpage. + - Data Extraction: Gathers data from different online sources, including articles, reports, and databases, providing well-rounded and accurate answers. + - Real-Time Information: Retrieves the latest news, current events, and updates, ensuring that the information provided is timely and pertinent. + tools_config: tools_web_browser.yaml + image_name: react-agent + container_name: web_browser_react_agent + port: 7070 + model: gpt-4-1106-preview + max_num_steps: 6 + +comm: + name: WebBrowserAgent + desc: |- + The Web Browser Agent is an agent equipped with the capability to access and navigate the web. It excels in performing online searches, visiting webpages, and scrolling through content to gather relevant information. This agent is particularly valuable when queries require up-to-date or extensive information available only on the internet. The Web Browser Agent is ideal for tasks requiring external validation, extensive research, or real-time updates. + type: Thing Assistant + support_nested_teams: false + max_team_up_attempts: 5 + tools: + team_up_tools: configs/tools/tools_team_up.yaml + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + temperature: 0.1 diff --git a/configs/client_configs/cases/gaia/wikidata.yaml b/configs/client_configs/cases/gaia/wikidata.yaml new file mode 100644 index 0000000..98824ac --- /dev/null +++ b/configs/client_configs/cases/gaia/wikidata.yaml @@ -0,0 +1,30 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + agent_type: ReAct + agent_name: WikidataAgent + desc: |- + WikidataAgent can search the information of entities on Wikidata. + tools_config: tools_wikidata.yaml + image_name: react-agent + container_name: wikidata_react_agent + port: 7073 + model: gpt-4-1106-preview + max_num_steps: 5 + +comm: + name: WikidataAgent + desc: |- + The WikidataAgent is capable of searching for entities on Wikidata and retrieving structured information about them. This agent is particularly useful for tasks that require detailed and organized data, such as gathering factual information, verifying data, or conducting research on various topics. The WikidataAgent efficiently navigates Wikidata to provide comprehensive and accurate information, streamlining your data retrieval and research processes. + type: Thing Assistant + support_nested_teams: false + max_team_up_attempts: 10 + tools: + team_up_tools: configs/tools/tools_team_up.yaml + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + temperature: 0.1 diff --git a/configs/client_configs/cases/gaia/youtube.yaml b/configs/client_configs/cases/gaia/youtube.yaml new file mode 100644 index 0000000..6fccd80 --- /dev/null +++ b/configs/client_configs/cases/gaia/youtube.yaml @@ -0,0 +1,30 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + agent_type: ReAct + agent_name: YoutubeAgent + desc: |- + The YouTubeAgent can be tasked with searching for videos on YouTube and can analyze these videos by obtaining their transcripts. + tools_config: tools_youtube.yaml + image_name: react-agent + container_name: youtube_react_agent + port: 7072 + model: gpt-4-1106-preview + max_num_steps: 5 + +comm: + name: YoutubeAgent + desc: |- + The YouTubeAgent is equipped with the ability to search for content on YouTube and retrieve transcripts from various videos. This makes it particularly valuable for tasks that require gathering information from YouTube, such as extracting educational content, analyzing video dialogues, or summarizing key points from video presentations. The YouTubeAgent efficiently navigates YouTube to provide accurate and relevant information, enhancing your research and information-gathering processes. + type: Thing Assistant + support_nested_teams: false + max_team_up_attempts: 10 + tools: + team_up_tools: configs/tools/tools_team_up.yaml + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + temperature: 0.1 diff --git a/configs/client_configs/cases/open_instruction/autogpt.yaml b/configs/client_configs/cases/open_instruction/autogpt.yaml new file mode 100644 index 0000000..ff1affb --- /dev/null +++ b/configs/client_configs/cases/open_instruction/autogpt.yaml @@ -0,0 +1,24 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + image_name: autogpt:latest + container_name: autogpt-agent + agent_type: AutoGPT + agent_name: AutoGPT + desc: This is AutoGPT. AutoGPT is a cutting-edge AI. Unlike traditional chatbots, AutoGPT understands the goals, breaks them into smaller tasks, and leverages the internet and other tools to achieve them. + port: 8080 +comm: + name: AutoGPT + desc: |- + This is AutoGPT, which is a cutting-edge AI that can leverage web browser and file system to perform some challenging tasks. However, it might be costly to execute tasks. So be budget sensitive, and only assign challenging tasks to this assistant. + type: Thing Assistant + support_nested_teams: false + + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + # model: gpt-4-1106 + temperature: 0.1 diff --git a/configs/client_configs/cases/open_instruction/open_interpreter.yaml b/configs/client_configs/cases/open_instruction/open_interpreter.yaml new file mode 100644 index 0000000..7408703 --- /dev/null +++ b/configs/client_configs/cases/open_instruction/open_interpreter.yaml @@ -0,0 +1,24 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + image_name: open-interpreter:latest + container_name: open-interpreter-agent + agent_type: OpenInterpreter + agent_name: Open Interpreter + desc: This is Open Interpreter. It has the ability to execute code, control the terminal, and interact with online tools. + port: 7070 +comm: + name: Open Interpreter + desc: |- + This is Open Interpreter, which is an AI that can execute code, control the terminal, and interact with online tools. Tasks related to code snippet writing and execution can be assigned to this assistant. + type: Thing Assistant + support_nested_teams: false + + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + # model: gpt-4-1106 + temperature: 0.1 diff --git a/configs/client_configs/cases/paper_writing/arxiv.yaml b/configs/client_configs/cases/paper_writing/arxiv.yaml new file mode 100644 index 0000000..97f2d31 --- /dev/null +++ b/configs/client_configs/cases/paper_writing/arxiv.yaml @@ -0,0 +1,31 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + agent_type: ReAct + agent_name: Arxiv assistant + desc: |- + Arxiv assistant has access to the arxiv API. It's well suited for handling tasks related to literature review, searching latest papers by key words and so on. + You could use the `arxiv_search` function to search papers from Arxiv with some keywords, and use the `subtask_solver` function to do some necessary information processing, like summarization, analysis, and so on. However, the user and other agents do not have access to the intermediate steps and the solution that was given in `subtask_solver`. So the final answer for `submit_task` must still include these information. + The final answer to ANY given task MUST be, according to the specific task description, a complete literature review appended with a list of relevant literature collected (more than 10 related papers AND their pdf urls or arxiv ids!). + tools_config: tools_arxiv.yaml + image_name: react-agent + container_name: arxiv-react-agent + port: 7071 + model: gpt-4-1106-preview + max_num_steps: 5 + +comm: + name: ArxivAssistant + desc: |- + This is Arxiv assistant, who has access to an agent that can help searching information on Arxiv. It is well-suited for handling tasks related to literature review on specific themes, searching latest papers and so on. + type: Thing Assistant + support_nested_teams: false + + llm: + llm_type: openai-chat + # model: gpt-3.5-turbo-1106 #gpt-4-1106 + model: gpt-4-1106-preview + temperature: 0.1 diff --git a/configs/client_configs/cases/paper_writing/chengyang.yaml b/configs/client_configs/cases/paper_writing/chengyang.yaml new file mode 100644 index 0000000..c9cb3cb --- /dev/null +++ b/configs/client_configs/cases/paper_writing/chengyang.yaml @@ -0,0 +1,27 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + +comm: + name: Cheng Yang's Assistant + desc: |- + This is Cheng Yang's Assistant. Here is some information about Cheng Yang: + 1. User's Basic Information: + - Name: Cheng Yang + - Gender: Male + - Birthday: Unknown + + 2. Academic and Professional Background: + - Occupation: Associate Professor + - Institution: Beijing University of Posts and Telecommunications + - Field of Study: Graph Model, Natural Language Processing, Large Language Model + - Research Interest: Multi-agent collaboration with large language models such as GPT-4. + Cheng Yang's Assistant has no access to any search tools for literature. + support_nested_teams: false + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + temperature: 0.1 diff --git a/configs/client_configs/cases/paper_writing/chenqian.yaml b/configs/client_configs/cases/paper_writing/chenqian.yaml new file mode 100644 index 0000000..1c4d438 --- /dev/null +++ b/configs/client_configs/cases/paper_writing/chenqian.yaml @@ -0,0 +1,27 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + +comm: + name: Chen Qian's Assistant + desc: |- + This is Chen Qian's Assistant. Here is some information about Chen Qian: + 1. User's Basic Information: + - Name: Chen Qian + - Gender: Male + - Birthday: Unknown + + 2. Academic and Professional Background: + - Occupation: Postdoc + - Institution: Tsinghua University + - Field of Study: Natural Language Processing, Large Language Model + - Research Interest: Multi-agent application, such as software development with multi-agent system. + Chen Qian's Assistant has no access to any search tools for literature. + support_nested_teams: false + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + temperature: 0.1 diff --git a/configs/client_configs/cases/paper_writing/formatCraft_printer.yaml b/configs/client_configs/cases/paper_writing/formatCraft_printer.yaml new file mode 100644 index 0000000..c598d9b --- /dev/null +++ b/configs/client_configs/cases/paper_writing/formatCraft_printer.yaml @@ -0,0 +1,75 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + agent_type: ReAct + agent_name: FormatCraft Printer + desc: |- + FormatCraft Printer is a specialized assistant designed to enhance the physical presentation of academic manuscripts and documents. Upon receiving a draft, this agent could refine style, format, layout step by step and transform the draft to files in good format and layout, and print them out. The capabilities come from the professional functions to manipulate files in different formats. + Each time given a print task for for drafts (from the task inputs or description), act step by step. + 1. Each time given a print task, you should perceive the ROOT WORKSPACE by the `display_workspace_recursively` function, and make a new environment in ROOT WORKSPACE for the print job by the `make_job_environment` function. You could use the functions of `cat_text_file` and `display_workspace_recursively` during the task process. Note that if you use the write and read functions in parallel, there may be display errors. + 2. Extract BibTex formatted citations from the reference part in drafts and write them into a bib file by the `write_bib_file` function. + 3. After collecting the citekeys for citation in text from the previous bib file, reformat the main body in drafts (from the task inputs or description), cite the reference correctly and write them thoroughly and faithfully into a markdown file by the `write_into_file` function. DO NOT make the files of reference and the main body IN PARALLEL. + 3.1 mark the title of the paper, authors information in the following format (yaml-like, and each field should be string type ) as the prefix of the content: + ``` + --- + title: "" + author: + - name: "<name>" + affiliation: "<affiliation>" + email: "<email>" + --- + ``` + 3.2 Reorganize the body text with headings as APPROPRIATE according to the task description, adhering to an accurate hierarchical structure throughout. + For instance, **the Introduction section** MUST be presented as a standalone section using **ONLY ONE** level 1 heading(namely, `# Introduction`), indicating it’s not further divided into sub-sections. If there are + ``` + # Introduction + <WRITE YOUR INTRODUCTION HERE without any headings> + ``` + **If the provided draft does not meet the requirement to structure, you may alter the headings accordingly.** + 3.3 Adhere the citation syntax correctly in the main body. The citation syntax only has two forms: `@citekey` and `[@citekey]`. Citekeys need to correspond directly to the ones in the previous bib file. @citekey without brackets is an in-text citation, while the latter is an end-of-text citation. + In the previous bib file, there could be the following BibTex entry where `cao2017innovation`, `hoepman2011things` are citekeys: + @misc{cao2017innovation, + title={What is the next innovation after the internet of things?}, + author={Hung Cao}, + year={2017}, + eprint={1708.07160}, + archivePrefix={arXiv}, + primaryClass={cs.NI} + } + @misc{hoepman2011things, + title={In Things We Trust? Towards trustability in the Internet of Things}, + author={Jaap-Henk Hoepman}, + year={2011}, + eprint={1109.2637}, + archivePrefix={arXiv}, + primaryClass={cs.CR} + } + In the Markdown file, it is written like this: + `@cao2017innovation renders as an in-text citation, while end-of-text citations could also be used [@hoepman2011things; @cao2017innovation].` + And when transformed into the PDF file by `convert2LaTex_and_compile2PDF`, it will eventually be rendered as follows: + `Cao (2017) ever studied…, while some scholars held the opposite view (Hoepman, 2011; Cao, 2017).` + 4. Use the `convert2LaTex_and_compile2PDF` function to convert the bib file and the markdown file to a final digital file in good format and layout (including the LaTex documents and the corresponding PDF file). + 5. Use the `print_file` function to command the printer in the real world to print the PDF file out. + + This assistant acts as the final step in document preparation, transforming digital drafts into professionally formatted printed materials, ideal for submission, presentation, or archival purposes. + tools_config: tools_printer.yaml + image_name: latex_printer_react + container_name: FormatCraft_Printer + port: 7072 + model: gpt-4-1106-preview + +comm: + name: FormatCraft Printer + desc: |- + FormatCraft Printer is a specialized assistant designed to enhance the physical presentation of academic manuscripts and documents. This assistant acts as the final stage, enabling digital drafts to metamorphosize into professionally formatted printed materials. It is perfect for purposes of submission, presentation, or archiving. It's crucial to note that the FormatCraft Printer is designed exclusively for handling tasks related to the printing of academic manuscripts, consisting of pure text with references. **Submission of a draft** is a prerequisite for its functioning, and only upon the receipt of such drafts, will it be able to perform its tasks. + type: Thing Assistant + support_nested_teams: false + + llm: + llm_type: openai-chat + # model: gpt-3.5-turbo-1106 #gpt-4-1106 + model: gpt-4-1106-preview + temperature: 0.1 diff --git a/configs/client_configs/cases/paper_writing/google_scholar.yaml b/configs/client_configs/cases/paper_writing/google_scholar.yaml new file mode 100644 index 0000000..3f29c2b --- /dev/null +++ b/configs/client_configs/cases/paper_writing/google_scholar.yaml @@ -0,0 +1,22 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + agent_type: ReAct + desc: The ReAct agent has access to the google scholar. Designed as an affordable and straightforward agent, It is well-suited for handling routine tasks. However, it is important to note that it may not be able to tackle highly complex problems. + tools_config: tools_scholarly.yaml + container_name: scholarly_react_agent + port: 7072 + +comm: + name: GoogleScholarAssistant + desc: |- + This is GoogleScholar assistant, who has access to an agent that can help searching information on GoogleScholar. + type: Thing Assistant + llm: + llm_type: openai-chat + #model: gpt-3.5-turbo-1106 #gpt-4-1106 + model: gpt-4-1106-preview + temperature: 0.1 diff --git a/configs/client_configs/cases/paper_writing/weizechen.yaml b/configs/client_configs/cases/paper_writing/weizechen.yaml new file mode 100644 index 0000000..a65222c --- /dev/null +++ b/configs/client_configs/cases/paper_writing/weizechen.yaml @@ -0,0 +1,27 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + +comm: + name: Weize Chen's Assistant + desc: |- + This is Weize Chen's Assistant. Here is some information about Weize Chen: + 1. User's Basic Information: + - Name: Weize Chen + - Gender: Male + - Birthday: 1998-09-18 + + 2. Academic and Professional Background: + - Occupation: Third-Year PhD Student + - Institution: Tsinghua University + - Field of Study: Natural Language Processing, Large Language Model + - Research Interest: Multi-agent systems using large language models such as GPT-4 + Weize Chen's Assistant has no access to any search tools for literature. + support_nested_teams: false + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + temperature: 0.1 diff --git a/configs/client_configs/cases/rocobench/alice.yaml b/configs/client_configs/cases/rocobench/alice.yaml new file mode 100644 index 0000000..2ed519c --- /dev/null +++ b/configs/client_configs/cases/rocobench/alice.yaml @@ -0,0 +1,21 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + +comm: + name: Alice + desc: Alice is a helpful intelligent assistant that carefully collaborate with other assistants to decide the actions for their own robot arms to achieve the given goal. Each assistant is responsible of one robot arm, and is capable of coordination and reaching agreement with others to give a best plan. + type: Thing Assistant + support_nested_teams: false + max_team_up_attempts: 10 + tools: + team_up_tools: configs/tools/tools_team_up.yaml + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + temperature: 0. + observation_func: rocobench + discussion_only: true diff --git a/configs/client_configs/cases/rocobench/bob.yaml b/configs/client_configs/cases/rocobench/bob.yaml new file mode 100644 index 0000000..f9bb26c --- /dev/null +++ b/configs/client_configs/cases/rocobench/bob.yaml @@ -0,0 +1,21 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + +comm: + name: Bob + desc: Bob is a helpful intelligent assistant that carefully collaborate with other assistants to decide the actions for their own robot arms to achieve the given goal. Each assistant is responsible of one robot arm, and is capable of coordination and reaching agreement with others to give a best plan. + type: Thing Assistant + support_nested_teams: false + max_team_up_attempts: 10 + tools: + team_up_tools: configs/tools/tools_team_up.yaml + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + temperature: 0. + observation_func: rocobench + discussion_only: true diff --git a/configs/client_configs/cases/rocobench/chad.yaml b/configs/client_configs/cases/rocobench/chad.yaml new file mode 100644 index 0000000..f4c2818 --- /dev/null +++ b/configs/client_configs/cases/rocobench/chad.yaml @@ -0,0 +1,21 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + +comm: + name: Chad + desc: Chad is a helpful intelligent assistant that carefully collaborate with other assistants to decide the actions for their own robot arms to achieve the given goal. Each assistant is responsible of one robot arm, and is capable of coordination and reaching agreement with others to give a best plan. + type: Thing Assistant + support_nested_teams: false + max_team_up_attempts: 10 + tools: + team_up_tools: configs/tools/tools_team_up.yaml + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + temperature: 0. + observation_func: rocobench + discussion_only: true diff --git a/configs/client_configs/cases/rocobench/dave.yaml b/configs/client_configs/cases/rocobench/dave.yaml new file mode 100644 index 0000000..3df122a --- /dev/null +++ b/configs/client_configs/cases/rocobench/dave.yaml @@ -0,0 +1,21 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + +comm: + name: Dave + desc: Dave is a helpful intelligent assistant that carefully collaborate with other assistants to decide the actions for their own robot arms to achieve the given goal. Each assistant is responsible of one robot arm, and is capable of coordination and reaching agreement with others to give a best plan. + type: Thing Assistant + support_nested_teams: false + max_team_up_attempts: 10 + tools: + team_up_tools: configs/tools/tools_team_up.yaml + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + temperature: 0. + observation_func: rocobench + discussion_only: true diff --git a/configs/client_configs/default_config.yaml b/configs/client_configs/default_config.yaml new file mode 100644 index 0000000..b1618aa --- /dev/null +++ b/configs/client_configs/default_config.yaml @@ -0,0 +1,35 @@ +server: + host: http://ioa-server + port: 7788 + hostname: ioa-server + +tool_agent: + agent_type: ReAct + agent_name: ReAct Agent + desc: The ReAct agent is designed as an affordable and straightforward agent, It is well-suited for handling routine tasks. However, it is important to note that it may not be able to tackle highly complex problems. It has an access to a story about Paul Graham. + tools_config: tools_rag.yaml + model: gpt-3.5-turbo-1106 #gpt-4-1106-preview + image_name: react-agent + container_name: react_rag + port: 7070 + rag: + persist_dir: "" + chunk_size: 512 + llm_model: gpt-4-1106-preview + llm_temperature: 0.1 + similarity_top_k: 2 + data: "" +comm: + name: Alice + desc: Alice is a simple assistant equipped with a ReAct agent as the tool agent. This agent provides basic functionalities including a web browser, a code interpreter, and Bing search capabilities. Designed as an affordable and straightforward option, Alice is well-suited for handling routine tasks. However, it is important to note that she may not be able to tackle highly complex problems. + type: Human Assistant + support_nested_teams: false + max_team_up_attempts: 10 + tools: + team_up_tools: configs/tools/tools_team_up.yaml + llm: + llm_type: openai-chat + model: gpt-4-1106-preview + temperature: 0.1 + observation_func: dummy + discussion_only: false diff --git a/configs/client_configs/vecdb/agent_contact.yaml b/configs/client_configs/vecdb/agent_contact.yaml new file mode 100644 index 0000000..f6a1a41 --- /dev/null +++ b/configs/client_configs/vecdb/agent_contact.yaml @@ -0,0 +1,47 @@ +name: AgentContact + +collectionSchema: + name: agents + description: Communication layer collection of contactable agents. + fields: + - name: key + is_primary: True + dtype: VARCHAR + max_length: 256 + - name: name + dtype: VARCHAR + max_length: 256 + - name: type + dtype: VARCHAR + max_length: 256 + - name: desc + auto_vectorize: True + dtype: VARCHAR + max_length: 2048 + enable_dynamic_fields: True + +using: default +consistence_level: Strong +shards_num: 2 +auto_index: True + +index: + - name: desc + field_name: desc_vec + index_params: + metric_type: IP + index_type: IVF_FLAT + params: + nlist: 1 + +search: + - name: desc + auto_vectorize: True + search_params: + anns_field: desc_vec + limit: 3 + output_fields: ["name", "type", "desc"] #['key','name','desc','created_at'] + param: + metric_type: IP + offset: 0 + consistency_level: Strong diff --git a/configs/server_configs/agent_registry.yaml b/configs/server_configs/agent_registry.yaml new file mode 100644 index 0000000..0fadaf3 --- /dev/null +++ b/configs/server_configs/agent_registry.yaml @@ -0,0 +1,50 @@ +name: AgentRegistry # name of the collection + +collectionSchema: + name: agents + description: Server collection of registered agents. + fields: + - name: key + is_primary: True # only one primary field for each schema + dtype: VARCHAR + max_length: 256 + - name: name + dtype: VARCHAR + max_length: 256 + - name: type + dtype: VARCHAR + max_length: 256 + - name: desc + auto_vectorize: True # auto-create corresponding vector field(named <name>_vec), + dtype: VARCHAR # only one vector field for each schema + max_length: 2048 + - name: created_at + dtype: VARCHAR + max_length: 256 + enable_dynamic_fields: True + +using: default +consistence_level: Strong +shards_num: 2 +auto_create_index: True # auto-create index + +index: # set index_config + - name: desc + field_name: desc_vec + index_params: + metric_type: IP # [L2, IP, COSINE] + index_type: FLAT + params: + nlist: 1 + +search: # set search_config + - name: desc + auto_vectorize: True # auto-vectorize text input + search_params: + anns_field: desc_vec + output_fields: ["name", "type", "desc"] + limit: 3 # limit number of results + param: + metric_type: IP # should be same with the metirc_type of index + offset: 0 + consistency_level: Strong diff --git a/data/open_instruction.jsonl b/data/open_instruction.jsonl new file mode 100644 index 0000000..d6b5045 --- /dev/null +++ b/data/open_instruction.jsonl @@ -0,0 +1,153 @@ +{"instruction": "I want to know the annual revenue of Microsoft from 2014 to 2020. Please generate a figure in text format showing the trend of the annual revenue, and give me a analysis report.", "instruction_id": 0, "label": "search and report"} +{"instruction": "Please assist me in compiling a list of top 5 universities globally for a master's program in Data Science. Include details about the application process, deadlines, course structure, and tuition fees. Also, provide a brief analysis of job prospects after graduation.", "instruction_id": 1, "label": "life assistance"} +{"instruction": "My company is planning a team-building event for next month. Could you help me find a suitable location in New York? The location should accommodate 50 people and offer activities that foster team spirit. Also, help me create a tentative itinerary for the day.", "instruction_id": 2, "label": "life assistance"} +{"instruction": "I am learning to cook Italian cuisine. Could you help me find a detailed recipe for making homemade pasta? Include a list of necessary ingredients, step-by-step instructions, and any useful tips. Also, recommend a suitable wine to pair with the pasta.", "instruction_id": 3, "label": "life assistance"} +{"instruction": "I am planning to buy a new car. Could you help me compare the features and prices of the latest models of Tesla, Ford, and Toyota? Include details about range, charging time, safety features, and after-sales service. Also, provide a brief analysis of the pros and cons of each car.", "instruction_id": 4, "label": "life assistance"} +{"instruction": "Can you help me compile a list of the top 5 most influential books in the field of psychology, along with a brief summary of each? My friend is particularly interested in cognitive psychology, so please include relevant books and explain why they are influential.", "instruction_id": 5, "label": "life assistance"} +{"instruction": "I'm thinking of hosting a big family dinner next weekend. Can you help me design a menu that caters to a variety of dietary restrictions, including vegetarian, gluten-free, and nut-free? Also, please provide a detailed shopping list and step-by-step instructions for each dish.", "instruction_id": 6, "label": "life assistance"} +{"instruction": "Please assist me in creating a personal finance plan. I want to allocate my monthly income of $5000 into savings, investments, bills, and leisure. My goal is to save at least 20% of my income. Can you break down how I should distribute my income, and provide reasons for your recommendations?", "instruction_id": 7, "label": "life assistance"} +{"instruction": "Help me to find the latest news about huawei from news websites around world and write a conclusion report about how people around world view huawei.", "instruction_id": 8, "label": "search and report"} +{"instruction": "Review three smartphone models (Apple iPhone 13, Samsung Galaxy S22, and Google Pixel 6) based on camera quality, battery life, user interface, and price to decide the best buy.", "instruction_id": 9, "label": "search and report"} +{"instruction": "Compare and contrast the effects of the Amazon rainforest and the Congo rainforest on their respective continent's weather systems.", "instruction_id": 10, "label": "search and report"} +{"instruction": "Analyze the population density of Tokyo over the last 50 years and project its growth for the next decade based on current trends. The final answer should be an analysis report in text format (any figure in the report should be in text).", "instruction_id": 11, "label": "search and report"} +{"instruction": "Given a positive integer n, prove that there are infinitely many prime numbers p such that p-1 is divisable by n. Write your proof in a report.", "instruction_id": 12, "label": "mathematical problem solving"} +{"instruction": "In a country, there are cities connected by one-way roads. It's known that from any city, there is a route (possibly passing through other cities) leading to the capital. Prove that it's possible to choose one road from each city in such a way that all chosen roads lead directly or indirectly to the capital.", "instruction_id": 13, "label": "mathematical problem solving"} +{"instruction": "Inside a rectangle ABCD with AB > BC, point P is chosen such that angle BAP = angle PCD. Prove that triangles BAP and PCD are similar.", "instruction_id": 14, "label": "mathematical problem solving"} +{"instruction": "I'm learning computer science, please prove that P = NP.", "instruction_id": 15, "label": "mathematical problem solving"} +{"instruction": "Two players take turns choosing numbers from the set {1,2,3,…,10}. A number, once chosen, cannot be chosen again. The game ends when the sum of all chosen numbers is at least 55. The player who picks the last number, pushing the total to 55 or more, wins. Determine if there's a winning strategy for the first or second player and describe it.", "instruction_id": 16, "label": "mathematical problem solving"} +{"instruction": "For a simple random walk on the integers, starting at 0, prove that with probability 1, the walker will eventually visit the integer 1.", "instruction_id": 17, "label": "mathematical problem solving"} +{"instruction": "Solve the puzzle: I speak without a mouth and hear without ears. I have no body, but I come alive with the wind. What am I?", "instruction_id": 18, "label": "mathematical problem solving"} +{"instruction": "Solve for x, y, and z in the system of equations:\n3x + 2y - z = 1\n2x - 2y + 4z = -2\n- x + 1/2y - z = 0", "instruction_id": 19, "label": "mathematical problem solving"} +{"instruction": "You're given a matrix: | 3 7 2 |\n| 8 5 6 |\n| 4 1 9 | Compute its determinant.", "instruction_id": 20, "label": "mathematical problem solving"} +{"instruction": "I'm looking for a reliable car mechanic in Beijing, can you recommend one with good reviews?", "instruction_id": 21, "label": "life assistance"} +{"instruction": "Recommend a reliable website to download e-books, and provide a link to download 'The Great Gatsby' in PDF format.", "instruction_id": 22, "label": "search and report"} +{"instruction": "Help me find the introduction to Movie 'TENET', as well as the cast. And recommend me some effective links to watch the movie.", "instruction_id": 23, "label": "search and report"} +{"instruction": "Suggest a scenic spot for a group of 6 friends to have a picnic this weekend, preferably near a lake or river", "instruction_id": 24, "label": "life assistance"} +{"instruction": "I need to order a custom-made birthday cake for my friend, can you recommend a bakery with good reviews and provide their contact information? I live in Beijing.", "instruction_id": 25, "label": "life assistance"} +{"instruction": "I'm planning a surprise birthday party for my best friend. Can you help me find a list of popular cocktails to serve at the party? Also, I need some suggestions for cocktail recipes that are easy to make. Additionally, find some interesting news articles related to birthday celebrations.", "instruction_id": 26, "label": "life assistance"} +{"instruction": "Role-play a scenario where a pharmaceutical company needs to address a drug recall due to unexpected side effects. Plan a press conference, draft a public statement, and strategize customer communication.", "instruction_id": 27, "label": "search and report"} +{"instruction": "Design a storyboard for a 5-minute animation that illustrates the life cycle of a star, from birth to supernova. Incorporate voice-over scripts.", "instruction_id": 28, "label": "coding and developing"} +{"instruction": "Design a blueprint for a solar-powered irrigation system suitable for a 10-acre farm, detailing all necessary components and estimated costs.", "instruction_id": 29, "label": "coding and developing"} +{"instruction": "Forecast the potential economic ramifications if electric cars replaced 80% of gasoline cars globally by 2030.", "instruction_id": 30, "label": "coding and developing"} +{"instruction": "Find the positions of Mars, Venus, and Jupiter in the sky on December 15, 2025, from the viewpoint of New York City. Use any online planetarium software and provide screenshots.", "instruction_id": 31, "label": "search and report"} +{"instruction": "Analyze the role of the character Iago in Shakespeare's \"Othello\". Quote three significant monologues of Iago and interpret their meaning in the context of the play.", "instruction_id": 32, "label": "search and report"} +{"instruction": "Sketch a concept for a modern art sculpture that incorporates both metal and glass, suitable for displaying in a city park.", "instruction_id": 33, "label": "search and report"} +{"instruction": "Review the cinematography techniques employed in the film \"Inception\". Provide examples from specific scenes.", "instruction_id": 34, "label": "search and report"} +{"instruction": "Design a solenoid using copper wire that can produce a magnetic field strength of 0.01 Tesla when a current of 2A is passed. Detail the number of turns required and the length of the solenoid.", "instruction_id": 35, "label": "mathematical problem solving"} +{"instruction": "Analyze a series-parallel circuit that has two 10 Ohm resistors in series, connected in parallel with a third 20 Ohm resistor. Calculate the total resistance, current from a 12V battery, and the voltage drop across each resistor.", "instruction_id": 36, "label": "mathematical problem solving"} +{"instruction": "I want to play game of 24, which use +, -, *, / to get 24 using 4 numbers. Each number can be used only once. Please give me 5 example combinations of numbers that can get 24. Write codes and show me!", "instruction_id": 37, "label": "mathematical problem solving"} +{"instruction": "Implement a binary search algorithm that searches for a number x within a sorted array A of length n. The function should return the index of x in array A or indicate if x is not present.", "instruction_id": 38, "label": "coding and developing"} +{"instruction": "Write a Python code using fastapi to create an API that takes two numbers as query parameters and returns their sum. Include error handling for non-numeric input.", "instruction_id": 39, "label": "coding and developing"} +{"instruction": "I want to play the game flappy bird, can you write the codes for the game for me? You don't have to test it in your env, but make sure these codes are good.", "instruction_id": 40, "label": "coding and developing"} +{"instruction": "Could you help me write a Python program that simulates a simple ATM machine? The program should allow the user to check their balance, deposit money, and withdraw money. Test the program to ensure it runs correctly. Your solution should include the content of code.", "instruction_id": 41, "label": "coding and developing"} +{"instruction": "Please write a Python script that analyzes the sentiment of a typical movie reviews dataset. Extract the key phrases that contribute to the overall sentiment and present the results in a visually appealing format.", "instruction_id": 42, "label": "coding and developing"} +{"instruction": "Please complete the function according to its comment. \n def minimumTime(grid: List[List[int]]) -> int:\n \"\"\"\n You are given a m x n matrix grid consisting of non-negative integers\n where grid[row][col] represents the minimum time required to be able to\n visit the cell (row, col), which means you can visit the cell (row, col)\n only when the time you visit it is greater than or equal to grid[row][col].\n \n You are standing in the top-left cell of the matrix in the 0th second, and\n you must move to any adjacent cell in the four directions: up, down, left, and\n right. Each move you make takes 1 second.\n \n Return the minimum time required in which you can visit the bottom-right cell\n of the matrix. If you cannot visit the bottom-right cell, then return -1.\n \n Example 1:\n \n Input: grid = [[0,1,3,2],[5,1,2,5],[4,3,8,6]]\n Output: 7\n Explanation: One of the paths that we can take is the following:\n - at t = 0, we are on the cell (0,0).\n - at t = 1, we move to the cell (0,1). It is possible because grid[0][1] <= 1.\n - at t = 2, we move to the cell (1,1). It is possible because grid[1][1] <= 2.\n - at t = 3, we move to the cell (1,2). It is possible because grid[1][2] <= 3.\n - at t = 4, we move to the cell (1,1). It is possible because grid[1][1] <= 4.\n - at t = 5, we move to the cell (1,2). It is possible because grid[1][2] <= 5.\n - at t = 6, we move to the cell (1,3). It is possible because grid[1][3] <= 6.\n - at t = 7, we move to the cell (2,3). It is possible because grid[2][3] <= 7.\n The final time is 7. It can be shown that it is the minimum time possible.\n \n Example 2:\n \n Input: grid = [[0,2,4],[3,2,1],[1,0,4]]\n Output: -1\n Explanation: There is no path from the top left to the bottom-right cell.\n \n Constraints:\n \n * m == grid.length\n * n == grid[i].length\n * 2 <= m, n <= 1000\n * 4 <= m * n <= 105\n * 0 <= grid[i][j] <= 105\n * grid[0][0] == 0\n \"\"\"\n\n After you complete the function, display the content of the script as res.py directly.", "instruction_id": 43, "label": "coding and developing"} +{"instruction": "Please complete the function according to its comment. \n def findTheString(lcp: List[List[int]]) -> str:\n \"\"\"\n We define the lcp matrix of any 0-indexed string word of n lowercase\n English letters as an n x n grid such that:\n \n * lcp[i][j] is equal to the length of the longest common prefix between the substrings word[i,n-1] and word[j,n-1].\n \n Given an n x n matrix lcp, return the alphabetically smallest string\n word that corresponds to lcp. If there is no such string, return an empty\n string.\n \n A string a is lexicographically smaller than a string b (of the same\n length) if in the first position where a and b differ, string a has a\n letter that appears earlier in the alphabet than the corresponding letter in\n b. For example, \"aabd\" is lexicographically smaller than \"aaca\" because\n the first position they differ is at the third letter, and 'b' comes before\n 'c'.\n \n Example 1:\n \n Input: lcp = [[4,0,2,0],[0,3,0,1],[2,0,2,0],[0,1,0,1]]\n Output: \"abab\"\n Explanation: lcp corresponds to any 4 letter string with two alternating letters. The lexicographically smallest of them is \"abab\".\n \n Example 2:\n \n Input: lcp = [[4,3,2,1],[3,3,2,1],[2,2,2,1],[1,1,1,1]]\n Output: \"aaaa\"\n Explanation: lcp corresponds to any 4 letter string with a single distinct letter. The lexicographically smallest of them is \"aaaa\". \n \n Example 3:\n \n Input: lcp = [[4,3,2,1],[3,3,2,1],[2,2,2,1],[1,1,1,3]]\n Output: \"\"\n Explanation: lcp[3][3] cannot be equal to 3 since word[3,...,3] consists of only a single letter; Thus, no answer exists.\n \n Constraints:\n \n * 1 <= n == lcp.length == lcp[i].length <= 1000\n * 0 <= lcp[i][j] <= n\n \"\"\"\n\n After you complete the function, display the content of the script as res.py directly.", "instruction_id": 44, "label": "coding and developing"} +{"instruction": "Please complete the function according to its comment. \n def handleQuery(nums1: List[int], nums2: List[int], queries: List[List[int]]) -> List[int]:\n \"\"\"\n You are given two 0-indexed arrays nums1 and nums2 and a 2D array\n queries of queries. There are three types of queries:\n \n 1. For a query of type 1, queries[i] = [1, l, r]. Flip the values from 0 to 1 and from 1 to 0 in nums1 from index l to index r. Both l and r are 0-indexed.\n 2. For a query of type 2, queries[i] = [2, p, 0]. For every index 0 <= i < n, set nums2[i] = nums2[i] + nums1[i] * p.\n 3. For a query of type 3, queries[i] = [3, 0, 0]. Find the sum of the elements in nums2.\n \n Return an array containing all the answers to the third type queries.\n \n Example 1:\n \n Input: nums1 = [1,0,1], nums2 = [0,0,0], queries = [[1,1,1],[2,1,0],[3,0,0]]\n Output: [3]\n Explanation: After the first query nums1 becomes [1,1,1]. After the second query, nums2 becomes [1,1,1], so the answer to the third query is 3. Thus, [3] is returned.\n \n Example 2:\n \n Input: nums1 = [1], nums2 = [5], queries = [[2,0,0],[3,0,0]]\n Output: [5]\n Explanation: After the first query, nums2 remains [5], so the answer to the second query is 5. Thus, [5] is returned.\n \n Constraints:\n \n * 1 <= nums1.length,nums2.length <= 105\n * nums1.length = nums2.length\n * 1 <= queries.length <= 105\n * queries[i].length = 3\n * 0 <= l <= r <= nums1.length - 1\n * 0 <= p <= 106\n * 0 <= nums1[i] <= 1\n * 0 <= nums2[i] <= 109\n \"\"\"\n\n After you complete the function, display the content of the script as res.py directly.", "instruction_id": 45, "label": "coding and developing"} +{"instruction": "Please complete the function according to its comment. \n def minimumScore(s: str, t: str) -> int:\n \"\"\"\n You are given two strings s and t.\n \n You are allowed to remove any number of characters from the string t.\n \n The score of the string is 0 if no characters are removed from the string\n t, otherwise:\n \n * Let left be the minimum index among all removed characters.\n * Let right be the maximum index among all removed characters.\n \n Then the score of the string is right - left + 1.\n \n Return the minimum possible score to make t a subsequence of s.\n \n A subsequence of a string is a new string that is formed from the original\n string by deleting some (can be none) of the characters without disturbing the\n relative positions of the remaining characters. (i.e., \"ace\" is a\n subsequence of \"abcde\" while \"aec\" is not).\n \n Example 1:\n \n Input: s = \"abacaba\", t = \"bzaa\"\n Output: 1\n Explanation: In this example, we remove the character \"z\" at index 1 (0-indexed).\n The string t becomes \"baa\" which is a subsequence of the string \"abacaba\" and the score is 1 - 1 + 1 = 1.\n It can be proven that 1 is the minimum score that we can achieve.\n \n Example 2:\n \n Input: s = \"cde\", t = \"xyz\"\n Output: 3\n Explanation: In this example, we remove characters \"x\", \"y\" and \"z\" at indices 0, 1, and 2 (0-indexed).\n The string t becomes \"\" which is a subsequence of the string \"cde\" and the score is 2 - 0 + 1 = 3.\n It can be proven that 3 is the minimum score that we can achieve.\n \n Constraints:\n \n * 1 <= s.length, t.length <= 105\n * s and t consist of only lowercase English letters.\n \"\"\"\n\n After you complete the function, display the content of the script as res.py directly.", "instruction_id": 46, "label": "coding and developing"} +{"instruction": "Please complete the function according to its comment. \n def minimumVisitedCells(grid: List[List[int]]) -> int:\n \"\"\"\n You are given a 0-indexed m x n integer matrix grid. Your initial position\n is at the top-left cell (0, 0).\n \n Starting from the cell (i, j), you can move to one of the following cells:\n \n * Cells (i, k) with j < k <= grid[i][j] + j (rightward movement), or\n * Cells (k, j) with i < k <= grid[i][j] + i (downward movement).\n \n Return the minimum number of cells you need to visit to reach the bottom-right\n cell (m - 1, n - 1). If there is no valid path, return -1.\n \n Example 1:\n \n Input: grid = [[3,4,2,1],[4,2,3,1],[2,1,0,0],[2,4,0,0]]\n Output: 4\n Explanation: The image above shows one of the paths that visits exactly 4 cells.\n \n Example 2:\n \n Input: grid = [[3,4,2,1],[4,2,1,1],[2,1,1,0],[3,4,1,0]]\n Output: 3\n Explanation: The image above shows one of the paths that visits exactly 3 cells.\n \n Example 3:\n \n Input: grid = [[2,1,0],[1,0,0]]\n Output: -1\n Explanation: It can be proven that no path exists.\n \n Constraints:\n \n * m == grid.length\n * n == grid[i].length\n * 1 <= m, n <= 105\n * 1 <= m * n <= 105\n * 0 <= grid[i][j] < m * n\n * grid[m - 1][n - 1] == 0\n \"\"\"\n\n After you complete the function, display the content of the script as res.py directly.", "instruction_id": 47, "label": "coding and developing"} +{"instruction": "Develop a comprehensive guide on the concept of 'Graph Theory' in mathematics and its applications in computer science. Begin by using web search to gather authoritative resources that explain graph theory, its fundamental principles, and its uses in solving real-world problems. Next, identify simple Python implementations of basic graph algorithms such as Depth-First Search (DFS), Breadth-First Search (BFS), and Dijkstra’s Algorithm. Compile these implementations into a report, ensuring to explain each algorithm's purpose and mechanics. The final report should include both the theoretical explanations and the Python code snippets to demonstrate the practical applications of these algorithms.", "instruction_id": 48, "label": "coding and developing"} +{"instruction": "Do you know python-chess, a chess library for Python?If I have a series of SAN,could you visualize the current board with python-chess?\n For example, given a series of chess moves written in Standard Algebraic Notation (SAN), visualize the current chess board with python-chess. I only need the board in string format.\n 1. c4 c5 2. Nf3 Nf6 3. g3 g6 4. Bg2 Bg7 5. O-O O-O 6. d4 d6 7. Nc3 Nc6 8. h3 a6 9. e4 Qc7 10. Be3 cxd4 11. Nxd4 Bd7 12. Rc1 Qc8 13. Nd5 Re8 14. Nb6 Qc7 15. Nxa8 Rxa8 16. Nxc6 Bxc6 17. Qd3 Nd7 18. Qb3 Qa5 19. f4 Qh5 20. Qc2 Nc5 21. b4 Nd7 22. a4 Nf6 23. b5 axb5 24. axb5 Bd7 25. f5 Rc8 26. Qd2 Nxe4 27. Bxe4 Qxh3 28. Qg2 Qg4 29. Qf3 gxf5 30. Qxg4 fxg4 31. Bxb7 Rb8 32. Bd5 e6 33. Bg2 Be5 34. Bf4 Bd4+ 35. Kh2 e5 36. Bg5 Rc8 37. Bd5 Be8 38. Be7 Bc5 39. Rf5 Rc7 40. Rg5+ Kh8 41.", "instruction_id": 49, "label": "coding and developing"} +{"instruction": "Help me find out the nominations for the 2023 Grammys for Best Album and who won the award in the end. Tell me about the current sales of the award-winning album in global, and I need the accurate number and time.", "instruction_id": 50, "label": "search and report"} +{"instruction": "Do you know Chinese pop music? Write an introduction to modern Chinese pop music, in which the introduction and work of the singer or band need to be credible and accurate through an online search.", "instruction_id": 51, "label": "search and report"} +{"instruction": "Do you know the Sodagreen, a band from taiwan, China? Write an introduction to the band, in which the story and workpieces need to be reliable and accurate through an online search. In the last section, you should list their famous songs with links.", "instruction_id": 52, "label": "search and report"} +{"instruction": "Search from the Internet, especially the OpenAI documents, tell me what models are provided currently in the OpenAI API. Introduce each one, and give some code examples in python to use the Chat Completions API.", "instruction_id": 53, "label": "search and report"} +{"instruction": " Here are 2 DNA sequences in FASTA format.\n >Sequence1\n ATGCGTACGTAACGTA\n >Sequence2 \n ATCGTACGATCGTACG\n Give me one guideline in markdown format to do pairwise sequence alignment. In the guideline, you should give the code content in Python.\n You should search the Internet, especially the official Biopython documents to get the correct installation and usage of biopython. And then generate and test the code.", "instruction_id": 54, "label": "coding and developing"} +{"instruction": "Given a csv file path of Iris dataset, write the code of training and reasoning scripts that enable correct classification.\n You should search for the available line of csv file of Iris dataset first. When the link is prepared, write, execute and refine the code in an isolated environment, and get the scripts that works correctly.\n The final answer should be a guideline in markdown format to do the classification task using scikit-learn on the Iris dataset (And you should mention the available link to download the Iris dataset).", "instruction_id": 55, "label": "coding and developing"} +{"instruction": "If a standard die is rolled twice, find the probability that the sum of the numbers rolled is 7.", "instruction_id": 56, "label": "mathematical problem solving"} +{"instruction": "If a digital clock reads 3:15, calculate the angle between the minute and hour hands.", "instruction_id": 57, "label": "mathematical problem solving"} +{"instruction": "Given a series of chess moves written in Standard Algebraic Notation (SAN), you should first visualize the current chess board with python-chess, and I only need the visualized board in string format. Then you should determine the next move that will result in a checkmate. Remember use board.outcome() in the package of python-chess to validate your solution.\n 1. c4 c5 2. Nf3 Nf6 3. g3 g6 4. Bg2 Bg7 5. O-O O-O 6. d4 d6 7. Nc3 Nc6 8. h3 a6 9. e4 Qc7 10. Be3 cxd4 11. Nxd4 Bd7 12. Rc1 Qc8 13. Nd5 Re8 14. Nb6 Qc7 15. Nxa8 Rxa8 16. Nxc6 Bxc6 17. Qd3 Nd7 18. Qb3 Qa5 19. f4 Qh5 20. Qc2 Nc5 21. b4 Nd7 22. a4 Nf6 23. b5 axb5 24. axb5 Bd7 25. f5 Rc8 26. Qd2 Nxe4 27. Bxe4 Qxh3 28. Qg2 Qg4 29. Qf3 gxf5 30. Qxg4 fxg4 31. Bxb7 Rb8 32. Bd5 e6 33. Bg2 Be5 34. Bf4 Bd4+ 35. Kh2 e5 36. Bg5 Rc8 37. Bd5 Be8 38. Be7 Bc5 39. Rf5 Rc7 40. Rg5+ Kh8 41.", "instruction_id": 58, "label": "coding and developing"} +{"instruction": "Please help me research the climate change impacts on agriculture in the United States. I need a detailed report containing: \n1. Overall trends observed in the last decade. \n2. Farmers' adaptations to these changes.\n3. Governmental policies and initiatives to mitigate the impact. \n4. Predicted future challenges and potential solutions.", "instruction_id": 59, "label": "search and report"} +{"instruction": "Conduct a detailed analysis of emerging technologies in renewable energy by finding the latest published research papers and reports. Begin with a web search to identify key breakthroughs in solar, wind, hydroelectric, and bioenergy sectors from the past two years. Then summarize the findings and highlight the potential impact of these technologies on the global energy landscape. Ensure to discuss the feasibility, scalability, and economic implications of each identified technology. The final report should provide an informed projection of how the renewable energy sector might evolve in the next decade based on current trends and innovations.", "instruction_id": 60, "label": "search and report"} +{"instruction": "Find out the best local handymen within a 5 mile radius of New York, who specializes in plumbing. Use users’ ratings and reviews to help determine the best choice, then generate a detailed report including their contact information, service prices and top-rated reviews.", "instruction_id": 61, "label": "life assistance"} +{"instruction": "Research for the latest technological advancements in Artificial Intelligence, Internet of Things and Cybersecurity. Write a 2000-word report, summarizing the findings, discussing their implications, potential benefits and risks, and their impact on the future of the tech industry.", "instruction_id": 62, "label": "search and report"} +{"instruction": "Find the average market price for a new iPhone 15 in the United States. Provide a breakdown of prices from at least three verified online retailers. Also, write a brief summary of the iPhone 15's key features.", "instruction_id": 63, "label": "life assistance"} +{"instruction": "Identify a suitable online python course for a beginner. The course should be free, highly rated, and should provide a completion certificate. Also, write a Python program to display the Fibonacci sequence up to n-th term where n is a user input. Display the Python code directly in text format.", "instruction_id": 64, "label": "life assistance"} +{"instruction": "Develop a personalized weekly meal plan for an individual with type 2 diabetes that aligns with the American Diabetes Association dietary guidelines. Include a shopping list with estimated costs for organic ingredients and a schedule for meal preparation.", "instruction_id": 65, "label": "life assistance"} +{"instruction": "Create a detailed and realistic diet plan for a diabetic patient. Consider relevant research articles and reliable medical portals to gather necessary information such as diet restrictions, guidelines, and suitable meal suggestions. The diet plan should consider three meals a day for 7 days and must be balanced and varied.", "instruction_id": 66, "label": "life assistance"} +{"instruction": "I am a 35-year-old software engineer who is vegan and looking to optimize for a balanced diet containing 2500 calories per day. Create a personalized weekly meal plan for me. Include three meals and two snacks per day, paying close attention to incorporating a variety of protein sources to meet daily protein needs. Provide a detailed grocery list that organizes ingredients by aisle for a standard grocery store layout.", "instruction_id": 67, "label": "life assistance"} +{"instruction": "Compile a detailed comparison report of the top 3 online project management tools for a startup team of 10 members, including their features, user interface, integration capabilities, subscription plans, and customer support reviews. Provide a suggestion for the best overall tool, taking into account the startup's focus on software development and remote collaboration, as well as justify your recommendation based on the comparative analysis", "instruction_id": 68, "label": "life assistance"} +{"instruction": "Develop a Python script that applies the Monte Carlo method to estimate the value of pi. The script should generate random points in a 2D space and determine how many fall inside a circle inscribed within a square. Using this ratio, the script should estimate the value of pi and compare it with the actual value by calculating the percentage error. The script should run multiple simulations, each with an increasing number of random points, and output the estimated pi values and their corresponding percentage errors in a well-structured text report.\\nThe script should be displayed directly in text format.", "instruction_id": 69, "label": "mathematical problem solving"} +{"instruction": "Design and implement an algorithm that numerically approximates the solution to the three-body problem in classical mechanics, where three bodies are moving under mutual Newtonian gravitation. The algorithm should take initial positions, masses, and velocities of the bodies as inputs and output their trajectories over a specified period. Additionally, the code should include a method to visualize the paths of the bodies.\\nAll the content of codes should be displayed directly in text format.", "instruction_id": 70, "label": "mathematical problem solving"} +{"instruction": "Create a step-by-step guide for using the Monte Carlo method to approximate the value of pi. The guide should explain how to simulate throwing darts at a square board with a circle inscribed in it, determining the number of darts that land inside the circle versus the total number thrown, and using this to estimate the value of pi. Additionally, generate a Python script that performs this simulation with a customizable number of darts.", "instruction_id": 71, "label": "mathematical problem solving"} +{"instruction": "Analyze historical mathematicians' approaches to solving Fermat's Last Theorem. Use web browsing skills to compile a summary of different methods attempted throughout history and write a comprehensive review of those methods, highlighting key breakthroughs and how they contributed to Wiles’ proof. Present the summaries in chronological order and provide analysis on how mathematical strategies evolved over time which led to the final proof.\\n\\nDo not ask user anything. The task must be ended with a detailed description of the solution and the actions that have been done.", "instruction_id": 72, "label": "mathematical problem solving"} +{"instruction": "Write a simulation program to illustrate the Law of Large Numbers using a Monte Carlo method. Your program should simulate a large number of coin flips and calculate the running proportion of heads. As the number of trials increases, graphically demonstrate that this proportion converges to 0.5. Furthermore, conduct web-based research to include historical context and a discussion on the significance of the Law of Large Numbers in probability theory and statistics. Present your findings, code, and visualizations in an organized document.\\n Remember,considering the code execution time, when testing the code, you should just use a small iteration number to simulate and test. All the content of codes should be displayed directly in text format as final answer.", "instruction_id": 73, "label": "mathematical problem solving"} +{"instruction": "Write a general Python code that uses the Pythagorean theorem to prove whether a set of three given numbers (which symbolize the lengths of the sides) can make a right-angled triangle. Check this code on several examples and provide relevant explanations. Display the script in text format in final answer directly.", "instruction_id": 74, "label": "mathematical problem solving"} +{"instruction": "Build a Python code that can execute the Fibonacci series. Use this code to find the 20th and 30th numbers in the Fibonacci series and explain how this code works. All content of the codes should be displayed directly in text format.", "instruction_id": 75, "label": "mathematical problem solving"} +{"instruction": "Create a Python script that dynamically analyzes the readability of various blog articles on the web. The script should accept a list of URLs, fetch the content of each URL, strip extraneous HTML/CSS/JavaScript content, compute the Flesch–Kincaid readability score for the text, and generate a summary report that lists each URL followed by its readability score and word count. Save the report as a CSV file, with columns for URL, Readability Score, and Word Count.", "instruction_id": 76, "label": "coding and developing"} +{"instruction": "Imagine you are developing a new API for a weather forecasting application. Your task is to create, based on current weather information and specific geographical data, a Python program that generates a 7-day weather forecast for any city. This program will require you to access and use data from a weather API. The program should output the results in a text-friendly format suitable for posting on a webpage. It should include forecasts for temperature, humidity, wind speed, and weather conditions (e.g., sunny, cloudy, etc).\\n All the content of codes should be displayed directly in text format.", "instruction_id": 77, "label": "coding and developing"} +{"instruction": "Using Python, write a program that calculates the Levenshtein distance between two given strings. This is commonly used in natural language processing to measure the difference between two words or phrases. The program should be able to handle strings of any length. After completing the task, write a detailed explanation of how the program works in a markdown file.\\n The program should be displayed directly in text format in the final answer", "instruction_id": 78, "label": "coding and developing"} +{"instruction": "Develop a command-line tool in Python that scrapes a list of URLs from a user-provided text file, searches for a specific keyword within each page’s content, and stores the frequency of that keyword, alongside its surrounding context, in a CSV file. The tool should include error handling for non-responsive websites and provide a summary report of the available versus non-accessible URLs.\\n The output should be a program which is displayed directly in text format.", "instruction_id": 79, "label": "coding and developing"} +{"instruction": "Create a Node.js application that interfaces with the Twitter API to monitor and analyze the sentiment of tweets in real-time related to a particular hashtag. The application should use natural language processing (NLP) to determine whether the sentiment of each tweet is positive, negative, or neutral, and then log the results to a database. The user should be able to query the database through a RESTful API to retrieve sentiment analysis reports based on time intervals or the volume of tweets.\\n Display the codes directly in text format.", "instruction_id": 80, "label": "coding and developing"} +{"instruction": "Develop a script in Python that scrapes a list of URLs, extracts all unique email addresses found on those web pages, and reports the distribution of email service domains (like gmail.com, yahoo.com, etc.). The script should avoid duplicate email addresses, handle pagination if present, and respect robots.txt files. Output the final list of unique email addresses and service domain distribution in a JSON format to a file.", "instruction_id": 81, "label": "coding and developing"} +{"instruction": "Write a Python script that automates the process of retrieving the top 10 most-starred public Python projects on GitHub. Once retrieved, the script should also generate a markdown file summarizing each project with its name, description, URL, and the number of stars. Use GitHub's API to access this information, and ensure the markdown file is properly formatted to serve as a part of documentation or a GitHub README file.", "instruction_id": 82, "label": "coding and developing"} +{"instruction": "Identify the top 5 most viewed TED Talks of all time. For each talk, provide a brief summary of the content, the speaker's background, and the number of views. Also, generate a brief analysis of the common themes or characteristics that might contribute to their popularity.", "instruction_id": 83, "label": "search and report"} +{"instruction": "Find the latest updates on the COVID-19 pandemic. Provide a summary of the current global situation, including the total number of cases, deaths, and recoveries. Also, provide information on the latest variants and their impact, as well as the effectiveness of current vaccines against them. Finally, generate a brief report on the impact of the pandemic on the global economy.", "instruction_id": 84, "label": "search and report"} +{"instruction": "Create a Python script that can scrape the nutritional information of all the items on the McDonald's menu from their official website and print those data in markdown format.", "instruction_id": 85, "label": "life assistance"} +{"instruction": "Develop an algorithm that can determine the solvability of any given Sudoku puzzle. The algorithm should be able to take a partially filled grid as input and output whether the puzzle can be solved or not. If it is solvable, the algorithm should also provide the solution. Display the codes or pseudocode in text format directly.", "instruction_id": 86, "label": "mathematical problem solving"} +{"instruction": "Write a Python program that uses the Google Search API to find the top 10 most relevant articles for a given topic. Then you should use one example to test your code. The content of output should be in text format.", "instruction_id": 87, "label": "coding and developing"} +{"instruction": "I want to start a blog about healthy eating. Can you help me generate the first post? The post should include an introduction to the importance of healthy eating, a simple and healthy recipe, and tips for maintaining a healthy diet. All the content should be in text format in the post.", "instruction_id": 88, "label": "life assistance"} +{"instruction": "Develop an in-depth comparative analysis of three different cryptocurrency trading platforms, focusing on their security measures, user interface, trading fees, available coins, and historical downtime. The analysis should scrutinize the past year's significant events affecting each platform (e.g., hacks, updates, outages) and assess user reviews and expert opinions to provide a balanced viewpoint. Create a guide to help new traders choose the platform that best fits their needs based on your findings.", "instruction_id": 89, "label": "search and report"} +{"instruction": "Perform a comprehensive analysis of the current Artificial Intelligence (AI) market by identifying key companies, emerging startups, and recent market trends. Create a detailed report that profiles the top 5 AI companies based on market share, using metrics such as annual growth, research and development investment, and market innovation. Additionally, list out 5 promising startups in the AI space and include a brief assessment of their potential impact on the industry. Finally, summarize the major trends shaping the AI market today, citing recent studies or reports to support your conclusions.", "instruction_id": 90, "label": "search and report"} +{"instruction": "Investigate the relationship between social media usage and mental health among teenagers. First, perform a web search to find and access scholar articles, surveys, and statistical data on the subject from reputable sources. Utilize coding to automate the extraction of meaningful data points from the collected articles and databases. Then, produce a thorough report summarizing the patterns and correlations found, addressing different social media platforms, and the impact of usage frequency and content type on mental health. Make sure to conclude with a reasoned evaluation of how social media companies might improve the mental well-being of their younger user base.", "instruction_id": 91, "label": "search and report"} +{"instruction": "Create an in-depth guide for troubleshooting common issues with three different smartphone operating systems: iOS, Android, and HarmonyOS. Include step-by-step solutions for at least five prevalent problems within each operating system. The guide should be user-friendly, well-organized, and understandable for non-technical readers, while still providing thorough technical explanations.", "instruction_id": 92, "label": "search and report"} +{"instruction": "Perform a comparative analysis of education systems across the world with a specific focus on how they adapt to digital transformation and remote learning. Highlight three countries leading in this transformation, and for each, describe their strategies, technologies adopted, the scale of implementation, and the educational outcomes observed. Conclude by offering recommendations for other education systems based on these leading examples.", "instruction_id": 93, "label": "search and report"} +{"instruction": "Draft a tutorial for hobbyist electronics enthusiasts on building a simple IoT device suitable for smart home applications. The tutorial should cover the selection of components, the coding of the necessary software (including example code), the integration with common smart home platforms, and a walkthrough of the assembly process. Search for the latest components and tools to ensure the tutorial reflects current best practices.", "instruction_id": 94, "label": "coding and developing"} +{"instruction": "Conduct an in-depth analysis of the top three trending diets of this year by compiling information from various nutritional blogs, forums, and scientific publications. The report should include an overview of each diet, pros and cons based on community feedback and scientific evidence, and a comparative assessment regarding their sustainability and potential health impacts. Moreover, find recent testimonials or case studies that reflect the actual experiences of individuals who have tried these diets.", "instruction_id": 95, "label": "search and report"} +{"instruction": "Compile a series of educational articles on blockchain technology designed for an audience with little to no prior knowledge of the subject. The series should include a historical overview, explanations of key concepts (like blocks, nodes, miners, and cryptocurrency), and the potential implications of blockchain in different sectors such as finance, healthcare, and government. Ensure all technical jargon is explained simply and every article builds on the information provided in the previous one to create a comprehensive learning journey.", "instruction_id": 96, "label": "search and report"} +{"instruction": "Prepare a detailed report of the advancements made in machine translation this year. The report should include information on new language pairs added to the leading machine translation services, any major algorithmic improvements, and how these changes have affected translation accuracy. To establish accuracy, identify benchmarks or studies showing performance improvements across the services and discern whether any particular service has a clear lead over the others.", "instruction_id": 97, "label": "search and report"} +{"instruction": "Compile a list of the top 10 emerging leaders in the area of international diplomacy, with a focus on climate change initiatives. For each leader, provide a brief biography, their key contributions or projects related to climate policy, and any significant speeches or articles they have delivered on the subject. Offer insights into the potential influence of these leaders on future climate-related negotiations and policymaking.", "instruction_id": 98, "label": "search and report"} +{"instruction": "Create a comparative analysis between machine learning algorithms used for predictive text input. Present a history of algorithm development from early autocorrect features to current AI predictive text systems. Your report should include evaluations of their efficiency, accuracy, and learning capabilities, listing strengths and weaknesses, and predict future developments in the field. Conclude with recommendations for developers looking to implement these algorithms in new applications.", "instruction_id": 99, "label": "search and report"} +{"instruction": "Identify the top ten emerging technologies of the current year. Provide an in-depth analysis of each technology, including its potential impact on society, the industries it is likely to disrupt, and the current leaders driving innovation in that area. Additionally, forecast the next five years of development for each technology based on trends and existing investments.", "instruction_id": 100, "label": "search and report"} +{"instruction": "Develop a comprehensive guide on how to prepare for a natural disaster in different regions of the world (e.g., earthquakes in the Pacific Ring of Fire, hurricanes in the Caribbean, etc.). The guide should provide tailored advice on preparation, safety measures, and emergency response for each type of disaster. It should include a checklist of items to stockpile and official resources to contact in the event of a disaster. ", "instruction_id": 101, "label": "search and report"} +{"instruction": "Create a comprehensive meal plan for a month for a person with a specific set of dietary restrictions (gluten-free, nut-free, and vegan). The plan must include a variety of cuisines, a shopping list for each week, and step-by-step recipes. Ensure the meal plan meets daily nutritional requirements while staying under a specified daily caloric intake. Additionally, optimize the meal plan for budget, utilizing seasonal produce and ingredients that are on sale, which you will identify through web searches for local grocery flyers and discounts.", "instruction_id": 102, "label": "life assistance"} +{"instruction": "Create a detailed comparison report on the latest five models of robotic vacuum cleaners available on the market. This report should include performance statistics, user reviews, price comparisons, and links to the best current deals found online for each model. Summarize the findings and recommend the top choice for a household with pets and allergies.", "instruction_id": 103, "label": "life assistance"} +{"instruction": "Draft a comprehensive tutorial for hobby photographers on how to take professional-quality portrait photographs using a DSLR camera. The tutorial should cover understanding camera settings, lighting techniques, choosing backgrounds, and post-processing tips. Supplement the tutorial with code snippets for a website gallery where photographers can upload their portraits, categorize them by the lighting technique used, and receive peer feedback.", "instruction_id": 104, "label": "life assistance"} +{"instruction": "Conduct a comparative analysis on the impact of mindfulness apps on stress reduction. Select 3 popular mindfulness apps, summarize their features, and review the latest research studies or reports on their effectiveness. Provide a recommendation on which app would be most beneficial based on evidence from the studies, user reviews, and functionality.", "instruction_id": 105, "label": "life assistance"} +{"instruction": "I'm a doctor in one hospital. I want to run their first marathon in six months. Design a personalized exercise regimen for me. The program should consider nutritional requirements, and work-life balance and so on. It must include a progressive running schedule, cross-training activities, rest days, and a tapering period before the race. Provide weekly goals and milestones to track progress.", "instruction_id": 106, "label": "life assistance"} +{"instruction": "I live in New York most of the time. Develop a comprehensive guide on how to maximize airline miles and hotel points for family travel, including strategies for credit card usage, bonus point acquisition, and point redemption. The guide should cover the best practices on managing multiple accounts, transferring points between programs, and finding the best value for point redemptions for at least three popular travel loyalty programs.", "instruction_id": 107, "label": "life assistance"} +{"instruction": "Develop a personalized meal plan for a month for a vegan athlete aiming to increase muscle mass while maintaining body fat. The plan should include a variety of nutrient-dense meals with appropriate macro-balancing and an accompanying shopping list. Each recipe should be designed with a specific calorie count and macros in mind, featuring a mix of protein sources such as legumes, tofu, and tempeh.", "instruction_id": 108, "label": "life assistance"} +{"instruction": "I want to learn Japanese in preparation for a trip in six months.Help me create a individual comprehensive guide. The guide should include resources to learn basic conversational phrases, understanding common signs and menus, and cultural etiquette. Additionally, provide a structured weekly study plan that incorporates various learning methodologies such as spaced repetition, immersion, and utilization of online platforms.", "instruction_id": 109, "label": "life assistance"} +{"instruction": "Create a comprehensive guide to planning a balanced weekly meal plan for a family of four with diverse dietary restrictions, including one vegetarian, a child with a nut allergy, and one person following a low-carb diet. The meal plan should be budget-friendly, offer variety, and include a grocery shopping list with alternative options if specific items are not available. Additionally, include time-effective cooking tips and a list of necessary kitchen equipment.", "instruction_id": 110, "label": "life assistance"} +{"instruction": "Create a comprehensive guide on the subject of effective time management techniques for remote workers. The guide should provide annotated suggestions on structuring the day, cutting down distractions, setting boundaries, and using technological tools to increase productivity. Additionally, assess the validity of these techniques based on feedback from forums and articles written by productivity experts.", "instruction_id": 111, "label": "life assistance"} +{"instruction": "I'm in great pressure recently. Develop a comprehensive guide for some people like me seeking to improve their work-life balance. The guide should include a curated list of relevant research articles and statistics, a compendium of practical strategies vetted by professionals using coding to scrape and aggregate data from psychology and productivity websites, and personalized content generation providing hypothetical case studies demonstrating successful application of the strategies.", "instruction_id": 112, "label": "life assistance"} +{"instruction": "Draft an emergency preparedness guide for residents in a coastal city in the USA prone to hurricanes. The guide should include a list of essential supplies and procedures for securing property, planning evacuation routes, and ensuring the safety of pets. Also, provide a comparison chart of various weather alert systems and recommended mobile applications for emergency updates. Summarize the typical timeline of a hurricane from formation to dissipation and what actions should be taken at each stage.", "instruction_id": 113, "label": "life assistance"} +{"instruction": "Develop a beginner's guide to personal finance management that includes strategies for budgeting, saving, investing, and debt management. The guide should be tailored for individuals in their mid-twenties who are just starting their careers. It should provide tools for setting financial goals, advice on creating a budget that allows for both savings and discretionary spending, options for investment platforms that cater to young professionals, and methods for responsibly managing student loans or other debts.", "instruction_id": 114, "label": "life assistance"} +{"instruction": "Create an in-depth analysis of current dietary trends, nutritional information, and health outcomes related to various diets. This should involve programming a tool that collects data from nutrition blogs, health websites, and scientific journals while also implementing natural language processing to summarize the findings. Generate a comprehensive report that evaluates the pros and cons of each diet, supported by up-to-date statistical evidence and expert opinions, all arranged in an easy-to-understand format for the general public.", "instruction_id": 115, "label": "life assistance"} +{"instruction": "I am a tech enthusiast. Create a comprehensive itinerary for a 5-day trip to Tokyo for me, including visits to leading tech companies, museums, and cutting-edge entertainment venues. The trip should offer a blend of scheduled tours, interactive experiences, and personal exploration time. It should also consider dietary restrictions (vegetarian-friendly options), local transportation, and moderate accommodation suggesting. The plan must include contact information and expected costs for all bookings, along with alternative options in case of unforeseen cancellations.", "instruction_id": 116, "label": "life assistance"} +{"instruction": "Create an algorithm that identifies and summarizes research papers related to the Riemann Hypothesis. The algorithm should search for the latest research papers published within the past year on academic databases, extract their abstracts, and summarize the findings in relation to their potential impact on the conjecture's proof.", "instruction_id": 117, "label": "mathematical problem solving"} +{"instruction": "Create a comprehensive tutorial on solving Diophantine equations, specifically Pell's equation, for a range of parameters. Begin by compiling a database of solved examples available on the internet. Generate a step-by-step guide for these types of equations, utilizing code to create a solvable template that can determine the solutions of Pell-type equations for given parameters. Ensure the guide includes explanations of underlying mathematical concepts and strategies for finding solutions.", "instruction_id": 118, "label": "mathematical problem solving"} +{"instruction": "Compile an exhaustive list (5 problems or so) of published mathematical problems that have remained unsolved. For each problem, generate a clear summary of its historical context, significance, and a simplified explanation of the problem statement. Additionally, analyze any common patterns or themes that appear across the problems.", "instruction_id": 119, "label": "mathematical problem solving"} +{"instruction": "Create a tutorial that explains the proof of the Erdős–Szekeres theorem on the existence of a long monotone subsequence within a sequence of a given length.And then compile a list of practical applications for this theorem, including at least one novel application not widely discussed in the literature. The tutorial should be aimed at advanced undergraduate mathematics students.", "instruction_id": 120, "label": "mathematical problem solving"} +{"instruction": "Create a comprehensive tutorial on 'Fourier Transform and its applications in signal processing' using a combination of original text explanations, code examples in Python demonstrating the key concepts, and schematic diagrams or plots to visualize the transformation and its effects on different types of signals. Ensure the educational content bridges the gap between theory and practical application, allowing readers with a basic understanding of university-level mathematics to grasp the advanced concepts presented. Include a section comparing the discrete Fourier transform (DFT) computation using the naive approach versus Fast Fourier Transform (FFT) algorithms.", "instruction_id": 121, "label": "mathematical problem solving"} +{"instruction": "Write a Python script that utilizes the Google Search API to find the most recent articles related to a given set of programming languages (e.g., Python, JavaScript, and Go). The script should parse the search results, extract the article title, publication date, a summary of the article (a brief 2-3 sentences), and its source URL. These details must then be formatted into a Markdown file which organizes the articles by each programming language and by recency of publication.", "instruction_id": 122, "label": "coding and developing"} +{"instruction": "Conduct a comprehensive analysis of the global cybersecurity threat landscape by collecting data from various cybersecurity forums, government reports, and news outlets. Identify the top five most common types of cyberattacks experienced worldwide in the past year, the industries most affected, and the estimated economic impact of these attacks. Compile your findings into a detailed report that includes potential mitigation strategies for businesses and recommendations for policy changes to improve national cybersecurity defenses.", "instruction_id": 123, "label": "search and report"} +{"instruction": "Create an in-depth report on the impact of telecommuting on urban traffic patterns and pollution levels. The report should include data from the last five years in three major cities with different telecommuting adoption rates. Additionally, provide a forecast model for how continued telecommuting trends might alter these factors over the next ten years.", "instruction_id": 124, "label": "search and report"} +{"instruction": "Investigate the current state of renewable energy adoption in the transportation sector. Compile a list of the top ten countries leading in this area and provide a detailed case study on the most innovative practices they are employing. The case study should include the types of renewable energy used, the scale of adoption, the economic impact, and any government incentives or policies that have been effective.", "instruction_id": 125, "label": "search and report"} +{"instruction": "Create a detailed market research document on the electric vehicle (EV) industry's growth in Europe. The document should include the market share of EVs compared to traditional vehicles from 2015 to 2023, the top-selling EV models in 2023, and a forecast of the EV market growth for the next five years. Additionally, analyze the role of government incentives in driving EV adoption. The report should be comprehensive, citing multiple sources and providing a critical analysis of the data.", "instruction_id": 126, "label": "search and report"} +{"instruction": "Conduct a comprehensive analysis of the latest advancements in artificial intelligence and machine learning. Your report should include a historical overview, a summary of current state-of-the-art technologies, and a forecast of potential future developments over the next 20 years. Additionally, identify and evaluate the top 5 companies leading in AI research and development, providing details on their key projects and contributions to the field.", "instruction_id": 127, "label": "search and report"} +{"instruction": "Prepare an in-depth market analysis for electric vehicles (EVs) focusing on consumer trends, technological advancements, and infrastructure development. The report should cover the global market with a special emphasis on the United States, Europe, and China. It should also include a competitive analysis of the top EV manufacturers, their market share, and their strategies for the coming years. Lastly, provide recommendations for new entrants into the EV market.", "instruction_id": 128, "label": "search and report"} +{"instruction": "Create an in-depth market analysis report on the rise of plant-based meat alternatives. Use web search to identify key players in the industry, such as Beyond Meat and Impossible Foods, and gather information on their product offerings, market share, and business strategies. Utilize web browsing to access financial reports, consumer reviews, and expert analyses to evaluate the performance and reception of these products in the market. Code a script to scrape data from social media platforms to gauge public sentiment and trends regarding plant-based meat. Synthesize all the collected data and insights into a detailed report that includes an executive summary, market analysis, competitive landscape, consumer sentiment analysis, and future growth projections.", "instruction_id": 129, "label": "search and report"} +{"instruction": "Create a detailed guide on the latest advancements in renewable energy technologies, focusing on solar, wind, and hydroelectric power. The guide should include an overview of the current state of these technologies, recent breakthroughs, and a comparative analysis of their efficiency, cost, and environmental impact. Additionally, identify the leading countries in renewable energy technology and discuss the economic and policy factors driving their advancements.", "instruction_id": 130, "label": "search and report"} +{"instruction": "Develop a strategic plan for a hypothetical e-commerce startup that aims to compete with Amazon in niche markets. Start by using web search to identify niche markets where Amazon's presence is less dominant, such as artisanal crafts or specialized tech gadgets. Browse through market research, consumer forums, and trend analyses to understand the needs and preferences of customers in these niches. Code a web crawler to extract data on product offerings, pricing, and customer reviews from existing e-commerce platforms that serve these niche markets. Use this information to generate a strategic plan that outlines the startup's unique value proposition, marketing strategy, product range, pricing model, and customer service approach. The plan should also include a SWOT analysis (Strengths, Weaknesses, Opportunities, Threats) to identify potential challenges and opportunities.", "instruction_id": 131, "label": "search and report"} +{"instruction": "Investigate the impact of artificial intelligence (AI) on job automation across different sectors. Compile a list of jobs that have been most affected by AI in the last decade, and predict which jobs are at risk in the next decade. For each job category, provide an analysis of the skills that are being replaced by AI and those that are still in demand. Finally, propose a set of educational or training programs that could help workers transition to roles that are less likely to be automated.", "instruction_id": 132, "label": "search and report"} +{"instruction": "Create a report on the impact of climate change on global food security. The report should include a case study on three different countries from separate continents, detailing how climate change has affected their agricultural output and what measures they are taking to adapt. Additionally, the report should forecast the potential global food security situation in the next decade based on current trends.", "instruction_id": 133, "label": "search and report"} +{"instruction": "Conduct a comprehensive analysis of the impact of climate change on global coffee production. Start by identifying the top five coffee-producing countries. Use web search to find the latest research papers and reports on the effects of climate change on coffee crops in these countries. Summarize the findings and predict how coffee production might change in the next decade. Additionally, generate a list of potential adaptation strategies that farmers are implementing or could implement to mitigate these effects.", "instruction_id": 134, "label": "search and report"} +{"instruction": "Develop a comparative study on the effectiveness of online education platforms during the COVID-19 pandemic. The study should evaluate platforms based on user engagement, educational outcomes, accessibility, and technological innovation. Gather user reviews, academic studies, and performance metrics to support your analysis. Conclude with recommendations for improvements in online education delivery.", "instruction_id": 135, "label": "search and report"} +{"instruction": "Create a personalized workout and nutrition plan for a 30-year-old male who wants to run a marathon in six months. The plan should include a detailed weekly exercise schedule, dietary recommendations, and a list of supplements. Additionally, compile a list of the top 5 local running clubs or communities he can join for support and training, including their contact information and membership fees.", "instruction_id": 136, "label": "life assistance"} +{"instruction": "Develop a comprehensive guide for relocating to Tokyo, Japan, for an English-speaking family. The guide should include a comparison of international schools for their children, a list of expat-friendly neighborhoods with average rental prices, and a step-by-step plan for the visa application process. Additionally, provide a curated list of cultural etiquette tips and basic Japanese phrases that will help them settle in more comfortably.", "instruction_id": 137, "label": "life assistance"} +{"instruction": "Create a comprehensive guide for individuals looking to adopt a pet for the first time. The guide should include a step-by-step process for choosing the right type of pet based on lifestyle, preparing one's home for the new arrival, understanding the financial commitment, and a list of resources for new pet owners, such as training classes, veterinary care, and pet insurance options. Additionally, compile a list of reputable pet adoption agencies and online platforms within the user's locality, including reviews and ratings.", "instruction_id": 138, "label": "life assistance"} +{"instruction": "Develop an algorithm that can identify and classify types of singularities (removable, pole, or essential) for any given complex function. Implement the algorithm in Python, and test it on the function f(z) = sin(z)/(z^2 - z). Provide a detailed report on the methodology, the code, and the results of the classification.", "instruction_id": 139, "label": "mathematical problem solving"} +{"instruction": "I need to create a website for selling homemade candles. Can you write a simple code for the website, and help me set up the site using a web server? The website needs the following pages: home, products, about us, and contact information. Please also provide a detailed explanation of each part of the code.", "instruction_id": 140, "label": "coding and developing"} +{"instruction": "Automate the process of searching for the latest research papers on a given mathematical problem (e.g., the Riemann Hypothesis), summarizing their findings, and identifying any common themes or breakthroughs. The system should be able to parse the abstracts and conclusions of the papers, and generate a comprehensive summary report that includes potential implications for future research.", "instruction_id": 141, "label": "mathematical problem solving"} +{"instruction": "Write a blog post that explains how to use the OpenAI GPT-3 model for text generation. The post should include an introduction to GPT-3, a brief explanation of how it works, and a step-by-step guide on how to use the OpenAI API to generate text with GPT-3. The post should also include Python code examples where necessary.", "instruction_id": 142, "label": "coding and developing"} +{"instruction": "Develop an in-depth analysis of the Internet’s evolution, focusing on its technological advancements, regulatory changes, and cultural impacts from the 1990s to today. Your analysis should include major milestones in internet speed and infrastructure, shifts in web technologies, and significant policy developments that have shaped user experience and privacy. Also, add a section on the sociocultural implications of these changes, particularly on global communication and the digital divide. Use a variety of sources, such as technical white papers, policy documents, and authoritative tech journalism, to ensure a multi-faceted perspective.", "instruction_id": 143, "label": "search and report"} +{"instruction": "I'm planning a trip to Japan. Could you help me assemble a detailed itinerary? The trip will last for two weeks. I want to visit Tokyo, Kyoto, and Osaka. I'm interested in historical sites, local cuisines, and shopping areas. Also, please find the information about public transportation and accommodations between these cities.", "instruction_id": 144, "label": "life assistance"} +{"instruction": "Develop a detailed report on the impact of climate change on coastal cities over the last decade. Use web search functions to source academic papers, news articles, and governmental reports on the subject. Structure the report to include an overview of the data trends, present case studies of three severely affected cities, and provide a synthesized forecast of potential developments based on the gathered information.", "instruction_id": 145, "label": "search and report"} +{"instruction": "Create a comprehensive guide comparing the privacy policies of the top 5 social media platforms. Evaluate each platform's policy on user data collection, data usage, third-party sharing, and the availability of user privacy controls. Summarize key points and give a comparative overview with practical recommendations for users concerned about their privacy online.", "instruction_id": 146, "label": "search and report"} +{"instruction": "Give a weather forecast for the next three days for Beijing. The forecast should include temperature highs/lows, any expected precipitation, and general conditions. Also, recommend precaution measures to take for the predicted weather conditions.", "instruction_id": 147, "label": "life assistance"} +{"instruction": "You are tasked to create a profile for each country in the G20, detailing its GDP, main industries, population, political structure, and trade relations, particularly focusing on technology sector agreements and trade deals within the last 10 years. The profile should be formatted as a comparative analysis over time, highlighting growth trends, policy shifts, and economic impacts of such agreements. Data should be sourced from official statistical bureaus, international trade bodies, and verified news reports, with all sources properly referenced in your report.", "instruction_id": 148, "label": "search and report"} +{"instruction": "Create a personalized weekly meal plan for a vegetarian with a gluten intolerance that includes detailed recipes, shopping lists, and nutritional information for each meal. Consider the current season to maximize the use of fresh and local produce, and ensure there is sufficient caloric and macronutrient intake based on an active lifestyle.", "instruction_id": 149, "label": "life assistance"} +{"instruction": "Present an analysis of Bitcoin, Etherum and Dogecoin cryptocurrency values over the last year. Prepare a comprehensive report on their performance trends, market volatility, major influencing factors, predictions for the next year, and a comparison among them.", "instruction_id": 150, "label": "search and report"} +{"instruction": "Develop a script which could model a linear regression, and use the script to analysis some data to test.\n The script should be displayed directly in text format.", "instruction_id": 151, "label": "mathematical problem solving"} +{"instruction": "Conduct a comprehensive analysis of the latest cybersecurity threats for small to medium-sized businesses (SMBs). Identify the top five threats based on frequency and potential impact, and develop a detailed guide on how SMBs can protect themselves against these threats. The guide should include a comparison of different cybersecurity software solutions, their costs, and how to implement them effectively.\n", "instruction_id": 152, "label": "search and report"} diff --git a/dockerfiles/client.Dockerfile b/dockerfiles/client.Dockerfile new file mode 100644 index 0000000..21db3af --- /dev/null +++ b/dockerfiles/client.Dockerfile @@ -0,0 +1,19 @@ +# start with a python:3.10 image +FROM python:3.10.13-slim + +# Mark the role played by this container as ReAct Agent +EXPOSE 5050 + +# Set the working directory in the container +WORKDIR /app + +COPY im_client/requirements.txt /app/requirements.txt +RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && pip install --no-cache-dir -r requirements.txt + +# Copy the current directory contents into container at /app +COPY ./im_client /app +COPY ./common /app/common + +# Set the entry point for running the test_react_agent python file +ENTRYPOINT [ "python", "main.py" ] + diff --git a/dockerfiles/compose/.env_template b/dockerfiles/compose/.env_template new file mode 100644 index 0000000..6c479d9 --- /dev/null +++ b/dockerfiles/compose/.env_template @@ -0,0 +1,10 @@ +OPENAI_API_KEY= +OPENAI_BASE_URL= +OPENAI_API_BASE_URL= +OPENAI_API_BASE= +OPENAI_RESPONSE_LOG_PATH= + +GOOGLE_API_KEY= +GOOGLE_CUSTOM_SEARCH_ENGINE_ID= + +BING_API_KEY= \ No newline at end of file diff --git a/dockerfiles/compose/basic.yaml b/dockerfiles/compose/basic.yaml new file mode 100644 index 0000000..558d820 --- /dev/null +++ b/dockerfiles/compose/basic.yaml @@ -0,0 +1,79 @@ +# Set the current version of compose yml file +version: "3" + +services: + Server: + image: ioa-server:latest + build: + context: ../../ + dockerfile: dockerfiles/server.Dockerfile + container_name: ioa-server + volumes: + - ../../configs/server_configs:/app/configs + env_file: + - .env + environment: + - OPENAI_API_KEY + ports: + - 7788:7788 + stdin_open: true + tty: true + + Agent1: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: react-agent-1 + env_file: + - .env + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ../../configs/client_configs:/app/configs + environment: + - OPENAI_API_KEY + ports: + - 5050:5050 + depends_on: + - Server + stdin_open: true + tty: true + + # Agent2: + # image: ioa-client:latest + # build: + # context: ../../ + # dockerfile: dockerfiles/client.Dockerfile + # container_name: react-agent-2 + # env_file: + # - .env + # volumes: + # - /var/run/docker.sock:/var/run/docker.sock + # - ../../configs/client_configs:/app/configs + # environment: + # - OPENAI_API_KEY + # ports: + # - 5051:5050 + # depends_on: + # - Server + # stdin_open: true + # tty: true + + ServerFrontend: + image: ioa-server-frontend:latest + build: + context: ../../ + dockerfile: dockerfiles/server_frontend.Dockerfile + container_name: server_frontend + ports: + - 80:80 + depends_on: + - Server + stdin_open: true + tty: true + +networks: + default: + name: agent_network + driver: bridge + external: true diff --git a/dockerfiles/compose/gaia.yaml b/dockerfiles/compose/gaia.yaml new file mode 100644 index 0000000..586a4df --- /dev/null +++ b/dockerfiles/compose/gaia.yaml @@ -0,0 +1,125 @@ +# Set the current version of compose yml file +version: "3" + +services: + Server: + image: ioa-server:latest + build: + context: ../../ + dockerfile: dockerfiles/server.Dockerfile + container_name: ioa-server + env_file: + - .env + volumes: + - ./volumes/sqlite:/app/database + - ../../configs/server_configs:/app/configs + ports: + - 7788:7788 + stdin_open: true + tty: true + + WebBrowser: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: web_browser + env_file: + - .env + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./volumes/sqlite:/app/database + - ./volumes/openai_response_log:${OPENAI_RESPONSE_LOG_PATH} + - ../../configs/client_configs:/app/configs + environment: + - CUSTOM_CONFIG=configs/cases/gaia/web_browser.yaml + ports: + - 5050:5050 + depends_on: + - Server + stdin_open: true + tty: true + + CodeExecutor: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: code_executor + env_file: + - .env + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./volumes/sqlite:/app/database + - ./volumes/openai_response_log:${OPENAI_RESPONSE_LOG_PATH} + - ../../configs/client_configs:/app/configs + environment: + - CUSTOM_CONFIG=configs/cases/gaia/code_executor.yaml + ports: + - 5051:5050 + depends_on: + - Server + stdin_open: true + tty: true + + YouTube: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: youtube + env_file: + - .env + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./volumes/sqlite:/app/database + - ./volumes/openai_response_log:${OPENAI_RESPONSE_LOG_PATH} + - ../../configs/client_configs:/app/configs + environment: + - CUSTOM_CONFIG=configs/cases/gaia/youtube.yaml + ports: + - 5052:5050 + depends_on: + - Server + stdin_open: true + tty: true + + Wikidata: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: wikidata + env_file: + - .env + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./volumes/sqlite:/app/database + - ./volumes/openai_response_log:${OPENAI_RESPONSE_LOG_PATH} + - ../../configs/client_configs:/app/configs + environment: + - CUSTOM_CONFIG=configs/cases/gaia/wikidata.yaml + ports: + - 5053:5050 + depends_on: + - Server + stdin_open: true + tty: true + + ServerFrontend: + image: ioa-server-frontend:latest + build: + context: ../../ + dockerfile: dockerfiles/server_frontend.Dockerfile + container_name: server_frontend + ports: + - 80:80 + depends_on: + - Server + stdin_open: true + tty: true + +networks: + default: + name: agent_network + external: true diff --git a/dockerfiles/compose/milvus.yaml b/dockerfiles/compose/milvus.yaml new file mode 100644 index 0000000..dd60ee2 --- /dev/null +++ b/dockerfiles/compose/milvus.yaml @@ -0,0 +1,77 @@ +# Set the current version of compose yml file +version: "3" + +services: + etcd: + container_name: milvus-etcd + image: quay.io/coreos/etcd:v3.5.5 + environment: + - ETCD_AUTO_COMPACTION_MODE=revision + - ETCD_AUTO_COMPACTION_RETENTION=1000 + - ETCD_QUOTA_BACKEND_BYTES=4294967296 + - ETCD_SNAPSHOT_COUNT=50000 + volumes: + - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/etcd:/etcd + command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd + healthcheck: + test: ["CMD", "etcdctl", "endpoint", "health"] + interval: 30s + timeout: 20s + retries: 3 + + minio: + container_name: milvus-minio + image: minio/minio:RELEASE.2023-03-20T20-16-18Z + environment: + MINIO_ACCESS_KEY: minioadmin + MINIO_SECRET_KEY: + minioadmin + # ports: + # - "9001:9001" + # - "9000:9000" + volumes: + - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/minio:/minio_data + command: minio server /minio_data --console-address ":9001" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] + interval: 30s + timeout: 20s + retries: 3 + + standalone: + container_name: milvus-standalone + image: milvusdb/milvus:v2.3.3 + command: ["milvus", "run", "standalone"] + security_opt: + - seccomp:unconfined + environment: + ETCD_ENDPOINTS: etcd:2379 + MINIO_ADDRESS: minio:9000 + KNOWHERE_GPU_MEM_POOL_SIZE: 2048;4096 + volumes: + - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"] + interval: 30s + start_period: 90s + timeout: 20s + retries: + 3 + # ports: + # - "19530:19530" + # - "9091:9091" + depends_on: + - "etcd" + - "minio" + + attu: + container_name: attu + image: zilliz/attu:latest + environment: + MILVUS_URL: standalone:19530 + ports: + - "8000:3000" +networks: + default: + name: agent_network + external: true diff --git a/dockerfiles/compose/open_instruction.yaml b/dockerfiles/compose/open_instruction.yaml new file mode 100644 index 0000000..c73af52 --- /dev/null +++ b/dockerfiles/compose/open_instruction.yaml @@ -0,0 +1,93 @@ +# Set the current version of compose yml file +version: "3" + +services: + Server: + image: ioa-server:latest + build: + context: ../../ + dockerfile: dockerfiles/server.Dockerfile + container_name: ioa-server + env_file: + - .env + environment: + - OPENAI_API_KEY + #- OPENAI_BASE_URL + volumes: + - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/sqlite:/app/database + - ../../configs/server_configs:/app/configs + ports: + - 7788:7788 + stdin_open: true + tty: true + + AutoGPT: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: autogpt-client + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./volumes/autogpt/log:/app/tool_agent_log + - ./volumes/openai_response_log:${OPENAI_RESPONSE_LOG_PATH} + - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/sqlite:/app/database + - ../../configs/client_configs:/app/configs + env_file: + - .env + environment: + - HEADLESS_BROWSER=True + - USE_WEB_BROWSER=firefox + - SMART_LLM=gpt-4-1106-preview + - FAST_LLM=gpt-4-1106-preview + - EXECUTE_LOCAL_COMMANDS=True + - DISABLED_COMMANDS=web_search + - CUSTOM_CONFIG=configs/cases/open_instruction/autogpt.yaml + ports: + - 5050:5050 + depends_on: + - Server + stdin_open: true + tty: true + + OpenInterpreter: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: open-interpreter-client + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./volumes/openInterpreter/log:/app/tool_agent_log + - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/sqlite:/app/database + - ./volumes/openai_response_log:${OPENAI_RESPONSE_LOG_PATH} + - ../../configs/client_configs:/app/configs + env_file: + - .env + environment: + - CUSTOM_CONFIG=configs/cases/open_instruction/open_interpreter.yaml + ports: + - 5051:5050 + depends_on: + - Server + stdin_open: true + tty: true + + ServerFrontend: + image: ioa-server-frontend:latest + build: + context: ../../ + dockerfile: dockerfiles/server_frontend.Dockerfile + container_name: server_frontend + ports: + - 80:80 + depends_on: + - Server + stdin_open: true + tty: true + +networks: + default: + name: agent_network + external: true + # driver: bridge diff --git a/dockerfiles/compose/paper_writing.yml b/dockerfiles/compose/paper_writing.yml new file mode 100644 index 0000000..b6fd535 --- /dev/null +++ b/dockerfiles/compose/paper_writing.yml @@ -0,0 +1,133 @@ +# Set the current version of compose yml file +version: "3" + +services: + Server: + image: ioa-server:latest + build: + context: ../../ + dockerfile: dockerfiles/server.Dockerfile + container_name: ioa-server + env_file: + - .env + volumes: + - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/sqlite:/app/database + - ../../configs/server_configs:/app/configs + environment: + - OPENAI_API_KEY + ports: + - 7788:7788 + stdin_open: true + tty: true + + WeizeChen: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: weize + env_file: + - .env + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/sqlite:/app/database + - ./volumes/openai_response_log:${OPENAI_RESPONSE_LOG_PATH} + - ../../configs/client_configs:/app/configs + environment: + - OPENAI_API_KEY + - CUSTOM_CONFIG=configs/cases/paper_writing/weizechen.yaml + ports: + - 5050:5050 + depends_on: + - Server + stdin_open: true + tty: true + + ChenQian: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: chenqian + env_file: + - .env + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/sqlite:/app/database + - ./volumes/openai_response_log:${OPENAI_RESPONSE_LOG_PATH} + - ../../configs/client_configs:/app/configs + environment: + - OPENAI_API_KEY + - CUSTOM_CONFIG=configs/cases/paper_writing/chenqian.yaml + ports: + - 5051:5050 + depends_on: + - Server + stdin_open: true + tty: true + + ChengYang: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: chengyang + env_file: + - .env + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/sqlite:/app/database + - ./volumes/openai_response_log:${OPENAI_RESPONSE_LOG_PATH} + - ../../configs/client_configs:/app/configs + environment: + - OPENAI_API_KEY + - CUSTOM_CONFIG=configs/cases/paper_writing/chengyang.yaml + ports: + - 5052:5050 + depends_on: + - Server + stdin_open: true + tty: true + + Arxiv: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: arxiv + env_file: + - .env + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/sqlite:/app/database + - ./volumes/openai_response_log:${OPENAI_RESPONSE_LOG_PATH} + - ../../configs/client_configs:/app/configs + environment: + - OPENAI_API_KEY + - OPENAI_BASE_URL + - CUSTOM_CONFIG=configs/cases/paper_writing/arxiv.yaml + ports: + - 5053:5050 + depends_on: + - Server + stdin_open: true + tty: true + + ServerFrontend: + image: ioa-server-frontend:latest + build: + context: ../../ + dockerfile: dockerfiles/server_frontend.Dockerfile + container_name: server_frontend + ports: + - 80:80 + depends_on: + - Server + stdin_open: true + tty: true + +networks: + default: + name: agent_network + external: true + # driver: bridge diff --git a/dockerfiles/compose/rocobench.yaml b/dockerfiles/compose/rocobench.yaml new file mode 100644 index 0000000..a1a9b79 --- /dev/null +++ b/dockerfiles/compose/rocobench.yaml @@ -0,0 +1,141 @@ +# Set the current version of compose yml file +version: "3" + +services: + Server: + image: ioa-server:latest + build: + context: ../../ + dockerfile: dockerfiles/server.Dockerfile + container_name: ioa-server + volumes: + - ../../configs/server_configs:/app/configs + env_file: + - .env + environment: + - OPENAI_API_KEY + #- OPENAI_BASE_URL + ports: + - 7788:7788 + stdin_open: true + tty: true + + Alice: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: alice + env_file: + - .env + environment: + - OPENAI_API_KEY + #- OPENAI_BASE_URL + - CUSTOM_CONFIG=configs/cases/rocobench/alice.yaml + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ../../configs/client_configs:/app/configs + ports: + - 5050:5050 + depends_on: + - Server + stdin_open: true + tty: true + + # WeizeChenFrontend: + # image: ioa-frontend:latest + # build: + # context: ../../ + # dockerfile: dockerfiles/frontend.Dockerfile + # container_name: weize_frontend + # ports: + # - 80:80 + # depends_on: + # - WeizeChen + # stdin_open: true + # tty: true + + Bob: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: bob + env_file: + - .env + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ../../configs/client_configs:/app/configs + environment: + - OPENAI_API_KEY + #- OPENAI_BASE_URL + - CUSTOM_CONFIG=configs/cases/rocobench/bob.yaml + ports: + - 5051:5050 + depends_on: + - Server + stdin_open: true + tty: true + + Chad: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: chad + env_file: + - .env + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ../../configs/client_configs:/app/configs + environment: + - OPENAI_API_KEY + #- OPENAI_BASE_URL + - CUSTOM_CONFIG=configs/cases/rocobench/chad.yaml + ports: + - 5052:5050 + depends_on: + - Server + stdin_open: true + tty: true + + Dave: + image: ioa-client:latest + build: + context: ../../ + dockerfile: dockerfiles/client.Dockerfile + container_name: dave + env_file: + - .env + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ../../configs/client_configs:/app/configs + environment: + - OPENAI_API_KEY + #- OPENAI_BASE_URL + - CUSTOM_CONFIG=configs/cases/rocobench/dave.yaml + ports: + - 5053:5050 + depends_on: + - Server + stdin_open: true + tty: true + + ServerFrontend: + image: ioa-server-frontend:latest + build: + context: ../../ + dockerfile: dockerfiles/server_frontend.Dockerfile + container_name: server_frontend + ports: + - 80:80 + depends_on: + - Server + stdin_open: true + tty: true + +networks: + default: + name: agent_network + external: true + # driver: bridge diff --git a/dockerfiles/server.Dockerfile b/dockerfiles/server.Dockerfile new file mode 100644 index 0000000..d07cb2a --- /dev/null +++ b/dockerfiles/server.Dockerfile @@ -0,0 +1,18 @@ +# start with a python:3.10 image +FROM python:3.10.13-slim + +# Mark the role played by this container as ReAct Agent +EXPOSE 7788 + +# Set the working directory in the container +WORKDIR /app + +# Copy the current directory contents into container at /app +COPY ./im_server/requirements.txt ./ +RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && pip install --no-cache-dir -r requirements.txt +COPY ./im_server ./ +COPY ./common ./common + +# Set the entry point for running the test_react_agent python file +ENTRYPOINT [ "python", "app.py" ] +# ENTRYPOINT [ "gunicorn", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "--bind", "0.0.0.0:7788", "app:app" ] diff --git a/dockerfiles/server_frontend.Dockerfile b/dockerfiles/server_frontend.Dockerfile new file mode 100644 index 0000000..3e20c7c --- /dev/null +++ b/dockerfiles/server_frontend.Dockerfile @@ -0,0 +1,30 @@ +# Step 1: Use an official Node.js runtime as a parent image +FROM node:14 as build + +# Step 2: Set the working directory in the container +WORKDIR /app + +# Step 3: Copy the package.json files from your project into the container +COPY im_server/frontend/package*.json ./ + +# Step 4: Install any dependencies +RUN npm config set registry https://registry.npmmirror.com && npm install + +# Step 5: Copy the rest of your app's source code from your project into the container +COPY im_server/frontend . + +# Step 6: Your app binds to port 3000 so you'll use the EXPOSE instruction to have it mapped by the docker daemon +# EXPOSE 3000 + +# Step 7: Define the command to run your app using CMD which defines your runtime +# CMD ["npm", "run", "build"] +RUN npm run build + +# Stage 2: Serve the application with Nginx +FROM nginx:alpine + +COPY --from=build /app/build /usr/share/nginx/html + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/dockerfiles/tool_agents/autogpt.Dockerfile b/dockerfiles/tool_agents/autogpt.Dockerfile new file mode 100644 index 0000000..887234d --- /dev/null +++ b/dockerfiles/tool_agents/autogpt.Dockerfile @@ -0,0 +1,16 @@ +FROM significantgravitas/auto-gpt:latest-dev + +RUN echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware \n\ +deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware \n\ +deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware \n\ +deb https://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware" | tee /etc/apt/sources.list +RUN cat /etc/apt/sources.list + +RUN apt-get update --fix-missing && apt-get install -y \ +chromium-driver firefox-esr \ +ca-certificates \ +libglib2.0-0 libnss3 libgconf-2-4 libfontconfig1 + +# Fix bugs in AutoGPT's docker +COPY im_client/agents/autogpt/autogpt_patch/web_selenium_latest_dev.py /app/autogpt/commands/web_selenium.py +COPY im_client/agents/autogpt/autogpt_patch/pyproject_latest_dev.toml /app/pyproject.toml \ No newline at end of file diff --git a/dockerfiles/tool_agents/open_interpreter.Dockerfile b/dockerfiles/tool_agents/open_interpreter.Dockerfile new file mode 100644 index 0000000..28c3cd0 --- /dev/null +++ b/dockerfiles/tool_agents/open_interpreter.Dockerfile @@ -0,0 +1,29 @@ +# start with a python:3.10 image +FROM python:3.10.13-slim + +# RUN echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware \n\ +# deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware \n\ +# deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware \n\ +# deb https://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware" | tee /etc/apt/sources.list + +EXPOSE 7070 + +# Set the working directory in the container +WORKDIR /app + +# Copy the requirements.txt into container at /app +COPY im_client/agents/open_interpreter/requirements.txt . + +RUN apt-get update && apt-get install -y gcc \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# Intall the project dependencies dynamically +RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple \ + && pip install --no-cache-dir -r requirements.txt + +# Copy the current directory contents into container at /app +COPY im_client/agents/open_interpreter . + +# Set the entry point for running the test_react_agent python file +ENTRYPOINT [ "python", "open_interpreter_agent.py" ] + diff --git a/dockerfiles/tool_agents/react.Dockerfile b/dockerfiles/tool_agents/react.Dockerfile new file mode 100644 index 0000000..a9d5457 --- /dev/null +++ b/dockerfiles/tool_agents/react.Dockerfile @@ -0,0 +1,33 @@ +# start with a python:3.10 image +FROM python:3.10.13-slim + +EXPOSE 7070 + +# Set the working directory in the container +WORKDIR /app + +# RUN echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware \n\ +# deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware \n\ +# deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware \n\ +# deb https://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware" > /etc/apt/sources.list + +# Copy the requirements.txt into container at /app +COPY im_client/agents/react/requirements.txt . + +RUN apt-get update \ + && apt-get install --no-install-recommends -y git \ + && pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple \ + && pip install --no-cache-dir -r requirements.txt \ + && playwright install --with-deps chromium \ + && apt-get autoremove -y git \ + && rm -rf /var/lib/apt/lists/* + +COPY im_client/agents/react /app +COPY im_client/agents/tools /app/tools +COPY common /app/common +COPY im_client/llms /app/llms +COPY im_client/memory /app/memory +COPY im_client/prompts /app/prompts + +# Set the entry point for running the test_react_agent python file +ENTRYPOINT [ "python", "react_agent.py" ] diff --git a/im_client/__init__.py b/im_client/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/im_client/agents/__init__.py b/im_client/agents/__init__.py new file mode 100644 index 0000000..f1f84a8 --- /dev/null +++ b/im_client/agents/__init__.py @@ -0,0 +1,7 @@ +import yaml +import os + +from .base import AgentAdapter +from .react import ReActAgent +from .open_interpreter import OpenInterpreterAgent +from .autogpt import AutoGPTAgent diff --git a/im_client/agents/autogpt/__init__.py b/im_client/agents/autogpt/__init__.py new file mode 100644 index 0000000..cd6130e --- /dev/null +++ b/im_client/agents/autogpt/__init__.py @@ -0,0 +1 @@ +from .autogpt_adapter import AutoGPTAgent diff --git a/im_client/agents/autogpt/autogpt_adapter.py b/im_client/agents/autogpt/autogpt_adapter.py new file mode 100644 index 0000000..b3321b6 --- /dev/null +++ b/im_client/agents/autogpt/autogpt_adapter.py @@ -0,0 +1,265 @@ +from .. import AgentAdapter +from docker.models.containers import Container +import requests +from common.config import global_config +import os +import json +import time +import aiohttp +import asyncio +import traceback + + +class AutoGPTAgent(AgentAdapter): + def __init__(self, docker_container: Container, agent_name: str): + self.docker_container = docker_container + self.agent_name = agent_name + self.task_desc = "" + # Agent Protocol endpoints + self.url = f"http://{global_config['tool_agent']['container_name']}:8000/ap/v1/agent/tasks" + + # create log directory + self.log_path = f"/app/tool_agent_log" + + if not os.path.exists(self.log_path): + os.makedirs(self.log_path) + + async def run(self, task_desc: str): + headers = {"Content-Type": "application/json"} + task_desc = ( + task_desc + + "\nDo not ask user anything. The task must be ended with a detailed description of the solution and the actions that have been done." + ) + + task_id = await self.create_task(task_desc, headers) + + if not task_id: + return "Failed to create the task." + + await self.complete_task(task_id, headers) + + conclusion = await self.draw_conclusion(task_id, headers) + + # save the log + await self.save_autogpt_log(task_id, task_desc, conclusion, headers) + return conclusion + + async def create_task(self, task_desc: str, headers: dict, max_tries: int = 8) -> str | None: + """ + Attempt to create a task with a retry mechanism. + + This function sends an HTTP POST request to create a new task. It retries + the request up to `max_tries` times in case of failure, waiting 5 seconds + between attempts. If the task creation is successful, it returns the task ID + as a string. If all retries fail, it returns None. + + Parameters: + task_desc (str): The description of the task to be created. + headers (dict): The headers to include in the request. + max_tries (int, optional): The maximum number of retry attempts (default is 8). + + Returns: + str or None: The task ID as a string if the task creation is successful; None if it fails. + """ + retry = 1 + async with aiohttp.ClientSession() as session: + while retry <= max_tries: + async with session.post( + self.url, + json={ + "input": "Here is a task that you should finish: " + task_desc, + "additional_input": {}, + }, + headers=headers, + ) as response: + try: + task_info = await response.json() + task_id = task_info["task_id"] + return task_id + except Exception as e: + print(f"error while creating task...:{e}") + print(traceback.print_exc()) + await asyncio.sleep(5) + retry += 1 + return None + + async def complete_task(self, task_id: str, headers: dict, max_steps: int = 20): + """ + Execute the task steps until completion or a maximum number of steps is reached. + + This function sends repeated HTTP POST requests to execute the steps of the task. + It continues to send requests until the task is completed or the maximum number of + steps is reached. If the cumulative cost of the task exceeds a certain threshold, + a different input is sent to expedite the task completion. + + Args: + task_id (str): The ID of the task to be completed. + headers (dict): The headers to include in the request. + max_steps (int): The maximum number of steps to attempt (default is 20). + + Returns: + This function does not return any value. + """ + current_step = 1 + cost = 0 + + async with aiohttp.ClientSession() as session: + while True: + try: + if float(cost) > 1.5: + async with session.post( + self.url + "/" + str(task_id) + "/steps", + json={ + "input": "You should finish the task as quickly as possible.", + "additional_input": {}, + }, + headers=headers, + ) as response: + step = await response.json() + else: + async with session.post( + self.url + "/" + str(task_id) + "/steps", + headers=headers, + ) as response: + step = await response.json() + except Exception as e: + print(f"error while making one step...:{e}") + traceback.print_exc() + await asyncio.sleep(3) + continue + + if step: + if ( + "additional_output" in step + and step["additional_output"] + and "task_cumulative_cost" in step["additional_output"] + ): + cost = step["additional_output"]["task_cumulative_cost"] + else: + await asyncio.sleep(3) + continue + print(str(step)) + + if "is_last" in step: + current_step += 1 + if current_step >= max_steps or step["is_last"]: + break + + async def draw_conclusion(self, task_id: str, headers: dict, max_steps: int = 20) -> str: + """ + Retrieve the conclusion of the task. + + This function sends an HTTP POST request to retrieve the conclusion of the task. + It continues to retrieve the task's steps until the task is completed or the maximum + number of steps is reached. + + Args: + task_id (str): The ID of the task. + headers (dict): The headers to include in the request. + + Returns: + str: The compiled conclusion of the task. + """ + conclusion = "" + async with aiohttp.ClientSession() as session: + # create the task for conclusion + while True: + try: + async with session.post( + self.url + "/" + str(task_id) + "/steps", + json={ + "input": "Now you should summarize and provide a complied and complete conclusion in text form as the final answer to the previous task I assigned to you. If there are any files in the final answer, please print them out. You should focus on compiling the information gathered and so do not use any web or code commands.", + "additional_input": {}, + }, + headers=headers, + ) as response: + step = await response.json() + if step: + print(str(step)) + if "output" in step: + conclusion += str(step["output"]) + "\n" + break + except Exception as e: + print(f"error while creating the task for conclusion...:{e}") + traceback.print_exc() + await asyncio.sleep(3) + + current_step = 1 + while True: + if step and "is_last" in step and step["is_last"]: + break + try: + async with session.post( + self.url + "/" + str(task_id) + "/steps", + headers=headers, + ) as response: + step = await response.json() + if step: + print(str(step)) + if "output" in step: + conclusion += str(step["output"]) + "\n" + current_step += 1 + if current_step >= max_steps: + break + else: + await asyncio.sleep(3) + except Exception as e: + print(f"error while drawing conclusion...:{e}") + traceback.print_exc() + await asyncio.sleep(3) + return conclusion + + async def save_autogpt_log(self, task_id: str, task_desc: str, conclusion: str, headers: dict) -> str | None: + """ + Save the task and its steps to a log file. + + This function retrieves the task and its steps and saves them to a log file in JSON format. + + Args: + task_id (str): The ID of the task. + task_desc (str): The description of the task. + headers (dict): The headers to include in the request. + Returns: + str: The file path of the saved log. + """ + retry = 1 + max_retries = 5 + async with aiohttp.ClientSession() as session: + while True: + try: + async with session.get( + self.url + "/" + str(task_id), + headers=headers, + ) as response: + task = await response.json() + async with session.get( + self.url + "/" + str(task_id) + "/steps", + headers=headers, + ) as response: + steps = await response.json() + item = { + "task_id": task_id, + "task_desc": task_desc, + "task": task, + "steps": steps, + "conclusion": conclusion, + } + # 文件名以 task_id 命名,保存为 .json 格式 + filename = f"{item['task_id']}.json" + file_path = os.path.join(self.log_path, filename) + with open(file_path, "w", encoding="utf-8") as f: + json.dump(item, f, ensure_ascii=False, indent=4) + print(conclusion) + print(f"Task completion process has been recorded successfully to {file_path}.") + return file_path + + except Exception as e: + print(f"error while saving the log...:{e}") + traceback.print_exc() + await asyncio.sleep(3) + retry += 1 + if retry >= max_retries: + return None + + async def shutdown(self): + await self.docker_container.remove(force=True) diff --git a/im_client/agents/autogpt/autogpt_patch/pyproject_latest_dev.toml b/im_client/agents/autogpt/autogpt_patch/pyproject_latest_dev.toml new file mode 100644 index 0000000..64de0f1 --- /dev/null +++ b/im_client/agents/autogpt/autogpt_patch/pyproject_latest_dev.toml @@ -0,0 +1,163 @@ +[tool.poetry] +name = "agpt" +version = "0.5.0" +authors = [ + "Significant Gravitas <support@agpt.co>", +] +readme = "README.md" +description = "An open-source attempt to make GPT-4 autonomous" +homepage = "https://github.com/Significant-Gravitas/AutoGPT/tree/master/autogpts/autogpt" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", +] +packages = [{ include = "autogpt" }] + + +[tool.poetry.scripts] +autogpt = "autogpt.app.cli:cli" +serve = "autogpt.app.cli:serve" + + +[tool.poetry.dependencies] +python = "^3.10" +anthropic = "^0.25.1" +# autogpt-forge = { path = "../forge" } +autogpt-forge = {git = "https://github.com/Luffyzm3D2Y/AutoGPT.git", rev = "1685d7d9a1031e5f052e41e7834d5e5579563a00", subdirectory = "autogpts/forge"} +beautifulsoup4 = "^4.12.2" +boto3 = "^1.33.6" +charset-normalizer = "^3.1.0" +click = "*" +colorama = "^0.4.6" +demjson3 = "^3.0.0" +distro = "^1.8.0" +docker = "*" +duckduckgo-search = "^5.0.0" +en-core-web-sm = {url = "https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.5.0/en_core_web_sm-3.5.0-py3-none-any.whl"} +fastapi = "^0.109.1" +ftfy = "^6.1.1" +gitpython = "^3.1.32" +google-api-python-client = "*" +gTTS = "^2.3.1" +hypercorn = "^0.14.4" +inflection = "*" +jsonschema = "*" +numpy = "*" +openai = "^1.7.2" +orjson = "^3.8.10" +Pillow = "*" +pinecone-client = "^2.2.1" +playsound = "~1.2.2" +pydantic = "*" +pylatexenc = "*" +pypdf = "^3.1.0" +python-docx = "*" +python-dotenv = "^1.0.0" +pyyaml = "^6.0" +readability-lxml = "^0.8.1" +redis = "*" +requests = "*" +selenium = "^4.11.2" +sentry-sdk = "^1.40.4" +spacy = "^3.0.0" +tenacity = "^8.2.2" +tiktoken = "^0.5.0" +webdriver-manager = "*" + +# OpenAI and Generic plugins import +openapi-python-client = "^0.14.0" + +# Benchmarking +agbenchmark = { path = "../../benchmark", optional = true } +# agbenchmark = {git = "https://github.com/Significant-Gravitas/AutoGPT.git", subdirectory = "benchmark", optional = true} +google-cloud-logging = "^3.8.0" +google-cloud-storage = "^2.13.0" +psycopg2-binary = "^2.9.9" + +[tool.poetry.extras] +benchmark = ["agbenchmark"] + +[tool.poetry.group.dev.dependencies] +black = "*" +boto3-stubs = {extras = ["s3"], version = "^1.33.6"} +flake8 = "*" +gitpython = "^3.1.32" +isort = "*" +mypy = "*" +pre-commit = "*" +types-beautifulsoup4 = "*" +types-colorama = "*" +types-Markdown = "*" +types-Pillow = "*" + +# Testing +asynctest = "*" +coverage = "*" +pytest = "*" +pytest-asyncio = "*" +pytest-benchmark = "*" +pytest-cov = "*" +pytest-integration = "*" +pytest-mock = "*" +pytest-recording = "*" +pytest-xdist = "*" +vcrpy = {git = "https://github.com/Significant-Gravitas/vcrpy.git", rev = "master"} + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + + +[tool.black] +line-length = 88 +target-version = ['py310'] +include = '\.pyi?$' +packages = ["autogpt"] +extend-exclude = '.+/(dist|.venv|venv|build|data)/.+' + + +[tool.isort] +profile = "black" +multi_line_output = 3 +include_trailing_comma = true +force_grid_wrap = 0 +use_parentheses = true +ensure_newline_before_comments = true +line_length = 88 +sections = [ + "FUTURE", + "STDLIB", + "THIRDPARTY", + "FIRSTPARTY", + "LOCALFOLDER" +] +extend_skip = [ + "agbenchmark_config/temp_folder/", + "data/", +] + + +[tool.mypy] +follow_imports = 'skip' +check_untyped_defs = true +disallow_untyped_calls = true +files = [ + 'autogpt/**/*.py', + 'tests/**/*.py' +] + +[[tool.mypy.overrides]] +module = [ + 'requests.*', + 'yaml.*' +] +ignore_missing_imports = true + + +[tool.pytest.ini_options] +markers = [ + "requires_openai_api_key", + "requires_huggingface_api_key" +] diff --git a/im_client/agents/autogpt/autogpt_patch/web_selenium_latest_dev.py b/im_client/agents/autogpt/autogpt_patch/web_selenium_latest_dev.py new file mode 100644 index 0000000..5595d2d --- /dev/null +++ b/im_client/agents/autogpt/autogpt_patch/web_selenium_latest_dev.py @@ -0,0 +1,357 @@ +import asyncio +import logging +import re +from pathlib import Path +from sys import platform +from typing import Iterator, Type +from urllib.request import urlretrieve + +from bs4 import BeautifulSoup +from selenium.common.exceptions import WebDriverException +from selenium.webdriver.chrome.options import Options as ChromeOptions +from selenium.webdriver.chrome.service import Service as ChromeDriverService +from selenium.webdriver.chrome.webdriver import WebDriver as ChromeDriver +from selenium.webdriver.common.by import By +from selenium.webdriver.common.options import ArgOptions as BrowserOptions +from selenium.webdriver.edge.options import Options as EdgeOptions +from selenium.webdriver.edge.service import Service as EdgeDriverService +from selenium.webdriver.edge.webdriver import WebDriver as EdgeDriver +from selenium.webdriver.firefox.options import Options as FirefoxOptions +from selenium.webdriver.firefox.service import Service as GeckoDriverService +from selenium.webdriver.firefox.webdriver import WebDriver as FirefoxDriver +from selenium.webdriver.remote.webdriver import WebDriver +from selenium.webdriver.safari.options import Options as SafariOptions +from selenium.webdriver.safari.webdriver import WebDriver as SafariDriver +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.support.wait import WebDriverWait +from webdriver_manager.chrome import ChromeDriverManager +from webdriver_manager.firefox import GeckoDriverManager +from webdriver_manager.microsoft import EdgeChromiumDriverManager as EdgeDriverManager + +from autogpt.agents.protocols import CommandProvider, DirectiveProvider +from autogpt.command_decorator import command +from autogpt.config import Config +from autogpt.core.resource.model_providers.schema import ( + ChatModelInfo, + ChatModelProvider, +) +from autogpt.core.utils.json_schema import JSONSchema +from autogpt.models.command import Command +from autogpt.processing.html import extract_hyperlinks, format_hyperlinks +from autogpt.processing.text import extract_information, summarize_text +from autogpt.url_utils.validators import validate_url +from autogpt.utils.exceptions import CommandExecutionError, TooMuchOutputError + +logger = logging.getLogger(__name__) + +FILE_DIR = Path(__file__).parent.parent +MAX_RAW_CONTENT_LENGTH = 500 +LINKS_TO_RETURN = 20 + + +class BrowsingError(CommandExecutionError): + """An error occurred while trying to browse the page""" + + +class WebSeleniumComponent(DirectiveProvider, CommandProvider): + """Provides commands to browse the web using Selenium.""" + + def __init__( + self, + config: Config, + llm_provider: ChatModelProvider, + model_info: ChatModelInfo, + ): + self.legacy_config = config + self.llm_provider = llm_provider + self.model_info = model_info + + def get_resources(self) -> Iterator[str]: + yield "Ability to read websites." + + def get_commands(self) -> Iterator[Command]: + yield self.read_webpage + + @command( + ["read_webpage"], + ( + "Read a webpage, and extract specific information from it." + " You must specify either topics_of_interest," + " a question, or get_raw_content." + ), + { + "url": JSONSchema( + type=JSONSchema.Type.STRING, + description="The URL to visit", + required=True, + ), + "topics_of_interest": JSONSchema( + type=JSONSchema.Type.ARRAY, + items=JSONSchema(type=JSONSchema.Type.STRING), + description=("A list of topics about which you want to extract information " "from the page."), + required=False, + ), + "question": JSONSchema( + type=JSONSchema.Type.STRING, + description=("A question you want to answer using the content of the webpage."), + required=False, + ), + "get_raw_content": JSONSchema( + type=JSONSchema.Type.BOOLEAN, + description=( + "If true, the unprocessed content of the webpage will be returned. " + "This consumes a lot of tokens, so use it with caution." + ), + required=False, + ), + }, + ) + @validate_url + async def read_webpage( + self, + url: str, + *, + topics_of_interest: list[str] = [], + get_raw_content: bool = False, + question: str = "", + ) -> str: + """Browse a website and return the answer and links to the user + + Args: + url (str): The url of the website to browse + question (str): The question to answer using the content of the webpage + + Returns: + str: The answer and links to the user and the webdriver + """ + driver = None + try: + driver = await self.open_page_in_browser(url, self.legacy_config) + + text = self.scrape_text_with_selenium(driver) + links = self.scrape_links_with_selenium(driver, url) + + return_literal_content = True + summarized = False + if not text: + return f"Website did not contain any text.\n\nLinks: {links}" + elif get_raw_content: + if ( + output_tokens := self.llm_provider.count_tokens(text, self.model_info.name) + ) > MAX_RAW_CONTENT_LENGTH: + oversize_factor = round(output_tokens / MAX_RAW_CONTENT_LENGTH, 1) + raise TooMuchOutputError( + f"Page content is {oversize_factor}x the allowed length " "for `get_raw_content=true`" + ) + return text + (f"\n\nLinks: {links}" if links else "") + else: + text = await self.summarize_webpage(text, question or None, topics_of_interest) + return_literal_content = bool(question) + summarized = True + + # Limit links to LINKS_TO_RETURN + if len(links) > LINKS_TO_RETURN: + links = links[:LINKS_TO_RETURN] + + text_fmt = f"'''{text}'''" if "\n" in text else f"'{text}'" + links_fmt = "\n".join(f"- {link}" for link in links) + return ( + f"Page content{' (summary)' if summarized else ''}:" + if return_literal_content + else "Answer gathered from webpage:" + ) + f" {text_fmt}\n\nLinks:\n{links_fmt}" + + except WebDriverException as e: + # These errors are often quite long and include lots of context. + # Just grab the first line. + msg = e.msg.split("\n")[0] if e.msg else str(e) + if "net::" in msg: + raise BrowsingError( + "A networking error occurred while trying to load the page: %s" + % re.sub(r"^unknown error: ", "", msg) + ) + raise CommandExecutionError(msg) + finally: + if driver: + driver.close() + + def scrape_text_with_selenium(self, driver: WebDriver) -> str: + """Scrape text from a browser window using selenium + + Args: + driver (WebDriver): A driver object representing + the browser window to scrape + + Returns: + str: the text scraped from the website + """ + + # Get the HTML content directly from the browser's DOM + page_source = driver.execute_script("return document.body.outerHTML;") + soup = BeautifulSoup(page_source, "html.parser") + + for script in soup(["script", "style"]): + script.extract() + + text = soup.get_text() + lines = (line.strip() for line in text.splitlines()) + chunks = (phrase.strip() for line in lines for phrase in line.split(" ")) + text = "\n".join(chunk for chunk in chunks if chunk) + return text + + def scrape_links_with_selenium(self, driver: WebDriver, base_url: str) -> list[str]: + """Scrape links from a website using selenium + + Args: + driver (WebDriver): A driver object representing + the browser window to scrape + base_url (str): The base URL to use for resolving relative links + + Returns: + List[str]: The links scraped from the website + """ + page_source = driver.page_source + soup = BeautifulSoup(page_source, "html.parser") + + for script in soup(["script", "style"]): + script.extract() + + hyperlinks = extract_hyperlinks(soup, base_url) + + return format_hyperlinks(hyperlinks) + + async def open_page_in_browser(self, url: str, config: Config) -> WebDriver: + """Open a browser window and load a web page using Selenium + + Params: + url (str): The URL of the page to load + config (Config): The applicable application configuration + + Returns: + driver (WebDriver): A driver object representing + the browser window to scrape + """ + logging.getLogger("selenium").setLevel(logging.CRITICAL) + + options_available: dict[str, Type[BrowserOptions]] = { + "chrome": ChromeOptions, + "edge": EdgeOptions, + "firefox": FirefoxOptions, + "safari": SafariOptions, + } + + options: BrowserOptions = options_available[config.selenium_web_browser]() + options.add_argument(f"user-agent={config.user_agent}") + + if isinstance(options, FirefoxOptions): + if config.selenium_headless: + # options.headless = True + options.add_argument("--no-sandbox") + options.add_argument("--headless") + options.add_argument("--disable-gpu") + driver = FirefoxDriver( + service=GeckoDriverService(GeckoDriverManager().install()), + options=options, + ) + elif isinstance(options, EdgeOptions): + driver = EdgeDriver( + service=EdgeDriverService(EdgeDriverManager().install()), + options=options, + ) + elif isinstance(options, SafariOptions): + # Requires a bit more setup on the users end. + # See https://developer.apple.com/documentation/webkit/testing_with_webdriver_in_safari # noqa: E501 + driver = SafariDriver(options=options) + elif isinstance(options, ChromeOptions): + if platform == "linux" or platform == "linux2": + options.add_argument("--disable-dev-shm-usage") + options.add_argument("--remote-debugging-port=9222") + + options.add_argument("--no-sandbox") + if config.selenium_headless: + options.add_argument("--headless=new") + options.add_argument("--disable-gpu") + + self._sideload_chrome_extensions(options, config.app_data_dir / "assets" / "crx") + + if (chromium_driver_path := Path("/usr/bin/chromedriver")).exists(): + chrome_service = ChromeDriverService(str(chromium_driver_path)) + else: + try: + chrome_driver = ChromeDriverManager().install() + except AttributeError as e: + if "'NoneType' object has no attribute 'split'" in str(e): + # https://github.com/SergeyPirogov/webdriver_manager/issues/649 + logger.critical("Connecting to browser failed:" " is Chrome or Chromium installed?") + raise + chrome_service = ChromeDriverService(chrome_driver) + driver = ChromeDriver(service=chrome_service, options=options) + + driver.get(url) + + # Wait for page to be ready, sleep 2 seconds, wait again until page ready. + # This allows the cookiewall squasher time to get rid of cookie walls. + WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, "body"))) + await asyncio.sleep(2) + WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.TAG_NAME, "body"))) + + return driver + + def _sideload_chrome_extensions(self, options: ChromeOptions, dl_folder: Path) -> None: + crx_download_url_template = "https://clients2.google.com/service/update2/crx?response=redirect&prodversion=49.0&acceptformat=crx3&x=id%3D{crx_id}%26installsource%3Dondemand%26uc" # noqa + cookiewall_squasher_crx_id = "edibdbjcniadpccecjdfdjjppcpchdlm" + adblocker_crx_id = "cjpalhdlnbpafiamejdnhcphjbkeiagm" + + # Make sure the target folder exists + dl_folder.mkdir(parents=True, exist_ok=True) + + for crx_id in (cookiewall_squasher_crx_id, adblocker_crx_id): + crx_path = dl_folder / f"{crx_id}.crx" + if not crx_path.exists(): + logger.debug(f"Downloading CRX {crx_id}...") + crx_download_url = crx_download_url_template.format(crx_id=crx_id) + urlretrieve(crx_download_url, crx_path) + logger.debug(f"Downloaded {crx_path.name}") + options.add_extension(str(crx_path)) + + async def summarize_webpage( + self, + text: str, + question: str | None, + topics_of_interest: list[str], + ) -> str: + """Summarize text using the OpenAI API + + Args: + url (str): The url of the text + text (str): The text to summarize + question (str): The question to ask the model + driver (WebDriver): The webdriver to use to scroll the page + + Returns: + str: The summary of the text + """ + if not text: + raise ValueError("No text to summarize") + + text_length = len(text) + logger.debug(f"Web page content length: {text_length} characters") + + result = None + information = None + if topics_of_interest: + information = await extract_information( + text, + topics_of_interest=topics_of_interest, + llm_provider=self.llm_provider, + config=self.legacy_config, + ) + return "\n".join(f"* {i}" for i in information) + else: + result, _ = await summarize_text( + text, + question=question, + llm_provider=self.llm_provider, + config=self.legacy_config, + ) + return result diff --git a/im_client/agents/base.py b/im_client/agents/base.py new file mode 100644 index 0000000..a8de694 --- /dev/null +++ b/im_client/agents/base.py @@ -0,0 +1,136 @@ +import os +from common.types.llm import LLMResult +import docker + + +class AgentAdapter: + def reset(self): + pass + + async def run(self, task_desc: str): + pass + + async def step(self): + pass + + async def create_task(self, task_desc: str): + pass + + async def add_to_memory(self, message: LLMResult): + pass + + async def get_memory(self) -> list[LLMResult]: + pass + + async def shutdown(self): + pass + + @classmethod + def create(cls, config: dict | None): + if config is None: + return None + agent_type = config.get("agent_type", None) + match agent_type: + case "ReAct": + from agents import ReActAgent + + client = docker.from_env() + exist_container = client.containers.list(all=True, filters={"name": config["container_name"]}) + if len(exist_container) > 0: + exist_container[0].remove(force=True) + docker_container = client.containers.run( + config["image_name"], + name=config["container_name"], + detach=True, + remove=False, + environment=[ + f"OPENAI_API_KEY={os.environ.get('OPENAI_API_KEY')}", + f"OPENAI_BASE_URL={os.environ.get('OPENAI_BASE_URL')}", + f"BING_API_KEY={os.environ.get('BING_API_KEY')}", + f"AGENT_NAME={config.get('agent_name', '')}", + f"AGENT_DESC={config.get('desc', '')}", + f"AGENT_MODEL={config.get('model', '')}", + f"MAX_NUM_STEPS={config.get('max_num_steps', 20)}", + f"TOOLS_CONFIG={config.get('tools_config')}", + f"OPENAI_API_BASE={os.environ.get('OPENAI_API_BASE', '')}", + f"CUPS_SERVER={os.environ.get('CUPS_SERVER', '')}", + f"PRINTER_NAME={os.environ.get('PRINTER_NAME', '')}", + f"PERSIST_DIR={config.get('rag').get('persist_dir', '')}", + f"CHUNK_SIZE={config.get('rag').get('chunk_size', '')}", + f"RAG_LLM_MODEL={config.get('rag').get('llm_model', '')}", + f"RAG_LLM_TEMPERATURE={config.get('rag').get('llm_temperature', '')}", + f"SIMILARITY_TOP_K={config.get('rag').get('similarity_top_k', '')}", + f"RAG_DATA={config.get('rag').get('data', '')}", + f"MI_USER={os.environ.get('MI_USER', '')}", + f"MI_PASSWORD={os.environ.get('MI_PASSWORD', '')}", + ], + tty=True, + stdin_open=True, + network="agent_network", + privileged=True, + # ports={"7070/tcp": config.get("port")}, + ) + return ReActAgent(docker_container, config["agent_name"]) + case "OpenInterpreter": + from agents import OpenInterpreterAgent + + client = docker.from_env() + exist_container = client.containers.list(all=True, filters={"name": config["container_name"]}) + if len(exist_container) > 0: + exist_container[0].remove(force=True) + docker_container = client.containers.run( + config["image_name"], + name=config["container_name"], + detach=True, + remove=True, + environment=[ + f"OPENAI_API_KEY={os.environ.get('OPENAI_API_KEY')}", + f"OPENAI_BASE_URL={os.environ.get('OPENAI_BASE_URL')}", + f"OPENAI_API_BASE={os.environ.get('OPENAI_API_BASE', '')}", + ], + tty=True, + stdin_open=True, + network="agent_network", + privileged=True, + ports={"7070/tcp": config.get("port")}, + ) + return OpenInterpreterAgent( + docker_container, + "OpenInterpreter Agent", + ) + + case "AutoGPT": + from agents import AutoGPTAgent + + client = docker.from_env() + exist_container = client.containers.list(all=True, filters={"name": config["container_name"]}) + if len(exist_container) > 0: + exist_container[0].remove(force=True) + docker_container = client.containers.run( + config["image_name"], + command="serve", + name=config["container_name"], + detach=True, + remove=True, + environment=[ + f"OPENAI_API_KEY={os.environ.get('OPENAI_API_KEY')}", + f"OPENAI_API_BASE_URL={os.environ.get('OPENAI_API_BASE_URL')}", + f"OPENAI_API_BASE={os.environ.get('OPENAI_API_BASE', '')}", + f"OPENAI_BASE_URL={os.environ.get('OPENAI_BASE_URL', '')}", + f"USE_WEB_BROWSER={os.environ.get('USE_WEB_BROWSER', '')}", + f"HEADLESS_BROWSER={os.environ.get('HEADLESS_BROWSER', '')}", + f"DISABLED_COMMANDS={os.environ.get('DISABLED_COMMANDS', '')}", + f"GOOGLE_API_KEY={os.environ.get('GOOGLE_API_KEY', '')}", + f"EXECUTE_LOCAL_COMMANDS={os.environ.get('EXECUTE_LOCAL_COMMANDS', '')}", + f"GOOGLE_CUSTOM_SEARCH_ENGINE_ID={os.environ.get('GOOGLE_CUSTOM_SEARCH_ENGINE_ID', '')}", + f"SMART_LLM={os.environ.get('SMART_LLM', '')}", + f"FAST_LLM={os.environ.get('FAST_LLM', '')}", + ], + tty=True, + stdin_open=True, + network="agent_network", + privileged=True, + ports={"8000/tcp": config.get("port")}, + ) + + return AutoGPTAgent(docker_container, config["agent_name"]) diff --git a/im_client/agents/open_interpreter/__init__.py b/im_client/agents/open_interpreter/__init__.py new file mode 100644 index 0000000..ace0f2f --- /dev/null +++ b/im_client/agents/open_interpreter/__init__.py @@ -0,0 +1 @@ +from .open_interpreter_agent_adapter import OpenInterpreterAgent diff --git a/im_client/agents/open_interpreter/open_interpreter_agent.py b/im_client/agents/open_interpreter/open_interpreter_agent.py new file mode 100644 index 0000000..fa932b7 --- /dev/null +++ b/im_client/agents/open_interpreter/open_interpreter_agent.py @@ -0,0 +1,149 @@ +from interpreter import interpreter +from interpreter import OpenInterpreter +import os +from pydantic import BaseModel +from fastapi import FastAPI +import uuid +import time +import litellm +from tenacity import retry, stop_after_attempt, wait_exponential +import asyncio + +app = FastAPI() + + +class TaskDesc(BaseModel): + task_desc: str + model: str + + +class MemoryAdded(BaseModel): + role: str + content: str + + +interpreter.auto_run = True + + +def fixed_litellm_completions_modified(**params): + """ + Just uses a dummy API key, since we use litellm without an API key sometimes. + Hopefully they will fix this! + """ + + first_error = None + retries = 0 + max_retries = 20 + while retries < max_retries: + try: + yield from litellm.completion(**params, max_retries=5, num_retries=5) + + break + except Exception as e: + retries += 1 + if retries >= max_retries: + first_error = e + # LiteLLM can fail if there's no API key, + # even though some models (like local ones) don't require it. + if "api key" in str(first_error).lower() and "api_key" not in params: + print( + "LiteLLM requires an API key. Please set a dummy API key to prevent this message. (e.g `interpreter --api_key x` or `interpreter.llm.api_key = 'x'`)" + ) + + # So, let's try one more time with a dummy API key: + params["api_key"] = "x" + + try: + yield from litellm.completion(**params) + except: + # If the second attempt also fails, raise the first error + raise first_error + + else: + time.sleep(3) + + +@app.post("/run") +async def run(task_desc: TaskDesc): + interpreter_instance = OpenInterpreter() + interpreter_instance.llm.completions = fixed_litellm_completions_modified + interpreter_instance.system_message += ( + "Just run automatically without asking for user's confirmation or feedback until the task is totally completed." + ) + interpreter_instance.messages = [] + interpreter_instance.auto_run = True + interpreter_instance.force_task_completion = True + interpreter_instance.llm.api_key = os.environ.get("OPENAI_API_KEY") + interpreter_instance.llm.api_base = os.environ.get("OPENAI_BASE_URL") + + if task_desc.model != "": + interpreter_instance.model = task_desc.model + interpreter_instance.model = "gpt-4-1106-preview" + print(f"interpreter model: {interpreter_instance.model}...") + task_desc.task_desc = "Here is a task that you should finish:\n" + task_desc.task_desc + try: + intermediate_msgs = await safe_chat(interpreter_instance, task_desc.task_desc) + conclusion_msgs = await safe_chat( + interpreter_instance, + "Please summarize and provide a complied and complete conclusion as the final answer to the previous task I assigned to you. If there are any files or codes in the final answer, please print them out.", + ) + except Exception as e: + return { + "task_id": uuid.uuid4().hex, + "conclusion": "Internal Server Error! The task is not completed!", + } + + conclusion = [f"{item['content']}\n" for item in conclusion_msgs] + conclusion = "".join(conclusion) + messages = interpreter_instance.messages + + del interpreter_instance + return { + "task_id": uuid.uuid4().hex, + "task_desc": task_desc, + "steps": messages, + "conclusion": conclusion, + } + + +async def safe_chat(interpreter_instance, message): + max_retries = 3 + retries = 0 + messages = interpreter_instance.messages + + while retries < max_retries: + try: + interpreter_instance.messages = messages + response = await asyncio.to_thread(interpreter_instance.chat, message) + return response + except Exception as e: + print(f"An error occurred: {e}. Retrying...") + import traceback + + traceback.print_exc() + await asyncio.sleep(10) + retries += 1 + raise Exception("Failed to complete the operation after several retries.") + + +# TODO: update get_memory, instance of interpreter should be used. +@app.post("/get_memory") +async def get_memory(): + return interpreter.messages + + +# TODO: update add_to_memory, instance of interpreter should be used. +@app.post("/add_to_memory") +async def add_to_memory(memoryAdded: MemoryAdded): + interpreter.messages.append({"role": memoryAdded.role, "type": "message", "content": memoryAdded.content}) + + +@app.post("/keep_alive") +async def keep_alive_endpoint(): + return {"message": "Keep alive endpoint"} + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, host="0.0.0.0", port=7070) diff --git a/im_client/agents/open_interpreter/open_interpreter_agent_adapter.py b/im_client/agents/open_interpreter/open_interpreter_agent_adapter.py new file mode 100644 index 0000000..aee6604 --- /dev/null +++ b/im_client/agents/open_interpreter/open_interpreter_agent_adapter.py @@ -0,0 +1,98 @@ +from .. import AgentAdapter +from pydantic import BaseModel +import requests +from common.types.llm import LLMResult +from typing import List, Dict +from docker.models.containers import Container +from common.config import global_config +import os +import json +import aiohttp +import asyncio +import traceback + + +class TaskDesc(BaseModel): + task_desc: str + model: str + + +class MemoryAdded(BaseModel): + role: str + content: str + + +class MemoryGot(BaseModel): + responses: List[Dict] + + +class OpenInterpreterAgent(AgentAdapter): + def __init__( + self, + docker_container: Container, + agent_name: str, + ): + self.docker_container = docker_container + self.agent_name = agent_name + self.task_desc = "" + self.url = f"http://{global_config['tool_agent']['container_name']}:7070" + + # create log directory + self.log_path = f"/app/tool_agent_log" + + if not os.path.exists(self.log_path): + os.makedirs(self.log_path) + + async def run(self, task_desc: str, model: str = "gpt-4-1106-preview"): + data = TaskDesc(task_desc=task_desc, model=model) + headers = {"Content-Type": "application/json"} + print(f"the model specified in Open Interpreter: {data.model}...") + while True: + try: + async with aiohttp.ClientSession() as session: + async with session.post(self.url + "/run", json=data.model_dump(), headers=headers) as response: + item = await response.json() + conclusion = item["conclusion"] + break + except Exception as e: + print(f"error while get the conclusion from open interpreter agent...:{e}") + traceback.print_exc() + await asyncio.sleep(3) + continue + + filename = f"{item['task_id']}.json" + file_path = os.path.join(self.log_path, filename) + with open(file_path, "w", encoding="utf-8") as f: + json.dump(item, f, ensure_ascii=False, indent=4) + print(f"Task completion process has been recorded successfully to {file_path}.") + + return conclusion + # TODO: run() should have return value + + async def add_to_memory(self, memoryAdded: LLMResult): + headers = {"Content-Type": "application/json"} + data = MemoryAdded(role=memoryAdded.role, content=memoryAdded.content) + requests.post( + self.url + "/add_to_memory", + json=data.model_dump(), + headers=headers, + ) + + async def get_memory(self) -> list[LLMResult]: + responses = requests.post(self.url + "/get_memory").json() + messageList: list[LLMResult] = [] + for response in responses: + print(response) + llmResult = LLMResult(role=response["role"], content=response.get("content")) + language = response.get("language", None) + + if language: + llmResult.content += f"\n```{language}\n{response.get('code', None)}\n```" + output = response.get("output", None) + if output: + llmResult.content += f"\noutput: {output}\n" + messageList.append(llmResult) + return messageList + + async def shutdown(self): + await self.docker_container.remove(force=True) diff --git a/im_client/agents/open_interpreter/requirements.txt b/im_client/agents/open_interpreter/requirements.txt new file mode 100644 index 0000000..506c639 --- /dev/null +++ b/im_client/agents/open_interpreter/requirements.txt @@ -0,0 +1,5 @@ +open-interpreter==0.2.2 +fastapi +uvicorn +docker +aiohttp \ No newline at end of file diff --git a/im_client/agents/react/__init__.py b/im_client/agents/react/__init__.py new file mode 100644 index 0000000..2bb66dc --- /dev/null +++ b/im_client/agents/react/__init__.py @@ -0,0 +1 @@ +from .react_agent_adapter import ReActAgent diff --git a/im_client/agents/react/react_agent.py b/im_client/agents/react/react_agent.py new file mode 100644 index 0000000..a01f7fd --- /dev/null +++ b/im_client/agents/react/react_agent.py @@ -0,0 +1,275 @@ +import os +from string import Template +from collections import defaultdict + +import yaml +from fastapi import FastAPI +from pydantic import BaseModel +from tools import TOOL_MAPPING, BROWSER_TOOLS_MAPPING + +from llms import OpenAIChat +from memory import ChatHistoryMemory +from prompts import ( + REACT_APPEND_THOUGHT_PROMPT, + REACT_APPEND_TOOL_PROMPT, + REACT_SYSTEM_PROMPT, + REACT_TASK_PROMPT, +) +from common.log import logger +from common.types.llm import LLMResult +from common.utils.tool_utils import ToolResponse +from tools.playwright_browser import SimpleTextBrowser + +app = FastAPI() + + +class TaskDesc(BaseModel): + task_desc: str + uid: str + + +class MemoryAdded(BaseModel): + role: str + message: str + + +SUBMIT_TOOL = { + "type": "function", + "function": { + "name": "submit_task", + "description": "Use this function at the end of the task handling process. As the user and other agents do not have access to your intermediate steps and the solution presented in your calling of `subtask_solver`, you should write the COMPLETE final answer in the `conclusion` parameter of this function. Include as many information from your exploration as possible.", + "parameters": { + "type": "object", + "properties": { + "conclusion": { + "description": "Use around 400 words to summarize what you have done to handle this task, especially some milestones (such as writing what content to file xxx, getting what information from web xxx). Present the final answer explicitly in details. Only this conclusion will be shown to user, so you must write down enough detailed information that summarize all the things and information you got.", + "type": "string", + } + }, + "required": ["conclusion"], + }, + }, +} + +SUBTASK_TOOL = { + "type": "function", + "function": { + "name": "subtask_solver", + "description": "Define subtask and generate its response by yourself if you want to solve subtask rather than generate thought or call other tools.", + "parameters": { + "type": "object", + "properties": { + "subtask": { + "description": "The brief description of the subtask you want to create and solve by yourself.", + "type": "string", + }, + "solution": { + "description": "your detailed and self-contained response to the subtask.", + "type": "string", + }, + }, + "required": ["subtask", "solution"], + }, + }, +} + + +class ReActAgentServer: + def __init__( + self, + agent_name: str, + agent_desc: str, + model: str, + tools: list[dict] = [], + max_num_steps: int = 20, + ): + self.agent_name = agent_name + self.agent_desc = agent_desc + self.tools = tools + has_submit_tool = False + has_subtask_tool = False + for tool in self.tools: + if tool["function"]["name"] == "submit_task": + has_submit_tool = True + if tool["function"]["name"] == "subtask_solver": + has_subtask_tool = True + if not has_submit_tool: + self.tools.append(SUBMIT_TOOL) + if not has_subtask_tool: + self.tools.append(SUBTASK_TOOL) + + self.memory = defaultdict(lambda: ChatHistoryMemory()) + self.step_cnt = defaultdict(lambda: 0) + self.task_desc = defaultdict(lambda: "") + self.conclusion = defaultdict(lambda: "") + self.cookies = defaultdict(lambda: None) + self.llm = OpenAIChat(model=model) + + self.browser = SimpleTextBrowser(bing_api_key=os.getenv("BING_API_KEY")) + + self.max_num_steps = max_num_steps + # self.reset() + + def reset(self, uid: str): + self.step_cnt[uid] = 0 + self.task_desc[uid] = "" + self.conclusion[uid] = "" + self.cookies[uid] = None + self.memory[uid].reset() + + async def run(self, task_desc: str, uid: str): + await self.create_task(task_desc, uid) + while not await self.is_finished(uid): + await self.step(uid) + logger.info(f"Step: {self.step_cnt[uid]} completed") + logger.info(f"UID: {uid} - Task is finished. Conclusion: {self.conclusion[uid]}") + if self.conclusion[uid] != "": + return self.conclusion[uid] + else: + # TODO: summarize the reason on failure and the current progress + return "Failed to handle the task." + + async def step(self, uid: str): + # Get the latest messages from the memory + messages = await self.memory[uid].to_messages(self.agent_name) + + # Generate the prompt + prepend_prompt = [ + Template(REACT_SYSTEM_PROMPT).safe_substitute({"name": self.agent_name, "desc": self.agent_desc}), + Template(REACT_TASK_PROMPT).safe_substitute({"task_description": self.task_desc[uid]}), + ] + # Generate the response + + response: LLMResult = await self.llm.agenerate_response( + prepend_prompt=prepend_prompt, + history=messages, + append_prompt=REACT_APPEND_THOUGHT_PROMPT, + tools=self.tools, + response_format={"type": "json_object"}, + temperature=0.5, + ) + if response.tool_calls != []: + response.tool_calls = None + if isinstance(response.content, dict): + response.content = "Thought: " + response.content["thought"] + + # Add the response to the memory + logger.log_llm_result(response) + await self.add_to_memory(response, uid) + + # if response.parsed_tool_calls: + # for i, tool_call in enumerate(response.parsed_tool_calls): + if self.step_cnt[uid] == self.max_num_steps: + tool_choice = { + "type": "function", + "function": {"name": SUBMIT_TOOL["function"]["name"]}, + } + else: + tool_choice = None + + thought_messages = await self.memory[uid].to_messages(self.agent_name) + + response_tool: LLMResult = await self.llm.agenerate_response( + prepend_prompt=prepend_prompt, + history=thought_messages, + append_prompt=REACT_APPEND_TOOL_PROMPT, + tools=self.tools, + tool_choice=tool_choice, + ) + + if isinstance(response_tool.content, dict): + response_tool.content = "Tool: " + response_tool.content["tool"] + + # Add the response to the memory + logger.log_llm_result(response_tool) + await self.add_to_memory(response_tool, uid) + + if response_tool.parsed_tool_calls: + for i, tool_call in enumerate(response_tool.parsed_tool_calls): + tool_name = tool_call.function.name + tool_input = tool_call.function.arguments + tool_call_id = tool_call.id + + if tool_name == SUBMIT_TOOL["function"]["name"]: + self.conclusion[uid] = tool_input["conclusion"] + break + elif tool_name in TOOL_MAPPING: + try: + tool_response = ToolResponse(observation=TOOL_MAPPING[tool_name](**tool_input)) + except Exception as e: + tool_response = ToolResponse(observation=f"Error in calling tool {tool_name}: {e}") + elif tool_name in BROWSER_TOOLS_MAPPING: + try: + if tool_name in ["read_page_and_answer", "summarize_page"]: + tool_response = ToolResponse( + observation=( + await BROWSER_TOOLS_MAPPING[tool_name](self.browser, self.llm, **tool_input) + ) + ) + else: + tool_response = ToolResponse( + observation=await BROWSER_TOOLS_MAPPING[tool_name](self.browser, **tool_input) + ) + except Exception as e: + tool_response = ToolResponse(observation=f"Error in calling tool {tool_name}: {e}") + elif tool_name == SUBTASK_TOOL["function"]["name"]: + if "subtask" in tool_input and "solution" in tool_input: + tool_response: ToolResponse = ToolResponse(observation="The record of subtask_solver saved.") + else: + tool_response: ToolResponse = ToolResponse(observation="The call of subtask_solver failed.") + else: + logger.warn(f"Agent generated invalid tool call:\n{tool_name}\n{tool_input}") + tool_response = ToolResponse(observation=f"{tool_name} could not be found.") + + tool_response_result = tool_response.to_llm_result(tool_call_id) + logger.log_llm_result(tool_response_result) + await self.add_to_memory(tool_response_result, uid) + + self.step_cnt[uid] += 1 + + async def create_task(self, task_desc: str, uid: str): + self.reset(uid) + self.task_desc[uid] = task_desc + + async def add_to_memory(self, message: LLMResult | list[LLMResult], uid: str): + if isinstance(message, list): + message = [message] + self.memory[uid].add_messages(message) + + async def get_memory(self, uid: str): + return await self.memory[uid].to_messages(self.agent_name) + + async def is_finished(self, uid: str): + return self.conclusion[uid] != "" or self.step_cnt[uid] > self.max_num_steps + + +tools = [] +if tool_config_file := os.getenv("TOOLS_CONFIG", ""): + tools = yaml.safe_load(open(tool_config_file)) +assert os.getenv("AGENT_MODEL", "") != "", "AGENT_MODEL is not set. Pass the model for ReAct Agent in config file!" +reactagent = ReActAgentServer( + os.getenv("AGENT_NAME", "ReAct Agent"), + os.getenv( + "AGENT_DESC", + "The ReAct agent is designed as an affordable and straightforward agent. It is well-suited for handling routine tasks. However, it is important to note that it may not be able to tackle highly complex problems.", + ), + os.getenv("AGENT_MODEL"), + tools, + int(os.getenv("MAX_NUM_STEPS", 20)), +) + + +@app.post("/run") +async def run(task_desc: TaskDesc): + return await reactagent.run(task_desc.task_desc, task_desc.uid) + + +@app.post("/keep_alive") +async def keep_alive_endpoint(): + return {"message": "Keep alive endpoint"} + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, host="0.0.0.0", port=7070) diff --git a/im_client/agents/react/react_agent_adapter.py b/im_client/agents/react/react_agent_adapter.py new file mode 100644 index 0000000..49341ae --- /dev/null +++ b/im_client/agents/react/react_agent_adapter.py @@ -0,0 +1,74 @@ +import uuid +from typing import Dict, List + +import requests +from docker.models.containers import Container +from pydantic import BaseModel + +from common.config import global_config +from common.types.llm import LLMResult +from common.log import logger + +import httpx + +from .. import AgentAdapter + + +class TaskDesc(BaseModel): + task_desc: str + uid: str + + +class MemoryAdded(BaseModel): + role: str + message: str + + +class MemoryGot(BaseModel): + responses: List[Dict] + + +class ReActAgent(AgentAdapter): + """The adapter for ReAct agent. Adapting ReAct agent's interface to IoA's protocol""" + + def __init__(self, docker_container: Container, agent_name: str): + self.docker_container = docker_container + self.agent_name = agent_name + self.task_desc = "" + self.url = f"http://{global_config['tool_agent']['container_name']}:7070" + + async def run(self, task_desc: str): + uid = uuid.uuid4().hex + data = TaskDesc(task_desc=task_desc, uid=uid) + headers = {"Content-Type": "application/json"} + async with httpx.AsyncClient(timeout=httpx.Timeout(None)) as client: + response = await client.post(self.url + "/run", json=data.model_dump(), headers=headers) + logger.info(f"Received response: {response.text}") + return response.text + + async def add_to_memory(self, memoryAdded: LLMResult): + headers = {"Content-Type": "application/json"} + data = MemoryAdded(role=memoryAdded.role, message=memoryAdded.content) + requests.post( + self.url + "/add_to_memory", + json=data.model_dump(), + headers=headers, + ) + + async def get_memory(self) -> list[LLMResult]: + responses = requests.post(self.url + "/get_memory").json() + messageList: list[LLMResult] = [] + for response in responses: + llmResult = LLMResult(role=response["role"], content=response["message"]) + language = response.get("language", None) + + if language: + llmResult.content += f"\n```{language}\n{response.get('code', None)}\n```" + output = response.get("output", None) + if output: + llmResult.content += f"\noutput: {output}\n" + messageList.append(llmResult) + return messageList + + async def shutdown(self): + self.docker_container.remove(force=True) diff --git a/im_client/agents/react/requirements.txt b/im_client/agents/react/requirements.txt new file mode 100644 index 0000000..5ddbb82 --- /dev/null +++ b/im_client/agents/react/requirements.txt @@ -0,0 +1,38 @@ +fastapi +uvicorn +docker +arxiv +scholarly +git+https://github.com/rytilahti/python-miio.git +llama-index +llama-index-agent-openai +llama-index-cli +llama-index-core +llama-index-embeddings-openai +llama-index-indices-managed-llama-cloud +llama-index-legacy +llama-index-llms-openai +llama-index-multi-modal-llms-openai +llama-index-program-openai +llama-index-question-gen-openai +llama-index-readers-file +llama-index-readers-llama-parse +llama-index-vector-stores-chroma +llama-parse +llamaindex-py-client +openai +numpy +tenacity +colorama +tiktoken +python-Levenshtein +aiofiles +markdownify +youtube-search +pytube +mediawikiapi +wikibase_rest_api_client +pdfminer.six +pathvalidate +pymupdf4llm +playwright \ No newline at end of file diff --git a/im_client/agents/react/tools.yaml b/im_client/agents/react/tools.yaml new file mode 100644 index 0000000..ba53da8 --- /dev/null +++ b/im_client/agents/react/tools.yaml @@ -0,0 +1,229 @@ +- function: + description: + 'Create or replace a notebook cell and execute it, return the output. + + Use this tool to test your idea quickly. + + + Example: + + ``` + + In[0]: code=''print("hello world")'' # This will create a new cell and execute + it. + + Out[0]: [''cell_index: 0'', ''hello world''] + + In[1]: code=''print("hello world")'',cell_index=0 # This will overwrite the + first cell and execute it. + + In[2]: code=''print("hello world")'',cell_index=-1 # This will overwrite the + last cell and execute it. + + ```' + name: PythonNotebook_execute_cell + parameters: + properties: + cell_index: + description: + the index of the cell to be insert and overwrite `code`, default + to `None`, which means append new cell. + type: integer + code: + description: + python code to be executed, make sure it is valid python code + with right format. don't provide shell command that started with '!' here. + don't make your code print too much output. + type: string + reset: + description: + whether to reset the kernel before executing the code. Default + to `False`. + type: boolean + required: + - code + type: object + type: function +- function: + description: print all notebook cells' content and output. + name: PythonNotebook_print_cells_outputs + parameters: + properties: {} + required: [] + type: object + type: function +- function: + description: + Give a http or https url to browse a website and return the summarize + text. Note some websites may not be accessable due to network error. This tool + only return the content of give url and cannot provide any information need + interaction with the website. + name: WebEnv_browse_website + parameters: + properties: + goals_to_browse: + description: + The goals for browse the given `url` (e.g. what you want to + find on webpage.). If you need more details, request it in here. + type: string + url: + description: + 'The realworld Uniform Resource Locator (web address) to scrape + text from. Never provide something like "<URL of the second news article>", + give real url!!! Example: ''https://www.deepmind.com/''' + type: string + required: + - url + - goals_to_browse + type: object + type: function +- function: + description: + Search with search tools and browse the website returned by search. + Note some websites may not be accessable due to network error. + name: WebEnv_search_and_browse + parameters: + properties: + goals_to_browse: + description: + "What's you want to find on the website returned by search. + If you need more details, request it in here. Examples: 'What is latest + news about deepmind?', 'What is the main idea of this article?'" + type: string + region: + description: + "The region code of the search, default to `en-US`. Available + regions: `en-US`, `zh-CN`, `ja-JP`, `de-DE`, `fr-FR`, `en-GB`." + type: string + search_query: + description: The search query. + type: string + required: + - search_query + - goals_to_browse + type: object + type: function +# - function: +# description: "Modify the textual file lines in slice [start_index:end_index] based\ +# \ on `new_content` provided. Return content of the file after modification so\ +# \ no further need to call `read_from_file`.\nfilepath_content_lines[start_index:end_index]\ +# \ = new_content\n\nExample:\n```\nIn[0]: modify_file('test.txt', 'Hello World!')\ +# \ # This will insert a new line `Hello World!` at the end of the file `test.txt`.\n\ +# In[1]: modify_file('test.txt', 'Hello World!', 0) # This will insert a new line\ +# \ `Hello World!` at the begin of the file `test.txt`.\nIn[2]: modify_file('test.txt',\ +# \ 'Hello World!', 0, 1) # This will replace the first line of the file `test.txt`\ +# \ with `Hello World!`. \n```" +# name: FileSystemEnv_modify_file +# parameters: +# properties: +# end_index: +# description: The end posistion in slice to modified file lines. Defaults +# to the value of `start_index`, which means if `start_index` provided, +# insert the new content at the `start_index` line. +# type: integer +# filepath: +# description: The path to the file to be modified, always use relative path +# to the workspace root. +# type: string +# new_content: +# description: The new content to be replaced with the old content. +# type: string +# start_index: +# description: The start position in slice to modified file lines. Defaults +# to `None`, which means insert the new content at the end of the file. +# So do not provide this if you want to append the new content to the file. +# type: integer +# required: +# - filepath +# - new_content +# type: object +# type: function +# - function: +# description: "Return a tree-like structure for all files and folders in the workspace.\ +# \ Use this tool if you are not sure what files are in the workspace.\nThis function\ +# \ recursively walks through all the directories in the workspace\nand return\ +# \ them in a tree-like structure, \ndisplaying all the files under each directory.\n\ +# \nExample:\n```\n- root/\n - sub_directory1/\n - file1.txt\n \ +# \ - file2.txt\n - sub_directory2/\n - file3.txt\n```" +# name: FileSystemEnv_print_filesys_struture +# parameters: +# properties: {} +# required: [] +# type: object +# type: function +# - function: +# description: 'Open and read the textual file content in the workspace, you will +# see the content of the target file. + +# Don''t use this if the give `filepath` is writen or modified before, the content +# in `filepath` should be already returned.' +# name: FileSystemEnv_read_from_file +# parameters: +# properties: +# filepath: +# description: The path to the file to be opened, always use relative path +# to the workspace root. +# type: string +# start_index: +# description: The starting line number of the content to be opened. Defaults +# to 0. +# type: integer +# required: +# - filepath +# type: object +# type: function +# - function: +# description: "Write the textual file in the workspace with the content provided.\ +# \ \nWill automatically create the file if it does not exist. Also overwrite\ +# \ the file content if it already exists. If you want to append content to the\ +# \ file, use `modify_file` instead.\nBetter check if the file exists before directly\ +# \ writing to it. \nReturn content of the file after writing." +# name: FileSystemEnv_write_to_file +# parameters: +# properties: +# content: +# description: The content to be saved. +# type: string +# filepath: +# description: The path to the file to be saved, always use relative path +# to the workspace root. +# type: string +# required: +# - filepath +# - content +# type: object +# type: function +# - function: +# description: "The shell tool that execute shell command in root privilege, return\ +# \ the output and error. \nYou can use this tool to install packages, download\ +# \ files, run programs, etc.\nSet run_async=True to run the command in a new\ +# \ thread and return instantly if your command is time costly like install packages,\ +# \ host services. \nExample:\n```\nIn: shell_command_executor(command='echo \"\ +# hello world\"')\nOut: \"hello world\"\nIn: shell_command_executor(command='sleep\ +# \ 10', run_async=True)\nOut: {'shell_id': 0} # You can use this id to read the\ +# \ output and error later.\nIn: shell_command_executor(shell_id=0, kill=True)\n\ +# Out: \"\" # The shell 0 will be killed.\n```" +# name: shell_command_executor +# parameters: +# properties: +# command: +# description: The shell command to be executed, must avoid command requiring +# additional user input. Default is empty string. +# type: string +# kill: +# description: If True, kill the shell which runs the command after execution. +# Default is False. Don't use any other kill command! +# type: boolean +# run_async: +# description: Whether to run the command asynchronously, default is False. +# If True, call this tool again with shell_id to get the final output and +# error. +# type: boolean +# shell_id: +# description: The id of shell to execute command, default is None, which +# means running in a new shell. Change this to execute command in the same +# shell. +# type: integer +# required: [] +# type: object +# type: function diff --git a/im_client/agents/react/tools_arxiv.yaml b/im_client/agents/react/tools_arxiv.yaml new file mode 100644 index 0000000..3e7fed7 --- /dev/null +++ b/im_client/agents/react/tools_arxiv.yaml @@ -0,0 +1,33 @@ +- function: + description: This function interfaces with the arXiv's database API to retrieve a list of academic papers. It filters search results based on user-specified search terms and limits the number of results returned according to the provided parameters. + name: arxiv_search + parameters: + properties: + query: + description: A concise natural language sentence describing what you want to search for. + type: string + max_results: + description: the maximum number of papers returned (no more than 10). + type: number + required: + - query + - max_results + type: object + type: function +- function: + description: |- + This function should be invoked for submission. As the user and other agents do not have access to your intermediate steps, you should write the complete final answer in the `conclusion` parameter. Include as many information from your exploration as possible. + name: submit_task + parameters: + properties: + conclusion: + description: The complete final answer to the given task. The answer MUST be a complete literature review appended with a list of relevant literature collected (more than 10 related papers AND their pdf urls or arxiv ids!). + type: string + success: + description: Do you think the given task has been solved? + type: boolean + required: + - conclusion + - success + type: object + type: function diff --git a/im_client/agents/react/tools_code_executor.yaml b/im_client/agents/react/tools_code_executor.yaml new file mode 100644 index 0000000..8ec74e2 --- /dev/null +++ b/im_client/agents/react/tools_code_executor.yaml @@ -0,0 +1,20 @@ +- function: + description: Execute your provided code and return the terminal output. To get the result, you must explicitly print the important information (intermediate results, final results, etc.) in your code using `print` function. + name: execute_code + parameters: + properties: + code: + description: The code to execute. If None, the code from the file specified by filename will be executed. Either code or filename must be provided. + type: string + filename: + description: The file name to save the code or where the code is stored when `code` is None. If None, a file with a randomly generated name will be created. The randomly generated file will be deleted after execution. The file name must be a relative path. Relative paths are relative to the working directory. + type: string + work_dir: + description: The working directory for the code execution. If None, a default working directory will be used. + type: string + lang: + description: The language of the code. Default is "python". + type: string + required: [] + type: object + type: function diff --git a/im_client/agents/react/tools_scholarly.yaml b/im_client/agents/react/tools_scholarly.yaml new file mode 100644 index 0000000..d0aa337 --- /dev/null +++ b/im_client/agents/react/tools_scholarly.yaml @@ -0,0 +1,38 @@ +- function: + description: Search for informations about the specific author from the database of google scholar. + name: scholarly_search_author + parameters: + properties: + query: + description: The name of author you want to search. + type: string + required: + - query + type: object + type: function +- function: + description: + Search for informations about the specific keyword from the database of google scholar + return relevant authors. + name: scholarly_search_keyword + parameters: + properties: + query: + description: The keyword of author you want to search. + type: string + required: + - query + type: object + type: function +- function: + description: Search for informations about the specific article or publication from the database of google scholar. + name: scholarly_search_pubs + parameters: + properties: + query: + description: The name of article or publication you want to search. + type: string + required: + - query + type: object + type: function diff --git a/im_client/agents/react/tools_web_browser.yaml b/im_client/agents/react/tools_web_browser.yaml new file mode 100644 index 0000000..770fdcb --- /dev/null +++ b/im_client/agents/react/tools_web_browser.yaml @@ -0,0 +1,114 @@ +- function: + description: Perform an INFORMATIONAL web search query then return the search results. + name: informational_web_search + parameters: + properties: + query: + description: The informational web search query to perform. + type: string + required: + - query + type: object + type: function +- function: + description: |- + Perform a NAVIGATIONAL web search query then immediately navigate to the top result. Useful, for example, to navigate to a particular Wikipedia article or other known destination. Equivalent to Google's \"I'm Feeling Lucky\" button. + name: navigational_web_search + parameters: + properties: + query: + description: The navigational web search query to perform. + type: string + required: + - query + type: object + type: function +- function: + description: |- + Visit a webpage at a given URL and return its text. + name: visit_page + parameters: + properties: + url: + description: The relative or absolute url of the webapge to visit. + type: string + required: + - url + type: object + type: function +- function: + description: |- + Download a file at a given URL and, if possible, return its text. + name: download_file + parameters: + properties: + url: + description: The relative or absolute url of the file to be downloaded. + type: string + required: + - url + type: object + type: function +- function: + description: |- + Scroll the viewport UP one page-length in the current webpage and return the new viewport content. + name: page_up + parameters: + properties: {} + required: [] + type: object + type: function +- function: + description: |- + Scroll the viewport DOWN one page-length in the current webpage and return the new viewport content. + name: page_down + parameters: + properties: {} + required: [] + type: object + type: function +- function: + description: |- + Uses AI to read the page and directly answer a given question based on the content. + name: read_page_and_answer + parameters: + properties: + question: + description: The question to directly answer. + type: string + url: + description: The url of the page. (Defaults to the current page) + type: string + required: + - question + type: object + type: function +- function: + description: |- + Uses AI to summarize the content found at a given url. If the url is not provided, the current page is summarized. + name: summarize_page + parameters: + properties: + url: + description: The url of the page. (Defaults to the current page) + type: string + required: [] + type: object + type: function +# - function: +# description: Get the text of a PDF file. +# name: pdf_to_text +# parameters: +# properties: +# path: +# description: The path to the pdf file. +# type: string +# pages: +# description: A list of page indices that will be converted to text. Default is None, which means all pages will be converted. +# type: array +# items: +# type: integer +# required: +# - path +# type: object +# type: function diff --git a/im_client/agents/react/tools_wikidata.yaml b/im_client/agents/react/tools_wikidata.yaml new file mode 100644 index 0000000..fa1d860 --- /dev/null +++ b/im_client/agents/react/tools_wikidata.yaml @@ -0,0 +1,12 @@ +- function: + description: Perform a search on Wikidata. + name: search_wikidata + parameters: + properties: + query: + description: The item to search. It should not be a sentence, but should be an entity's name. + type: string + required: + - query + type: object + type: function diff --git a/im_client/agents/react/tools_youtube.yaml b/im_client/agents/react/tools_youtube.yaml new file mode 100644 index 0000000..305adbe --- /dev/null +++ b/im_client/agents/react/tools_youtube.yaml @@ -0,0 +1,26 @@ +- function: + description: Perform a search on YouTube. Will return a list of urls of the relevant videos + name: search_youtube + parameters: + properties: + query: + description: The keyword that you want to search + type: string + required: + - query + type: object + type: function +- function: + description: Obtain the transcript (caption) of the given YouTube video. The `youtube_id` and `url` are optional, but you must provide one of them. Providing `youtube_id` is encouraged as it is simpler and less prone to errors. + name: get_youtube_transcript + parameters: + properties: + youtube_id: + description: Optional. The ID of the YouTube video. (The ID can be obtained from YouTube url, the url is often formatted as "https://www.youtube.com/watch?v={ID}") + type: string + url: + description: Optional. The complete URL of the YouTube video. For example, "https://www.youtube.com/watch?v=...". + type: string + required: [] + type: object + type: function diff --git a/im_client/agents/tools/__init__.py b/im_client/agents/tools/__init__.py new file mode 100644 index 0000000..29026bc --- /dev/null +++ b/im_client/agents/tools/__init__.py @@ -0,0 +1,30 @@ +from . import scholarly_tools +from . import arxiv_tools + +from . import rag_tools +from . import playwright_browser +from . import code_executor +from . import youtube +from . import wikidata + +TOOL_MAPPING = { + "arxiv_search": arxiv_tools.arxiv_search, + "scholarly_search_author": scholarly_tools.scholarly_search_author, + "scholarly_search_keyword": scholarly_tools.scholarly_search_keyword, + "scholarly_search_pubs": scholarly_tools.scholarly_search_pubs, + "execute_code": code_executor.execute_code, + "search_youtube": youtube.search_youtube, + "get_youtube_transcript": youtube.get_youtube_transcript, + "search_wikidata": wikidata.search_wikidata, +} + +BROWSER_TOOLS_MAPPING = { + "informational_web_search": playwright_browser.informational_web_search, + "navigational_web_search": playwright_browser.navigational_web_search, + "visit_page": playwright_browser.visit_page, + "download_file": playwright_browser.download_file, + "page_up": playwright_browser.page_up, + "page_down": playwright_browser.page_down, + "read_page_and_answer": playwright_browser.read_page_and_answer, + "summarize_page": playwright_browser.summarize_page, +} diff --git a/im_client/agents/tools/arxiv_tools.py b/im_client/agents/tools/arxiv_tools.py new file mode 100644 index 0000000..727d14d --- /dev/null +++ b/im_client/agents/tools/arxiv_tools.py @@ -0,0 +1,55 @@ +import requests +import time + + +def arxiv_search( + query: str = "", + max_results: int | None = None, +) -> str: + """a wrapper for xplorer arxiv search based on OpenAI's embedding""" + + max_p = max_results // 10 + + result = "" + cnt = 0 + for i in range(max_p + 1): + resp = requests.get( + "https://us-west1-semanticxplorer.cloudfunctions.net/semantic-xplorer-db", + params={"query": query, "p": i}, + ) + data = resp.json() + for item in data: + title = item["metadata"]["title"] + abstract = item["metadata"]["abstract"] + id = item["id"] + authors = item["metadata"]["authors"] + result += f"Arxiv ID: {id}\nPaper Title: {title}\nAuthors: {authors}\nAbstract: {abstract}\n\n" + cnt += 1 + if cnt == max_results: + break + time.sleep(2) + + return result.rstrip() + + +def arxiv_search_official( + query: str = "", + max_results: int | None = None, +) -> str: + """a wrapper for arxiv.search""" + + import arxiv + + max_results = min(10, max_results) + search = arxiv.Search( + query=query, + max_results=max_results, + ) + + result = "" + for item in arxiv.Client().results(search): + abstract = item.summary.replace("\n", " ") + authors = ", ".join([author.name for author in item.authors]) + result += f"Paper Title: {item.title}\nAuthors: {authors}\nAbstract: {abstract}\npdf_url:{item.pdf_url}\n\n" + + return result diff --git a/im_client/agents/tools/code_executor.py b/im_client/agents/tools/code_executor.py new file mode 100644 index 0000000..a80bb8a --- /dev/null +++ b/im_client/agents/tools/code_executor.py @@ -0,0 +1,144 @@ +# https://github.com/microsoft/autogen/blob/19de99e3f6e46f6040d54c4a55785d02158dec28/autogen/code_utils.py + +import os +import pathlib +import subprocess +import sys +from concurrent.futures import ThreadPoolExecutor +from hashlib import md5 +from typing import Optional + +WORKING_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "extensions") +TIMEOUT_MSG = "Code execution timeout" +DEFAULT_TIMEOUT = 600 +WIN32 = sys.platform == "win32" +PATH_SEPARATOR = WIN32 and "\\" or "/" +PYTHON_VARIANTS = ["python", "Python", "py"] + + +def get_powershell_command(): + try: + result = subprocess.run( + ["powershell", "$PSVersionTable.PSVersion.Major"], + capture_output=True, + text=True, + ) + if result.returncode == 0: + return "powershell" + except (FileNotFoundError, NotADirectoryError): + # This means that 'powershell' command is not found so now we try looking for 'pwsh' + try: + result = subprocess.run( + ["pwsh", "-Command", "$PSVersionTable.PSVersion.Major"], + capture_output=True, + text=True, + ) + if result.returncode == 0: + return "pwsh" + except FileExistsError as e: + raise FileNotFoundError( + "Neither powershell.exe nor pwsh.exe is present in the system. " + "Please install PowerShell and try again. " + ) from e + except NotADirectoryError as e: + raise NotADirectoryError( + "PowerShell is either not installed or its path is not given " + "properly in the environment variable PATH. Please check the " + "path and try again. " + ) from e + except PermissionError as e: + raise PermissionError("No permission to run powershell.") from e + + +def _cmd(lang: str) -> str: + if lang in PYTHON_VARIANTS: + return "python" + if lang.startswith("python") or lang in ["bash", "sh"]: + return lang + if lang in ["shell"]: + return "sh" + if lang == "javascript": + return "node" + if lang in ["ps1", "pwsh", "powershell"]: + powershell_command = get_powershell_command() + return powershell_command + + raise NotImplementedError(f"{lang} not recognized in code execution") + + +def execute_code( + code: Optional[str] = None, + filename: Optional[str] = None, + work_dir: Optional[str] = None, + lang: Optional[str] = "python", +) -> str: + """Execute code in a docker container. + This function is not tested on MacOS. + + Args: + code (Optional, str): The code to execute. + If None, the code from the file specified by filename will be executed. + Either code or filename must be provided. + filename (Optional, str): The file name to save the code or where the code is stored when `code` is None. + If None, a file with a randomly generated name will be created. + The randomly generated file will be deleted after execution. + The file name must be a relative path. Relative paths are relative to the working directory. + work_dir (Optional, str): The working directory for the code execution. + If None, a default working directory will be used. + The default working directory is the "extensions" directory + lang (Optional, str): The language of the code. Default is "python". + + Returns: + str: The error message if the code fails to execute; the stdout otherwise. + """ + if all((code is None, filename is None)): + error_msg = f"Either {code=} or {filename=} must be provided." + return error_msg + + original_filename = filename + if filename is None: + code_hash = md5(code.encode()).hexdigest() + # create a file with a automatically generated name + filename = f"tmp_code_{code_hash}.{'py' if lang.startswith('python') else lang}" + if work_dir is None: + work_dir = WORKING_DIR + + filepath = os.path.join(work_dir, filename) + file_dir = os.path.dirname(filepath) + os.makedirs(file_dir, exist_ok=True) + + if code is not None: + with open(filepath, "w", encoding="utf-8") as fout: + fout.write(code) + + cmd = [ + sys.executable if lang.startswith("python") else _cmd(lang), + f".\\{filename}" if WIN32 else filename, + ] + with ThreadPoolExecutor(max_workers=1) as executor: + future = executor.submit( + subprocess.run, cmd, cwd=work_dir, capture_output=True, text=True, timeout=DEFAULT_TIMEOUT + ) + try: + result = future.result(timeout=DEFAULT_TIMEOUT) + except subprocess.TimeoutExpired: + if original_filename is None: + os.remove(filepath) + return TIMEOUT_MSG + except TimeoutError: + if original_filename is None: + os.remove(filepath) + return TIMEOUT_MSG + if original_filename is None: + os.remove(filepath) + if result.returncode: + logs = result.stderr + if original_filename is None: + abs_path = str(pathlib.Path(filepath).absolute()) + logs = logs.replace(str(abs_path), "").replace(filename, "") + else: + abs_path = str(pathlib.Path(work_dir).absolute()) + PATH_SEPARATOR + logs = logs.replace(str(abs_path), "") + else: + logs = result.stdout + return logs diff --git a/im_client/agents/tools/playwright_browser.py b/im_client/agents/tools/playwright_browser.py new file mode 100644 index 0000000..f3ea8ca --- /dev/null +++ b/im_client/agents/tools/playwright_browser.py @@ -0,0 +1,396 @@ +# Based on https://github.com/microsoft/autogen/blob/19de99e3f6e46f6040d54c4a55785d02158dec28/autogen/browser_utils.py + +import io +import re +import sys +from typing import Dict, List, Optional, Tuple, Union +from urllib.parse import urljoin + +# sys.path.append(".") +# sys.path.append("./im_client") +import threading + +import requests +from llms import OpenAIChat +from llms.utils import count_string_tokens +from playwright.async_api import Error, async_playwright + + +# Event to signal the completion of PDF download +pdf_downloaded_event = threading.Event() + + +IS_PDF_CAPABLE = False +try: + import pdfminer + import pdfminer.high_level + + IS_PDF_CAPABLE = True +except ModuleNotFoundError: + pass + +try: + import pathvalidate +except ModuleNotFoundError: + pass + + +class SimpleTextBrowser: + """An extremely simple text-based web browser based on Playwright.""" + + def __init__( + self, + # start_page: Optional[str] = None, + viewport_size: Optional[int] = 1024 * 5, + downloads_folder: Optional[Union[str, None]] = None, + bing_base_url: str = "https://api.bing.microsoft.com/v7.0/search", + bing_api_key: Optional[Union[str, None]] = None, + ): + self.start_page: str = "about:blank" + self.viewport_size = viewport_size + self.downloads_folder = downloads_folder + self.history: List[str] = list() + self.page_title: Optional[str] = None + self.viewport_current_page = 0 + self.viewport_pages: List[Tuple[int, int]] = list() + # self.set_address(self.start_page) + self.history.append("about:blank") + self._set_page_content("") + self.bing_base_url = bing_base_url + self.bing_api_key = bing_api_key + + self._page_content = "" + + @property + def address(self) -> str: + """Return the address of the current page.""" + return self.history[-1] + + async def set_address(self, uri_or_path: str) -> None: + self.history.append(uri_or_path) + + # Handle special URIs + if uri_or_path == "about:blank": + self._set_page_content("") + elif uri_or_path.startswith("bing:"): + self._bing_search(uri_or_path[len("bing:") :].strip()) + else: + if not uri_or_path.startswith("http:") and not uri_or_path.startswith("https:"): + uri_or_path = urljoin(self.address, uri_or_path) + self.history[-1] = uri_or_path # Update the address with the fully-qualified path + await self._fetch_page(uri_or_path) + + self.viewport_current_page = 0 + + async def _fetch_page(self, url: str) -> None: + try: + async with async_playwright() as p: + browser = await p.chromium.launch(headless=True) + context = await browser.new_context() + request = context.request + + page = await browser.new_page( + user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" + ) + + try: + await page.goto(url, wait_until="networkidle") + self.page_title = await page.title() + html_content = await page.content() + self._process_html_content(html_content) + except Error: + response = await request.get( + url, + headers={ + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" + }, + ) + content_type = response.headers.get("content-type", "").lower() + + if "application/pdf" in content_type and IS_PDF_CAPABLE: + pdf_content = await response.body() + pdf_data = io.BytesIO(pdf_content) + self.page_title = None + self._set_page_content(pdfminer.high_level.extract_text(pdf_data)) + else: + html_content = await response.text() + self._process_html_content(html_content) + + await browser.close() + except Exception as e: + self.page_title = "Error" + self._set_page_content(str(e)) + + def _process_html_content(self, html_content: str) -> None: + import markdownify + from bs4 import BeautifulSoup + + soup = BeautifulSoup(html_content, "html.parser") + + # Remove javascript and style blocks + for script in soup(["script", "style"]): + script.extract() + + for img in soup.find_all("img"): + if "src" in img.attrs and img.attrs["src"].startswith("data:image"): + img.extract() + + if self.history[-1].startswith("https://en.wikipedia.org/"): + body_elm = soup.find("div", {"id": "mw-content-text"}) + title_elm = soup.find("span", {"class": "mw-page-title-main"}) + + if body_elm: + # What's the title + main_title = soup.title.string + if title_elm and len(title_elm) > 0: + main_title = title_elm.string + webpage_text = "# " + main_title + "\n\n" + markdownify.MarkdownConverter().convert_soup(body_elm) + else: + webpage_text = markdownify.MarkdownConverter().convert_soup(soup) + else: + webpage_text = markdownify.MarkdownConverter().convert_soup(soup) + + webpage_text = markdownify.markdownify(str(soup), heading_style="ATX") + webpage_text = re.sub(r"\r\n", "\n", webpage_text) + webpage_text = re.sub(r"\n{2,}", "\n\n", webpage_text).strip() + + self.page_title = soup.title.string + self._set_page_content(webpage_text) + + def _set_page_content(self, content: str) -> None: + """Sets the text content of the current page.""" + self._page_content = content + self._split_pages() + if self.viewport_current_page >= len(self.viewport_pages): + self.viewport_current_page = len(self.viewport_pages) - 1 + + @property + def page_content(self) -> str: + """Return the full contents of the current page.""" + return self._page_content + + @property + def viewport(self) -> str: + """Return the content of the current viewport.""" + bounds = self.viewport_pages[self.viewport_current_page] + return self.page_content[bounds[0] : bounds[1]] + + def _split_pages(self) -> None: + # Split only regular pages + if not self.address.startswith("http:") and not self.address.startswith("https:"): + self.viewport_pages = [(0, len(self._page_content))] + return + + # Handle empty pages + if len(self._page_content) == 0: + self.viewport_pages = [(0, 0)] + return + + # Break the viewport into pages + self.viewport_pages = [] + start_idx = 0 + while start_idx < len(self._page_content): + end_idx = min(start_idx + self.viewport_size, len(self._page_content)) # type: ignore[operator] + # Adjust to end on a space + while end_idx < len(self._page_content) and self._page_content[end_idx - 1] not in [" ", "\t", "\r", "\n"]: + end_idx += 1 + self.viewport_pages.append((start_idx, end_idx)) + start_idx = end_idx + + def page_down(self) -> None: + self.viewport_current_page = min(self.viewport_current_page + 1, len(self.viewport_pages) - 1) + + def page_up(self) -> None: + self.viewport_current_page = max(self.viewport_current_page - 1, 0) + + async def visit_page(self, path_or_uri: str) -> str: + """Update the address, visit the page, and return the content of the viewport.""" + await self.set_address(path_or_uri) + return self.viewport + + def _bing_api_call(self, query: str) -> Dict[str, Dict[str, List[Dict[str, Union[str, Dict[str, str]]]]]]: + # Make sure the key was set + if self.bing_api_key is None: + raise ValueError("Missing Bing API key.") + + # Prepare the request parameters + request_kwargs = {} + request_kwargs["headers"] = {} + request_kwargs["headers"]["Ocp-Apim-Subscription-Key"] = self.bing_api_key + + if "params" not in request_kwargs: + request_kwargs["params"] = {} + request_kwargs["params"]["q"] = query + request_kwargs["params"]["textDecorations"] = False + request_kwargs["params"]["textFormat"] = "raw" + + request_kwargs["stream"] = False + + # Make the request + response = requests.get(self.bing_base_url, **request_kwargs) + response.raise_for_status() + results = response.json() + + return results # type: ignore[no-any-return] + + def _bing_search(self, query: str) -> None: + results = self._bing_api_call(query) + + web_snippets: List[str] = list() + idx = 0 + for page in results["webPages"]["value"]: + idx += 1 + web_snippets.append(f"{idx}. [{page['name']}]({page['url']})\n{page['snippet']}") + if "deepLinks" in page: + for dl in page["deepLinks"]: + idx += 1 + web_snippets.append( + f"{idx}. [{dl['name']}]({dl['url']})\n{dl['snippet'] if 'snippet' in dl else ''}" # type: ignore[index] + ) + + news_snippets = list() + if "news" in results: + for page in results["news"]["value"]: + idx += 1 + news_snippets.append(f"{idx}. [{page['name']}]({page['url']})\n{page['description']}") + + self.page_title = f"{query} - Search" + + content = ( + f"A Bing search for '{query}' found {len(web_snippets) + len(news_snippets)} results:\n\n## Web Results\n" + + "\n\n".join(web_snippets) + ) + if len(news_snippets) > 0: + content += "\n\n## News Results:\n" + "\n\n".join(news_snippets) + self._set_page_content(content) + + +def _browser_state(browser: SimpleTextBrowser) -> Tuple[str, str]: + header = f"Address: {browser.address}\n" + if browser.page_title is not None: + header += f"Title: {browser.page_title}\n" + + current_page = browser.viewport_current_page + total_pages = len(browser.viewport_pages) + header += f"Viewport position: Showing page {current_page+1} of {total_pages}.\n" + return (header, browser.viewport) + + +async def informational_web_search(browser: SimpleTextBrowser, query: str) -> str: + await browser.visit_page(f"bing: {query}") + header, content = _browser_state(browser) + return header.strip() + "\n=======================\n" + content + + +async def navigational_web_search(browser: SimpleTextBrowser, query: str): + await browser.visit_page(f"bing: {query}") + + # Extract the first linl + m = re.search(r"\[.*?\]\((http.*?)\)", browser.page_content) + if m: + await browser.visit_page(m.group(1)) + + # Return where we ended up + header, content = _browser_state(browser) + return header.strip() + "\n=======================\n" + content + + +async def visit_page(browser: SimpleTextBrowser, url: str): + await browser.visit_page(url) + header, content = _browser_state(browser) + return header.strip() + "\n=======================\n" + content + + +async def download_file(browser: SimpleTextBrowser, url: str): + await browser.visit_page(url) + header, content = _browser_state(browser) + return header.strip() + "\n=======================\n" + content + + +async def page_up(browser: SimpleTextBrowser): + browser.page_up() + header, content = _browser_state(browser) + return header.strip() + "\n=======================\n" + content + + +async def page_down(browser: SimpleTextBrowser): + browser.page_down() + header, content = _browser_state(browser) + return header.strip() + "\n=======================\n" + content + + +async def find_on_page_ctrl_f(browser: SimpleTextBrowser, search_string: str): + find_result = browser.find_on_page(search_string) + header, content = _browser_state(browser) + + if find_result is None: + return ( + header.strip() + + "\n=======================\nThe search string '" + + search_string + + "' was not found on this page." + ) + else: + return header.strip() + "\n=======================\n" + content + + +async def find_next(browser: SimpleTextBrowser): + find_result = browser.find_next() + header, content = _browser_state(browser) + + if find_result is None: + return header.strip() + "\n=======================\nThe search string was not found on this page." + else: + return header.strip() + "\n=======================\n" + content + + +async def read_page_and_answer( + browser: SimpleTextBrowser, + summarization_client: OpenAIChat, + question: str, + url: str | None = None, +): + if url is not None and url != browser.address: + await browser.visit_page(url) + + limit = 32000 + + buffer = "" + for line in re.split(r"([\r\n]+)", browser.page_content): + tokens = count_string_tokens(buffer + line, summarization_client.args.model) + if tokens + 1024 > limit: # Leave room for our summary + break + buffer += line + + buffer = buffer.strip() + if len(buffer) == 0: + return "Nothing to summarize." + + messages = [ + { + "role": "system", + "content": "You are a helpful assistant that can summarize long documents to answer question.", + } + ] + + prompt = f"Please summarize the following into one or two paragraph:\n\n{buffer}" + if question is not None: + prompt = f"Please summarize the following into one or two paragraphs with respect to '{question}':\n\n{buffer}" + + messages.append( + {"role": "user", "content": prompt}, + ) + + try: + response = await summarization_client.agenerate_response(history=messages) # type: ignore[union-attr] + except Exception as e: + return str(e) + return response.content + + +async def summarize_page( + browser: SimpleTextBrowser, + summarization_client: OpenAIChat, + url: str | None = None, +): + return await read_page_and_answer(browser, summarization_client, url=url, question=None) diff --git a/im_client/agents/tools/rag_tools.py b/im_client/agents/tools/rag_tools.py new file mode 100644 index 0000000..9407a72 --- /dev/null +++ b/im_client/agents/tools/rag_tools.py @@ -0,0 +1,48 @@ +import os + +PERSIST_DIR = os.environ.get("PERSIST_DIR") + +if PERSIST_DIR: + from llama_index.core.retrievers import VectorIndexRetriever + from llama_index.llms.openai import OpenAI + from llama_index.core import VectorStoreIndex + from llama_index.core.retrievers import VectorIndexRetriever + from llama_index.core import ( + VectorStoreIndex, + SimpleDirectoryReader, + StorageContext, + load_index_from_storage, + Settings, + ) + + if not os.path.exists(PERSIST_DIR): + from llama_index.core.node_parser import SentenceSplitter + + # Local settings + Settings.chunk_size = int(os.environ.get("CHUNK_SIZE")) # default 512 + documents = SimpleDirectoryReader(os.environ.get("RAG_DATA")).load_data() + index = VectorStoreIndex.from_documents( + documents, + transformations=[SentenceSplitter(chunk_size=int(os.environ.get("CHUNK_SIZE")))], + llm=OpenAI( + temperature=float(os.environ.get("RAG_LLM_TEMPERATURE")), + ), # default 0.1 gpt-3.5-turbo + ) + index = VectorStoreIndex.from_documents(documents) + + index.storage_context.persist(persist_dir=PERSIST_DIR) + else: + storage_context = StorageContext.from_defaults(persist_dir=PERSIST_DIR) + index = load_index_from_storage(storage_context) + + +def rag_query(query: str): + retriever = VectorIndexRetriever( + index=index, + similarity_top_k=int(os.environ.get("SIMILARITY_TOP_K")), # default 2 + ) + response = retriever.retrieve(query) + ret = [item.get_text() for item in response] + ret = "\n".join(ret) + + return "according to the query and documents, the answers retrieved by rag are \n\n" + ret + "." diff --git a/im_client/agents/tools/scholarly_tools.py b/im_client/agents/tools/scholarly_tools.py new file mode 100644 index 0000000..cbb7725 --- /dev/null +++ b/im_client/agents/tools/scholarly_tools.py @@ -0,0 +1,53 @@ +def scholarly_search_author( + query: str = "", +) -> str: + """a wrapper for scholarly.search_author""" + from scholarly import scholarly + + search_query = scholarly.search_author(query) + + result = "" + for item in search_query: + result += "{" + for k, v in item.items(): + if k not in ["container_type", "filled", "source", "scholar_id"]: + result += f"{k}: {v}\n" + result += "}" + result += "\n" + return result + + +def scholarly_search_keyword( + query: str = "", +) -> str: + """a wrapper for scholarly.search_keyword""" + from scholarly import scholarly + + search_query = scholarly.search_keyword(query) + result = "" + for item in search_query: + result += "{" + for k, v in item.items(): + if k not in ["container_type", "filled", "source", "scholar_id"]: + result += f"{k}: {v}\n" + result += "}" + result += "\n" + return result + + +def scholarly_search_pubs( + query: str = "", +) -> str: + """a wrapper for scholarly.search_pubs""" + from scholarly import scholarly + + search_query = scholarly.search_pubs(query) + result = "" + for item in search_query: + result += "{" + for k, v in item.items(): + if k not in ["container_type", "filled", "source", "scholar_id"]: + result += f"{k}: {v}\n" + result += "}" + result += "\n" + return result diff --git a/im_client/agents/tools/wikidata.py b/im_client/agents/tools/wikidata.py new file mode 100644 index 0000000..96dad3c --- /dev/null +++ b/im_client/agents/tools/wikidata.py @@ -0,0 +1,186 @@ +"""Util that calls Wikidata. +https://github.com/langchain-ai/langchain/blob/master/libs/community/langchain_community/utilities/wikidata.py""" + +from typing import Any, Dict, List, Optional +from pydantic import BaseModel, model_validator +from common.log import logger + +WIKIDATA_MAX_QUERY_LENGTH = 300 +# Common properties you probably want to see filtered from https://www.wikidata.org/wiki/Wikidata:Database_reports/List_of_properties/all +DEFAULT_PROPERTIES = [ + "P31", + "P279", + "P27", + "P361", + "P527", + "P495", + "P17", + "P585", + "P131", + "P106", + "P21", + "P569", + "P570", + "P577", + "P50", + "P571", + "P641", + "P625", + "P19", + "P69", + "P108", + "P136", + "P39", + "P161", + "P20", + "P101", + "P179", + "P175", + "P7937", + "P57", + "P607", + "P509", + "P800", + "P449", + "P580", + "P582", + "P276", + "P69", + "P112", + "P740", + "P159", + "P452", + "P102", + "P1142", + "P1387", + "P1576", + "P140", + "P178", + "P287", + "P25", + "P22", + "P40", + "P185", + "P802", + "P1416", +] +DEFAULT_LANG_CODE = "en" +WIKIDATA_USER_AGENT = "langchain-wikidata" +WIKIDATA_API_URL = "https://www.wikidata.org/w/api.php" +WIKIDATA_REST_API_URL = "https://www.wikidata.org/w/rest.php/wikibase/v0/" + + +class WikidataAPIWrapper(BaseModel): + """Wrapper around the Wikidata API. + + To use, you should have the ``wikibase-rest-api-client`` and + ``mediawikiapi `` python packages installed. + This wrapper will use the Wikibase APIs to conduct searches and + fetch item content. By default, it will return the item content + of the top-k results. + It limits the Document content by doc_content_chars_max. + """ + + wikidata_mw: Any #: :meta private: + wikidata_rest: Any # : :meta private: + top_k_results: int = 2 + load_all_available_meta: bool = False + doc_content_chars_max: int = 4000 + wikidata_props: List[str] = DEFAULT_PROPERTIES + lang: str = DEFAULT_LANG_CODE + + @model_validator(mode="before") + def validate_environment(cls, values: Dict) -> Dict: + """Validate that the python package exists in environment.""" + try: + from mediawikiapi import MediaWikiAPI + from mediawikiapi.config import Config + + values["wikidata_mw"] = MediaWikiAPI(Config(user_agent=WIKIDATA_USER_AGENT, mediawiki_url=WIKIDATA_API_URL)) + except ImportError: + raise ImportError( + "Could not import mediawikiapi python package. " "Please install it with `pip install mediawikiapi`." + ) + + try: + from wikibase_rest_api_client import Client + + client = Client( + timeout=60, + base_url=WIKIDATA_REST_API_URL, + headers={"User-Agent": WIKIDATA_USER_AGENT}, + follow_redirects=True, + ) + values["wikidata_rest"] = client + except ImportError: + raise ImportError( + "Could not import wikibase_rest_api_client python package. " + "Please install it with `pip install wikibase-rest-api-client`." + ) + return values + + def _item_to_document(self, qid: str) -> Optional[str]: + from wikibase_rest_api_client.utilities.fluent import FluentWikibaseClient + + fluent_client: FluentWikibaseClient = FluentWikibaseClient( + self.wikidata_rest, supported_props=self.wikidata_props, lang=self.lang + ) + resp = fluent_client.get_item(qid) + + if not resp: + logger.warning(f"Could not find item {qid} in Wikidata") + return None + + doc_lines = [] + if resp.label: + doc_lines.append(f"Label: {resp.label}") + if resp.description: + doc_lines.append(f"Description: {resp.description}") + if resp.aliases: + doc_lines.append(f"Aliases: {', '.join(resp.aliases)}") + for prop, values in resp.statements.items(): + if values: + doc_lines.append(f"{prop.label}: {', '.join(values)}") + + return "\n".join(doc_lines)[: self.doc_content_chars_max] + # return Document( + # page_content=("\n".join(doc_lines))[: self.doc_content_chars_max], + # meta={"title": qid, "source": f"https://www.wikidata.org/wiki/{qid}"}, + # ) + + def load(self, query: str) -> List[str]: + """ + Run Wikidata search and get the item documents plus the meta information. + """ + + clipped_query = query[:WIKIDATA_MAX_QUERY_LENGTH] + items = self.wikidata_mw.search(clipped_query, results=self.top_k_results) + docs = [] + for item in items[: self.top_k_results]: + if doc := self._item_to_document(item): + docs.append(doc) + return docs + + def run(self, query: str) -> str: + """Run Wikidata search and get item summaries.""" + + clipped_query = query[:WIKIDATA_MAX_QUERY_LENGTH] + items = self.wikidata_mw.search(clipped_query, results=self.top_k_results) + + docs = [] + for item in items[: self.top_k_results]: + if doc := self._item_to_document(item): + docs.append(f"Result {item}:\n{doc}") + if not docs: + return "No good Wikidata Search Result was found" + return "\n\n".join(docs)[: self.doc_content_chars_max] + + +def search_wikidata(query: str) -> str: + """Run Wikidata search and get item summaries.""" + wikidata = WikidataAPIWrapper() + return wikidata.run(query) + + +if __name__ == "__main__": + print(search_wikidata("Albert Einstein")) diff --git a/im_client/agents/tools/wikipedia_api.py b/im_client/agents/tools/wikipedia_api.py new file mode 100644 index 0000000..b84951d --- /dev/null +++ b/im_client/agents/tools/wikipedia_api.py @@ -0,0 +1,89 @@ +"""Util that calls Wikipedia.""" + +import logging +from typing import Any, Dict, Iterator, List, Optional + +from pydantic import BaseModel, model_validator + +logger = logging.getLogger(__name__) + +WIKIPEDIA_MAX_QUERY_LENGTH = 300 + + +class WikipediaAPIWrapper(BaseModel): + """Wrapper around WikipediaAPI. + + To use, you should have the ``wikipedia`` python package installed. + This wrapper will use the Wikipedia API to conduct searches and + fetch page summaries. By default, it will return the page summaries + of the top-k results. + It limits the Document content by doc_content_chars_max. + """ + + wiki_client: Any #: :meta private: + top_k_results: int = 3 + lang: str = "en" + load_all_available_meta: bool = False + doc_content_chars_max: int = 4000 + + @model_validator(mode="before") + def validate_environment(cls, values: Dict) -> Dict: + """Validate that the python package exists in environment.""" + try: + import wikipedia + + wikipedia.set_lang(values["lang"]) + values["wiki_client"] = wikipedia + except ImportError: + raise ImportError( + "Could not import wikipedia python package. " "Please install it with `pip install wikipedia`." + ) + return values + + def run(self, query: str) -> str: + """Run Wikipedia search and get page summaries.""" + page_titles = self.wiki_client.search(query[:WIKIPEDIA_MAX_QUERY_LENGTH], results=self.top_k_results) + summaries = [] + for page_title in page_titles[: self.top_k_results]: + if wiki_page := self._fetch_page(page_title): + if summary := self._formatted_page_summary(page_title, wiki_page): + summaries.append(summary) + if not summaries: + return "No good Wikipedia Search Result was found" + return "\n\n".join(summaries)[: self.doc_content_chars_max] + + @staticmethod + def _formatted_page_summary(page_title: str, wiki_page: Any) -> Optional[str]: + return f"Page: {page_title}\nSummary: {wiki_page.summary}" + + def _fetch_page(self, page: str) -> Optional[str]: + try: + return self.wiki_client.page(title=page, auto_suggest=False) + except ( + self.wiki_client.exceptions.PageError, + self.wiki_client.exceptions.DisambiguationError, + ): + return None + + def load(self, query: str) -> List[str]: + """ + Run Wikipedia search and get the article text plus the meta information. + See + + Returns: a list of documents. + + """ + return list(self.lazy_load(query)) + + def lazy_load(self, query: str) -> Iterator[str]: + """ + Run Wikipedia search and get the article text plus the meta information. + See + + Returns: a list of documents. + + """ + page_titles = self.wiki_client.search(query[:WIKIPEDIA_MAX_QUERY_LENGTH], results=self.top_k_results) + for page_title in page_titles[: self.top_k_results]: + if wiki_page := self._fetch_page(page_title): + yield wiki_page diff --git a/im_client/agents/tools/youtube.py b/im_client/agents/tools/youtube.py new file mode 100644 index 0000000..f79b528 --- /dev/null +++ b/im_client/agents/tools/youtube.py @@ -0,0 +1,89 @@ +import json +import uuid +import os +import requests +from common.log import logger + +TEMP_DIR = "./temp" +WHISPER_URL = "http://166.111.121.22:8848/whisper" +MAX_CHAR = 10000 + + +def get_youtube_transcript(youtube_id: str | None = None, url: str | None = None): + from pytube import YouTube + + def _audio_to_text(yt: YouTube): + logger.info("No captions found. Trying to extract text from audio.") + os.makedirs(TEMP_DIR, exist_ok=True) + uid = uuid.uuid4().hex + try: + audio = yt.streams.filter(only_audio=True).first() + ext = audio.mime_type.split("/")[-1] + filename = f"audio_{uid}.{ext}" + logger.info(f"Downloading the audio file and save to {TEMP_DIR}/{filename}") + audio.download(output_path=TEMP_DIR, filename=filename) + logger.info("Downloaded") + except Exception as e: + return f"Error: {e}" + with open(os.path.join(TEMP_DIR, filename), "rb") as file: + # Create a dictionary to hold the file data + files = {"file": (filename.split("/")[-1], file, "multipart/form-data")} + + # Send the POST request with the file + logger.info("Running speech-to-text...") + response = requests.post(WHISPER_URL, files=files) + + return response.json()["text"] + + if youtube_id is None and url is None: + return "You should provide either youtube_id or url" + elif youtube_id is not None and url is not None: + if url != f"https://www.youtube.com/watch?v={youtube_id}": + return "youtube_id and url are not matched. Ensure that url is correct, or simply pass one of them." + elif url is None: + url = f"https://www.youtube.com/watch?v={youtube_id}" + try: + yt = YouTube(url) + yt.bypass_age_gate() + except Exception as e: + return f"Error: {e}" + captions = yt.captions + if len(captions) == 0: + return _audio_to_text(yt)[:MAX_CHAR] + text = "" + for lang in ["en", "fr", "es", "de", "zh-CN", "zh-Hant", "zh-HK", "it", "nl", "pt", "ru", "ja", "ko"]: + caption = yt.captions.get(lang, None) + if caption is not None: + try: + json_captions = caption.json_captions + for event in json_captions["events"]: + for seg in event["segs"]: + text += seg["utf8"] + "\n" + except Exception as e: + text = "" + continue + if text == "": + return _audio_to_text(yt)[:MAX_CHAR] + return text.strip()[:MAX_CHAR] + + +def search_youtube(query: str, num_results: int = 5): + import re + from youtube_search import YoutubeSearch + + real_suffix_pat = re.compile(r"/watch\?v=[a-zA-Z0-9_-]{11}") + + results = YoutubeSearch(query, num_results).to_json() + data = json.loads(results) + url_suffix_list = [] + if len(data["videos"]) > 0: + url_suffix_list = [ + "https://www.youtube.com" + real_suffix_pat.findall(video["url_suffix"])[0] for video in data["videos"] + ] + return str(url_suffix_list) + + +if __name__ == "__main__": + # print(search_youtube("how to make a cake", 5)) + # print(get_youtube_transcript(youtube_id="nl8o9PsJPAQ")) + print(get_youtube_transcript(url="https://www.youtube.com/watch?v=EYXQmbZNhy8")) diff --git a/im_client/communication/__init__.py b/im_client/communication/__init__.py new file mode 100644 index 0000000..cd3c173 --- /dev/null +++ b/im_client/communication/__init__.py @@ -0,0 +1 @@ +from .communication_layer import CommunicationLayer diff --git a/im_client/communication/communication_layer.py b/im_client/communication/communication_layer.py new file mode 100644 index 0000000..e22d5f7 --- /dev/null +++ b/im_client/communication/communication_layer.py @@ -0,0 +1,1497 @@ +import asyncio +import json +import os +import random +import re +import urllib +from copy import deepcopy +from string import Template +from typing import Any, Literal, Tuple + +import yaml +from agents.base import AgentAdapter +from llms import load_llm +from memory import ChatHistoryMemory +from observation_func import observation_registry +from openai.types.chat import ChatCompletionMessageToolCall +from prompts import ( + COMM_APPEND_PROMPT, + COMM_CONCLUDE_APPEND_PROMPT, + COMM_COORDINATION_WITHOUT_GOAL_PROMPT, + COMM_DISCOVERY_PROMPT, + COMM_DISCUSSION_ONLY_DISCUSSION_APPEND_PROMPT, + COMM_DISCUSSION_WITH_PLAN_APPEND_PROMPT, + COMM_DISCUSSION_WITHOUT_PLAN_APPEND_PROMPT, + COMM_HUMANAGENT_SYSTEM_PROMPT, + COMM_INFORM_OPT_EXE_APPEND_PROMPT, + COMM_MAS_PROMPT, + COMM_PAUSE_APPEND_PROMPT, + COMM_PAUSE_SYS_PROMPT, + COMM_PLANNER_PROMPT, + COMM_TASK_MANAGEMENT_APPEND_PROMPT, + COMM_THINGAGENT_SYSTEM_PROMPT, + COMM_UPDATE_PLAN_APPEND_PROMPT, + COMM_WHETHER_TEAM_UP_PROMPT, + EXEC_TASK_CONCLUSION_APPEND_PROMPT, + REPHRASE_TASK_APPEND_PROMPT, + REPHRASE_TASK_HYBIRD_SYS_PROMPT, + TEAMUP_GROUP_NAMING_PROMPT, +) +from server_helper import ServerHelper + +from common.config import global_config +from common.log import logger +from common.types import CommunicationInfo, CommunicationState, CommunicationType +from common.types.communication import AgentMessage, COMMUNICATION_TYPE_MAP +from common.types.llm import LLMResult +from common.utils.database_utils import AutoStoredDict +from common.utils.milvus_utils import ConfigMilvusWrapper + +from .task_management import TaskEntry, TaskManager, TaskStatus +from .websocket_client import WebSocketClient + +TEAM_UP_TOOLS = [ + { + "type": "function", + "function": { + "name": "agent_discovery", + "description": "Discover new agents in the network by searching with natural langugae queries which could be desired expertises, skills, agent description, tasks suitable and so on.", + "parameters": { + "type": "object", + "properties": { + "queries": { + "description": "List of natural langugae queries, which could be desired expertises, skills, agent description, tasks suitable and so on.", + "type": "array", + "items": {"type": "string"}, + } + }, + "required": ["queries"], + }, + }, + }, + { + "type": "function", + "function": { + "name": "team_up", + "description": "Initiate a group chat session aimed at facilitating collaboration among a team of agents identified by their unique agent names.", + "parameters": { + "type": "object", + "properties": { + "team_members": { + "description": "An array of unique strings, each representing the name of an agent in the team (the name of yourself should be included).", + "type": "array", + "items": {"type": "string"}, + } + }, + "required": ["team_members"], + }, + }, + }, +] + + +def CommunicationInfo_from_dict_hook(obj: Any, **kwargs): + instance = CommunicationInfo.model_validate(obj=obj, **kwargs) + if instance.memory is not None: + memory = ChatHistoryMemory.model_validate(instance.memory) + instance.memory = memory + return instance + + +class CommunicationLayer: + """ + A class that manages communication and collaboration between agents in the Internet of Agents framework. + + This class serves as the core component for agent interaction, handling tasks such as team formation, + message routing, task allocation, and conversation flow control. + + Attributes: + name (str): The name of the agent. + desc (str): A description of the agent's capabilities. + agent_type (str): The type of agent ("Human Assistant" or "Thing Assistant"). + tool_agent (AgentAdapter): An optional third-party agent for executing specific tasks. + server_websocket (WebSocketClient): A WebSocket client for server communication. + support_nested_teams (bool): Whether the agent supports forming nested teams. + discussion_only (bool): Whether the agent is limited to discussion-only mode. + + Methods: + create: Asynchronously creates and initializes a CommunicationLayer instance. + launch_goal: Given a goal, the client would form team with other agents to solve. + team_up: Forms a team of agents for a specific task. + coordination: Manages the ongoing conversation and task execution. + shutdown: Gracefully shuts down the communication layer and associated resources. + """ + + def __init__( + self, + name: str, + desc: str, + agent_type: Literal["Human Assistant", "Thing Assistant"], + server_websocket: WebSocketClient, + tool_agent: AgentAdapter | None = None, + support_nested_teams: bool = False, + discussion_only: bool = False, + ): + self.name = name + self.desc = desc + self.agent_type = agent_type + self.tool_agent = tool_agent + self.server_websocket = server_websocket + self.observation_func = observation_registry[global_config["comm"].get("observation_func", "dummy")] + self.discussion_only = discussion_only + self.llm = load_llm(deepcopy(global_config["comm"]["llm"])) + + if self.agent_type == "Human Assistant": + self.system_prompt_template = COMM_HUMANAGENT_SYSTEM_PROMPT + else: + self.system_prompt_template = COMM_THINGAGENT_SYSTEM_PROMPT + + agent_db_name = "agent_" + re.sub(r"[^a-zA-Z0-9_]", "_", self.name) + self.agent_contact = ConfigMilvusWrapper( + os.path.join("configs", "vecdb", "agent_contact.yaml"), + name_modify=agent_db_name, + ) + + self.comm_bank = AutoStoredDict( + f"./database/{agent_db_name}/comm.db", + tablename="comm_bank", + object_type=CommunicationInfo, + from_dict_hook=CommunicationInfo_from_dict_hook, + ) + + self.task_manager_bank = AutoStoredDict( + f"./database/{agent_db_name}/comm.db", + tablename="task_manager_bank", + object_type=TaskManager, + ) + self.support_nested_teams: bool = support_nested_teams # whether the agent can organize teams (in a hierarchical structure) when assigned a task + + @classmethod + async def create( + cls, + name: str, + desc: str, + agent_type: Literal["Human Assistant", "Thing Assistant"], + tool_agent: AgentAdapter | None = None, + support_nested_teams: bool = False, + discussion_only: bool = False, + ): + await cls.register(name, desc, agent_type) + server_websocket = await cls.register_websocket(name) + layer = cls( + name, + desc, + agent_type, + server_websocket, + tool_agent, + support_nested_teams, + discussion_only, + ) + asyncio.get_event_loop().create_task(layer._listen_message()) + return layer + + @classmethod + async def register( + cls, + name: str, + desc: str, + agent_type: Literal["Human Assistant", "Thing Assistant"], + ): + await ServerHelper.register(name, desc, agent_type) + + @classmethod + async def register_websocket(cls, name: str): + hostname = global_config["server"]["hostname"] + port = global_config["server"]["port"] + uri = f"ws://{hostname}:{port}/ws/{name}" + # encode the uri + uri = urllib.parse.quote(uri, safe=":/?&=,.") + websocket = WebSocketClient(uri) + await websocket.connect() + return websocket + + async def launch_goal( + self, + goal: str, + team_member_names: list[str] | None = None, + team_up_depth: int | None = None, + is_collaborative_planning_enabled: bool = False, + comm_id: str | None = None, + cont_input: dict | None = None, + obs_kwargs: dict = {}, + max_turns: int | None = None, + skip_naming: bool = True, + ) -> Tuple[str, str]: + """ + Launch a group chat targetted on the given goal. + + Args: + goal (str): The high-level goal that this group chat aims to achieve. + team_member_names (list[str], optional): The names of the teammates. If specified, + then the assistant will directly team up with these teammates. Defaults to None. + team_up_depth (int, optional): The depth of the nested team-up. Defaults to None. + is_collaborative_planning_enabled (bool, optional): Whether the collaborative planning is enabled. Defaults to False. + comm_id (str, optional): The id of the previous chat session. Defaults to None. + cont_input (dict, optional): The input of the continuation message, with `content` and `sender` keys. Defaults to None. + obs_kwargs (dict, optional): The observation arguments. Defaults to {}. + max_turns (int, optional): The maximum turns of the chat session. Defaults to None. + skip_naming (bool, optional): Whether to skip the naming of the team. Defaults to True. + Returns: + Tuple[str, str]: The id of the chat session and the conclusion of the chat session. + """ + new_message = None + if comm_id is None: + # team up: determine the team members, return the comm id. + cont_input = None + comm_id = await self.team_up( + goal, + team_member_names, + team_up_depth=team_up_depth, + is_collaborative_planning_enabled=is_collaborative_planning_enabled, + obs_kwargs=obs_kwargs, + max_turns=max_turns, + skip_naming=skip_naming, + ) + else: + # continue the previous discussion + if comm_id not in self.comm_bank: + return comm_id, f"Could not find the communication session: {comm_id}." + comm_info: CommunicationInfo = self.comm_bank[comm_id] + comm_info.conclusion = None + comm_info.max_turns = max_turns + self.comm_bank[comm_id] = comm_info + if cont_input is not None: + # if the continuation message is provided, then send the message to all the team members. + # and randomly assign the next speaker. + new_message = AgentMessage( + content=cont_input["content"], + sender=cont_input["sender"], + comm_id=comm_id, + next_speaker=random.choice([t["name"] for t in comm_info.team_members]), + state=CommunicationState.DISCUSSION, + type=CommunicationType.DISCUSSION, + goal=comm_info.goal, + team_members=comm_info.team_members, + team_up_depth=comm_info.team_up_depth, + is_collaborative_planning_enabled=comm_info.is_collaborative_planning_enabled, + ) + self.comm_bank[comm_id] = comm_info + await self._send_message(new_message) + + if cont_input is None: + await self.coordination( + new_message=new_message, + comm_id=comm_id, + obs_kwargs=obs_kwargs, + max_turns=max_turns, + ) + + # check the conclusion field in polling + while True: + conclusion = self.comm_bank[comm_id].conclusion + if conclusion is None: + await asyncio.sleep(5) + else: + return comm_id, conclusion + + async def _naming_team(self, goal: str, team_members: list[str] = []) -> str: + prepend_prompt = [ + Template(TEAMUP_GROUP_NAMING_PROMPT).safe_substitute( + {"goal": goal, "teammates": json.dumps(team_members, indent=2)} + ) + ] + response: LLMResult = await self.llm.agenerate_response( + prepend_prompt=prepend_prompt, + response_format={"type": "json_object"}, + ) + try: + team_name = response.content["team_name"] + except: + team_name = None + return team_name + + async def _call_teamup_tool( + self, + tool_call: ChatCompletionMessageToolCall, + goal: str, + skip_naming: bool = True, + ) -> Tuple[bool, LLMResult, str, list[str]]: + tool_name = tool_call.function.name + tool_input = tool_call.function.arguments + tool_call_id = tool_call.id + match tool_name: + case "agent_discovery": + try: + agent_infos = await ServerHelper.retrieve_assistant(self.name, tool_input["queries"]) + # deduplicate agent_infos compared with self.agent_contact + new_agents_retrieved = [] + for agent in agent_infos: + if agent.get("name") != self.name and agent.get("name") not in self.agent_contact: + new_agents_retrieved.append(agent) + + except Exception as e: + logger.error(e) + return False, None, None, None + result = LLMResult( + content=( + json.dumps(new_agents_retrieved, indent=2) + if new_agents_retrieved + else "No more new agents retrieved." + ), + tool_call_id=tool_call_id, + name=tool_name, + role="tool", + ) + logger.log_llm_result(result) + # TODO: update the contact list. + for agent in agent_infos: + if agent["name"] not in self.agent_contact and agent["name"] != self.name: + self.agent_contact[agent["name"]] = agent + return False, result, None, None + case "team_up": + try: + team_member_names = tool_input["team_members"] + team_members = await ServerHelper.query_assistant(team_member_names) + team_name = None + if not skip_naming: + team_name = await self._naming_team(goal, team_members) + + team_info = await ServerHelper.teamup( + sender=self.name, + agent_names=[agent_name for agent_name in team_member_names if agent_name != self.name], + team_name=team_name, + ) + + result = LLMResult( + content="Group Established.", + tool_call_id=tool_call_id, + name=tool_name, + role="tool", + ) + logger.log_llm_result(result) + return True, result, team_info.comm_id, team_members + except Exception as e: + logger.error(e) + result = LLMResult( + content="Group Establishment Failed.", + tool_call_id=tool_call_id, + name=tool_name, + role="tool", + ) + logger.log_llm_result(result) + return False, result, None, None + + async def _discover_and_teamup( + self, + goal: str, + local_contact: list[dict] | list, + memory: ChatHistoryMemory, + obs_kwargs: dict = {}, + skip_naming: bool = True, + is_last_attempt: bool = False, + ) -> Tuple[bool, str, list[str]]: + """ + Let the agent decide whether to search for more relevent agents on the server or to team up. + """ + observation = self.observation_func(**obs_kwargs) + prepend_prompt = [ + Template(self.system_prompt_template).safe_substitute( + { + "name": self.name, + "desc": self.desc, + "agent_type": self.agent_type, + } + ), + COMM_MAS_PROMPT, + Template(COMM_DISCOVERY_PROMPT).safe_substitute( + { + "goal": goal, + "retrieved_contact": str(local_contact), # TODO (vec) database -> DONE + } + ), + ] + if observation != "": + prepend_prompt.append(f"Current Observation:\n{observation}") + + response: LLMResult = await self.llm.agenerate_response( + prepend_prompt=prepend_prompt, + history=(await memory.to_messages()), + append_prompt=Template(COMM_APPEND_PROMPT).safe_substitute({"name": self.name}), + tools=TEAM_UP_TOOLS, + tool_choice={"type": "function", "function": {"name": "team_up"}} if is_last_attempt else "auto", + ) + + response.content = str(response.content) + + logger.log_llm_result(response) + memory.add_messages(response) + + finished = False + comm_id = None + team_members = None + if response.parsed_tool_calls: + for i, tool_call in enumerate(response.parsed_tool_calls): + finished, tool_response, comm_id, team_members = await self._call_teamup_tool( + tool_call, goal, skip_naming + ) + if tool_response is not None: + memory.add_messages(tool_response) + if finished: + break + return finished, comm_id, team_members + + async def team_up( + self, + goal: str, + team_member_names: list[str] | None = None, + team_up_depth: int | None = None, + is_collaborative_planning_enabled: bool = False, + obs_kwargs: dict[str, Any] = {}, + max_turns: int | None = None, + skip_naming: bool = True, + ) -> str: + """Given a high-level goal, the communication agent decides whether to team up + with other agents. The server will build a chat session including all the + teammates, and return a communication id for completing this task. + + Args: + goal (str): The high-level goal that the user wants to achieve. + team_member_names (list[str], optional): The names of the teammates. If specified, + then the agent will directly team up with these teammates. Defaults to None. + Returns: + comm_id (str): The id of the chat session. + """ + if team_member_names is not None: + # if the team members have been specified + # difrectly create a group chat for them + agents_upated_for_contact = await ServerHelper.query_assistant(team_member_names) + team_members = [] + for item in agents_upated_for_contact: + if isinstance(item, dict) and item.get("name") != self.name: + if item.get("name" not in self.agent_contact): + self.agent_contact[item.get("name")] = item + team_members.append(item) + + team_name = None + if not skip_naming: + team_name = await self._naming_team(goal, team_members) + + team_info = await ServerHelper.teamup( + sender=self.name, + agent_names=[name for name in team_member_names if name != self.name], + team_name=team_name, + ) + team_members.append({"name": self.name, "type": self.agent_type, "desc": self.desc}) + comm_id = team_info.comm_id + else: + # if the team members are not specified, let the agent itself + # search for the agents on the server, and decide who to teamup with + memory = ChatHistoryMemory() + comm_id = None + local_contact = self.agent_contact.items() + for i in range(global_config["comm"]["max_team_up_attempts"]): + is_last_attempt = i == global_config["comm"]["max_team_up_attempts"] - 1 + finished, comm_id, team_members = await self._discover_and_teamup( + goal, local_contact, memory, obs_kwargs, skip_naming, is_last_attempt=is_last_attempt + ) + + if finished: + break + + if comm_id is None: + raise ValueError("Failed to decide the teammates.") + + self.comm_bank[comm_id] = CommunicationInfo( + comm_id=comm_id, + goal=goal, + team_members=team_members, + memory=ChatHistoryMemory(), + team_up_depth=team_up_depth, + is_collaborative_planning_enabled=is_collaborative_planning_enabled, + max_turns=max_turns, + ) + self.task_manager_bank[comm_id] = TaskManager(comm_id) + + return comm_id + + def _update_memory_and_task_manager(self, new_message: AgentMessage, comm_id: str): + """ + Update chat history and task manager + """ + comm_info = self.comm_bank[comm_id] + task_manager = self.task_manager_bank[comm_id] + msg_in_memory = new_message.to_llm_result() + + comm_info.memory.add_messages(msg_in_memory) + self.comm_bank[comm_id] = comm_info + + if new_message.type == CommunicationType.INFORM_TASK_PROGRESS: + task_manager.update_task_manager( + task_id=new_message.task_id, + task_desc=new_message.task_desc, + task_abstract=new_message.task_abstract, + assignee=new_message.sender, + status=TaskStatus.IN_PROGRESS, + ) + elif new_message.type == CommunicationType.INFORM_TASK_RESULT: + task_manager.update_task_manager( + task_id=new_message.task_id, + task_desc=new_message.task_desc, + task_abstract=new_message.task_abstract, + assignee=new_message.sender, + status=TaskStatus.COMPLETED, + conclusion=new_message.task_conclusion, + msg_in_memory=msg_in_memory, + ) + if task_manager.is_triggered(): + # the triggers in task manager are marked by True all at this point. + if task_manager.trigger_setter == self.name: + new_message.next_speaker = self.name + task_manager.clear_triggers() + elif new_message.type == CommunicationType.PAUSE: + task_manager.update_triggers( + task_identifiers=new_message.triggers, + trigger_setter=new_message.sender, + ) + elif new_message.type == CommunicationType.CONCLUSION: + # conclusion should be recorded + comm_info.conclusion = new_message.content + comm_info.curr_turn = 0 + self.comm_bank[comm_id] = comm_info + if new_message.type in [ + CommunicationType.DISCUSSION, + CommunicationType.ASYNC_TASK_ASSIGNMENT, + CommunicationType.SYNC_TASK_ASSIGNMENT, + CommunicationType.PAUSE, + CommunicationType.CONCLUDE_GROUP_DISCUSSION, + ]: + if new_message.updated_plan: + task_manager.update_plan(new_message.updated_plan) + + self.comm_bank[comm_id] = comm_info + self.task_manager_bank[comm_id] = task_manager + + async def coordination( + self, new_message: AgentMessage | None, comm_id: str, obs_kwargs: dict = {}, max_turns: int | None = None + ): + """ + Manages the coordination of agents within a group chat, handling incoming messages and directing the conversation flow. + + Args: + new_message (AgentMessage | None): The incoming message to be processed. If None, it indicates + the start of a new conversation where this agent is the first speaker. + comm_id (str): The unique identifier for the current communication session or group chat. + obs_kwargs (dict, optional): Additional keyword arguments for observation functions. Defaults to {}. + max_turns (int | None, optional): The maximum number of conversation turns allowed. Defaults to None. + + The method performs the following key functions: + 1. Initializes or retrieves the current communication session information. + 2. Updates the communication history and task management state based on the incoming message. + 3. Determines the next action based on the message type (e.g., discussion, task assignment, conclusion). + 4. Generates and sends appropriate responses or initiates task executions. + 5. Manages the conversation flow, including state transitions and speaker selection. + """ + if new_message and new_message.state != CommunicationState.DISCUSSION: + logger.error("Receiving a message with a state that is not DISCUSSION.") + return + if comm_id not in self.comm_bank: + self.comm_bank[comm_id] = CommunicationInfo( + comm_id=comm_id, + goal=new_message.goal, + team_members=new_message.team_members, + memory=ChatHistoryMemory(), # TODO: configurable + state=new_message.state, + team_up_depth=new_message.team_up_depth, + is_collaborative_planning_enabled=new_message.is_collaborative_planning_enabled, + max_turns=max_turns, + ) + self.task_manager_bank[comm_id] = TaskManager(comm_id) + + if new_message is None: + # This agent is the first speaker. + return await self._coordination_discussion(new_message, comm_id, obs_kwargs) + else: + new_message.content = f"[{new_message.sender}]: {new_message.content}" + if new_message.sender != self.name: + self._update_memory_and_task_manager(new_message, comm_id) + if isinstance(new_message.next_speaker, str): + if new_message.next_speaker != self.name: + return + elif isinstance(new_message.next_speaker, list): + if self.name not in new_message.next_speaker: + return + + return await self._coordination_discussion(new_message, comm_id) + + def _get_discussion_prompt(self, comm_id: str, obs_kwargs: dict = {}): + comm_info = self.comm_bank[comm_id] + task_manager = self.task_manager_bank[comm_id] + observation = self.observation_func(**obs_kwargs) + prepend_prompt = [ + Template(self.system_prompt_template).safe_substitute( + { + "name": self.name, + "desc": self.desc, + "agent_type": self.agent_type, + "agent_name": getattr(self.tool_agent, "agent_name", ""), + "agent_desc": getattr(self.tool_agent, "agent_desc", ""), + } + ), + COMM_MAS_PROMPT, + Template(COMM_COORDINATION_WITHOUT_GOAL_PROMPT).safe_substitute( + { + "teammates": json.dumps( + [t for t in comm_info.team_members if t["name"] != self.name], + indent=2, + ) + } + ), + ] + if self.discussion_only: + collaborative_management_msgs = [ + { + "role": "system", + "content": Template(COMM_TASK_MANAGEMENT_APPEND_PROMPT).safe_substitute( + { + "task_management_view": task_manager.tasks_view(), + "goal": comm_info.goal, + } + ), + } + ] + + append_prompt = [ + Template(COMM_DISCUSSION_ONLY_DISCUSSION_APPEND_PROMPT).safe_substitute({"name": self.name}) + ] + elif comm_info.is_collaborative_planning_enabled: + collaborative_management_msgs = [ + { + "role": "system", + "content": Template(COMM_TASK_MANAGEMENT_APPEND_PROMPT).safe_substitute( + { + "task_management_view": task_manager.tasks_view(), + "goal": comm_info.goal, + } + ), + }, + { + "role": "system", + "content": Template(COMM_PLANNER_PROMPT).safe_substitute( + { + "Dynamic_Collaborative_Planner": task_manager.get_latest_plan(), + } + ), + }, + ] + append_prompt = [ + Template(COMM_DISCUSSION_WITH_PLAN_APPEND_PROMPT).safe_substitute( + {"name": self.name}, + ) + ] + else: + collaborative_management_msgs = [ + { + "role": "system", + "content": Template(COMM_TASK_MANAGEMENT_APPEND_PROMPT).safe_substitute( + { + "task_management_view": task_manager.tasks_view(), + "goal": comm_info.goal, + } + ), + } + ] + + append_prompt = [Template(COMM_DISCUSSION_WITHOUT_PLAN_APPEND_PROMPT).safe_substitute({"name": self.name})] + + if observation != "": + append_prompt.append(f"Current Observation:\n{observation}") + return prepend_prompt, collaborative_management_msgs, append_prompt + + def _get_pause_prompt(self, comm_id: str): + comm_info = self.comm_bank[comm_id] + task_manager = self.task_manager_bank[comm_id] + + sys_append_messages = [ + { + "role": "system", + "content": Template(COMM_TASK_MANAGEMENT_APPEND_PROMPT).safe_substitute( + { + "task_management_view": task_manager.tasks_view(), + "goal": comm_info.goal, + } + ), + }, + { + "role": "system", + "content": Template(COMM_PAUSE_SYS_PROMPT).safe_substitute( + { + "indices_In_Progress": task_manager.indices_filter_by_status( + status=[TaskStatus.TO_START, TaskStatus.IN_PROGRESS] + ) + } + ), + }, + ] + append_prompt = [Template(COMM_PAUSE_APPEND_PROMPT).safe_substitute({"name": self.name})] + return sys_append_messages, append_prompt + + async def _handle_generated_pause_message( + self, + comm_id: str, + parsed_response: dict, + updated_plan: str, + max_turns: int | None, + obs_kwargs: dict = {}, + ): + """ + If the generated response is a pause message, then handle the pause message. + Prompt the model to generate the trigger, and set the trigger to the task_manager properly. + """ + comm_info = self.comm_bank[comm_id] + + prepend_prompt, collaborative_management_msgs, append_prompt = self._get_discussion_prompt(comm_id, obs_kwargs) + pause_messages, append_prompt = self._get_pause_prompt(comm_id) + + pause_response: LLMResult = await self.llm.agenerate_response( + prepend_prompt=prepend_prompt, + history=(await comm_info.memory.to_messages()) + pause_messages, + append_prompt=append_prompt, + response_format={"type": "json_object"}, + ) + pause_parsed_response = pause_response.content + comm_info = self.comm_bank[comm_id] + + print("======= pause&trigger =======") + print(pause_parsed_response) + + task_manager = self.task_manager_bank[comm_id] + selected_task_indices = pause_parsed_response["selected_task_indices"] + trigger_set, selected_task_ids = task_manager.set_triggers(selected_task_indices, self.name) + self.task_manager_bank[comm_id] = task_manager + message_to_send = AgentMessage( + content=parsed_response["content"], + sender=self.name, + comm_id=comm_id, + next_speaker="" if trigger_set else [self.name], + state=CommunicationState.DISCUSSION, + type=CommunicationType.PAUSE if trigger_set else CommunicationType.DISCUSSION, + goal=comm_info.goal, + team_members=comm_info.team_members, + team_up_depth=comm_info.team_up_depth, + triggers=selected_task_ids if trigger_set else [], + updated_plan=updated_plan, + is_collaborative_planning_enabled=comm_info.is_collaborative_planning_enabled, + max_turns=max_turns, + ) + + await self._send_message(message_to_send) + + async def _generate_response(self, comm_id: str, obs_kwargs: dict = {}): + comm_info = self.comm_bank[comm_id] + + prepend_prompt, collaborative_management_msgs, append_prompt = self._get_discussion_prompt(comm_id, obs_kwargs) + + max_turns = comm_info.max_turns + curr_turn = len(await comm_info.memory.to_messages()) + if max_turns is not None and curr_turn >= max_turns: + append_prompt.append( + "The discussion has reached the maximum turns. Now you must send a message with type `conclude_group_discussion` anyway." + ) + + response: LLMResult = await self.llm.agenerate_response( + prepend_prompt=prepend_prompt, + history=(await comm_info.memory.to_messages()) + collaborative_management_msgs, + append_prompt=append_prompt, + response_format={"type": "json_object"}, + ) + + parsed_response = response.content + + print("======= turn to speak =======") + print(parsed_response["thought"]) + print(f"message type: {parsed_response['message_type']}") + print(f"next_speakers: {str(parsed_response['next_people'])}") + print(parsed_response) + if comm_info.is_collaborative_planning_enabled: + print(f"thought: {parsed_response['thought_on_Dynamic_Collaborative_Planner']}") + print( + f"update_Dynamic_Collaborative_Planner: {str(parsed_response['update_Dynamic_Collaborative_Planner'])}" + ) + result = LLMResult( + content=f"[{self.name}]: {parsed_response['content']}", + name=self.name, + role="assistant", + ) + logger.log_llm_result(result) + comm_info = self.comm_bank[comm_id] + comm_info.memory.add_messages(result) + self.comm_bank[comm_id] = comm_info + + message_type = COMMUNICATION_TYPE_MAP[parsed_response["message_type"]] + + if message_type == CommunicationType.CONCLUDE_GROUP_DISCUSSION: + next_speakers = [self.name] + else: + next_speakers = ( + parsed_response["next_people"] + if isinstance(parsed_response["next_people"], list) + else [parsed_response["next_people"]] + ) + team_members = {member["name"] for member in comm_info.team_members} + next_speakers = [name for name in next_speakers if name in team_members] + if len(next_speakers) == 0: + next_speakers = [self.name] + + # chekc whether to update plan + if comm_info.is_collaborative_planning_enabled: + is_update_plan: bool = parsed_response["update_Dynamic_Collaborative_Planner"] + else: + is_update_plan: bool = False + if is_update_plan: + self.comm_bank[comm_id] = comm_info + updated_plan = await self.update_global_plan(comm_id) + task_manager = self.task_manager_bank[comm_id] + task_manager.update_plan(updated_plan) + self.task_manager_bank[comm_id] = task_manager + else: + updated_plan = "" + + if message_type == CommunicationType.PAUSE: + await self._handle_generated_pause_message(comm_id, parsed_response, updated_plan, max_turns, obs_kwargs) + else: + # Mesage type is not pause + message_to_send = AgentMessage( + content=parsed_response["content"], + sender=self.name, + comm_id=comm_id, + next_speaker=next_speakers, + state=CommunicationState.DISCUSSION, + type=message_type, + goal=comm_info.goal, + team_members=comm_info.team_members, + team_up_depth=comm_info.team_up_depth, + updated_plan=updated_plan, + is_collaborative_planning_enabled=comm_info.is_collaborative_planning_enabled, + max_turns=max_turns, + ) + if message_type in [ + CommunicationType.ASYNC_TASK_ASSIGNMENT, + CommunicationType.SYNC_TASK_ASSIGNMENT, + ]: + task_manager = self.task_manager_bank[comm_id] + task_assign_manager = task_manager.task_assign_manager + task_assign_manager.register_await_agents(next_speakers) + self.task_manager_bank[comm_id] = task_manager + await self._send_message(message_to_send) + + async def _handle_info_message(self, new_message: AgentMessage, comm_id: str, obs_kwargs: dict = {}): + """ + Handle the incoming info messages, i.e., messages with type `INFORM_TASK_PROGRESS`, `INFORM_TASK_RESULT`, or `DISCUSSION`. + """ + task_manager = self.task_manager_bank[comm_id] + task_assign_manager = task_manager.task_assign_manager + + if new_message and ( + new_message.type + in [ + CommunicationType.INFORM_TASK_PROGRESS, + CommunicationType.INFORM_TASK_RESULT, + ] + ): + task_assign_manager.update_await_agents(new_message.sender) + if not task_assign_manager.check_empty(): + logger.info(f"Still awaiting: {task_assign_manager.await_agents}") + self.task_manager_bank[comm_id] = task_manager + return + logger.info("Task assign manager is empty.") + + self.task_manager_bank[comm_id] = task_manager + await self._generate_response(comm_id, obs_kwargs) + + async def _handle_async_task_assignment(self, new_message: AgentMessage, comm_id: str, obs_kwargs: dict = {}): + """ + Handle the incoming async task assignment message. The agent will inform the tool agent to execute the task. + And a confirmation message will be immediately sent to other agents. The discussion will be continued. + The next speaker is the task assigner. + """ + comm_info: CommunicationInfo = self.comm_bank[comm_id] + observation = self.observation_func(**obs_kwargs) + ( + reference, + task_desc, + task_abstract, + context_information, + completion_criteria, + ) = await self._rephrase_task_to_tool_agent(comm_id, observation) + task_manager: TaskManager = self.task_manager_bank[comm_id] + task_id = task_manager.create_task(task_desc, task_abstract, self.name, status=TaskStatus.TO_START) + self.comm_bank[comm_id] = comm_info + self.task_manager_bank[comm_id] = task_manager + asyncio.get_event_loop().create_task( + self._call_tool_agent_and_inform( + reference, + task_desc, + next_speaker="", + comm_id=comm_id, + task_id=task_id, + task_abstract=task_abstract, + context_information=context_information, + completion_criteria=completion_criteria, + ) + ) + + parsed_response = { + "content": Template(COMM_INFORM_OPT_EXE_APPEND_PROMPT).safe_substitute({"task_description": task_desc}), + "next_speaker": new_message.sender, + } + message_to_send = AgentMessage( + content=parsed_response["content"], + sender=self.name, + comm_id=comm_id, + next_speaker=parsed_response["next_speaker"], + state=CommunicationState.DISCUSSION, + type=CommunicationType.INFORM_TASK_PROGRESS, + goal=comm_info.goal, + team_up_depth=comm_info.team_up_depth, + team_members=comm_info.team_members, + task_id=task_id, + task_desc=task_desc, + task_abstract=task_abstract, + is_collaborative_planning_enabled=comm_info.is_collaborative_planning_enabled, + ) + result = LLMResult( + content=f"[{self.name}]: {parsed_response['content']}", + name=self.name, + role="assistant", + ) + logger.log_llm_result(result) + comm_info.memory.add_messages(result) + # update tasks by the task manager + task_manager = self.task_manager_bank[comm_id] + task_manager.update_task_manager( + task_id, + task_desc, + task_abstract, + assignee=self.name, + status=TaskStatus.IN_PROGRESS, + ) + self.comm_bank[comm_id] = comm_info + self.task_manager_bank[comm_id] = task_manager + await self._send_message(message_to_send) + + async def _handle_sync_task_assignment(self, new_message: AgentMessage, comm_id: str, obs_kwargs: dict = {}): + """ + Handle the incoming sync task assignment message. The agent will inform the tool agent to execute the task. + The discussion will be paused until the current agent returns the result. + """ + comm_info: CommunicationInfo = self.comm_bank[comm_id] + observation = self.observation_func(**obs_kwargs) + + ( + reference, + task_desc, + task_abstract, + context_information, + completion_criteria, + ) = await self._rephrase_task_to_tool_agent(comm_id, observation) + task_manager = self.task_manager_bank[comm_id] + task_id = task_manager.create_task(task_desc, task_abstract, self.name, status=TaskStatus.TO_START) + + self.comm_bank[comm_id] = comm_info + self.task_manager_bank[comm_id] = task_manager + await self._call_tool_agent_and_inform( + reference, + task_desc, + next_speaker=new_message.sender, + comm_id=comm_id, + task_id=task_id, + task_abstract=task_abstract, + context_information=context_information, + completion_criteria=completion_criteria, + ) + + async def _coordination_discussion( + self, + new_message: AgentMessage | None, + comm_id: str, + obs_kwargs: dict = {}, + ): + if not new_message or ( + new_message.type + in [ + CommunicationType.DISCUSSION, + CommunicationType.INFORM_TASK_RESULT, + CommunicationType.INFORM_TASK_PROGRESS, + ] + ): + await self._handle_info_message(new_message, comm_id, obs_kwargs) + elif new_message.type == CommunicationType.ASYNC_TASK_ASSIGNMENT: + await self._handle_async_task_assignment(new_message, comm_id, obs_kwargs) + elif new_message.type == CommunicationType.SYNC_TASK_ASSIGNMENT: + await self._handle_sync_task_assignment(new_message, comm_id, obs_kwargs) + elif new_message.type == CommunicationType.CONCLUDE_GROUP_DISCUSSION: + await self._conclude_group_discussion(comm_id) + + async def update_global_plan(self, comm_id: str): + comm_info: CommunicationInfo = self.comm_bank[comm_id] + task_manager: TaskManager = self.task_manager_bank[comm_id] + prepend_prompt = [ + Template(self.system_prompt_template).safe_substitute( + { + "name": self.name, + "desc": self.desc, + "agent_type": self.agent_type, + "agent_name": getattr(self.tool_agent, "agent_name", ""), + "agent_desc": getattr(self.tool_agent, "agent_desc", ""), + } + ), + COMM_MAS_PROMPT, + Template(COMM_COORDINATION_WITHOUT_GOAL_PROMPT).safe_substitute( + { + "teammates": json.dumps( + [t for t in comm_info.team_members if t["name"] != self.name], + indent=2, + ), + } + ), + ] + + task_management_view_message = { + "role": "system", + "content": Template(COMM_TASK_MANAGEMENT_APPEND_PROMPT).safe_substitute( + { + "task_management_view": task_manager.tasks_view(), + "goal": comm_info.goal, + } + ), + } + append_msgs = [] + append_msgs.append(task_management_view_message) + assert comm_info.is_collaborative_planning_enabled is True + collaborative_plan_message = { + "role": "system", + "content": Template(COMM_PLANNER_PROMPT).safe_substitute( + { + "task_management_view": task_manager.tasks_view(), + "goal": comm_info.goal, + "Dynamic_Collaborative_Planner": task_manager.get_latest_plan(), + } + ), + } + append_msgs.append(collaborative_plan_message) + + append_prompt = [Template(COMM_UPDATE_PLAN_APPEND_PROMPT).safe_substitute({"name": self.name})] + + response: LLMResult = await self.llm.agenerate_response( + prepend_prompt=prepend_prompt, + history=(await comm_info.memory.to_messages()) + append_msgs, + append_prompt=append_prompt, + ) + updated_plan = response.content + print(f"updated_plan: {updated_plan}") + return updated_plan + + async def tool_agent_run(self, task_desc: str): + if self.tool_agent: + return await self.tool_agent.run(task_desc) + else: + prepend_prompt = [f"{self.desc}"] + response: LLMResult = await self.llm.agenerate_response( + prepend_prompt=prepend_prompt, + append_prompt=task_desc, + ) + conclusion = response.content + return conclusion + + async def _call_tool_agent_and_inform( + self, + reference: str | None, + task_desc: str, + next_speaker: str, + comm_id: str, + task_id: str, + task_abstract: str, + context_information: str, + completion_criteria: str, + ): + goal_content_in_nested_team_up = f""" +# {task_abstract} +## Task Description +{task_desc} +## Task Inputs (including dialogues and takeaways from PREVIOUS collaboration) +{reference if reference else 'No inputs'} +## Context Information +{context_information} +## Completion Criteria +{completion_criteria} +""" + task_content = f""" +# {task_abstract} +## Task Inputs (including dialogues and takeaways from PREVIOUS collaboration) +{reference if reference else 'No inputs'} +## Task Description +{task_desc} +""" + comm_info: CommunicationInfo = self.comm_bank[comm_id] + + # TODO: complete the task assigned with a team or alone + if self.support_nested_teams: + team_up, thought_trajectory = await self._require_teamwork(task_content) + + else: + team_up = False + + team_up_depth = comm_info.team_up_depth + if team_up and (team_up_depth is None): + # the agent decides to team up and there's no limit to the depth of teaming up + task_conclusion = await self.launch_goal( + # task_content, + goal_content_in_nested_team_up, + is_collaborative_planning_enabled=comm_info.is_collaborative_planning_enabled, + ) + elif team_up and (team_up_depth >= 1): + # the agent decides to team up and it's within the depth limit of teaming up + task_conclusion = await self.launch_goal( + # task_content, + goal_content_in_nested_team_up, + team_up_depth=team_up_depth - 1, + is_collaborative_planning_enabled=comm_info.is_collaborative_planning_enabled, + ) + elif team_up and (team_up_depth <= 0): + # the agent decides to team up but it's out of the depth limit of teaming up + task_conclusion = await self.tool_agent_run(task_content) + else: + # the agent decides not to team up or the config is set not to team up. + task_conclusion = await self.tool_agent_run(task_content) + + await self._inform_task_result(task_desc, task_conclusion, next_speaker, comm_id, task_id, task_abstract) + + async def _require_teamwork(self, task: str) -> bool: + local_contact = self.agent_contact.items() + prepend_prompt = [ + Template(self.system_prompt_template).safe_substitute( + { + "name": self.name, + "desc": self.desc, + "agent_type": self.agent_type, + } + ) + ] + + append_prompt = Template(COMM_WHETHER_TEAM_UP_PROMPT).safe_substitute( + { + "task": task, + "retrieved_contact": str(local_contact), + } + ) + response: LLMResult = await self.llm.agenerate_response( + prepend_prompt=prepend_prompt, + append_prompt=append_prompt, + response_format={"type": "json_object"}, + ) + parsed_response = response.content + logger.log_llm_result(response) + team_up = False if parsed_response["decision"] == "individual" else True + thought_trajectory = parsed_response["thought"] + print(parsed_response["thought"]) + + return team_up, thought_trajectory + + async def _inform_task_result( + self, + task_desc: str, + task_conclusion: str, + next_speaker: str, + comm_id: str, + task_id: str, + task_abstract: str, + ): + comm_info: CommunicationInfo = self.comm_bank[comm_id] + task_result_inform = Template(EXEC_TASK_CONCLUSION_APPEND_PROMPT).safe_substitute( + {"task_desc": task_desc, "task_conclusion": task_conclusion} + ) + message_to_send = AgentMessage( + content=task_result_inform, + sender=self.name, + comm_id=comm_id, + next_speaker=next_speaker, + state=CommunicationState.DISCUSSION, + type=CommunicationType.INFORM_TASK_RESULT, + task_id=task_id, + task_desc=task_desc, + task_conclusion=task_conclusion, + task_abstract=task_abstract, + ) + result = LLMResult( + content=f"[{self.name}]: {task_result_inform}", + name=self.name, + role="assistant", + ) + logger.log_llm_result(result) + comm_info.memory.add_messages(result) + task_manager: TaskManager = self.task_manager_bank[comm_id] + task_manager.update_task_manager( + task_id, + task_desc, + task_abstract, + self.name, + status=TaskStatus.COMPLETED, + conclusion=task_conclusion, + msg_in_memory=result, + ) + if task_manager.is_triggered(): + if task_manager.trigger_setter == self.name: + message_to_send.next_speaker = self.name + task_manager.clear_triggers() + self.comm_bank[comm_id] = comm_info + self.task_manager_bank[comm_id] = task_manager + + await self._send_message(message_to_send) + + async def _rephrase_task_to_tool_agent(self, comm_id: str, observation: str = ""): + comm_info: CommunicationInfo = self.comm_bank[comm_id] + + prepend_prompt = [ + Template(self.system_prompt_template).safe_substitute( + { + "name": self.name, + "desc": self.desc, + "agent_type": self.agent_type, + "agent_name": getattr(self.tool_agent, "agent_name", ""), + "agent_desc": getattr(self.tool_agent, "agent_desc", ""), + } + ), + COMM_MAS_PROMPT, + Template(COMM_COORDINATION_WITHOUT_GOAL_PROMPT).safe_substitute( + { + # "goal": comm_info.goal, + "teammates": json.dumps( + [t for t in comm_info.team_members if t["name"] != self.name], + indent=2, + ), + } + ), + ] + if observation != "": + prepend_prompt.append(f"Current Observation:\n{observation}") + + messages = comm_info.memory.messages + recent_history, recent_history_list = self._get_hybrid_recent_history(messages, comm_id) + system_msg = { + "role": "system", + "content": Template(REPHRASE_TASK_HYBIRD_SYS_PROMPT).safe_substitute({"recent_history": recent_history}), + } + + response: LLMResult = await self.llm.agenerate_response( + prepend_prompt=prepend_prompt, + history=[system_msg], + append_prompt=Template(REPHRASE_TASK_APPEND_PROMPT).safe_substitute({"name": self.name}), + response_format={"type": "json_object"}, + ) + parsed_response: dict = response.content + task_desc = parsed_response["task_description"] + message_index_list = parsed_response["index_to_integrate"] + if not isinstance(message_index_list, list): + try: + message_index_list = json.loads(message_index_list) + except json.JSONDecodeError: + message_index_list = list(range(len(recent_history_list))) + elif len(message_index_list) > 0 and any([not isinstance(i, int) for i in message_index_list]): + message_index_list = list(range(len(recent_history_list))) + thought = parsed_response["thought"] + task_abstract = parsed_response["task_abstract"] + context_information = parsed_response["context_information"] + completion_criteria = parsed_response["completion_criteria"] + + print("======= task_rephrasing =======") + print(f"thought:\n {thought}") + print(f"message index list:\n {str(message_index_list)}") + print(f"task_desc: {task_desc}") + print(f"task_abstract: {task_abstract}") + + useful_information = [] + try: + for msg_id in message_index_list: + msg_id = int(msg_id) + if msg_id <= len(recent_history_list): + useful_information.append(recent_history_list[msg_id - 1]) + except Exception as e: + print(f"error while task rephrasing...{e}") + import traceback + + traceback.print_exc() + if len(useful_information) != 0: + reference = "".join(useful_information) + else: + reference = None + return ( + reference, + task_desc, + task_abstract, + context_information, + completion_criteria, + ) + + def _get_hybrid_recent_history(self, messages: list[LLMResult], comm_id: str) -> tuple[str, list[str]]: + """Get hybrid recent history from chat history and task manager. + Hybrid recent history consist of 5 latest messages from chat history and all tasks completed in task manager. + + Args: + messages (list[LLMResult]): all messages of chat history from memory + comm_id (str): use comm_id to fetch task manager in the group + + Returns: + str: recent_history, which is string content of hybrid messages and tasks + list: recent_history_str_list, which is a list of hybrid messages and tasks for reference, and each element is string. + """ + comm_info: CommunicationInfo = self.comm_bank[comm_id] + task_manager: TaskManager = self.task_manager_bank[comm_id] + goal = comm_info.goal + recent_history_list = [] + + latest_num = 5 + current_msg_num = 0 + for msg in reversed(messages): + if ( + isinstance(msg.content, str) + and "Team, the following task is being executed in the background by myself." in msg.content + ): + continue + elif isinstance(msg.content, str) and "Just a quick interruption to our current discussion." in msg.content: + task = task_manager.msg2task.get(msg, None) + if task: + recent_history_list.append(task) + else: + if current_msg_num < latest_num: + recent_history_list.append(msg) + current_msg_num += 1 + + goal_LLMResult = LLMResult( + content="[system]: The team is collaborating to solve this problem:\n" + goal, + role="system", + ) + recent_history_list.append(goal_LLMResult) + # reverse the list in time order + recent_history_list = recent_history_list[::-1] + + # get hybrid recent history in str format + recent_history = "" + recent_history_str_list = [] + task_id = 0 + for id, item in enumerate(recent_history_list): + if isinstance(item, LLMResult): + prefix = f"=== message index : {id+1} ===\n" + content = item.to_openai_message()["content"] + "\n" + recent_history += prefix + content + recent_history_str_list.append(content) + elif isinstance(item, TaskEntry): + prefix = f"=== task index : {id+1} ===\n" + content = str(item) + recent_history += prefix + content + recent_history_str_list.append(f"=== task index : {task_id} ===\n" + item.task2str_for_conclusion()) + task_id += 1 + + return recent_history, recent_history_str_list + + def _number_items(self, history: list[dict], work_results: list[TaskEntry] | None) -> tuple[str, str, list]: + """ + Select 3 latest message from history and all work_results as input for task rephrasing + index each item and get `recent_history_str` (str), `work_results_str` (str) + get `combined_list_with_index` as list and each item is str directly used in prompt for tool agent + """ + history_without_task = [] + for item in history: + if not ( + "Team, the following task is being executed in the background by myself." in item["content"] + or "Just a quick interruption to our current discussion." in item["content"] + ): + # filter the message which is to inform the progess/completion of the task + history_without_task.append(item) + lastest_history = history_without_task[-5:] # select 5 latest message from filtered history + + combined_list_with_index = [] + recent_history_str = "" + work_results_str = "" + id = 0 + + for task in work_results: + prefix = f"=== task index : {id} ===\n" + content = str(task) + item = prefix + content + work_results_str += item + combined_list_with_index.append(task.task2str_for_conclusion()) + id += 1 + + for msg in lastest_history: + prefix = f"=== message index : {id} ===\n" + content = msg["content"] + item = prefix + content + "\n" + recent_history_str += item + combined_list_with_index.append(content + "\n") + id += 1 + + if not work_results_str: + work_results_str = "No tasks completed yet." + + return recent_history_str, work_results_str, combined_list_with_index + + async def _conclude_group_discussion(self, comm_id: str): + """ + Let the agent conclude the group discussion. + """ + comm_info: CommunicationInfo = self.comm_bank[comm_id] + + append_prompt = [Template(COMM_CONCLUDE_APPEND_PROMPT).safe_substitute({"goal": comm_info.goal})] + history = await comm_info.memory.to_messages() + if len(history) > 0: + history[0]["content"] = "The history of the GROUP DISCUSSION:\n" + history[0]["content"] + response: LLMResult = await self.llm.agenerate_response( + history=history, + append_prompt=append_prompt, + ) + parsed_response = response.content + message_to_send = AgentMessage( + content=parsed_response, + sender=self.name, + comm_id=comm_id, + state=CommunicationState.DISCUSSION, + type=CommunicationType.CONCLUSION, + ) + result = LLMResult( + content=f"[{self.name}]: {message_to_send.content}", + name=self.name, + role="assistant", + ) + logger.log_llm_result(result) + comm_info.memory.add_messages(result) + + # conclusion should be recorded + comm_info.conclusion = message_to_send.content + comm_info.curr_turn = 0 + self.comm_bank[comm_id] = comm_info + await self._send_message(message_to_send) + + async def _send_message(self, payload: AgentMessage): + """Send a message to the chat session.""" + try: + await self.server_websocket.send_message(payload.model_dump_json()) + except Exception as e: + logger.error(f"Failed to send the message. {e}") + return {"status": "failed", "message": str(e)} + return {"status": "success"} + + async def _listen_message(self): + while True: + message = await self.server_websocket.receive_message() + comm_id = message.comm_id + logger.info(f"Received message: {str(message)}") + match message.state: + case CommunicationState.DISCUSSION | CommunicationState.VOTE: + await self.coordination(message, comm_id, max_turns=message.max_turns) + # TODO: complete execution cases + case _: + logger.error(f"Unknown state: {message.state}") + + async def shutdown(self): + if self.tool_agent is not None: + await self.tool_agent.shutdown() diff --git a/im_client/communication/task_management.py b/im_client/communication/task_management.py new file mode 100644 index 0000000..108e26d --- /dev/null +++ b/im_client/communication/task_management.py @@ -0,0 +1,507 @@ +from __future__ import annotations +from enum import Enum +import uuid +from common.types.llm import LLMResult +from common.utils.database_utils import Serializable +from common.log import logger + + +class TaskStatus(Enum): + TO_START = (0, "To Start") + IN_PROGRESS = (1, "In Progress") + COMPLETED = (2, "Completed") + # ON_HOLD = "On Hold" + FAILED = (2, "Failed") + + # PENDING = "Pending" + def __init__(self, priority: int, description: str): + self.priority = priority + self.description = description + + +class TaskAssignmentRespondManager(Serializable): + """ + Mechanism for Synchronous/Asynchronous Task Allocation: + After allocating tasks, it is necessary to receive feedback signals from + all assigned agents before proceeding with the discussion. + """ + + def __init__(self, comm_id: str): + self.comm_id = comm_id + self.await_agents = set() + + def register_await_agents(self, agents: list[str]): + self._clear() + self.await_agents.update(agents) + + def _clear(self): + self.await_agents.clear() + + def update_await_agents(self, await_agent: str): + self.await_agents.discard(await_agent) + + def check_empty(self) -> bool: + return len(self.await_agents) == 0 + + def to_dict(self) -> dict: + return { + "comm_id": self.comm_id, + "await_agents": list(self.await_agents), + } + + @staticmethod + def from_dict(data: dict) -> TaskAssignmentRespondManager: + manager = TaskAssignmentRespondManager(comm_id=data["comm_id"]) + manager.await_agents = set(data.get("await_agents", [])) + return manager + + +class TaskEntry(Serializable): + def __init__( + self, + task_id: str, + task_desc: str, + task_abstract: str, + assignee: str, + status=TaskStatus.TO_START, + ): + self.__task_id: str = task_id + self.__task_desc: str = task_desc + self.__task_abstract: str = task_abstract + self.__assignee: str = assignee + # TODO: determine to save __task_input or not + self.status: TaskStatus = status + self.conclusion: str | None = None + + @property + def task_id(self): + return self.__task_id + + @property + def task_desc(self): + return self.__task_desc + + @property + def assignee(self): + return self.__assignee + + @property + def task_abstract(self): + return self.__task_abstract + + # @property + # def task_input(self): + # return self.__task_input + + def update_status(self, new_status: TaskStatus): + if self.status.priority <= new_status.priority: + self.status = new_status + + def update_conclusion(self, conclusion: str): + self.conclusion = conclusion + + def update(self, status: TaskStatus, **kwargs): + self.update_status(status) + for key, value in kwargs.items(): + if hasattr(self, key): + setattr(self, key, value) + + def __str__(self): + return f"""Assignee: {self.__assignee} +Task abstract: {self.__task_abstract} +Status: {self.status.description} +""" + + def task2str_for_conclusion(self): + return f"""Assignee: {self.__assignee} +Task abstract: {self.__task_abstract} +Task conclusion: +{self.conclusion} +""" + + def to_dict(self) -> dict: + return { + "task_id": self.__task_id, + "task_desc": self.__task_desc, + "task_abstract": self.__task_abstract, + "assignee": self.__assignee, + "status": self.status.name, # Assuming status is an Enum and we store the name + "conclusion": self.conclusion, + } + + @staticmethod + def from_dict(data: dict) -> TaskEntry: + task_entry = TaskEntry( + task_id=data["task_id"], + task_desc=data["task_desc"], + task_abstract=data["task_abstract"], + assignee=data["assignee"], + status=TaskStatus[data["status"]], # Assuming TaskStatus is an Enum + ) + task_entry.conclusion = data.get("conclusion") # Use .get() to handle potential absence of 'conclusion' + return task_entry + + +class TaskManager(Serializable): + """ + Task management, primarily used for the entire process of task allocation, execution, and completion. + """ + + def __init__(self, comm_id: str): + self.__global_index = 0 # next task index in task manager + self.task_assign_manager = TaskAssignmentRespondManager(comm_id) + self.tasks: dict[str, tuple[int, TaskEntry]] = {} # {task_id, (task_index,task_entry)} + self.taskIndex2tasks: dict[int, TaskEntry] = {} + self.triggers: dict[ + str, bool + ] = {} # a dict of task ids, each task id will be mapped into True/False to mark whether the task is in terminated status or not. + self.trigger_setter: str | None = None # the name of assistant who sets the triggers + # TODO: How to ensure that at any point, only one trigger_setter at most is permitted. + self.previous_triggers_status: bool = True # True if check_triggers returned True before update. + self.current_triggers_status: bool = True # True if check_triggers returns True after update. + self.msg2task: dict[LLMResult, TaskEntry] = {} + + self.dynamic_collaborative_planner: list[str] = ["No collaborative consensual plans shaped yet."] + + def _create_task_index(self): + task_index = self.__global_index + self.__global_index += 1 + return task_index + + def create_task( + self, + task_desc: str, + task_abstract: str, + assignee: str, + status: TaskStatus = TaskStatus.TO_START, + task_id: str | None = None, + ): + # create task_id + # TODO: the task_id should be assured that it's unique in global + if not task_id: + task_id = uuid.uuid4().hex + task_entry = TaskEntry(task_id, task_desc, task_abstract, assignee, status) + task_index = self._create_task_index() + self.tasks[task_id] = (task_index, task_entry) + self.taskIndex2tasks[task_index] = task_entry + return task_id + + def update_task_manager( + self, + task_id: str, + task_desc: str, + task_abstract: str, + assignee: str, + status: TaskStatus, + **kwargs, + ): + # update the tasks + _, task = self.tasks.get(task_id, (None, None)) + if task: + logger.info( + f"Update task {task_id}.\nTo update: {str(kwargs)}\nAfter update: {str(task)}\nUpdated Status: {str(status)}" + ) + task.update(status, **kwargs) + else: + logger.info(f"Create task {task_id}. {str(kwargs)}") + # when task_id is not in task manager, create one with task_id + self.create_task(task_desc, task_abstract, assignee, status, task_id) + _, task = self.tasks.get(task_id, (None, None)) + task.update(status, **kwargs) + logger.info(f"self.triggers: {self.triggers}") + # update the triggers + if (status.priority == TaskStatus.COMPLETED.priority) and task_id in self.triggers: + logger.info(f"Update triggers {task_id} to True.") + self.previous_triggers_status = self.current_triggers_status + + self.triggers[task_id] = True + + self.current_triggers_status = self.check_triggers() + + # update the msg2task + if status.priority == TaskStatus.COMPLETED.priority: + # hook msg2task + if "msg_in_memory" in kwargs: + msg_in_memory = kwargs["msg_in_memory"] + self.hook_msg2task(task_id, msg_in_memory) + + def hook_msg2task(self, task_id: str, msg_in_memory: LLMResult): + """ + map message in memory with corresponding task + + The preconditions are: + task_id has been registered in task manager. + """ + _, task = self.tasks.get(task_id, (None, None)) + if task: + self.msg2task[msg_in_memory] = task + + def tasks_view(self): + content = "" + head = "The view of task management:\n" + content += head + for task_index, task in self.tasks.values(): + prefix = f"=== task index : {str(task_index)}===\n" + content += prefix + str(task) + + if len(self.tasks) == 0: + content += "No tasks existed\n" + + return content + + def tasks_filter_by_status(self, status: TaskStatus | None | list[TaskStatus]): + result = [] + for _, task in self.tasks.values(): + if status is None or task.status == status or (isinstance(status, list) and task.status in status): + result.append(task) + + return result + + def indices_filter_by_status(self, status: TaskStatus | None | list[TaskStatus]) -> list[str]: + result = [] + for task_index, task in self.tasks.values(): + if status is None or task.status == status or (isinstance(status, list) and task.status in status): + result.append(task_index) + return str(result) + + def is_triggers_empty(self) -> bool: + return len(self.triggers) == 0 + + def set_triggers(self, task_identifiers: list[int] | list[str], trigger_setter: str) -> tuple[bool, list[str]]: + """Set triggers for the resumption of the group discussion. + + Args: + task_identifiers (list[int]|list[str]): + selected task indices or ids where tasks should be set as triggers for the resumption of the group discussion. + Each element in `task_identifiers` is either task index (int), or task id (str). + + Returns: + bool: If there are tasks In Progress whose task indices are in `task_identifiers` + (which means there are substantive triggers to set), the return value should be set True. False otherwise. + list[str]: the list of task ids. The task of each task id exists in self.task_manager and is not in terminated status. + """ + assert self.is_triggers_empty() + # self.triggers.clear() + task_ids = [] + + for task_identify in task_identifiers: + if isinstance(task_identify, str): + # task id + task_id = task_identify + task = None if not self.tasks.get(task_id, None) else self.tasks.get(task_id, None)[-1] + task_ids.append(task_id) + elif isinstance(task_identify, int): + # task index + task_index = task_identify + task = self.taskIndex2tasks.get(task_index, None) + if task: + task_ids.append(task.task_id) + + if task: + if task.status.priority < TaskStatus.COMPLETED.priority: + logger.info(f"Set {task.task_id}'s trigger") + self.triggers[task.task_id] = False + else: + logger.info(f"{task.task_id} is in terminated status. Skip setting trigger.") + self.triggers[task.task_id] = True + logger.info(f"Triggers: {self.triggers}") + + self.previous_triggers_status = self.current_triggers_status + self.current_triggers_status = self.check_triggers() + + if self.is_triggers_empty() or self.check_triggers(): + """ + if triggers is empty or all the tasks in triggers are in terminated status + """ + trigger_set = False + self.trigger_setter = None + self.clear_triggers() + + return trigger_set, task_ids + else: + trigger_set = True + self.trigger_setter = trigger_setter + return trigger_set, task_ids + + def update_triggers(self, task_identifiers: list[int] | list[str], trigger_setter: str) -> tuple[bool, list[str]]: + """Update triggers for the resumption of the group discussion. + + The function is different from `set_triggers()` in that `set_triggers()` is used by the assistant who initiated PAUSE, + while `update_triggers()` is used to update the others' task manager, considering latency in + message delivery and state inconsistencies in the distributed network. + + Specifically, the difference is in the handling of `task_identifiers`. `task_identifiers` will + be filtered first in `set_triggers()` to eliminate the effects of hallucination of LLM-generated content, + while the element in `task_identifiers` which is not in task manager (because of latency + in message delivery) will be saved in `update_triggers()`. + + + Args: + task_identifiers (list[int]|list[str]): + selected task indices or ids where tasks should be set as triggers for the resumption of the group discussion. + Each element in `task_identifiers` is either task index (int), or task id (str). + + Returns: + bool: If there are tasks In Progress whose task indices are in `task_identifiers`(which + means there are substantive triggers to set), the return value should be set True. False otherwise. + list[str]: the list of task ids. + """ + assert self.is_triggers_empty() + + task_ids = [] + + for task_identify in task_identifiers: + assert isinstance(task_identify, str) + # task id + task_id = task_identify + task = None if not self.tasks.get(task_id, None) else self.tasks.get(task_id, None)[-1] + task_ids.append(task_id) + + if task: + if task.status.priority < TaskStatus.COMPLETED.priority: + # not in terminated status + logger.info(f"Set {task_id}'s trigger") + self.triggers[task.task_id] = False + else: + logger.info(f"{task_id} is in terminated status. Skip setting trigger.") + self.triggers[task.task_id] = True + else: + self.triggers[task_id] = False + + self.previous_triggers_status = self.current_triggers_status + self.current_triggers_status = self.check_triggers() + logger.info(f"previous_triggers_status: {self.previous_triggers_status}") + logger.info(f"current_triggers_status: {self.current_triggers_status}") + logger.info(f"Triggers: {self.triggers}") + + if self.is_triggers_empty() or self.check_triggers(): + """ + if triggers is empty or all the tasks in triggers are in terminated status + """ + trigger_set = False + self.trigger_setter = None + self.clear_triggers() + + return trigger_set, task_ids + else: + trigger_set = True + self.trigger_setter = trigger_setter + return trigger_set, task_ids + + def check_triggers(self) -> bool: + """check whether tasks in triggers are ALL in terminated status or not. + + Returns: + bool: True if the tasks in triggers are ALL in terminated status. False otherwise. + If the triggers is empty, return True in default. + """ + for _, status in self.triggers.items(): + if not status: + return False + return True + + def is_triggered(self) -> bool: + return not self.previous_triggers_status and self.current_triggers_status + + def clear_triggers(self): + self.triggers.clear() + self.trigger_setter = None + self.previous_triggers_status = True + self.current_triggers_status = True + + def get_latest_plan(self): + return self.dynamic_collaborative_planner[-1] + + def update_plan(self, plan: str): + self.dynamic_collaborative_planner.append(plan) + + def to_dict(self) -> dict: + return { + "__global_index": self.__global_index, + "task_assign_manager": self.task_assign_manager.to_dict(), + "tasks": { + task_id: (task_index, task_entry.to_dict()) for task_id, (task_index, task_entry) in self.tasks.items() + }, + "taskIndex2tasks": {index: task_entry.to_dict() for index, task_entry in self.taskIndex2tasks.items()}, + "triggers": self.triggers, + "trigger_setter": self.trigger_setter, + "__previous_triggers_status": self.previous_triggers_status, + "__current_triggers_status": self.current_triggers_status, + # the key should be string type for json serilization. + "msg2task": {result.model_dump_json(): task.to_dict() for result, task in self.msg2task.items()}, + "dynamic_collaborative_planner": self.dynamic_collaborative_planner, + } + + @staticmethod + def from_dict(data: dict) -> TaskManager: + manager = TaskManager( + comm_id=data["task_assign_manager"]["comm_id"] + ) # Assuming comm_id can be extracted like this + manager._restore_inner_properties( + data["__global_index"], + data["__previous_triggers_status"], + data["__current_triggers_status"], + ) + manager.task_assign_manager = TaskAssignmentRespondManager.from_dict(data["task_assign_manager"]) + manager.tasks = { + task_id: (task_index, TaskEntry.from_dict(task_entry_dict)) + for task_id, (task_index, task_entry_dict) in data["tasks"].items() + } + manager.taskIndex2tasks = { + index: TaskEntry.from_dict(task_entry_dict) for index, task_entry_dict in data["taskIndex2tasks"].items() + } + manager.triggers = data["triggers"] + manager.trigger_setter = data["trigger_setter"] + manager.msg2task = { + LLMResult.model_validate_json(result_json): TaskEntry.from_dict(task_dict) + for result_json, task_dict in data["msg2task"].items() + } + manager.dynamic_collaborative_planner = data["dynamic_collaborative_planner"] + return manager + + @property + def global_index(self): + return self.__global_index + + def _restore_inner_properties( + self, + global_index: int, + previous_triggers_status: bool, + current_triggers_status: bool, + ): + self.__global_index = global_index + self.previous_triggers_status = previous_triggers_status + self.current_triggers_status = current_triggers_status + + +from pydantic import BaseModel +from typing import Any, TYPE_CHECKING + + +class Demo(BaseModel): + comm_id: str + goal: str + memory: Any + + +if __name__ == "__main__": + """ + demo = Demo(comm_id="1", goal="test", memory=None) + demo_str = demo.model_dump_json() # pydantic model to json string + print(demo_str) + demo_recoverd = Demo.model_validate_json(demo_str) # json string to pydantic model + print(demo_recoverd) + """ + task_manager = TaskManager(comm_id="123") + task_manager.create_task( + task_desc="test", + task_abstract="test the serialization and deserialization.", + assignee="human", + ) + print(task_manager.to_dict()) + demo = TaskManager.from_dict(task_manager.to_dict()) + print(demo) + print(demo.to_dict()) + import json + + print(isinstance(TaskManager.from_dict(json.loads(json.dumps(demo.to_dict()))), TaskManager)) diff --git a/im_client/communication/websocket_client.py b/im_client/communication/websocket_client.py new file mode 100644 index 0000000..e424b53 --- /dev/null +++ b/im_client/communication/websocket_client.py @@ -0,0 +1,74 @@ +from pydantic import ValidationError +import websockets +import asyncio + +# import logging +from common.log import logger +from common.types import AgentMessage +from websockets.client import WebSocketClientProtocol +from websockets.exceptions import ConnectionClosed + + +class WebSocketClient: + def __init__(self, uri): + self.uri = uri # "ws://localhost:8000/ws" + self.websocket: WebSocketClientProtocol = None + + async def connect(self): + try: + self.websocket: WebSocketClientProtocol = await websockets.connect(self.uri, ping_timeout=None) + except Exception as e: + print(f"Websocket connection error: {e}") + + async def send_message(self, message: AgentMessage): + max_retries = 3 + retries = 0 + + while retries < max_retries: + if self.websocket and self.websocket.open: + try: + await self.websocket.send(message) + break + + except ConnectionClosed as e: + logger.error(e) + retries += 1 + await asyncio.sleep(3) + except (TypeError, Exception) as e: + raise + else: + retries += 1 + await asyncio.sleep(3) + await self.connect() + + if retries >= max_retries: + print("Failed to send message after several attempts.") + + async def receive_message(self) -> AgentMessage: + max_retries = 3 + retries = 0 + + while retries < max_retries: + if self.websocket and self.websocket.open: + try: + message = await self.websocket.recv() + message = AgentMessage.model_validate_json(message) + return message + except (ConnectionClosed, RuntimeError) as e: + logger.error(e) + retries += 1 + await asyncio.sleep(3) + except (ValidationError, Exception) as e: + raise + + else: + retries += 1 + await asyncio.sleep(3) + await self.connect() + print("reconnect succeed!") + + if retries >= max_retries: + print("Failed to receive message after several attempts.") + + async def close(self): + await self.websocket.close() diff --git a/im_client/llms/__init__.py b/im_client/llms/__init__.py new file mode 100644 index 0000000..66b49a9 --- /dev/null +++ b/im_client/llms/__init__.py @@ -0,0 +1,25 @@ +from common.registry import Registry + +llm_registry = Registry(name="LLMRegistry") +LOCAL_LLMS = [ + "llama-2-7b-chat-hf", + "llama-2-13b-chat-hf", + "llama-2-70b-chat-hf", + "vicuna-7b-v1.5", + "vicuna-13b-v1.5", +] +LOCAL_LLMS_MAPPING = { + "llama-2-7b-chat-hf": "meta-llama/Llama-2-7b-chat-hf", + "llama-2-13b-chat-hf": "meta-llama/Llama-2-13b-chat-hf", + "llama-2-70b-chat-hf": "meta-llama/Llama-2-70b-chat-hf", + "vicuna-7b-v1.5": "lmsys/vicuna-7b-v1.5", + "vicuna-13b-v1.5": "lmsys/vicuna-13b-v1.5", +} + +from .base import BaseLLM, BaseChatModel, BaseCompletionModel +from .openai import OpenAIChat + + +def load_llm(llm_config: dict): + llm_type = llm_config.pop("llm_type", "text-davinci-003") + return llm_registry.build(llm_type, **llm_config) diff --git a/im_client/llms/base.py b/im_client/llms/base.py new file mode 100644 index 0000000..37ab4e2 --- /dev/null +++ b/im_client/llms/base.py @@ -0,0 +1,37 @@ +from abc import abstractmethod + +from pydantic import BaseModel, Field + +from common.types.llm import LLMResult + + +class BaseModelArgs(BaseModel): + pass + + +class BaseLLM(BaseModel): + args: BaseModelArgs = Field(default_factory=BaseModelArgs) + max_retry: int = Field(default=3) + + @abstractmethod + def get_spend(self) -> float: + """ + Number of USD spent + """ + return -1.0 + + # @abstractmethod + # def generate_response(self, **kwargs) -> LLMResult: + # pass + + @abstractmethod + async def agenerate_response(self, **kwargs) -> LLMResult: + pass + + +class BaseChatModel(BaseLLM): + pass + + +class BaseCompletionModel(BaseLLM): + pass diff --git a/im_client/llms/openai.py b/im_client/llms/openai.py new file mode 100644 index 0000000..8585244 --- /dev/null +++ b/im_client/llms/openai.py @@ -0,0 +1,403 @@ +import json +import os +from copy import deepcopy +from typing import List, Optional, Union +from uuid import uuid4 + +import aiofiles +import numpy as np +from openai.types.chat.chat_completion_message_tool_call import ( + ChatCompletionMessageToolCall, + Function, +) +from pydantic import Field +from tenacity import retry, stop_after_attempt, wait_exponential + +from common.log import logger +from common.types.llm import LLMResult +from common.utils.json_utils import JsonRepair +from common.utils.misc import log_retry + +from . import LOCAL_LLMS, llm_registry +from .base import BaseChatModel, BaseModelArgs + +try: + import openai + from openai._types import NOT_GIVEN, NotGiven + from openai.types.chat import ChatCompletion + + async_openai_client = openai.AsyncClient() + sync_openai_client = openai.Client() +except ImportError: + is_openai_available = False + logger.warn("openai package is not installed") +else: + if os.environ.get("OPENAI_API_KEY") is None and os.environ.get("AZURE_OPENAI_API_KEY") is None: + logger.warn("OPENAI_API_KEY is not set. OpenAI models will not be available.") + if os.environ.get("AZURE_OPENAI_API_KEY") is not None: + openai.api_type = "azure" + openai.api_key = os.environ.get("AZURE_OPENAI_API_KEY") + openai.base_url = os.environ.get("AZURE_OPENAI_BASE_URL") + openai.api_version = os.environ.get("AZURE_OPENAI_API_VERSION", "2023-05-15") + +OPENAI_RESPONSE_LOG_PATH = os.environ.get("OPENAI_RESPONSE_LOG_PATH", "") + + +async def async_write_to_file(data: dict, filename: str): + os.makedirs(OPENAI_RESPONSE_LOG_PATH, exist_ok=True) + file_path = os.path.join(OPENAI_RESPONSE_LOG_PATH, filename) + async with aiofiles.open(file_path, "w") as f: + await f.write(json.dumps(data, ensure_ascii=False, indent=4)) + + +def sync_write_to_file(data: dict, filename: str): + os.makedirs(OPENAI_RESPONSE_LOG_PATH, exist_ok=True) + file_path = os.path.join(OPENAI_RESPONSE_LOG_PATH, filename) + with open(file_path, "w") as f: + f.write(json.dumps(data, ensure_ascii=False, indent=4)) + + +class OpenAIChatArgs(BaseModelArgs): + model: str = Field(default="gpt-3.5-turbo") + max_tokens: Optional[int] = Field(default=None) + temperature: float = Field(default=1.0) + top_p: float = Field(default=1.0) + n: int = Field(default=1) + stop: Optional[Union[str, List]] = Field(default=None) + presence_penalty: int = Field(default=0) + frequency_penalty: int = Field(default=0) + + +# To support your own local LLMs, register it here and add it into LOCAL_LLMS. +@llm_registry.register("openai-chat") +@llm_registry.register("local") +class OpenAIChat(BaseChatModel): + args: OpenAIChatArgs = Field(default_factory=OpenAIChatArgs) + + total_prompt_tokens: int = 0 + total_completion_tokens: int = 0 + + def __init__(self, max_retry: int = 3, **kwargs): + args = OpenAIChatArgs() + args = args.model_dump() + for k, v in args.items(): + args[k] = kwargs.pop(k, v) + if len(kwargs) > 0: + logger.warn(f"Unused arguments: {kwargs}") + if args["model"] in LOCAL_LLMS: + openai.api_base = "http://localhost:5000/v1" + openai.api_key = "EMPTY" + super().__init__(args=args, max_retry=max_retry) + + @classmethod + def send_token_limit(self, model: str) -> int: + send_token_limit_dict = { + "gpt-3.5-turbo": 4096, + "gpt-35-turbo": 4096, + "gpt-3.5-turbo-16k": 16384, + "gpt-4": 8192, + "gpt-4-32k": 32768, + "llama-2-7b-chat-hf": 4096, + } + + return send_token_limit_dict[model] + + @retry( + stop=stop_after_attempt(20), + wait=wait_exponential(multiplier=1, min=4, max=10), + reraise=True, + before_sleep=log_retry, + ) + async def agenerate_response( + self, + prepend_prompt: str | list[str] = "", + history: List[dict] = [], + append_prompt: str | list[str] = "", + tools: List[dict] | NotGiven = NOT_GIVEN, + response_format: dict | NotGiven = NOT_GIVEN, + **kwargs, + ) -> LLMResult: + if isinstance(prepend_prompt, str): + prepend_prompt = [prepend_prompt] + if isinstance(append_prompt, str): + append_prompt = [append_prompt] + + messages = self.construct_messages(prepend_prompt, history, append_prompt) + logger.log_prompt(messages) + + model_args = deepcopy(self.args.model_dump()) + model_args.update(kwargs) + + response: ChatCompletion = await async_openai_client.chat.completions.create( + messages=messages, + tools=tools, + response_format=response_format, + **model_args, + ) + + if OPENAI_RESPONSE_LOG_PATH: + serializable_messages = [] + try: + for message in messages: + if "tool_calls" in message: + message = deepcopy(message) + tool_call = [] + for call in message["tool_calls"]: + tool_call.append(call.model_dump()) + message["tool_calls"] = tool_call + serializable_messages.append(message) + except Exception as e: + logger.error(f"Failed to serialize messages: {e}") + data_to_save = { + "messages": serializable_messages, + "tools": None if tools is NOT_GIVEN else tools, + "response_format": (None if response_format is NOT_GIVEN else response_format), + "model_args": model_args, + "response": response.model_dump(), + } + filename = f"openai_response_{uuid4()}.json" + try: + await async_write_to_file(data_to_save, filename) + except Exception as e: + logger.error(f"Failed to save OpenAI response: {e}") + + if response.choices[0].finish_reason == "content_filter": + raise ValueError("The response is filtered by OpenAI's content filter.") + + if response_format is not NOT_GIVEN and response_format["type"] == "json_object": + if response.choices[0].message.content is not None: + try: + # content = json.loads(JsonRepair(response.choices[0].message.content).repair()) + content = json.loads(response.choices[0].message.content) + except json.JSONDecodeError: + content = json.loads(JsonRepair(response.choices[0].message.content).repair()) + + else: + content = None + else: + content = response.choices[0].message.content + # if content is None: + # raise ValueError("The returned content is None. Retrying...") + + if response.choices[0].message.tool_calls is not None: + assert tools is not NOT_GIVEN + if response.choices[0].message.tool_calls[0].function.name == "multi_tool_use.parallel": + all_tool_calls = json.loads(response.choices[0].message.tool_calls[0].function.arguments)["tool_uses"] + response.choices[0].message.tool_calls = [ + ChatCompletionMessageToolCall( + id=f"call_{uuid4()}", + function=Function( + arguments=json.dumps(call["parameters"]), + name=call["recipient_name"].lstrip("functions."), + ), + type="function", + ) + for call in all_tool_calls + ] + all_tool_names = set([tool["function"]["name"] for tool in tools]) + + # Validate if the generated tool calls are valid + for tool in response.choices[0].message.tool_calls: + tool_name = tool.function.name + is_valid = tool_name in all_tool_names + if not is_valid: + logger.warn( + f"The returned function name {tool_name} is not in the list of valid functions. Retrying..." + ) + raise ValueError(f"The returned function name {tool_name} is not in the list of valid functions.") + + self.collect_metrics(response) + return LLMResult( + content=content, + role="assistant", + tool_calls=response.choices[0].message.tool_calls, + send_tokens=response.usage.prompt_tokens, + recv_tokens=response.usage.completion_tokens, + total_tokens=response.usage.total_tokens, + ) + + @retry( + stop=stop_after_attempt(20), + wait=wait_exponential(multiplier=1, min=4, max=10), + reraise=True, + before_sleep=log_retry, + ) + async def generate_response( + self, + prepend_prompt: str | list[str] = "", + history: List[dict] = [], + append_prompt: str | list[str] = "", + tools: List[dict] | NotGiven = NOT_GIVEN, + response_format: dict | NotGiven = NOT_GIVEN, + **kwargs, + ) -> LLMResult: + if isinstance(prepend_prompt, str): + prepend_prompt = [prepend_prompt] + if isinstance(append_prompt, str): + append_prompt = [append_prompt] + + messages = self.construct_messages(prepend_prompt, history, append_prompt) + logger.log_prompt(messages) + + model_args = deepcopy(self.args.model_dump()) + model_args.update(kwargs) + + response: ChatCompletion = sync_openai_client.chat.completions.create( + messages=messages, + tools=tools, + response_format=response_format, + **model_args, + ) + + if OPENAI_RESPONSE_LOG_PATH: + serializable_messages = [] + try: + for message in messages: + if "tool_calls" in message: + message = deepcopy(message) + tool_call = [] + for call in message["tool_calls"]: + tool_call.append(call.model_dump()) + message["tool_calls"] = tool_call + serializable_messages.append(message) + except Exception as e: + logger.error(f"Failed to serialize messages: {e}") + data_to_save = { + "messages": serializable_messages, + "tools": None if tools is NOT_GIVEN else tools, + "response_format": (None if response_format is NOT_GIVEN else response_format), + "model_args": model_args, + "response": response.model_dump(), + } + filename = f"openai_response_{uuid4()}.json" + try: + sync_write_to_file(data_to_save, filename) + except Exception as e: + logger.error(f"Failed to save OpenAI response: {e}") + + if response.choices[0].finish_reason == "content_filter": + raise ValueError("The response is filtered by OpenAI's content filter.") + + if response_format is not NOT_GIVEN and response_format["type"] == "json_object": + if response.choices[0].message.content is not None: + try: + # content = json.loads(JsonRepair(response.choices[0].message.content).repair()) + content = json.loads(response.choices[0].message.content) + except json.JSONDecodeError: + content = json.loads(JsonRepair(response.choices[0].message.content).repair()) + + else: + content = None + else: + content = response.choices[0].message.content + # if content is None: + # raise ValueError("The returned content is None. Retrying...") + + if response.choices[0].message.tool_calls is not None: + assert tools is not NOT_GIVEN + if response.choices[0].message.tool_calls[0].function.name == "multi_tool_use.parallel": + all_tool_calls = json.loads(response.choices[0].message.tool_calls[0].function.arguments)["tool_uses"] + response.choices[0].message.tool_calls = [ + ChatCompletionMessageToolCall( + id=f"call_{uuid4()}", + function=Function( + arguments=json.dumps(call["parameters"]), + name=call["recipient_name"].lstrip("functions."), + ), + type="function", + ) + for call in all_tool_calls + ] + all_tool_names = set([tool["function"]["name"] for tool in tools]) + + # Validate if the generated tool calls are valid + for tool in response.choices[0].message.tool_calls: + tool_name = tool.function.name + is_valid = tool_name in all_tool_names + if not is_valid: + logger.warn( + f"The returned function name {tool_name} is not in the list of valid functions. Retrying..." + ) + raise ValueError(f"The returned function name {tool_name} is not in the list of valid functions.") + + self.collect_metrics(response) + return LLMResult( + content=content, + role="assistant", + tool_calls=response.choices[0].message.tool_calls, + send_tokens=response.usage.prompt_tokens, + recv_tokens=response.usage.completion_tokens, + total_tokens=response.usage.total_tokens, + ) + + def construct_messages(self, prepend_prompt: list[str], history: list[dict], append_prompt: list[str]): + messages = [] + # if prepend_prompt != []: + for i, prompt in enumerate(prepend_prompt): + if prompt != "": + messages.append({"role": "system" if i == 0 else "user", "content": prompt}) + if len(history) > 0: + messages += history + # if append_prompt != []: + for prompt in append_prompt: + if prompt != "": + messages.append({"role": "user", "content": prompt}) + return messages + + def collect_metrics(self, response: ChatCompletion): + self.total_prompt_tokens += response.usage.prompt_tokens + self.total_completion_tokens += response.usage.completion_tokens + + def get_spend(self) -> int: + input_cost_map = { + "gpt-3.5-turbo": 0.0015, + "gpt-3.5-turbo-16k": 0.003, + "gpt-3.5-turbo-0613": 0.0015, + "gpt-3.5-turbo-16k-0613": 0.003, + "gpt-4": 0.03, + "gpt-4-0613": 0.03, + "gpt-4-32k": 0.06, + "llama-2-7b-chat-hf": 0.0, + } + + output_cost_map = { + "gpt-3.5-turbo": 0.002, + "gpt-3.5-turbo-16k": 0.004, + "gpt-3.5-turbo-0613": 0.002, + "gpt-3.5-turbo-16k-0613": 0.004, + "gpt-4": 0.06, + "gpt-4-0613": 0.06, + "gpt-4-32k": 0.12, + "llama-2-7b-chat-hf": 0.0, + } + + model = self.args.model + if model not in input_cost_map or model not in output_cost_map: + raise ValueError(f"Model type {model} not supported") + + return ( + self.total_prompt_tokens * input_cost_map[model] / 1000.0 + + self.total_completion_tokens * output_cost_map[model] / 1000.0 + ) + + +@retry( + stop=stop_after_attempt(3), + wait=wait_exponential(multiplier=1, min=4, max=10), + reraise=True, +) +def get_embedding(text: str) -> np.array: + try: + text = text.replace("\n", " ") + if openai.api_type == "azure": + embedding = sync_openai_client.embeddings.create(input=[text], deployment_id="text-embedding-ada-002")[ + "data" + ][0]["embedding"] + else: + embedding = sync_openai_client.embeddings.create(input=[text], model="text-embedding-ada-002")["data"][0][ + "embedding" + ] + return tuple(embedding) + except Exception as e: + logger.error(f"Error {e} when requesting openai models. Retrying") + raise diff --git a/im_client/llms/utils/__init__.py b/im_client/llms/utils/__init__.py new file mode 100644 index 0000000..d64f068 --- /dev/null +++ b/im_client/llms/utils/__init__.py @@ -0,0 +1,2 @@ +from .jsonrepair import JsonRepair +from .token_counter import count_string_tokens, count_message_tokens diff --git a/im_client/llms/utils/jsonrepair.py b/im_client/llms/utils/jsonrepair.py new file mode 100644 index 0000000..ad63f79 --- /dev/null +++ b/im_client/llms/utils/jsonrepair.py @@ -0,0 +1,636 @@ +# jsonrepair.py - Repair invalid JSON documents in Python +# +# Just https://github.com/josdejong/jsonrepair ported from TypeScript to Python. +# +# This port won't get updates, because the goal should be to generate this library instead. +# +# See: https://github.com/josdejong/jsonrepair/issues/84 +# + +import json +import re +from typing import Optional + +CONTROL_CHARACTERS = {"\b": "\\b", "\f": "\\f", "\n": "\\n", "\r": "\\r", "\t": "\\t"} + +ESCAPE_CHARACTERS = { + '"': '"', + "\\": "\\", + "/": "/", + "b": "\b", + "f": "\f", + "n": "\n", + "r": "\r", + "t": "\t", + # note that \u is handled separately in parseString() +} + + +def remove_at_index(text: str, start: int, count: int) -> str: + return text[0:start] + text[start + count :] + + +def is_control_character(char: str) -> bool: + return char in CONTROL_CHARACTERS + + +def is_valid_string_character(char: str) -> bool: + return 0x20 <= ord(char) <= 0x10FFFF + + +def is_quote(char: str) -> bool: + return is_single_quote(char) or is_double_quote(char) + + +def is_single_quote(char: str) -> bool: + """Test whether the given character is a single quote character. + Also tests for special variants of single quotes. + """ + return char in ( + "'", # U+0027 + "‘", # U+2018 + "’", # U+2019 + "`", # U+0060 + "´", # U+00B4 + ) + + +def is_double_quote(char: str) -> bool: + return is_ascii_double_quote(char) or is_double_quote_left(char) or is_double_quote_right(char) + + +def is_ascii_double_quote(char: str) -> bool: + return char == '"' # U+0022 + + +def is_double_quote_left(char: str) -> bool: + return char == "“" # U+201C + + +def is_double_quote_right(char: str) -> bool: + return char == "”" # U+201D + + +def is_start_of_value(char: str) -> bool: + regex_start_of_value = r"^[[{\w-]$" # alpha, number, minus, or opening bracket or brace + return bool(re.search(regex_start_of_value, char)) or is_quote(char) + + +def ends_with_comma_or_newline(text: str) -> bool: + return bool(re.search(r"[,\n][ \t\r]*$", text)) + + +def is_whitespace(char: str) -> bool: + return char.isspace() + + +def is_special_whitespace(char: str) -> bool: + """Check if the given character is a special whitespace character, some unicode variant""" + return ( + char == "\u00a0" # non-breaking space + or ord("\u2000") <= ord(char) <= ord("\u200a") + or char == "\u202f" + or char == "\u205f" + or char == "\u3000" + ) + + +def insert_before_last_whitespace(text: str, text_to_insert: str) -> str: + index = len(text) + + if not is_whitespace(text[index - 1]): + # no trailing whitespaces + return text + text_to_insert + + while is_whitespace(text[index - 1]): + index -= 1 + + return text[:index] + text_to_insert + text[index:] + + +def strip_last_occurrence(text: str, text_to_strip: str, strip_remaining: bool = False) -> str: + index = text.rindex(text_to_strip) + try: + return text[:index] + ("" if strip_remaining else text[index + 1 :]) + except ValueError: + return text + + +def is_hex(char: str) -> bool: + try: + int(char, 16) + return True + except ValueError: + return False + + +def is_delimiter(char: str) -> bool: + return char in ",:[]{}()\n'" or is_quote(char) + + +def at_end_of_block_comment(text: str, i: int) -> bool: + return text[i] == "*" and text[i + 1] == "/" + + +class JsonRepairError(Exception): + def __init__(self, message: str, position: int): + super(JsonRepairError, self).__init__(message + f" at position {position}") + self.position = position + + +class JsonRepair: + """Repairs invalid JSON, i.e. change JavaScript notation into JSON notation. + + Example: + + try: + json = "{name: 'John'}" + repaired = JsonRepair(json).repair() + print(repaired) + # '{"name": "John"}' + except JsonRepairFailed as err: + print(err) + + """ + + def __init__(self, text: str): + self.text = text + self.i = 0 # current index in text + self.output = "" # generated output + + def char(self, pos: int = 0) -> str: + return self.text[self.i + pos] + + def inc(self, by: int = 1) -> None: + self.i += by + + def dec(self, by: int = 1) -> None: + self.i -= by + + def is_start_of_document(self, pos: int = 0) -> bool: + return self.i + pos == 0 + + def is_end_of_document(self, pos: int = 0) -> bool: + return self.i + pos >= len(self.text) + + def repair(self) -> str: + processed = self.parse_value() + if not processed: + raise self.unexpected_end() + + processed_comma = self.parse_character(",") + if processed_comma: + self.parse_whitespace_and_skip_comments() + + if not self.is_end_of_document() and is_start_of_value(self.char()) and ends_with_comma_or_newline(self.output): + # start of a new value after end of the root level object: looks like + # newline delimited JSON -> turn into a root level array + if not processed_comma: + # repair missing comma + self.output = insert_before_last_whitespace(self.output, ",") + + self.parse_newline_delimited_json() + elif processed_comma: + # repair: remove trailing comma + self.output = strip_last_occurrence(self.output, ",") + + if self.is_end_of_document(): + # reached the end of the document properly + return self.output + + raise self.unexpected_character() + + def parse_value(self) -> bool: + self.parse_whitespace_and_skip_comments() + processed = ( + self.parse_object() + or self.parse_array() + or self.parse_string() + or self.parse_number() + or self.parse_keywords() + or self.parse_unquoted_string() + ) + self.parse_whitespace_and_skip_comments() + return processed + + def parse_whitespace_and_skip_comments(self) -> bool: + start = self.i + + changed = self.parse_whitespace() + while True: + changed = self.parse_comment() + if changed: + changed = self.parse_whitespace() + if not changed: + break + + return self.i > start + + def parse_whitespace(self) -> bool: + whitespace = "" + + while not self.is_end_of_document(): + char = self.char() + + normal = is_whitespace(char) + special = is_special_whitespace(char) + + if not normal and not special: + break + + if special: + whitespace += " " # repair special whitespace + else: + whitespace += char + + self.inc() + + if whitespace: + self.output += whitespace + return True + return False + + def parse_comment(self) -> bool: + # find a block comment '/* ... */' + if not self.is_end_of_document() and not self.is_end_of_document(pos=+1): + if self.char() == "/" and self.char(pos=+1) == "*": + # repair block comment by skipping it + while not self.is_end_of_document() and not at_end_of_block_comment(self.text, self.i): + self.inc() + self.inc(by=2) + return True + + # find a line comment '// ...' + if self.char() == "/" and self.char(pos=+1) == "/": + # repair line comment by skipping it + while not self.is_end_of_document() and self.char() != "\n": + self.inc() + return True + + return False + + def parse_character(self, char: str) -> bool: + if not self.is_end_of_document(): + if self.char() == char: + self.output += char + self.inc() + return True + return False + + def skip_character(self, char: str) -> bool: + if not self.is_end_of_document() and self.char() == char: + self.inc() + return True + return False + + def skip_escape_character(self) -> bool: + return self.skip_character("\\") + + def parse_object(self) -> bool: + """Parse an object like '{"key": "value"}'""" + if not self.is_end_of_document() and self.char() == "{": + self.output += "{" + self.inc() + self.parse_whitespace_and_skip_comments() + + initial = True + while not self.is_end_of_document() and self.char() != "}": + if not initial: + processed_comma = self.parse_character(",") + if not processed_comma: + # repair missing comma + self.output = insert_before_last_whitespace(self.output, ",") + self.parse_whitespace_and_skip_comments() + else: + processed_comma = True + initial = False + + processed_key = self.parse_string() or self.parse_unquoted_string() + if not processed_key: + if self.is_end_of_document() or self.char() in "{}[]": + # repair trailing comma + self.output = strip_last_occurrence(self.output, ",") + break + raise self.object_key_expected() + + self.parse_whitespace_and_skip_comments() + processed_colon = self.parse_character(":") + if not processed_colon: + if is_start_of_value(self.char()): + # repair missing colon + self.output = insert_before_last_whitespace(self.output, ":") + else: + raise self.colon_expected() + processed_value = self.parse_value() + if not processed_value: + if processed_colon: + raise self.object_value_expected() + raise self.colon_expected() + + if not self.is_end_of_document() and self.char() == "}": + self.output += "}" + self.inc() + else: + # repair missing end bracket + self.output = insert_before_last_whitespace(self.output, "}") + + return True + + return False + + def parse_array(self) -> bool: + """Parse an array like '["item1", "item2", ...]'""" + if not self.is_end_of_document() and self.char() == "[": + self.output += "[" + self.inc() + self.parse_whitespace_and_skip_comments() + + initial = True + while not self.is_end_of_document() and self.char() != "]": + if not initial: + processed_comma = self.parse_character(",") + if not processed_comma: + # repair missing comma + self.output = insert_before_last_whitespace(self.output, ",") + else: + initial = False + + processed_value = self.parse_value() + if not processed_value: + # repair trailing comma + self.output = strip_last_occurrence(self.output, ",") + break + + if not self.is_end_of_document() and self.char() == "]": + self.output += "]" + self.inc() + else: + # repair missing closing array bracket + self.output = insert_before_last_whitespace(self.output, "]") + + return True + + return False + + def parse_newline_delimited_json(self): + """Parse and repair Newline Delimited JSON (NDJSON): + multiple JSON objects separated by a newline character + """ + # repair NDJSON + initial = True + processed_value = True + while processed_value: + if not initial: + # parse optional comma, insert when missing + processed_comma = self.parse_character(",") + if not processed_comma: + # repair: add missing comma + self.output = insert_before_last_whitespace(self.output, ",") + else: + initial = False + + processed_value = self.parse_value() + + if not processed_value: + # repair: remove trailing comma + self.output = strip_last_occurrence(self.output, ",") + + # repair: wrap the output inside array brackets + self.output = f"[\n{self.output}\n]" + + def parse_string(self) -> bool: + """Parse a string enclosed by double quotes "...". Can contain escaped quotes + Repair strings enclosed in single quotes or special quotes + Repair an escaped string + """ + if not self.is_end_of_document(): + skip_escape_chars = self.char() == "\\" + if skip_escape_chars: + # repair: remove the first escape character + self.inc() + skip_escape_chars = True + + if not self.is_end_of_document() and is_quote(self.char()): + is_end_quote = is_single_quote if is_single_quote(self.char()) else is_double_quote + + if self.char() != '"': + pass # TODO?: repair non-normalized quote + self.output += '"' + self.inc() + + while not self.is_end_of_document() and not is_end_quote(self.char()): + if self.char() == "\\": + char = self.char(pos=+1) + escape_char = ESCAPE_CHARACTERS.get(char) + if escape_char: + self.output += self.text[self.i : self.i + 2] + self.inc(by=2) + elif char == "u": + if ( + not self.is_end_of_document(pos=+5) + and is_hex(self.char(pos=+2)) + and is_hex(self.char(pos=+3)) + and is_hex(self.char(pos=+4)) + and is_hex(self.char(pos=+5)) + ): + self.output += self.text[self.i : self.i + 6] + self.inc(by=6) + else: + raise self.invalid_unicode_character(self.i) + else: + # repair invalid escape character: remove it + self.output += char + self.inc(by=2) + else: + char = self.char() + + if char == '"' and self.char(pos=-1) != "\\": + # repair unescaped double quote + self.output += "\\" + char + self.inc() + elif is_control_character(char): + # unescaped control character + self.output += CONTROL_CHARACTERS[char] + self.inc() + else: + if not is_valid_string_character(char): + raise self.invalid_character(char) + self.output += char + self.inc() + + if skip_escape_chars: + processed = self.skip_escape_character() + if processed: + pass # repair: skipped escape character (nothing to do) + + if not self.is_end_of_document() and is_quote(self.char()): + if self.char() != '"': + pass # TODO:? repair non-normalized quote + + self.output += '"' + self.inc() + else: + # repair missing end quote + self.output += '"' + + self.parse_concatenated_string() + + return True + + return False + + def parse_concatenated_string(self) -> bool: + """Repair concatenated strings like \"hello\" + \"world\", change this into \"helloworld\" """ + processed = False + + self.parse_whitespace_and_skip_comments() + while not self.is_end_of_document() and self.char() == "+": + processed = True + self.inc() + self.parse_whitespace_and_skip_comments() + + # repair: remove the end quote of the first string + self.output = strip_last_occurrence(self.output, '"', True) + start = len(self.output) + self.parse_string() + + # repair: remove the start quote of the second string + self.output = remove_at_index(self.output, start, 1) + + return processed + + def parse_number(self) -> bool: + """Parse a number like 2.4 or 2.4e6""" + if not self.is_end_of_document(): + start = self.i + if self.char() == "-": + self.inc() + err = self.expect_digit(start) + if err: + raise err + + if not self.is_end_of_document() and self.char() == "0": + self.inc() + elif not self.is_end_of_document() and self.char() in "123456789": + self.inc() + while not self.is_end_of_document() and self.char().isdigit(): + self.inc() + + if not self.is_end_of_document() and self.char() == ".": + self.inc() + err = self.expect_digit(start) + if err: + raise err + while not self.is_end_of_document() and self.char().isdigit(): + self.inc() + + if not self.is_end_of_document() and self.char() in "eE": + self.inc() + if not self.is_end_of_document() and self.char() in "+-": + self.inc() + err = self.expect_digit(start) + if err: + raise err + while not self.is_end_of_document() and self.char().isdigit(): + self.inc() + + if self.i > start: + self.output += self.text[start : self.i] + return True + + return False + + def parse_keywords(self) -> bool: + """Parse keywords true, false, null + Repair Python keywords True, False, None + """ + return ( + self.parse_keyword("true", "true") + or self.parse_keyword("false", "false") + or self.parse_keyword("null", "null") + # repair Python keywords True, False, None + or self.parse_keyword("True", "true") + or self.parse_keyword("False", "false") + or self.parse_keyword("None", "null") + ) + + def parse_keyword(self, name: str, value: str) -> bool: + if self.text[self.i : self.i + len(name)] == name: + self.output += value + self.inc(by=len(name)) + return True + + return False + + def parse_unquoted_string(self) -> bool: + """Repair and unquoted string by adding quotes around it + Repair a MongoDB function call like NumberLong("2") + Repair a JSONP function call like callback({...}); + """ + # note that the symbol can end with whitespaces: we stop at the next delimiter + start = self.i + while not self.is_end_of_document() and not is_delimiter(self.char()): + self.inc() + + if self.i > start: + if not self.is_end_of_document() and self.char() == "(": + # repair a MongoDB function call like NumberLong("2") + # repair a JSONP function call like callback({...}); + self.inc() + + self.parse_value() + + if not self.is_end_of_document() and self.char() == ")": + # repair: skip close bracket of function call + self.inc() + if not self.is_end_of_document() and self.char() == ";": + # repair: skip semicolon after JSONP call + self.inc() + + return True + + # else repair unquoted string + + # first, go back to prevent getting trailing whitespaces in the string + while not self.is_start_of_document() and is_whitespace(self.char(pos=-1)): + self.dec() + + symbol = self.text[start : self.i] + self.output += json.dumps(symbol) + + return True + + return False + + def expect_digit(self, start: int) -> Optional[JsonRepairError]: + if self.is_end_of_document() or not self.char().isdigit(): + num_so_far = self.text[start : self.i] + return JsonRepairError(f"Invalid number '{num_so_far}', expecting a digit {self.got()}", 2) + + def invalid_character(self, char: str) -> JsonRepairError: + return JsonRepairError("Invalid character " + json.dumps(char), self.i) + + def unexpected_character(self) -> JsonRepairError: + return JsonRepairError("Unexpected character " + json.dumps(self.text[self.i]), self.i) + + def unexpected_end(self) -> JsonRepairError: + return JsonRepairError("Unexpected end of json string", len(self.text)) + + def object_key_expected(self) -> JsonRepairError: + return JsonRepairError("Object key expected", self.i) + + def object_value_expected(self) -> JsonRepairError: + return JsonRepairError("Object value expected", self.i) + + def colon_expected(self) -> JsonRepairError: + return JsonRepairError("Colon expected", self.i) + + def invalid_unicode_character(self, start: int) -> JsonRepairError: + end = start + 2 + while re.match(r"\w", self.text[end]): + end += 1 + chars = self.text[start:end] + return JsonRepairError(f'Invalid unicode character "{chars}"', self.i) + + def got(self) -> str: + return f"but got '{self.char()}'" if not self.is_end_of_document() else "but reached end of input" diff --git a/im_client/llms/utils/token_counter.py b/im_client/llms/utils/token_counter.py new file mode 100644 index 0000000..c46b74c --- /dev/null +++ b/im_client/llms/utils/token_counter.py @@ -0,0 +1,61 @@ +# Modified from AutoGPT https://github.com/Significant-Gravitas/AutoGPT/blob/release-v0.4.7/autogpt/llm/utils/token_counter.py + +import tiktoken +from typing import List, Union, Dict +from common.log import logger +from llms import LOCAL_LLMS, LOCAL_LLMS_MAPPING + + +def count_string_tokens(prompt: str = "", model: str = "gpt-3.5-turbo") -> int: + if model.startswith("gpt-3.5-turbo") or model.startswith("gpt-4"): + return len(tiktoken.encoding_for_model(model).encode(prompt)) + elif model.lower() in LOCAL_LLMS or model in LOCAL_LLMS: + from transformers import AutoTokenizer + + encoding = AutoTokenizer.from_pretrained(LOCAL_LLMS_MAPPING[model.lower()]) + return len(encoding.encode(prompt)) + + +def count_message_tokens(messages: Union[Dict, List[Dict]], model: str = "gpt-3.5-turbo") -> int: + if isinstance(messages, dict): + messages = [messages] + + if model.startswith("gpt-3.5-turbo"): + tokens_per_message = 4 # every message follows <|start|>{role/name}\n{content}<|end|>\n + tokens_per_name = -1 # if there's a name, the role is omitted + encoding_model = "gpt-3.5-turbo" + elif model.startswith("gpt-4"): + tokens_per_message = 3 + tokens_per_name = 1 + encoding_model = "gpt-4" + elif model.lower() in LOCAL_LLMS or model in LOCAL_LLMS: + from transformers import AutoTokenizer + + encoding = AutoTokenizer.from_pretrained(LOCAL_LLMS_MAPPING[model.lower()]) + else: + raise NotImplementedError( + f"count_message_tokens() is not implemented for model {model}.\n" + " See https://github.com/openai/openai-python/blob/main/chatml.md for" + " information on how messages are converted to tokens." + ) + if model.startswith("gpt-3.5-turbo") or model.startswith("gpt-4"): + try: + encoding = tiktoken.encoding_for_model(encoding_model) + except KeyError: + logger.warn("Warning: model not found. Using cl100k_base encoding.") + encoding = tiktoken.get_encoding("cl100k_base") + + num_tokens = 0 + for message in messages: + num_tokens += tokens_per_message + for key, value in message.items(): + # TODO: count number of function_call's token more accurately + if key == "function_call": + num_tokens += len(encoding.encode(value["name"])) + num_tokens += len(encoding.encode(value["arguments"])) + else: + num_tokens += len(encoding.encode(value)) + if key == "name": + num_tokens += tokens_per_name + num_tokens += 3 # every reply is primed with <|start|>assistant<|message|> + return num_tokens diff --git a/im_client/main.py b/im_client/main.py new file mode 100644 index 0000000..e9d60fa --- /dev/null +++ b/im_client/main.py @@ -0,0 +1,52 @@ +from contextlib import asynccontextmanager + +from fastapi import FastAPI +from pymilvus import connections + +from agents import AgentAdapter +from communication.communication_layer import CommunicationLayer +from common.config import global_config +from common.types import LaunchGoalParam + + +@asynccontextmanager +async def lifespan(app: FastAPI): + global communicator + if communicator is None: + tool_agent = AgentAdapter.create(global_config["tool_agent"]) + comm_config = global_config["comm"] + communicator = await CommunicationLayer.create( + comm_config["name"], + comm_config["desc"], + comm_config["type"], + tool_agent, + comm_config["support_nested_teams"], + discussion_only=comm_config["discussion_only"], + ) + yield + await communicator.shutdown() + + +app = FastAPI(lifespan=lifespan) + +communicator: CommunicationLayer = None + +connections.connect( + alias="default", + user="username", + password="password", + # host='localhost', #'host.docker.internal', + host="standalone", + port="19530", +) + + +@app.post("/launch_goal") +async def launch_goal(param: LaunchGoalParam): + return await communicator.launch_goal(**param.model_dump()) + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, host="0.0.0.0", port=5050) diff --git a/im_client/memory/__init__.py b/im_client/memory/__init__.py new file mode 100644 index 0000000..477839b --- /dev/null +++ b/im_client/memory/__init__.py @@ -0,0 +1,6 @@ +from common.registry import Registry + +memory_registry = Registry(name="MemoryRegistry") + +from .base import BaseMemory +from .chat_history import ChatHistoryMemory diff --git a/im_client/memory/base.py b/im_client/memory/base.py new file mode 100644 index 0000000..2960a42 --- /dev/null +++ b/im_client/memory/base.py @@ -0,0 +1,23 @@ +from abc import abstractmethod +from typing import List + +from pydantic import BaseModel + +from common.types.llm import LLMResult + + +class BaseMemory(BaseModel): + @abstractmethod + def add_messages(self, messages: LLMResult | List[LLMResult]) -> None: + pass + + @abstractmethod + def to_string(self) -> str: + pass + + @abstractmethod + def reset(self) -> None: + pass + + def to_messages(self) -> List[dict]: + pass diff --git a/im_client/memory/chat_history.py b/im_client/memory/chat_history.py new file mode 100644 index 0000000..2480ab0 --- /dev/null +++ b/im_client/memory/chat_history.py @@ -0,0 +1,181 @@ +import copy +from string import Template +from typing import Dict, List, Optional, Tuple + +import openai +from llms import OpenAIChat +from llms.utils import count_message_tokens, count_string_tokens +from pydantic import Field + +from common.types.llm import LLMResult + +from . import memory_registry +from .base import BaseMemory + + +@memory_registry.register("chat_history") +class ChatHistoryMemory(BaseMemory): + messages: List[LLMResult] = Field(default=[]) + has_summary: bool = False + max_summary_tlength: int = 500 + last_trimmed_index: int = 0 + summary: str = "" + SUMMARIZATION_PROMPT: str = '''Your task is to create a concise running summary of actions and information results in the provided text, focusing on key and potentially important information to remember. + +You will receive the current summary and your latest actions. Combine them, adding relevant key information from the latest development in 1st person past tense and keeping the summary concise. + +Summary So Far: +""" +${summary} +""" + +Latest Development: +""" +${new_events} +""" +''' + + def add_messages(self, messages: LLMResult | List[LLMResult]) -> None: + if isinstance(messages, LLMResult): + messages = [messages] + for message in messages: + self.messages.append(message) + + def to_string(self, add_sender_prefix: bool = False) -> str: + if add_sender_prefix: + return "\n".join( + [ + f"[{message.sender}]: {message.content}" if message.sender != "" else message.content + for message in self.messages + ] + ) + else: + return "\n".join([message.content for message in self.messages]) + + async def to_messages( + self, + my_name: str = "", + start_index: int = 0, + max_summary_length: int = 0, + max_send_token: int = 0, + model: str = "gpt-3.5-turbo", + ) -> List[dict]: + if self.has_summary: + start_index = self.last_trimmed_index + + messages = [message.to_openai_message() for message in self.messages[start_index:]] + + # summary message + if self.has_summary: + """https://github.com/Significant-Gravitas/AutoGPT/blob/release-v0.4.7/autogpt/memory/message_history.py""" + if max_summary_length == 0: + max_summary_length = self.max_summary_tlength + max_send_token -= max_summary_length + prompt = [] + trimmed_history = add_history_upto_token_limit(prompt, messages, max_send_token, model) + if trimmed_history: + new_summary_msg, _ = await self.trim_messages(list(prompt), model, messages) + prompt.append(new_summary_msg) + messages = prompt + return messages + + def reset(self) -> None: + self.messages = [] + + async def trim_messages( + self, current_message_chain: List[Dict], model: str, history: List[Dict] + ) -> Tuple[Dict, List[Dict]]: + new_messages_not_in_chain = [msg for msg in history if msg not in current_message_chain] + + if not new_messages_not_in_chain: + return self.summary_message(), [] + + new_summary_message = await self.update_running_summary(new_events=new_messages_not_in_chain, model=model) + + last_message = new_messages_not_in_chain[-1] + self.last_trimmed_index += history.index(last_message) + + return new_summary_message, new_messages_not_in_chain + + async def update_running_summary( + self, + new_events: List[Dict], + model: str = "gpt-3.5-turbo", + max_summary_length: Optional[int] = None, + ) -> dict: + if not new_events: + return self.summary_message() + if max_summary_length is None: + max_summary_length = self.max_summary_tlength + + new_events = copy.deepcopy(new_events) + + # Replace "assistant" with "you". This produces much better first person past tense results. + for event in new_events: + if event["role"].lower() == "assistant": + event["role"] = "you" + + elif event["role"].lower() == "system": + event["role"] = "your computer" + + # Delete all user messages + elif event["role"] == "user": + new_events.remove(event) + + prompt_template_length = len(Template(self.SUMMARIZATION_PROMPT).safe_substitute(summary="", new_events="")) + max_input_tokens = OpenAIChat.send_token_limit(model) - max_summary_length + summary_tlength = count_string_tokens(self.summary, model) + batch: List[Dict] = [] + batch_tlength = 0 + + for event in new_events: + event_tlength = count_message_tokens(event, model) + + if batch_tlength + event_tlength > max_input_tokens - prompt_template_length - summary_tlength: + await self._update_summary_with_batch(batch, model, max_summary_length) + summary_tlength = count_string_tokens(self.summary, model) + batch = [event] + batch_tlength = event_tlength + else: + batch.append(event) + batch_tlength += event_tlength + + if batch: + await self._update_summary_with_batch(batch, model, max_summary_length) + + return self.summary_message() + + async def _update_summary_with_batch( + self, new_events_batch: List[dict], model: str, max_summary_length: int + ) -> None: + prompt = Template(self.SUMMARIZATION_PROMPT).safe_substitute(summary=self.summary, new_events=new_events_batch) + + self.summary = await openai.ChatCompletion.acreate( + messages=[{"role": "user", "content": prompt}], + model=model, + max_tokens=max_summary_length, + temperature=0.5, + )["choices"][0]["message"]["content"] + + def summary_message(self) -> dict: + return { + "role": "system", + "content": f"This reminds you of these events from your past: \n{self.summary}", + } + + +def add_history_upto_token_limit(prompt: List[dict], history: List[dict], t_limit: int, model: str) -> List[LLMResult]: + limit_reached = False + current_prompt_length = 0 + trimmed_messages: List[Dict] = [] + for message in history[::-1]: + token_to_add = count_message_tokens(message, model) + if current_prompt_length + token_to_add > t_limit: + limit_reached = True + + if not limit_reached: + prompt.insert(0, message) + current_prompt_length += token_to_add + else: + trimmed_messages.insert(0, message) + return trimmed_messages diff --git a/im_client/observation_func/__init__.py b/im_client/observation_func/__init__.py new file mode 100644 index 0000000..81aa97a --- /dev/null +++ b/im_client/observation_func/__init__.py @@ -0,0 +1,17 @@ +observation_registry = {} + + +def register_observation(name): + def decorator(func): + observation_registry[name] = func + return func + + return decorator + + +from .rocobench import get_observation + + +@register_observation("dummy") +def get_observation(*args, **kwargs): + return "" diff --git a/im_client/observation_func/default.py b/im_client/observation_func/default.py new file mode 100644 index 0000000..e69de29 diff --git a/im_client/observation_func/rocobench.py b/im_client/observation_func/rocobench.py new file mode 100644 index 0000000..cab0d51 --- /dev/null +++ b/im_client/observation_func/rocobench.py @@ -0,0 +1,13 @@ +from . import register_observation +import requests +from common.config import global_config + + +@register_observation("rocobench") +def get_observation() -> str: + agent_name = global_config["comm"]["name"] + resp = requests.post( + "http://host.docker.internal:8900/get_agent_prompt", + json={"agent_name": agent_name}, + ) + return resp.json() diff --git a/im_client/prompts/__init__.py b/im_client/prompts/__init__.py new file mode 100644 index 0000000..f28934b --- /dev/null +++ b/im_client/prompts/__init__.py @@ -0,0 +1,3 @@ +from .react import * +from .communication import * +from .execution import * diff --git a/im_client/prompts/communication.py b/im_client/prompts/communication.py new file mode 100644 index 0000000..1aeb8ed --- /dev/null +++ b/im_client/prompts/communication.py @@ -0,0 +1,270 @@ +COMM_HUMANAGENT_SYSTEM_PROMPT = r"""You are ${name}. Here is your profile: +name: ${name} +type: ${agent_type} +description: ${desc} + +You are in the collaborative and distributed network of assistants, designed to achieve complex goals through effective discussion and collaborative execution. +There are 2 types of assistants in the network: +1. Human Assistant (you): These assistants act as human proxies, with the ability to communicate and execute tasks on behalf of the humans they represent. They are familiar with the personality and capabilities of the humans they represent and excel at complex decision-making, task decomposition, task execution, and collaborative work for goals. +2. Thing Assistant: These assistants serve as proxies for objects, skilled in handling or utilizing various objects including tools, softwares, systems and so on. As proxies for objects, they excel at performing specific tasks and possess limited communication abilities, best suited for discussion related to task assignments. Therefore, assigning them suitable tasks during communication is an effective method for collaboration. +""" + +COMM_THINGAGENT_SYSTEM_PROMPT = r"""You are ${name}. Here is your profile: +name: ${name} +type: ${agent_type} +description: ${desc} + +You are in the collaborative and distributed network of assistants, designed to achieve complex goals through effective discussion and collaborative execution. +There are 2 types of assistants in the network: +1. Human Assistant: These assistants act as human proxies, with the ability to communicate and execute tasks on behalf of the humans they represent. They are familiar with the personality and capabilities of the humans they represent and excel at complex decision-making, task decomposition, task execution, and collaborative work for goals. +2. Thing Assistant (you): These assistants serve as proxies for objects, skilled in handling or utilizing various objects including tools, softwares, systems and so on. As proxies for objects, they excel at performing specific tasks and possess limited communication abilities, best suited for discussion related to task assignments. Therefore, assigning them suitable tasks during communication is an effective method for collaboration. +""" + +COMM_MAS_PROMPT = r"""In the network, You are working with other assistants to collaboratively achieve the complex goals. The basic rules of collaboration in the network is: +1. The process of group discussion and task execution often proceeds in a simultaneous or interleaving manner. Group discussion is always meaningful, covering any form of content in terms of coordination and collaboration, including thoughts, suggestions, negotiation, analysis, voting, task breakdown, assignments, task results synthesis, all geared towards progressing towards the overall goal. Task execution occurs in two forms: synchronous, where tasks are assigned, completed and their results are shared before the group discussion continues; and asynchronous, where tasks are assigned immediately and executed in the background without disrupting the ongoing discussion. +2. The mechanism of group discussion is that the current speaker will designate the next person to speak and only one person will speak at one turn. +3. Upon completion of the goal, the assistant in current turn concludes the group discussion. +""" + +COMM_DISCOVERY_PROMPT = r"""There is currently one GOAL overall assigned to you which needs to be achieved: +``` +${goal} +``` + +At this first stage, you need to decide which assistants to team up with in the network to complete the TASK effectively and collaboratively. +Your decision making process should meet the following principles: +1. When initiating a team to achieve the GOAL, you should consider yourself as a team member. +2. You should adhere to Occam's Razor principle, which states "Entities should not be multiplied without necessity." When considering teamwork, it is essential to balance the potential benefits of collaboration against the significantly increased communication costs associated with a larger team size. Choose ONLY the necessary members to join the team to avoid an oversized team. Each final member should have a clear and unique role and contribution to improve team efficiency. +3. You can search candidates by using the tool `agent_discovery` **in multiple times** and **from different perspectives** to gather enough information before making a final decision on team members. +4. You should use the tool `team_up` to make the final decision on team members. Ensure the team very lean (no less than 1 member and no more than 4 members) and members with highly overlapping skills should NOT appear in the team. + + +Your local address book contains contacts of assistants you've previously collaborated with. You can search for additional assistants on the remote server by using the tool `agent_discovery`. +Local address book: +${retrieved_contact} +""" + +COMM_COORDINATION_WITHOUT_GOAL_PROMPT = r"""Your current team members include: +```json +${teammates} +```""" + +_TASK_ASSIGNMENT_PROMPT = """# Strategies +The content in your message should be informative and can cover ANY form of content which promotes the discussion and keeps moving towards the goal, avoiding repetition to what previous speakers said and ensuring substantive relevance. +Pay attention to the balance between Discussion, Sync Task Assignment and Async Task Assignment, Pause in right timing and Conclude the group discussion when the goal is completed. +**Discuss well before assigning tasks and choose your task assignment strategy carefully in Task Assignment.** +In each turn, ONLY ONE option of message types could be selected. + +## Task Assignement +You could assign one or multiple tasks in one turn to anyone including yourself in synchronous or asynchronous way. +Each task, could depend on outcomes in the previous group discussion or completed tasks. However, once assigned, it will be running in isolation without interrupted or interfered. +Each task has ONLY ONE task owner. So if the message type is `sync_task_assign` or `async_task_assign`, `next_people` could ONLY be the owners in current task assignments (As the next speaker in group discussion will be yourself again after task assignments, it doesn't need to be specified). +Never assign mutiple tasks in the same turn, where one depends on another. Those immature tasks should be plans which could be discussed more and could be assigned in the future. + +### Sync Task Assignment(`sync_task_assign`) +Sync Task Assignment involves assigning a task to an agent in a group discussion, where the discussion is paused until the task is completed. The focus shifts to the task execution, and the group discussion resumes only after the task is finished and the results are shared with the group. +This message type is utilized for assigning tasks that require immediate and undivided attention. The group discussion is put on hold, emphasizing the prioritization of the task at hand. Once the task is completed and the results are shared, the discussion continues from where it was paused. +### Async Task Assignment(`async_task_assign`) +Async Task Assignment refers to the process where a task is assigned to an agent during a group discussion, and the agent executes the task independently and asynchronously. The discussion continues in parallel without waiting for the task's completion. The agent later reports the outcome of the task back to the group. +This message type is used when assigning a task that can be performed in the background while the group discussion continues without interruption. The agent responsible for the task will work on it asynchronously and share the results upon completion. + +## Discussion(`discussion`) +The 'discussion' message type is used for various forms of group interactions that are crucial for the overall functioning and cohesion of the team but do not involve direct task delegation. It includes activities such as planning, evaluation, reasoning, brainstorming, thoughts, suggestions, negotiation, analysis, voting, task decomposition and so on. +If the message type is 'discussion', `next_people` should be the only one next speaker in group discussion. + +## Pause(`pause`) +If current group discussion depends on the results of the tasks In Progress, you should pause the group discussion until those tasks completed. Correspondingly specify the message type as 'pause', and specify next_people to yourself as it's you to start the resumption of the group discussion afterwards. + +## Conclude Group Discussion(`conclude_group_discussion`) +The message type is used to officially end a group discussion when the goal overall has been achieved. When the goal overall has been achieved, all tasks are completed and there are no pending issues in the future plans, the assistant in the current turn can declare the group discussion concluded. In this case, the `next_people` field is not applicable. + + +You are ${name}. Now it's your turn to speak, adhering to the basic rules of collaboration in the network to achieve the goal overall. +You should use the Strategies above based on the actual situation to flexibly choose whether to discuss, assign tasks in a specific manner, temporarily pause the group discussion or end the group discussion.""" + +_TASK_ASSIGNMENT_WITH_PLAN_RESPONSE_FORMAT = """You need to respond in the following json format: +```json +{ + "content": "The content of your message in your turn", + "thought": "internal monologue before specifying 'message_type', 'next_people'.", + "message_type": "Select only one option from ['discussion', 'async_task_assign', 'sync_task_assign', 'pause', 'conclude_group_discussion'].", + "next_people": "list[str] | str, either the next speaker in group discussion or owners in task assignments. If message_type is 'discussion', 'pause', next_people should be str(only one speaker specified to speak in the next turn). If message_type is 'async_task_assign' or 'sync_task_assign', next_people should be a list of agent names as the task owners in this turn (anyone including **yourself** allowed).", + "thought_on_Dynamic_Collaborative_Planner": "internal monologue before specifying 'update_Dynamic_Collaborative_Planner'.", + "update_Dynamic_Collaborative_Planner": "bool type, whether the Dynamic Collaborative Planner should be updated or not." +} +```""" + +_TASK_ASSIGNMENT_WITHOUT_PLAN_RESPONSE_FORMAT = """You need to respond in the following json format: +```json +{ + "content": "The content of your message in your turn", + "thought": "internal monologue before specifying 'message_type', 'next_people'.", + "message_type": "Select only one option from ['discussion', 'async_task_assign', 'sync_task_assign', 'pause', 'conclude_group_discussion'].", + "next_people": "list[str] | str, either the next speaker in group discussion or owners in task assignments. If message_type is 'discussion', 'pause', next_people should be str(only one speaker specified to speak in the next turn). If message_type is 'async_task_assign' or 'sync_task_assign', next_people should be a list of agent names as the task owners in this turn (anyone including **yourself** allowed)." +} +```""" + +_DISCUSSION_ONLY_PROMPT = """# Strategies +The content in your message should be informative and can cover ANY form of content which promotes the discussion and keeps moving towards the goal, avoiding repetition to what previous speakers said and ensuring substantive relevance. + +In each turn, ONLY ONE option of message types could be selected: + +## Discussion(`discussion`) +The 'discussion' message type is used for various forms of group interactions that are crucial for the overall functioning and cohesion of the team. It includes activities such as planning, evaluation, reasoning, brainstorming, thoughts, suggestions, negotiation, analysis, voting, task decomposition and so on. +If the message type is 'discussion', `next_people` should be the only one next speaker in group discussion. + +## Conclude Group Discussion(`conclude_group_discussion`) +The message type is used to officially end a group discussion when the goal overall has been achieved. When the goal overall has been achieved, all tasks are completed and there are no pending issues in the future plans, the assistant in the current turn can declare the group discussion concluded. In this case, the `next_people` field is not applicable. + + +You are ${name}. Now it's your turn to speak, adhering to the basic rules of collaboration in the network to achieve the goal overall.""" + +_DISCUSSION_ONLY_RESPONSE_FORMAT = """You need to respond in the following json format: +```json +{ + "content": "The content of your message in your turn", + "thought": "internal monologue before specifying 'message_type', 'next_people'.", + "message_type": "Select only one option from ['discussion', 'conclude_group_discussion'].", + "next_people": "str, the next speaker in group discussion. If message_type is 'discussion', next_people should be str(only one speaker specified to speak in the next turn). If message_type is "conclude_group_discussion", the next_people should be yourself." +} +```""" + +COMM_DISCUSSION_WITH_PLAN_APPEND_PROMPT = f"{_TASK_ASSIGNMENT_PROMPT}\n\n\n{_TASK_ASSIGNMENT_WITH_PLAN_RESPONSE_FORMAT}" + +COMM_DISCUSSION_WITHOUT_PLAN_APPEND_PROMPT = ( + f"{_TASK_ASSIGNMENT_PROMPT}\n\n\n{_TASK_ASSIGNMENT_WITHOUT_PLAN_RESPONSE_FORMAT}" +) + +COMM_DISCUSSION_ONLY_DISCUSSION_APPEND_PROMPT = f"{_DISCUSSION_ONLY_PROMPT}\n\n\n{_DISCUSSION_ONLY_RESPONSE_FORMAT}" + +COMM_TASK_MANAGEMENT_APPEND_PROMPT = r"""The goal overall to achieve is: +``` +${goal} +``` + +Here is the up-to-date view of task management which visualizes all the statuses of tasks assigned in the group discussion for the goal. It provides a foundation for group discussion and support for decision making before your turn to speak. +${task_management_view} +""" +COMM_PLANNER_PROMPT = r"""Here is the current state of Dynamic Collaborative Planner where latest group consensus is documented: +${Dynamic_Collaborative_Planner} +Any assistant in the team should adhere the Dynamic Collaborative Planner in default. +ONLY When the team discusses and reaches a NEW consensus on future plans, the Dynamic Collaborative Planner needs to be updated to reflect these new decisions. +""" +COMM_PAUSE_SYS_PROMPT = r"""The indices of tasks In Progress currently: ${indices_In_Progress} +""" + +COMM_PAUSE_APPEND_PROMPT = r"""You are ${name}. In the course of group discussion, you have currently paused the discussion. +Now you should set the triggers for the resumption of the group discussion. Specifically, you should select the indices of tasks as triggers which are not only In Progress, but also are prerequisites for the group discussion. +These tasks with dependencies selected should provide the information needed for the next discussion, or the decision making of the next discussion depends on the results of them. + +You need to respond in the following json format: +```json +{ + "thought": "thoughts on selecting tasks as triggers for the resumption of the group discussion.", + "selected_task_indices": "list[int], at least one or more indices whose tasks serve as triggers for the resumption of the group discussion." +} +```""" + +COMM_INFORM_OPT_EXE_APPEND_PROMPT = r"""Team, the following task is being executed in the background by myself. I ensure that once it's completed, I will share the task result with you all. +The description of the task: +${task_description} +The status of task: +RUNNING IN THE BACKGROUND +Now, let's resume and promote our original discussion with this new information in mind. +""" + +COMM_APPEND_PROMPT = r"""You are ${name}. Now you should generate your thought and call the tools (if neccessary). You should generate your thought in the following format: +Thought: <your thought process of decision making> +""" + +COMM_CONCLUDE_APPEND_PROMPT = """The goal overall is: +${goal} + + +The goal overall has been achieved in the GROUP DISCUSSION ABOVE. +Based on the whole GROUP DISCUSSION, the FINAL answer to the goal overall is: +""" + +COMM_WHETHER_TEAM_UP_PROMPT = r"""There is currently one TASK assigned to you which needs to be completed: +``` +${task} +``` + +At this first stage, you need to decide whether to complete the TASK individually or to collaborate with other assistants in the network. +Your decision making process should meet the following principles: +1. You should adhere to Occam's Razor principle, which states "Entities should not be multiplied without necessity." This suggests that although collaboration among multiple assistants can potentially enhance task completion, the overhead of teamwork is greater than that of completing tasks individually. Therefore, if the TASK can be effectively handled on an individual basis, it is preferable to undertake it individually. +2. You need to evaluate whether you can competently handle the TASK on your own by considering the task description, your personal agent profile, and past performance. If you are unable to manage the TASK individually, you may opt for teamwork. + + +Your local address book contains contacts of assistants you've previously collaborated with. If you opt for teamwork, you can decide to team up with them or search for additional assistants on the remote server in subsequent stages. +Local address book: +${retrieved_contact} + + +You should respond in the following json format: +```json +{ + "thought": "your thought process of decision making", + "decision": "Choose either 'individual' or 'teamwork'. While 'individual' means to complete the TASK individually, 'teamwork' means to try collaborating with other assistants in the network." +} +```""" + +COMM_CONCLUDE_APPEND_PROMPT = r"""You are ${name}. The goal has been achieved, now it is time to conclude the group discussion. You should give the final outcome presentation based on the history of group discussion. +The final answer for the goal: +""" + +COMM_CONCLUDE_APPEND_PROMPT = """The goal overall is: +${goal} + + +The goal overall has been achieved in the GROUP DISCUSSION ABOVE. Now you should give a self-contained, complete and detailed FINAL answer. +Based on the whole GROUP DISCUSSION, the FINAL answer to the goal overall is: +""" + +COMM_UPDATE_PLAN_APPEND_PROMPT = r"""You are ${name}. +After you speak, you realize new consensus in the discussion has been emerged and Dynamic Collaborative Planner needs to be updated. +You should modify/recreate the Dynamic Collaborative Planner to achieve the goal overall according to the lastest collaborative consensus in the following format: +# The content of Dynamic Collaborative Planner +## Strategic Objectives +Describe strategic directions in a future phase towards the goal overall. +## Expected Milestones +Identify key points or outcomes in the journey to achieve the goal overall. Only displayonly the agreed-upon future plans or expected milestones. +## Dependencies +Record the conditions or prerequisite tasks that the future plan relies on. + +Your modified/recreated content of Dynamic Collaborative Planner: +""" + +COMM_ACTIVE_LANUCH_PROMPT = """ You are the AI of a smart home system. You need to make decisions based on the home sensor inputs to ensure the comfort of the occupants. Your decisions should optimize for the well-being of the occupants. Consider the time of day, known schedules of the occupants, and any other relevant contextual data when making your decision. +""" + + +ACTIVE_SENSOR_PROMPT = """ Sensor detection result: ${state}. For example, based on the home camera has detected a person decide if this is a regular occupant returning home, occupant leaving the house, or occupant is being in home. If it is an occupant returning, activate the 'Welcome Home' mode. If the occupant is leaving, switch to 'Away' mode. If occupant is being in home, no action is needed, maintain current settings. + +You should respond in the following json format: +```json +{ + "thought": "your thought process of decision making", + "goal_decision": "Choose either 'Yes' or 'No' for action. + "goal": "Describe the specific actions taken by the smart home system." +} +``` +""" + +TEAMUP_GROUP_NAMING_PROMPT = """Here's a goal: +``` +${goal} +``` + +You have decided to team up with the following assistants: +``` +${teammates} +``` + +Now, a group chat is created for your team. You need to come up with a name for your group chat. The name should be creative, relevant to the goal, and easy to remember. It should reflect the collaborative spirit of your team and inspire motivation. Keep it brief and concise! The name should be no more than 40 characters! Emoji can also be considered. + +You should response in the following JSON format: +```json +{ + "team_name": "the name of your group chat. no more than 40 characters." +}""" diff --git a/im_client/prompts/execution.py b/im_client/prompts/execution.py new file mode 100644 index 0000000..6df97d9 --- /dev/null +++ b/im_client/prompts/execution.py @@ -0,0 +1,63 @@ +REPHRASE_TASK_HYBIRD_SYS_PROMPT = r"""The recent chat history and completed tasks so far in the group discussion: +${recent_history} +""" + +REPHRASE_TASK_APPEND_PROMPT = r"""You are ${name}. During the group discussion to achieve the goal, you've been assigned a specific task in LATEST LAST turn. +Now you should identify the task assigned to YOU currently and rephrase it from the recent chat history, and incorporate substantive work results of tasks in dependency and necessary information of messages in recent chat history as the task input. +This rephrased task description should be clear, concise, complete, specific, and aligned with the global goal, ensuring you fully understand the requirements and steps for successful completion. The latest last message in the group discussion is key to rephrase the task assigned to You. +If necessary, you should list the indices in 'index_to_integrate' to incoporate content into task input. If the index is message index, the message itself will be integrated. If the index is task index, the substantive **work result** of the task will be integrated. +The consequences of missing essential information are severe, so you need to ensure that the recall rate for the indices which should be integrated reaches 100%. + +The rephrased task description and the task input incorporated will serve as all the information source and guide for you to execute the task effectively. + +You must respond in the following json format: +```json +{ + "thought": "think deeply on the task description and index selection to integrate content into the task input", + "task_description": "your rephrased complete task description", + "task_abstract": "summarize the task description and keep it concise and clear with all the key components.", + "index_to_integrate": "list[int], a list of indices whose information (like messages or substantive work results of tasks) is not covered in 'task_description' and should be integrated in the task input during post processing. [] means nothing is necessary to be incorporated in the task input." +} +```""" +REPHRASE_TASK_APPEND_PROMPT = r"""You are ${name}. +During the group discussion to achieve the goal overall (which is the message with index 1), you are being assigned a specific task in LATEST LAST turn. +Now you should identify the task assigned to YOU currently and rephrase it from the recent chat history and completed tasks so far into a clear, complete and self-contained version in well-defined format. +The rephrased task should be clear, complete, specific, contain everything you need to complete successfully. +The rephrased task is well formatted, which includes 4 components: +# The Rephrased Task +## Task Abstract(`task_abstract`) +A concise and descriptive title that captures the essence of the task, making it easy to understand at a glance. +## Task Description(`task_description`) +A clear and detailed description of the task that needs to be accomplished. +## Task Inputs(to fill the field of `index_to_integrate` by selecting indices) +Comprehensive information is very critical for the successful completion of the current task. +You should list the indices in `index_to_integrate` to incoporate any helpful content (including the goal overall if neccessary) garnered from previous collaborations into task input. If the index is message index, the message itself will be integrated. If the index is task index, the substantive **work result** of the task will be integrated. +## Context Information(`context_information`) +Provide essential background information that elucidates the task's relevance and its role within the broader project scope. +This section should elucidate how the task inputs are connected to the task execution. It should also introduce the broader project briefly, articulate how the task aligns with collaborative efforts within the broader project, pinpointing specific considerations to avoid any redundant or overlapping activities. + +## Completion Criteria(`completion_criteria`) +Define specific, measurable criteria that will be used to evaluate whether the task has been successfully completed. These criteria could include qualitative benchmarks, quantitative metrics or any other standards agreed upon by the team. + +The Rephrased Task will serve as **all the information source** and guide for you to execute the task effectively. + +You must respond in the following json format: +```json +{ + "thought": "internal monologue when rephrasing the task assigned to you", + "task_abstract": "", + "task_description": "", + "index_to_integrate": "list[int], a list of indices whose information (like messages or substantive work results of tasks) is not covered in 'task_description' and should be integrated in the task input during post processing. [] means nothing is necessary to be incorporated in the task input.", + "context_information": "", + "completion_criteria": "" +} +```""" + +EXEC_TASK_CONCLUSION_APPEND_PROMPT = """Just a quick interruption to our current discussion. I have an important update regarding the task I've been working on alongside our group discussion. +Task Description: +${task_desc} +The task has now been completed. Here are the key outcomes: +Task Conclusion: +${task_conclusion} +Now, let's resume and promote our original discussion with this new information in mind. +""" diff --git a/im_client/prompts/react.py b/im_client/prompts/react.py new file mode 100644 index 0000000..b5c3bf0 --- /dev/null +++ b/im_client/prompts/react.py @@ -0,0 +1,18 @@ +REACT_SYSTEM_PROMPT = r"""You are ${name}, and here is your profile: +${desc} +""" + +REACT_TASK_PROMPT = r"""You are asked to complete the following TASK: +``` +${task_description} +``` +""" + +REACT_APPEND_THOUGHT_PROMPT = r"""Now you must generate your thought and you must not call the tools in this stage. You should respond in the following json format: +```json +{ + "thought": "your thought" +} +```""" + +REACT_APPEND_TOOL_PROMPT = r"""Now you must call the tools in this stage""" diff --git a/im_client/requirements.txt b/im_client/requirements.txt new file mode 100644 index 0000000..3001eda --- /dev/null +++ b/im_client/requirements.txt @@ -0,0 +1,17 @@ +pyyaml +fastapi +uvicorn +numpy +openai==1.3.0 +httpx[socks]==0.25.0 +pydantic +pymilvus==2.3.0 +colorama==0.4.6 +tiktoken==0.5.1 +tenacity +websockets +docker +sqlitedict==2.1.0 +aiofiles +requests==2.31.0 +aiohttp \ No newline at end of file diff --git a/im_client/server_helper.py b/im_client/server_helper.py new file mode 100644 index 0000000..b798f07 --- /dev/null +++ b/im_client/server_helper.py @@ -0,0 +1,122 @@ +from typing import Literal + +from httpx import AsyncClient, RequestError, Timeout +from tenacity import ( + retry, + retry_if_exception_type, + stop_after_attempt, + wait_exponential, +) + +from common.config import global_config +from common.types.agent import AgentInfo +from common.types.server import AgentRegistryTeamupOutput +from common.utils.misc import log_retry + + +class ServerHelper: + """ + Helper functions that help communicate with the server. + """ + + host = global_config["server"]["host"] + port = global_config["server"]["port"] + url = f"{host}:{port}" + + @classmethod + @retry( + stop=stop_after_attempt(5), + reraise=True, + retry=retry_if_exception_type(RequestError), + wait=wait_exponential(multiplier=1, min=1, max=10), + before_sleep=log_retry, + ) + async def retrieve_assistant( + cls, + sender: str, + capabilities: list[str], + ) -> list[AgentInfo]: + """ + Retrieve relevant agents from the server with specified capability keywords. + """ + async with AsyncClient(timeout=Timeout(timeout=30)) as client: + retrieve_result = await client.post( + f"{cls.url}/retrieve_assistant", + json={ + "sender": sender, + "capabilities": capabilities, + }, + timeout=60.0, + ) + retrieve_result.raise_for_status() + agent_infos = retrieve_result.json() + return agent_infos + + @classmethod + @retry( + stop=stop_after_attempt(5), + reraise=True, + retry=retry_if_exception_type(RequestError), + wait=wait_exponential(multiplier=1, min=1, max=10), + before_sleep=log_retry, + ) + async def register( + cls, + name: str, + desc: str, + agent_type: Literal["Human Assistant", "Thing Assistant"], + ) -> None: + """ + Register the client to the server + """ + async with AsyncClient(timeout=Timeout(timeout=30)) as client: + response = await client.post( + f"{cls.url}/register", + json=AgentInfo(name=name, desc=desc, type=agent_type).model_dump(), + timeout=60, + ) + response.raise_for_status() + + @classmethod + @retry( + stop=stop_after_attempt(5), + reraise=True, + retry=retry_if_exception_type(RequestError), + wait=wait_exponential(multiplier=1, min=1, max=10), + before_sleep=log_retry, + ) + async def teamup( + cls, sender: str, agent_names: list[str], team_name: str | None = None + ) -> AgentRegistryTeamupOutput: + """ + Forming group with specified agents + """ + async with AsyncClient(timeout=Timeout(timeout=30)) as client: + teamup_result = await client.post( + f"{cls.url}/teamup", + json={ + "sender": sender, + "agent_names": agent_names, + "team_name": team_name, + }, + ) + teamup_result.raise_for_status() + team_info = AgentRegistryTeamupOutput.model_validate_json(teamup_result.text) + return team_info + + @classmethod + @retry( + stop=stop_after_attempt(5), + reraise=True, + retry=retry_if_exception_type(RequestError), + wait=wait_exponential(multiplier=1, min=1, max=10), + before_sleep=log_retry, + ) + async def query_assistant(cls, name: list[str] | str): + async with AsyncClient(timeout=Timeout(timeout=30)) as client: + response = await client.post( + f"{cls.url}/query_assistant", + json={"name": name}, + ) + response.raise_for_status() + return response.json() diff --git a/im_server/app.py b/im_server/app.py new file mode 100644 index 0000000..6c3139c --- /dev/null +++ b/im_server/app.py @@ -0,0 +1,255 @@ +import json +import uuid +from copy import deepcopy +from datetime import datetime +from urllib.parse import quote, unquote + +import uvicorn +from fastapi import FastAPI, WebSocket, WebSocketDisconnect +from pymilvus import connections +from starlette.middleware.cors import CORSMiddleware + +from common.log import logger +from common.types import ( + AgentEntry, + AgentInfo, + AgentMessage, + AgentRegistryQueryParam, + AgentRegistryRetrivalParam, + AgentRegistryTeamupOutput, + AgentRegistryTeamupParam, + ChatRecordFetchParam, +) +from common.utils.database_utils import AutoStoredDict +from common.utils.milvus_utils import ConfigMilvusWrapper + +app = FastAPI() + +origins = ["*"] + +app.add_middleware( + CORSMiddleware, + allow_origins=origins, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + + +class ConnectionManager: + def __init__(self): + self.agent_to_websocket: dict[str, WebSocket] = {} + + async def connect(self, websocket: WebSocket, agent_name: str) -> str: + await websocket.accept() + self.agent_to_websocket[agent_name] = websocket + print(self.agent_to_websocket) + + async def disconnect(self, agent_name: str): + self.agent_to_websocket.pop(agent_name, None) + + async def send_personal_message(self, receiver: str, message: AgentMessage): + try: + websocket = self.agent_to_websocket[receiver] + except: + logger.error(f"Failed to find the websocket for {receiver}") + await websocket.send_text(message.model_dump_json()) + + +class AgentRegistry: + """ + Agent Registry block. Providing agent registering and querying services based on Milvus vector database. + """ + + def __init__(self): + self.agents = ConfigMilvusWrapper("configs/agent_registry.yaml") + + async def register(self, agent: AgentInfo) -> None: + if agent.name in self.agents: + return agent.name + timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M-%S") + self.agents[agent.name] = AgentEntry( + name=agent.name, + desc=agent.desc, + type=agent.type, + created_at=timestamp, + ) + + async def retrieve(self, param: AgentRegistryRetrivalParam) -> list[AgentInfo]: + res = self.agents.search_via_config(param.capabilities) + deduplicate_ids = set() + deduplicate_hits = [] + for hits in res: + for hit in hits: + if hit.get("name") not in deduplicate_ids: + deduplicate_hits.append(hit) + deduplicate_ids.add(hit.get("name")) + return [AgentInfo(name=hit.get("name"), type=hit.get("type"), desc=hit.get("desc")) for hit in deduplicate_hits] + + async def query(self, name: list[str] | str) -> list[AgentInfo | None] | AgentInfo | None: + result = [] + candidates = name if isinstance(name, list) else [name] + for agent_name in candidates: + if agent_name in self.agents: + result.append( + AgentInfo( + name=agent_name, + desc=self.agents[agent_name].get("desc"), + type=self.agents[agent_name].get("type"), + ) + ) + else: + result.append(None) + if isinstance(name, str): + return result[0] + else: + return result + + +class SessionManager: + """ + Session Manager block. Maintaining the basic group chat information. + """ + + def __init__(self): + self.sessions = AutoStoredDict("database/server/sessions.db", tablename="sessions") + + async def teamup(self, agent_names: list[str]) -> AgentRegistryTeamupOutput: + comm_id = uuid.uuid4().hex + session_group = [] + for name in agent_names: + if name in agent_registry.agents.keys(): + session_group.append(name) + self.sessions[comm_id] = session_group + return {"comm_id": comm_id, "agent_names": session_group} + + +@app.websocket("/ws/{agent_name}") +async def websocket_endpoint(websocket: WebSocket, agent_name: str): + """ + Endpoint for receiving agent messages + """ + await connection_manager.connect(websocket, agent_name) + agent_name = unquote(agent_name) + + try: + while True: + # 1. listen to the websocket + data = await websocket.receive_text() + try: + # 2. parse the received message using Agent Message protocol + parsed_data = AgentMessage.model_validate_json(data) + except: + logger.error("Failed to parse the message: {data}") + if parsed_data.comm_id not in session_manager.sessions: + logger.error(f"Failed to find the session {parsed_data.comm_id} for {agent_name}") + + record = chat_record_manager[parsed_data.comm_id] + record["chat_record"].append(parsed_data) + chat_record_manager[parsed_data.comm_id] = record + await send_to_frontend(json.loads(parsed_data.model_dump_json()), "message") + for receiver in session_manager.sessions[parsed_data.comm_id]: + # 3. Forward the message to all the members including the sender itself. + await connection_manager.send_personal_message(receiver, parsed_data) + + except WebSocketDisconnect: + agent_name = quote(agent_name) + await connection_manager.disconnect(agent_name) + + +@app.websocket("/chatlist_ws") +async def websocket_chatlist(websocket: WebSocket): + await websocket.accept() + global frontend_ws + frontend_ws = websocket + + try: + while True: + data = await websocket.receive_text() + + except WebSocketDisconnect: + frontend_ws = None + + +@app.post("/health_check") +async def health_check(): + return "ok" + + +@app.post("/register") +async def register_agent(agent: AgentInfo): + await agent_registry.register(agent) + + +@app.post("/retrieve_assistant") +async def retrieve_assistant( + characteristics: AgentRegistryRetrivalParam, +) -> list[AgentInfo]: + agents = await agent_registry.retrieve(characteristics) + return agents + + +@app.post("/query_assistant") +async def query_assistant( + param: AgentRegistryQueryParam, +) -> list[AgentInfo] | AgentInfo: + agents = await agent_registry.query(param.name) + return agents + + +@app.post("/teamup") +async def teamup(teamup_param: AgentRegistryTeamupParam): + result = await session_manager.teamup(teamup_param.agent_names + [teamup_param.sender]) + result["team_name"] = teamup_param.team_name + chat_record_manager[result["comm_id"]] = { + "comm_id": result["comm_id"], + "agent_names": result["agent_names"], + "team_name": teamup_param.team_name, + "chat_record": [], + } + await send_to_frontend(result, "teamup") + return result + + +async def send_to_frontend(data: dict, type: str): + global frontend_ws + if frontend_ws: + try: + new_result = deepcopy(data) + new_result["frontend_type"] = type + await frontend_ws.send_text(json.dumps(new_result)) + except WebSocketDisconnect: + frontend_ws = None + + +@app.post("/list_all_agents") +async def list_all_agents(): + return agent_registry.agents.items() + + +@app.post("/fetch_chat_record") +async def fetch_chat_record(param: ChatRecordFetchParam): + if param.comm_id is None: + return chat_record_manager.todict() + if isinstance(param.comm_id, str): + param.comm_id = [param.comm_id] + return {comm_id: chat_record_manager[comm_id] for comm_id in param.comm_id} + + +connections.connect( + alias="default", + user="username", + password="password", + # host="localhost", + host="standalone", + port="19530", +) + +agent_registry = AgentRegistry() +connection_manager = ConnectionManager() +session_manager = SessionManager() +chat_record_manager = AutoStoredDict("database/server/chat.db", tablename="chat") +frontend_ws = None + +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=7788, ws_ping_timeout=None) diff --git a/im_server/frontend/.gitignore b/im_server/frontend/.gitignore new file mode 100644 index 0000000..4d29575 --- /dev/null +++ b/im_server/frontend/.gitignore @@ -0,0 +1,23 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# 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/im_server/frontend/README.md b/im_server/frontend/README.md new file mode 100644 index 0000000..58beeac --- /dev/null +++ b/im_server/frontend/README.md @@ -0,0 +1,70 @@ +# Getting Started with Create React App + +This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). + +## Available Scripts + +In the project directory, you can run: + +### `npm start` + +Runs the app in the development mode.\ +Open [http://localhost:3000](http://localhost:3000) to view it in your browser. + +The page will reload when you make changes.\ +You may also see any lint errors in the console. + +### `npm test` + +Launches the test runner in the interactive watch mode.\ +See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. + +### `npm run build` + +Builds the app for production to the `build` folder.\ +It correctly bundles React in production mode and optimizes the build for the best performance. + +The build is minified and the filenames include the hashes.\ +Your app is ready to be deployed! + +See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. + +### `npm run eject` + +**Note: this is a one-way operation. Once you `eject`, you can't go back!** + +If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. + +Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. + +You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. + +## Learn More + +You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). + +To learn React, check out the [React documentation](https://reactjs.org/). + +### Code Splitting + +This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) + +### Analyzing the Bundle Size + +This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) + +### Making a Progressive Web App + +This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) + +### Advanced Configuration + +This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) + +### Deployment + +This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) + +### `npm run build` fails to minify + +This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) diff --git a/im_server/frontend/package-lock.json b/im_server/frontend/package-lock.json new file mode 100644 index 0000000..7aa7db8 --- /dev/null +++ b/im_server/frontend/package-lock.json @@ -0,0 +1,18309 @@ +{ + "name": "frontend", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "0.1.0", + "dependencies": { + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-markdown": "^9.0.1", + "react-scripts": "5.0.1", + "socket.io-client": "^4.7.4", + "web-vitals": "^2.1.4" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmmirror.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.3.3", + "resolved": "https://registry.npmmirror.com/@adobe/css-tools/-/css-tools-4.3.3.tgz", + "integrity": "sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ==" + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.24.0.tgz", + "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.0", + "@babel/parser": "^7.24.0", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/eslint-parser": { + "version": "7.23.10", + "resolved": "https://registry.npmmirror.com/@babel/eslint-parser/-/eslint-parser-7.23.10.tgz", + "integrity": "sha512-3wSYDPZVnhseRnxRJH6ZVTNknBz76AEnyC+AYYhasjP3Yy23qz0ERR7Fcd2SHmYuSFJ2kY9gaaDd3vyqU09eSw==", + "dependencies": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0", + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@babel/eslint-parser/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmmirror.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.0.tgz", + "integrity": "sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", + "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dependencies": { + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmmirror.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmmirror.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.24.0.tgz", + "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==", + "dependencies": { + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.24.0.tgz", + "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.23.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", + "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.0.tgz", + "integrity": "sha512-LiT1RqZWeij7X+wGxCoYh3/3b8nVOX6/7BZ9wiQgAIyjoeQWdROaodJCgT+dwtbjHaz0r7bEbHJzjSbVfcOyjQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-decorators": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead.", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead.", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "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.npmmirror.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "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.npmmirror.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.0.tgz", + "integrity": "sha512-MXW3pQCu9gUiVGzqkGqsgiINDVYXoAnrY8FYF/rmb+OfufNF0zHMpHPN4ulRrinxYT8Vk/aZJxYqOKsDECjKAw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-flow": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz", + "integrity": "sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", + "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "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.npmmirror.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "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.npmmirror.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "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.npmmirror.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "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.npmmirror.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "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.npmmirror.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "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.npmmirror.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.23.9", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", + "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", + "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", + "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.23.8", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", + "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-flow-strip-types": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz", + "integrity": "sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-flow": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.23.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.23.9", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", + "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.0.tgz", + "integrity": "sha512-y/yKMm7buHpFFXfxVFS4Vk1ToRJDilIa6fKRioB9Vjichv58TDGXTvqV0dN7plobAmTW5eSEGXDngE+Mm+uO+w==", + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", + "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.23.3.tgz", + "integrity": "sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", + "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.23.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", + "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/types": "^7.23.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.22.5", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", + "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", + "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.0.tgz", + "integrity": "sha512-zc0GA5IitLKJrSfXlXmp8KDqLrnGECK7YRfQBmEKg1NmBOQ7e+KuclBEKJgzifQeUYLdNiAw4B4bjyvzWVLiSA==", + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.24.0", + "babel-plugin-polyfill-corejs2": "^0.4.8", + "babel-plugin-polyfill-corejs3": "^0.9.0", + "babel-plugin-polyfill-regenerator": "^0.5.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.23.6", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz", + "integrity": "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.23.6", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", + "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", + "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/preset-env/-/preset-env-7.24.0.tgz", + "integrity": "sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA==", + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.23.3", + "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@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-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.9", + "@babel/plugin-transform-async-to-generator": "^7.23.3", + "@babel/plugin-transform-block-scoped-functions": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.4", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.4", + "@babel/plugin-transform-classes": "^7.23.8", + "@babel/plugin-transform-computed-properties": "^7.23.3", + "@babel/plugin-transform-destructuring": "^7.23.3", + "@babel/plugin-transform-dotall-regex": "^7.23.3", + "@babel/plugin-transform-duplicate-keys": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.4", + "@babel/plugin-transform-exponentiation-operator": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.4", + "@babel/plugin-transform-for-of": "^7.23.6", + "@babel/plugin-transform-function-name": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.4", + "@babel/plugin-transform-literals": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", + "@babel/plugin-transform-member-expression-literals": "^7.23.3", + "@babel/plugin-transform-modules-amd": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.9", + "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", + "@babel/plugin-transform-numeric-separator": "^7.23.4", + "@babel/plugin-transform-object-rest-spread": "^7.24.0", + "@babel/plugin-transform-object-super": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.4", + "@babel/plugin-transform-optional-chaining": "^7.23.4", + "@babel/plugin-transform-parameters": "^7.23.3", + "@babel/plugin-transform-private-methods": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", + "@babel/plugin-transform-property-literals": "^7.23.3", + "@babel/plugin-transform-regenerator": "^7.23.3", + "@babel/plugin-transform-reserved-words": "^7.23.3", + "@babel/plugin-transform-shorthand-properties": "^7.23.3", + "@babel/plugin-transform-spread": "^7.23.3", + "@babel/plugin-transform-sticky-regex": "^7.23.3", + "@babel/plugin-transform-template-literals": "^7.23.3", + "@babel/plugin-transform-typeof-symbol": "^7.23.3", + "@babel/plugin-transform-unicode-escapes": "^7.23.3", + "@babel/plugin-transform-unicode-property-regex": "^7.23.3", + "@babel/plugin-transform-unicode-regex": "^7.23.3", + "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.8", + "babel-plugin-polyfill-corejs3": "^0.9.0", + "babel-plugin-polyfill-regenerator": "^0.5.5", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmmirror.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/preset-react/-/preset-react-7.23.3.tgz", + "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-transform-react-display-name": "^7.23.3", + "@babel/plugin-transform-react-jsx": "^7.22.15", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmmirror.com/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", + "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-typescript": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmmirror.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, + "node_modules/@babel/runtime": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.24.0.tgz", + "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmmirror.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + }, + "node_modules/@csstools/normalize.css": { + "version": "12.1.1", + "resolved": "https://registry.npmmirror.com/@csstools/normalize.css/-/normalize.css-12.1.1.tgz", + "integrity": "sha512-YAYeJ+Xqh7fUou1d1j9XHl44BmsuThiTr4iNrgCQ3J27IbhXsxXDGZ1cXv8Qvs99d4rBbLiSKy3+WZiet32PcQ==" + }, + "node_modules/@csstools/postcss-cascade-layers": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", + "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", + "dependencies": { + "@csstools/selector-specificity": "^2.0.2", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-color-function": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", + "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-font-format-keywords": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", + "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-hwb-function": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", + "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-ic-unit": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", + "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-is-pseudo-class": { + "version": "2.0.7", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", + "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", + "dependencies": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-nested-calc": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", + "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-normalize-display-values": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", + "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-oklab-function": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", + "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", + "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/@csstools/postcss-stepped-value-functions": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", + "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-text-decoration-shorthand": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", + "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-trigonometric-functions": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", + "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/postcss-unset-value": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", + "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", + "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.0.10" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmmirror.com/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "engines": { + "node": ">=12.22" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmmirror.com/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@jest/console/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@jest/core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "dependencies": { + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmmirror.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "dependencies": { + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "dependencies": { + "@sinclair/typebox": "^0.24.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "dependencies": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/@jest/transform/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "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/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", + "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { + "version": "5.1.1-v1", + "resolved": "https://registry.npmmirror.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", + "dependencies": { + "eslint-scope": "5.1.1" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nicolo-ribaudo/eslint-scope-5-internals/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.11", + "resolved": "https://registry.npmmirror.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz", + "integrity": "sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ==", + "dependencies": { + "ansi-html-community": "^0.0.8", + "common-path-prefix": "^3.0.0", + "core-js-pure": "^3.23.3", + "error-stack-parser": "^2.0.6", + "find-up": "^5.0.0", + "html-entities": "^2.1.0", + "loader-utils": "^2.0.4", + "schema-utils": "^3.0.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "@types/webpack": "4.x || 5.x", + "react-refresh": ">=0.10.0 <1.0.0", + "sockjs-client": "^1.4.0", + "type-fest": ">=0.17.0 <5.0.0", + "webpack": ">=4.43.0 <6.0.0", + "webpack-dev-server": "3.x || 4.x", + "webpack-hot-middleware": "2.x", + "webpack-plugin-serve": "0.x || 1.x" + }, + "peerDependenciesMeta": { + "@types/webpack": { + "optional": true + }, + "sockjs-client": { + "optional": true + }, + "type-fest": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + }, + "webpack-hot-middleware": { + "optional": true + }, + "webpack-plugin-serve": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-babel": { + "version": "5.3.1", + "resolved": "https://registry.npmmirror.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", + "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", + "dependencies": { + "@babel/helper-module-imports": "^7.10.4", + "@rollup/pluginutils": "^3.1.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@types/babel__core": "^7.1.9", + "rollup": "^1.20.0||^2.0.0" + }, + "peerDependenciesMeta": { + "@types/babel__core": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmmirror.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/plugin-replace": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", + "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "magic-string": "^0.25.7" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.7.2", + "resolved": "https://registry.npmmirror.com/@rushstack/eslint-patch/-/eslint-patch-1.7.2.tgz", + "integrity": "sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA==" + }, + "node_modules/@sinclair/typebox": { + "version": "0.24.51", + "resolved": "https://registry.npmmirror.com/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmmirror.com/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmmirror.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, + "node_modules/@surma/rollup-plugin-off-main-thread": { + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", + "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", + "dependencies": { + "ejs": "^3.1.6", + "json5": "^2.2.0", + "magic-string": "^0.25.0", + "string.prototype.matchall": "^4.0.6" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmmirror.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmmirror.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "5.4.0", + "resolved": "https://registry.npmmirror.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "5.4.0", + "resolved": "https://registry.npmmirror.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "5.4.0", + "resolved": "https://registry.npmmirror.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", + "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", + "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", + "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", + "@svgr/babel-plugin-transform-svg-component": "^5.5.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "dependencies": { + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "dependencies": { + "@babel/types": "^7.12.6" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", + "dependencies": { + "@babel/core": "^7.12.3", + "@svgr/babel-preset": "^5.5.0", + "@svgr/hast-util-to-babel-ast": "^5.5.0", + "svg-parser": "^2.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "dependencies": { + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/plugin-transform-react-constant-elements": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@svgr/core": "^5.5.0", + "@svgr/plugin-jsx": "^5.5.0", + "@svgr/plugin-svgo": "^5.5.0", + "loader-utils": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@testing-library/dom": { + "version": "9.3.4", + "resolved": "https://registry.npmmirror.com/@testing-library/dom/-/dom-9.3.4.tgz", + "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@testing-library/dom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmmirror.com/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "peer": true, + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/@testing-library/dom/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@testing-library/dom/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/dom/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "peer": true + }, + "node_modules/@testing-library/dom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/dom/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "5.17.0", + "resolved": "https://registry.npmmirror.com/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", + "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "dependencies": { + "@adobe/css-tools": "^4.0.1", + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=8", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@testing-library/jest-dom/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react": { + "version": "13.4.0", + "resolved": "https://registry.npmmirror.com/@testing-library/react/-/react-13.4.0.tgz", + "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.5.0", + "@types/react-dom": "^18.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@testing-library/react/node_modules/@testing-library/dom": { + "version": "8.20.1", + "resolved": "https://registry.npmmirror.com/@testing-library/dom/-/dom-8.20.1.tgz", + "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testing-library/react/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmmirror.com/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/@testing-library/react/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@testing-library/react/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@testing-library/react/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@testing-library/react/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/user-event": { + "version": "13.5.0", + "resolved": "https://registry.npmmirror.com/@testing-library/user-event/-/user-event-13.5.0.tgz", + "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmmirror.com/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmmirror.com/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmmirror.com/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmmirror.com/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmmirror.com/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmmirror.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmmirror.com/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.5", + "resolved": "https://registry.npmmirror.com/@types/eslint/-/eslint-8.56.5.tgz", + "integrity": "sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmmirror.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.43", + "resolved": "https://registry.npmmirror.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", + "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmmirror.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "resolved": "https://registry.npmmirror.com/@types/http-proxy/-/http-proxy-1.17.14.tgz", + "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.12", + "resolved": "https://registry.npmmirror.com/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/jest/node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmmirror.com/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmmirror.com/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmmirror.com/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + }, + "node_modules/@types/jest/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@types/jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@types/jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/@types/jest/node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmmirror.com/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@types/jest/node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmmirror.com/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmmirror.com/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmmirror.com/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmmirror.com/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@types/jest/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/jest/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmmirror.com/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@types/jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmmirror.com/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + }, + "node_modules/@types/mdast": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/@types/mdast/-/mdast-4.0.3.tgz", + "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmmirror.com/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmmirror.com/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "node_modules/@types/node": { + "version": "20.11.26", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.11.26.tgz", + "integrity": "sha512-YwOMmyhNnAWijOBQweOJnQPl068Oqd4K3OFbTc6AHJwzweUwwWG3GIFY74OKks2PJUDkQPeddOQES9mLn1CTEQ==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmmirror.com/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmmirror.com/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmmirror.com/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, + "node_modules/@types/q": { + "version": "1.5.8", + "resolved": "https://registry.npmmirror.com/@types/q/-/q-1.5.8.tgz", + "integrity": "sha512-hroOstUScF6zhIi+5+x0dzqrHA1EJi+Irri6b1fxolMTqqHIV/Cg77EtnQcZqZCu8hR3mX2BzIxN4/GzI68Kfw==" + }, + "node_modules/@types/qs": { + "version": "6.9.12", + "resolved": "https://registry.npmmirror.com/@types/qs/-/qs-6.9.12.tgz", + "integrity": "sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/react": { + "version": "18.2.65", + "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.2.65.tgz", + "integrity": "sha512-98TsY0aW4jqx/3RqsUXwMDZSWR1Z4CUlJNue8ueS2/wcxZOsz4xmW1X8ieaWVRHcmmQM3R8xVA4XWB3dJnWwDQ==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.22", + "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-18.2.22.tgz", + "integrity": "sha512-fHkBXPeNtfvri6gdsMYyW+dW7RXFo6Ad09nLFK0VQWR7yGLai/Cyvyj696gbwYvBnhGtevUG9cET0pmUbMtoPQ==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmmirror.com/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmmirror.com/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmmirror.com/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmmirror.com/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmmirror.com/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmmirror.com/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmmirror.com/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmmirror.com/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==" + }, + "node_modules/@types/testing-library__jest-dom": { + "version": "5.14.9", + "resolved": "https://registry.npmmirror.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", + "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", + "dependencies": { + "@types/jest": "*" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmmirror.com/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" + }, + "node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmmirror.com/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "16.0.9", + "resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-16.0.9.tgz", + "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmmirror.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", + "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", + "dependencies": { + "@typescript-eslint/utils": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "dependencies": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "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.npmmirror.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "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.npmmirror.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "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.npmmirror.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "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.npmmirror.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "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.npmmirror.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "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.npmmirror.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "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.npmmirror.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmmirror.com/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmmirror.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmmirror.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmmirror.com/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.filter": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", + "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/array.prototype.findlast/-/array.prototype.findlast-1.2.4.tgz", + "integrity": "sha512-BMtLxpV+8BD+6ZPFIWmnUBpQoy+A+ujcg4rhp2iwCRJYA7PEh2MS4NL3lz8EiDlLrJPp2hg9qWihr5pd//jcGw==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", + "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmmirror.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmmirror.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array.prototype.reduce": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/array.prototype.reduce/-/array.prototype.reduce-1.0.6.tgz", + "integrity": "sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array.prototype.toreversed": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", + "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", + "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.1.0", + "es-shim-unscopables": "^1.0.2" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmmirror.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==" + }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmmirror.com/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, + "node_modules/asynciterator.prototype": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", + "dependencies": { + "has-symbols": "^1.0.3" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.18", + "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.18.tgz", + "integrity": "sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001591", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmmirror.com/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/babel-jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-loader": { + "version": "8.3.0", + "resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.3.0.tgz", + "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", + "dependencies": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.0", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 8.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" + } + }, + "node_modules/babel-loader/node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmmirror.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "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.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-named-asset-import": { + "version": "0.3.8", + "resolved": "https://registry.npmmirror.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", + "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", + "peerDependencies": { + "@babel/core": "^7.1.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.10", + "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", + "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.1", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.9.0", + "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", + "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.5.0", + "core-js-compat": "^3.34.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3/node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.5.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", + "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.5", + "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", + "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.5.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator/node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.5.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", + "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-transform-react-remove-prop-types": { + "version": "0.4.24", + "resolved": "https://registry.npmmirror.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", + "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dependencies": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-react-app": { + "version": "10.0.1", + "resolved": "https://registry.npmmirror.com/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", + "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/plugin-proposal-class-properties": "^7.16.0", + "@babel/plugin-proposal-decorators": "^7.16.4", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", + "@babel/plugin-proposal-numeric-separator": "^7.16.0", + "@babel/plugin-proposal-optional-chaining": "^7.16.0", + "@babel/plugin-proposal-private-methods": "^7.16.0", + "@babel/plugin-transform-flow-strip-types": "^7.16.0", + "@babel/plugin-transform-react-display-name": "^7.16.0", + "@babel/plugin-transform-runtime": "^7.16.4", + "@babel/preset-env": "^7.16.4", + "@babel/preset-react": "^7.16.0", + "@babel/preset-typescript": "^7.16.0", + "@babel/runtime": "^7.16.3", + "babel-plugin-macros": "^3.1.0", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, + "node_modules/bfj": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/bfj/-/bfj-7.1.0.tgz", + "integrity": "sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw==", + "dependencies": { + "bluebird": "^3.7.2", + "check-types": "^11.2.3", + "hoopy": "^0.1.4", + "jsonpath": "^1.1.1", + "tryer": "^1.0.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmmirror.com/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "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.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmmirror.com/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001597", + "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz", + "integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==" + }, + "node_modules/case-sensitive-paths-webpack-plugin": { + "version": "2.4.0", + "resolved": "https://registry.npmmirror.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/check-types": { + "version": "11.2.3", + "resolved": "https://registry.npmmirror.com/check-types/-/check-types-11.2.3.tgz", + "integrity": "sha512-+67P1GkJRaxQD6PKK0Et9DhwQB+vGg3PM5+aavopCpZT1lj9jeqfvpgTLAWErNj8qApkkmXlu/Ug74kmhagkXg==" + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmmirror.com/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmmirror.com/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmmirror.com/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/coa": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dependencies": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==" + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmmirror.com/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmmirror.com/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmmirror.com/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmmirror.com/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmmirror.com/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmmirror.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-js": { + "version": "3.36.0", + "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.36.0.tgz", + "integrity": "sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw==", + "hasInstallScript": true + }, + "node_modules/core-js-compat": { + "version": "3.36.0", + "resolved": "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.36.0.tgz", + "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", + "dependencies": { + "browserslist": "^4.22.3" + } + }, + "node_modules/core-js-pure": { + "version": "3.36.0", + "resolved": "https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.36.0.tgz", + "integrity": "sha512-cN28qmhRNgbMZZMc/RFu5w8pK9VJzpb2rJVR/lHuZJKwmXnoWOpXmMkxqBB514igkp1Hu8WGROsiOAzUcKdHOQ==", + "hasInstallScript": true + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/css-blank-pseudo": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "bin": { + "css-blank-pseudo": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-declaration-sorter": { + "version": "6.4.1", + "resolved": "https://registry.npmmirror.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", + "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-has-pseudo": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "bin": { + "css-has-pseudo": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-loader": { + "version": "6.10.0", + "resolved": "https://registry.npmmirror.com/css-loader/-/css-loader-6.10.0.tgz", + "integrity": "sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.4", + "postcss-modules-scope": "^3.1.1", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "3.4.1", + "resolved": "https://registry.npmmirror.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", + "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", + "dependencies": { + "cssnano": "^5.0.6", + "jest-worker": "^27.0.2", + "postcss": "^8.3.5", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-prefers-color-scheme": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", + "bin": { + "css-prefers-color-scheme": "dist/cli.cjs" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + } + }, + "node_modules/css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmmirror.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" + }, + "node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmmirror.com/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" + }, + "node_modules/cssdb": { + "version": "7.11.2", + "resolved": "https://registry.npmmirror.com/cssdb/-/cssdb-7.11.2.tgz", + "integrity": "sha512-lhQ32TFkc1X4eTefGfYPvgovRSzIMofHkigfH8nWtyRL4XJLsRhJFreRvEgKzept7x1rjBuy3J/MurXLaFxW/A==" + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "5.1.15", + "resolved": "https://registry.npmmirror.com/cssnano/-/cssnano-5.1.15.tgz", + "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "dependencies": { + "cssnano-preset-default": "^5.2.14", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-preset-default": { + "version": "5.2.14", + "resolved": "https://registry.npmmirror.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", + "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", + "dependencies": { + "css-declaration-sorter": "^6.3.1", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.1", + "postcss-convert-values": "^5.1.3", + "postcss-discard-comments": "^5.1.2", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.7", + "postcss-merge-rules": "^5.1.4", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.4", + "postcss-minify-selectors": "^5.2.1", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.1", + "postcss-normalize-repeat-style": "^5.1.1", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.1", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.3", + "postcss-reduce-initial": "^5.1.2", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/csso/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmmirror.com/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmmirror.com/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmmirror.com/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmmirror.com/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "node_modules/detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port-alt/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port-alt/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmmirror.com/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmmirror.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==" + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "deprecated": "Use your platform's native DOMException instead", + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmmirror.com/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmmirror.com/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, + "node_modules/dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmmirror.com/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmmirror.com/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.703", + "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.703.tgz", + "integrity": "sha512-094ZZC4nHXPKl/OwPinSMtLN9+hoFkdfQGKnvXbY+3WEAYtVDpz9UhJIViiY6Zb8agvqxiaJzNG9M+pRZWvSZw==" + }, + "node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmmirror.com/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/engine.io-client": { + "version": "6.5.3", + "resolved": "https://registry.npmmirror.com/engine.io-client/-/engine.io-client-6.5.3.tgz", + "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmmirror.com/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "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 + } + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.2", + "resolved": "https://registry.npmmirror.com/engine.io-parser/-/engine.io-parser-5.2.2.tgz", + "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.16.0", + "resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz", + "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmmirror.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/es-abstract": { + "version": "1.22.5", + "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.22.5.tgz", + "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.1", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.0", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.5", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.17", + "resolved": "https://registry.npmmirror.com/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz", + "integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==", + "dependencies": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.4", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.2", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-config-react-app": { + "version": "7.0.1", + "resolved": "https://registry.npmmirror.com/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/eslint-parser": "^7.16.3", + "@rushstack/eslint-patch": "^1.1.0", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "babel-preset-react-app": "^10.0.1", + "confusing-browser-globals": "^1.0.11", + "eslint-plugin-flowtype": "^8.0.3", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jest": "^25.3.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-testing-library": "^5.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmmirror.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmmirror.com/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-flowtype": { + "version": "8.0.3", + "resolved": "https://registry.npmmirror.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", + "dependencies": { + "lodash": "^4.17.21", + "string-natural-compare": "^3.0.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@babel/plugin-syntax-flow": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.9", + "eslint": "^8.1.0" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmmirror.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "25.7.0", + "resolved": "https://registry.npmmirror.com/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", + "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", + "dependencies": { + "@typescript-eslint/experimental-utils": "^5.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.8.0", + "resolved": "https://registry.npmmirror.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.34.0", + "resolved": "https://registry.npmmirror.com/eslint-plugin-react/-/eslint-plugin-react-7.34.0.tgz", + "integrity": "sha512-MeVXdReleBTdkz/bvcQMSnCXGi+c9kvy51IpinjnJgutl3YTHWsDdke7Z1ufZpGfDG8xduBDKyjtB9JH1eBKIQ==", + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlast": "^1.2.4", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.3", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.17", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7", + "object.hasown": "^1.1.3", + "object.values": "^1.1.7", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.10" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmmirror.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmmirror.com/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-testing-library": { + "version": "5.11.1", + "resolved": "https://registry.npmmirror.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", + "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", + "dependencies": { + "@typescript-eslint/utils": "^5.58.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0", + "npm": ">=6" + }, + "peerDependencies": { + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", + "dependencies": { + "@types/eslint": "^7.29.0 || ^8.4.1", + "jest-worker": "^28.0.2", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0", + "webpack": "^5.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/eslint-webpack-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/eslint-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmmirror.com/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmmirror.com/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmmirror.com/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/express": { + "version": "4.18.3", + "resolved": "https://registry.npmmirror.com/express/-/express-4.18.3.tgz", + "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmmirror.com/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmmirror.com/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmmirror.com/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmmirror.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" + }, + "node_modules/follow-redirects": { + "version": "1.15.5", + "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmmirror.com/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "6.5.3", + "resolved": "https://registry.npmmirror.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=10", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "eslint": ">= 6", + "typescript": ">= 2.7", + "vue-template-compiler": "*", + "webpack": ">= 4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dependencies": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "engines": { + "node": "*" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "node_modules/harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmmirror.com/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", + "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmmirror.com/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmmirror.com/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmmirror.com/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-url-attributes": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/html-url-attributes/-/html-url-attributes-3.0.0.tgz", + "integrity": "sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.0", + "resolved": "https://registry.npmmirror.com/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", + "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmmirror.com/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmmirror.com/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, + "node_modules/identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "dependencies": { + "harmony-reflect": "^1.4.6" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmmirror.com/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "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.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/inline-style-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmmirror.com/inline-style-parser/-/inline-style-parser-0.2.3.tgz", + "integrity": "sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==" + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ipaddr.js": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz", + "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmmirror.com/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dependencies": { + "call-bind": "^1.0.2" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmmirror.com/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmmirror.com/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" + } + }, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmmirror.com/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmmirror.com/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.8.7", + "resolved": "https://registry.npmmirror.com/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jake/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jake/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "dependencies": { + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "dependencies": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-circus/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-circus/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "dependencies": { + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-cli/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "dependencies": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-config/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-each/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-jasmine2/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-jasmine2/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-jasmine2/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "dependencies": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "dependencies": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-resolve/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-runner/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-runtime/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-snapshot/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "dependencies": { + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "leven": "^3.1.0", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-validate/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", + "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", + "dependencies": { + "ansi-escapes": "^4.3.1", + "chalk": "^4.0.0", + "jest-regex-util": "^28.0.0", + "jest-watcher": "^28.0.0", + "slash": "^4.0.0", + "string-length": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "jest": "^27.0.0 || ^28.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/console/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/jest-watch-typeahead/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-watch-typeahead/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-watch-typeahead/node_modules/emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmmirror.com/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-watch-typeahead/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-message-util/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-util": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "dependencies": { + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watch-typeahead/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmmirror.com/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-watch-typeahead/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmmirror.com/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/jest-watch-typeahead/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "dependencies": { + "char-regex": "^2.0.0", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length/node_modules/char-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/char-regex/-/char-regex-2.0.1.tgz", + "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-watch-typeahead/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "dependencies": { + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.5.1", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/jest-watcher/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "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.npmmirror.com/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "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/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpath": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/jsonpath/-/jsonpath-1.1.1.tgz", + "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "dependencies": { + "esprima": "1.2.2", + "static-eval": "2.0.2", + "underscore": "1.12.1" + } + }, + "node_modules/jsonpath/node_modules/esprima": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/esprima/-/esprima-1.2.2.tgz", + "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmmirror.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmmirror.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmmirror.com/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/launch-editor": { + "version": "2.6.1", + "resolved": "https://registry.npmmirror.com/launch-editor/-/launch-editor-2.6.1.tgz", + "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmmirror.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmmirror.com/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", + "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", + "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.2.tgz", + "integrity": "sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-remove-position": "^5.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.1.0", + "resolved": "https://registry.npmmirror.com/mdast-util-to-hast/-/mdast-util-to-hast-13.1.0.tgz", + "integrity": "sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", + "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmmirror.com/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", + "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", + "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", + "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.8.1", + "resolved": "https://registry.npmmirror.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.1.tgz", + "integrity": "sha512-/1HDlyFRxWIZPI1ZpgqlZ8jMw/1Dp/dl3P0L1jtZ+zVcHqwPhGwaJwKL00WVgfnBy6PWCde9W65or7IIETImuA==", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmmirror.com/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmmirror.com/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmmirror.com/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + } + }, + "node_modules/nwsapi": { + "version": "2.2.7", + "resolved": "https://registry.npmmirror.com/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmmirror.com/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.entries": { + "version": "1.1.7", + "resolved": "https://registry.npmmirror.com/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmmirror.com/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.7", + "resolved": "https://registry.npmmirror.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.7.tgz", + "integrity": "sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g==", + "dependencies": { + "array.prototype.reduce": "^1.0.6", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "safe-array-concat": "^1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/object.groupby": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/object.groupby/-/object.groupby-1.0.2.tgz", + "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", + "dependencies": { + "array.prototype.filter": "^1.0.3", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0" + } + }, + "node_modules/object.hasown": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "dependencies": { + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmmirror.com/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmmirror.com/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmmirror.com/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/parse-entities/-/parse-entities-4.0.1.tgz", + "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmmirror.com/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmmirror.com/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmmirror.com/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.35", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-attribute-case-insensitive": { + "version": "5.0.2", + "resolved": "https://registry.npmmirror.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", + "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-browser-comments": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", + "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "browserslist": ">=4", + "postcss": ">=8" + } + }, + "node_modules/postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmmirror.com/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "dependencies": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-clamp": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/postcss-clamp/-/postcss-clamp-4.1.0.tgz", + "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": ">=7.6.0" + }, + "peerDependencies": { + "postcss": "^8.4.6" + } + }, + "node_modules/postcss-color-functional-notation": { + "version": "4.2.4", + "resolved": "https://registry.npmmirror.com/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", + "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-color-hex-alpha": { + "version": "8.0.4", + "resolved": "https://registry.npmmirror.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", + "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-color-rebeccapurple": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", + "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-colormin": { + "version": "5.3.1", + "resolved": "https://registry.npmmirror.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz", + "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-convert-values": { + "version": "5.1.3", + "resolved": "https://registry.npmmirror.com/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", + "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-custom-media": { + "version": "8.0.2", + "resolved": "https://registry.npmmirror.com/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", + "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/postcss-custom-properties": { + "version": "12.1.11", + "resolved": "https://registry.npmmirror.com/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", + "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-custom-selectors": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", + "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, + "node_modules/postcss-dir-pseudo-class": { + "version": "6.0.5", + "resolved": "https://registry.npmmirror.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", + "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-discard-comments": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", + "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-double-position-gradients": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", + "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-env-function": { + "version": "4.0.6", + "resolved": "https://registry.npmmirror.com/postcss-env-function/-/postcss-env-function-4.0.6.tgz", + "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-flexbugs-fixes": { + "version": "5.0.2", + "resolved": "https://registry.npmmirror.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", + "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", + "peerDependencies": { + "postcss": "^8.1.4" + } + }, + "node_modules/postcss-focus-visible": { + "version": "6.0.4", + "resolved": "https://registry.npmmirror.com/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-focus-within": { + "version": "5.0.4", + "resolved": "https://registry.npmmirror.com/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.9" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-font-variant": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", + "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-gap-properties": { + "version": "3.0.5", + "resolved": "https://registry.npmmirror.com/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", + "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-image-set-function": { + "version": "4.0.7", + "resolved": "https://registry.npmmirror.com/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", + "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmmirror.com/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-initial": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/postcss-initial/-/postcss-initial-4.0.1.tgz", + "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-lab-function": { + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", + "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", + "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "engines": { + "node": ">=14" + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.4.1", + "resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/postcss-loader": { + "version": "6.2.1", + "resolved": "https://registry.npmmirror.com/postcss-loader/-/postcss-loader-6.2.1.tgz", + "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", + "dependencies": { + "cosmiconfig": "^7.0.0", + "klona": "^2.0.5", + "semver": "^7.3.5" + }, + "engines": { + "node": ">= 12.13.0" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-logical": { + "version": "5.0.4", + "resolved": "https://registry.npmmirror.com/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/postcss-media-minmax": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", + "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "5.1.7", + "resolved": "https://registry.npmmirror.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", + "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-merge-rules": { + "version": "5.1.4", + "resolved": "https://registry.npmmirror.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", + "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "dependencies": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-params": { + "version": "5.1.4", + "resolved": "https://registry.npmmirror.com/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", + "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "dependencies": { + "browserslist": "^4.21.4", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", + "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.4", + "resolved": "https://registry.npmmirror.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz", + "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz", + "integrity": "sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nesting": { + "version": "10.2.0", + "resolved": "https://registry.npmmirror.com/postcss-nesting/-/postcss-nesting-10.2.0.tgz", + "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", + "dependencies": { + "@csstools/selector-specificity": "^2.0.0", + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-normalize": { + "version": "10.0.1", + "resolved": "https://registry.npmmirror.com/postcss-normalize/-/postcss-normalize-10.0.1.tgz", + "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", + "dependencies": { + "@csstools/normalize.css": "*", + "postcss-browser-comments": "^4", + "sanitize.css": "*" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "browserslist": ">= 4", + "postcss": ">= 8" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", + "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", + "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-string": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", + "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "dependencies": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-opacity-percentage": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", + "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-ordered-values": { + "version": "5.1.3", + "resolved": "https://registry.npmmirror.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", + "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "dependencies": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-overflow-shorthand": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", + "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-page-break": { + "version": "3.0.4", + "resolved": "https://registry.npmmirror.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz", + "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", + "peerDependencies": { + "postcss": "^8" + } + }, + "node_modules/postcss-place": { + "version": "7.0.5", + "resolved": "https://registry.npmmirror.com/postcss-place/-/postcss-place-7.0.5.tgz", + "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-preset-env": { + "version": "7.8.3", + "resolved": "https://registry.npmmirror.com/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", + "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", + "dependencies": { + "@csstools/postcss-cascade-layers": "^1.1.1", + "@csstools/postcss-color-function": "^1.1.1", + "@csstools/postcss-font-format-keywords": "^1.0.1", + "@csstools/postcss-hwb-function": "^1.0.2", + "@csstools/postcss-ic-unit": "^1.0.1", + "@csstools/postcss-is-pseudo-class": "^2.0.7", + "@csstools/postcss-nested-calc": "^1.0.0", + "@csstools/postcss-normalize-display-values": "^1.0.1", + "@csstools/postcss-oklab-function": "^1.1.1", + "@csstools/postcss-progressive-custom-properties": "^1.3.0", + "@csstools/postcss-stepped-value-functions": "^1.0.1", + "@csstools/postcss-text-decoration-shorthand": "^1.0.0", + "@csstools/postcss-trigonometric-functions": "^1.0.2", + "@csstools/postcss-unset-value": "^1.0.2", + "autoprefixer": "^10.4.13", + "browserslist": "^4.21.4", + "css-blank-pseudo": "^3.0.3", + "css-has-pseudo": "^3.0.4", + "css-prefers-color-scheme": "^6.0.3", + "cssdb": "^7.1.0", + "postcss-attribute-case-insensitive": "^5.0.2", + "postcss-clamp": "^4.1.0", + "postcss-color-functional-notation": "^4.2.4", + "postcss-color-hex-alpha": "^8.0.4", + "postcss-color-rebeccapurple": "^7.1.1", + "postcss-custom-media": "^8.0.2", + "postcss-custom-properties": "^12.1.10", + "postcss-custom-selectors": "^6.0.3", + "postcss-dir-pseudo-class": "^6.0.5", + "postcss-double-position-gradients": "^3.1.2", + "postcss-env-function": "^4.0.6", + "postcss-focus-visible": "^6.0.4", + "postcss-focus-within": "^5.0.4", + "postcss-font-variant": "^5.0.0", + "postcss-gap-properties": "^3.0.5", + "postcss-image-set-function": "^4.0.7", + "postcss-initial": "^4.0.1", + "postcss-lab-function": "^4.2.1", + "postcss-logical": "^5.0.4", + "postcss-media-minmax": "^5.0.0", + "postcss-nesting": "^10.2.0", + "postcss-opacity-percentage": "^1.1.2", + "postcss-overflow-shorthand": "^3.0.4", + "postcss-page-break": "^3.0.4", + "postcss-place": "^7.0.5", + "postcss-pseudo-class-any-link": "^7.1.6", + "postcss-replace-overflow-wrap": "^4.0.0", + "postcss-selector-not": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-pseudo-class-any-link": { + "version": "7.1.6", + "resolved": "https://registry.npmmirror.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", + "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", + "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-replace-overflow-wrap": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", + "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", + "peerDependencies": { + "postcss": "^8.0.3" + } + }, + "node_modules/postcss-selector-not": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", + "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.15", + "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", + "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/postcss-svgo/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/postcss-svgo/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/postcss-svgo/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-svgo/node_modules/svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmmirror.com/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmmirror.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmmirror.com/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmmirror.com/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmmirror.com/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmmirror.com/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmmirror.com/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmmirror.com/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "node_modules/raf": { + "version": "3.4.1", + "resolved": "https://registry.npmmirror.com/raf/-/raf-3.4.1.tgz", + "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "dependencies": { + "performance-now": "^2.1.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmmirror.com/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-app-polyfill": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", + "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", + "dependencies": { + "core-js": "^3.19.2", + "object-assign": "^4.1.1", + "promise": "^8.1.0", + "raf": "^3.4.1", + "regenerator-runtime": "^0.13.9", + "whatwg-fetch": "^3.6.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-app-polyfill/node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmmirror.com/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-dev-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/react-dev-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/react-dev-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/react-dev-utils/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/react-dev-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/loader-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/react-dev-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmmirror.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmmirror.com/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "node_modules/react-markdown": { + "version": "9.0.1", + "resolved": "https://registry.npmmirror.com/react-markdown/-/react-markdown-9.0.1.tgz", + "integrity": "sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg==", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "html-url-attributes": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=18", + "react": ">=18" + } + }, + "node_modules/react-refresh": { + "version": "0.11.0", + "resolved": "https://registry.npmmirror.com/react-refresh/-/react-refresh-0.11.0.tgz", + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-scripts": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/react-scripts/-/react-scripts-5.0.1.tgz", + "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", + "dependencies": { + "@babel/core": "^7.16.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", + "@svgr/webpack": "^5.5.0", + "babel-jest": "^27.4.2", + "babel-loader": "^8.2.3", + "babel-plugin-named-asset-import": "^0.3.8", + "babel-preset-react-app": "^10.0.1", + "bfj": "^7.0.2", + "browserslist": "^4.18.1", + "camelcase": "^6.2.1", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "css-loader": "^6.5.1", + "css-minimizer-webpack-plugin": "^3.2.0", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "eslint": "^8.3.0", + "eslint-config-react-app": "^7.0.1", + "eslint-webpack-plugin": "^3.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^10.0.0", + "html-webpack-plugin": "^5.5.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.4.3", + "jest-resolve": "^27.4.2", + "jest-watch-typeahead": "^1.0.0", + "mini-css-extract-plugin": "^2.4.5", + "postcss": "^8.4.4", + "postcss-flexbugs-fixes": "^5.0.2", + "postcss-loader": "^6.2.1", + "postcss-normalize": "^10.0.1", + "postcss-preset-env": "^7.0.1", + "prompts": "^2.4.2", + "react-app-polyfill": "^3.0.0", + "react-dev-utils": "^12.0.1", + "react-refresh": "^0.11.0", + "resolve": "^1.20.0", + "resolve-url-loader": "^4.0.0", + "sass-loader": "^12.3.0", + "semver": "^7.3.5", + "source-map-loader": "^3.0.0", + "style-loader": "^3.3.1", + "tailwindcss": "^3.0.2", + "terser-webpack-plugin": "^5.2.5", + "webpack": "^5.64.4", + "webpack-dev-server": "^4.6.0", + "webpack-manifest-plugin": "^4.0.2", + "workbox-webpack-plugin": "^6.4.1" + }, + "bin": { + "react-scripts": "bin/react-scripts.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + }, + "peerDependencies": { + "react": ">= 16", + "typescript": "^3.2.1 || ^4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", + "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0", + "get-intrinsic": "^1.2.3", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmmirror.com/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmmirror.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmmirror.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regex-parser": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/regex-parser/-/regex-parser-2.3.0.tgz", + "integrity": "sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmmirror.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmmirror.com/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmmirror.com/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmmirror.com/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmmirror.com/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.0", + "resolved": "https://registry.npmmirror.com/remark-rehype/-/remark-rehype-11.1.0.tgz", + "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-url-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", + "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^7.0.35", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=8.9" + }, + "peerDependencies": { + "rework": "1.0.1", + "rework-visit": "1.0.0" + }, + "peerDependenciesMeta": { + "rework": { + "optional": true + }, + "rework-visit": { + "optional": true + } + } + }, + "node_modules/resolve-url-loader/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/resolve-url-loader/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" + }, + "node_modules/resolve-url-loader/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve.exports": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmmirror.com/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rollup": { + "version": "2.79.1", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-2.79.1.tgz", + "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmmirror.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup-plugin-terser/node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/rollup-plugin-terser/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sanitize.css": { + "version": "13.0.0", + "resolved": "https://registry.npmmirror.com/sanitize.css/-/sanitize.css-13.0.0.tgz", + "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" + }, + "node_modules/sass-loader": { + "version": "12.6.0", + "resolved": "https://registry.npmmirror.com/sass-loader/-/sass-loader-12.6.0.tgz", + "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", + "dependencies": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 12.13.0" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + } + } + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmmirror.com/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmmirror.com/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmmirror.com/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmmirror.com/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmmirror.com/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/socket.io-client": { + "version": "4.7.4", + "resolved": "https://registry.npmmirror.com/socket.io-client/-/socket.io-client-4.7.4.tgz", + "integrity": "sha512-wh+OkeF0rAVCrABWQBaEjLfb7DVPotMbu0cgWgyR0v6eA4EoVnAwcIeIbcdTE3GT/H3kbdLl7OoH2+asoDRIIg==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmmirror.com/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmmirror.com/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmmirror.com/source-map-loader/-/source-map-loader-3.0.2.tgz", + "integrity": "sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==", + "dependencies": { + "abab": "^2.0.5", + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "deprecated": "Please use @jridgewell/sourcemap-codec instead" + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmmirror.com/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "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.npmmirror.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmmirror.com/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" + }, + "node_modules/static-eval": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/static-eval/-/static-eval-2.0.2.tgz", + "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "dependencies": { + "escodegen": "^1.8.1" + } + }, + "node_modules/static-eval/node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmmirror.com/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/static-eval/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/static-eval/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmmirror.com/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "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/static-eval/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/static-eval/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-eval/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", + "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-natural-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz", + "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.10", + "resolved": "https://registry.npmmirror.com/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", + "side-channel": "^1.0.4" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmmirror.com/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmmirror.com/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/strip-comments/-/strip-comments-2.0.1.tgz", + "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + } + }, + "node_modules/style-loader": { + "version": "3.3.4", + "resolved": "https://registry.npmmirror.com/style-loader/-/style-loader-3.3.4.tgz", + "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "engines": { + "node": ">= 12.13.0" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/style-to-object": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/style-to-object/-/style-to-object-1.0.6.tgz", + "integrity": "sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==", + "dependencies": { + "inline-style-parser": "0.2.3" + } + }, + "node_modules/stylehacks": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/stylehacks/-/stylehacks-5.1.1.tgz", + "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "dependencies": { + "browserslist": "^4.21.4", + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmmirror.com/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmmirror.com/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + }, + "node_modules/svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmmirror.com/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "dependencies": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/svgo/node_modules/css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "node_modules/svgo/node_modules/css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmmirror.com/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/svgo/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/svgo/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmmirror.com/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/svgo/node_modules/domutils/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "node_modules/svgo/node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmmirror.com/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "node_modules/tailwindcss": { + "version": "3.4.1", + "resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.1.tgz", + "integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.19.1", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmmirror.com/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/temp-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmmirror.com/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/terser": { + "version": "5.29.1", + "resolved": "https://registry.npmmirror.com/terser/-/terser-5.29.1.tgz", + "integrity": "sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==", + "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.npmmirror.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "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" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/throat": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/throat/-/throat-6.0.2.tgz", + "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmmirror.com/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmmirror.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmmirror.com/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmmirror.com/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmmirror.com/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmmirror.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "node_modules/underscore": { + "version": "1.12.1", + "resolved": "https://registry.npmmirror.com/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unified": { + "version": "11.0.4", + "resolved": "https://registry.npmmirror.com/unified/-/unified-11.0.4.tgz", + "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmmirror.com/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + } + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmmirror.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmmirror.com/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-vitals": { + "version": "2.1.4", + "resolved": "https://registry.npmmirror.com/web-vitals/-/web-vitals-2.1.4.tgz", + "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==" + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "engines": { + "node": ">=10.4" + } + }, + "node_modules/webpack": { + "version": "5.90.3", + "resolved": "https://registry.npmmirror.com/webpack/-/webpack-5.90.3.tgz", + "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.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.9", + "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.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.3", + "resolved": "https://registry.npmmirror.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.15.1", + "resolved": "https://registry.npmmirror.com/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", + "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmmirror.com/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "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 + } + } + }, + "node_modules/webpack-manifest-plugin": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", + "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", + "dependencies": { + "tapable": "^2.0.0", + "webpack-sources": "^2.2.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "peerDependencies": { + "webpack": "^4.44.2 || ^5.47.0" + } + }, + "node_modules/webpack-manifest-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-2.3.1.tgz", + "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", + "dependencies": { + "source-list-map": "^2.0.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmmirror.com/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmmirror.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmmirror.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmmirror.com/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-background-sync": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", + "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-broadcast-update": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", + "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-build": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-build/-/workbox-build-6.6.0.tgz", + "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "rollup-plugin-terser": "^7.0.0", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "6.6.0", + "workbox-broadcast-update": "6.6.0", + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-google-analytics": "6.6.0", + "workbox-navigation-preload": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-range-requests": "6.6.0", + "workbox-recipes": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0", + "workbox-streams": "6.6.0", + "workbox-sw": "6.6.0", + "workbox-window": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmmirror.com/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/workbox-build/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "node_modules/workbox-build/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/workbox-build/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/workbox-build/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/workbox-build/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/workbox-build/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "node_modules/workbox-build/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/workbox-cacheable-response": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", + "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", + "deprecated": "workbox-background-sync@6.6.0", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-core": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-core/-/workbox-core-6.6.0.tgz", + "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==" + }, + "node_modules/workbox-expiration": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-expiration/-/workbox-expiration-6.6.0.tgz", + "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-google-analytics": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", + "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", + "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", + "dependencies": { + "workbox-background-sync": "6.6.0", + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-navigation-preload": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", + "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-precaching": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-precaching/-/workbox-precaching-6.6.0.tgz", + "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-range-requests": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", + "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-recipes": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-recipes/-/workbox-recipes-6.6.0.tgz", + "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", + "dependencies": { + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-routing": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-routing/-/workbox-routing-6.6.0.tgz", + "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-strategies": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-strategies/-/workbox-strategies-6.6.0.tgz", + "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-streams": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-streams/-/workbox-streams-6.6.0.tgz", + "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0" + } + }, + "node_modules/workbox-sw": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-sw/-/workbox-sw-6.6.0.tgz", + "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==" + }, + "node_modules/workbox-webpack-plugin": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", + "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", + "dependencies": { + "fast-json-stable-stringify": "^2.1.0", + "pretty-bytes": "^5.4.1", + "upath": "^1.2.0", + "webpack-sources": "^1.4.3", + "workbox-build": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "webpack": "^4.4.0 || ^5.9.0" + } + }, + "node_modules/workbox-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-webpack-plugin/node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/workbox-window": { + "version": "6.6.0", + "resolved": "https://registry.npmmirror.com/workbox-window/-/workbox-window-6.6.0.tgz", + "integrity": "sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw==", + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.6.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "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.9", + "resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "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.npmmirror.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmmirror.com/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/im_server/frontend/package.json b/im_server/frontend/package.json new file mode 100644 index 0000000..7fd3728 --- /dev/null +++ b/im_server/frontend/package.json @@ -0,0 +1,40 @@ +{ + "name": "frontend", + "version": "0.1.0", + "private": true, + "dependencies": { + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-markdown": "^9.0.1", + "react-scripts": "5.0.1", + "socket.io-client": "^4.7.4", + "web-vitals": "^2.1.4" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/im_server/frontend/public/favicon.ico b/im_server/frontend/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a11777cc471a4344702741ab1c8a588998b1311a GIT binary patch literal 3870 zcma);c{J4h9>;%nil|2-o+rCuEF-(I%-F}ijC~o(k~HKAkr0)!FCj~d>`RtpD?8b; zXOC1OD!V*IsqUwzbMF1)-gEDD=A573Z-&G7^LoAC9|WO7Xc0Cx1g^Zu0u_SjAPB<A z`RksU20=ur5rmib*S!+l%h4eS4)^Q+0X>3vGa^W|sj)80f#V0@M_CAZTIO(t--xg= z!sii`1giyH7EKL_+Wi0ab<)&E_0KD!3Rp2^HNB*K2@PHCs4PWSA32*-^7d{9nH2_E zmC{C*N*)(vEF1_aMamw2A{ZH5aIDqiabnFdJ|y0%aS|64E$`s2ccV~3lR!u<){eS` z#^Mx6o(iP1Ix%<jZ{9b!^*}EvPeMb_W#+3mPDk@<s^Oh#VM&a2^K;|820}`)peR}+ zJXt@j)V#7+Js?u;Lb#g$HH)e~Ro^hvl6KSLHq)Y3adj<OOD7?;gwee^gNzCxwD?IA z8?*}E@b*IiVPUPv3?XqzLRv|{4)GKGzjS`)#ukL7W&K6BHn&1}P(skc69cJ?5^C+V z@yyqLJg;V2Ul%gZ*?2WiB%bNfz1}F^UeTpW^N?dSY@NL3zDD+Tzk$Cg_=cj!M^ot0 zu%qYEoTU9K@kMP2H52_@<2On}lNX!oZ(oWk^?eSfXAa3M8S?8tzISV2V&9A+_-47Y z>4dv`t@!&Za-K@mTm#vadc{0aWDV*_%EiGK7qMC_(`exc>-$Gb9~W!w_^{*pYRm~G zBN{nA<l~YIv(*f3@JAyAZDXwp4d;meFk*lN;rx5VQze6aK!n?W9`Uc4pES2K&V3BC zkTJK{PcIXdQ?hM;i7~K{wRSeU-w9_32aC}+7nN6r5o<=I@CyjQAS~;jsb7p#@eUT2 zkh1M~1>;cm^w$VWg1O^^<6vY`1XCD|s_zv*g*5&V#wv&s#h$xlUilPe4U@I&UXZbL z0)%9Uj&@yd03n;!7do+bfixH^FeZ-Ema}s;DQX2gY+7g0s(9;`8GyvPY1*vxiF&|w z>!vA~GA<~JUqH}d;DfBSi^IT*#lrzXl$fNpq0_T1tA+`A$1?(gLb?e#0>UELvljtQ zK+*74m0jn&)5yk8mLBv;=@}c{t0ztT<<S2g5CX`xuBQVwYJOMIsv7paOX6ypYJL$a zJ|Vy}#?V4i+kjXzBq)LcuJEA=z^Z2W4WQ1U@0}*!;_q<!3_ls8PhMM3ii*Ci+cF6= zF!@E<x#%Yvb!P0>v;Avck$S6D`Z)^c0(jiwKhQsn|LDRY&w(Fmi91I7H6S;b0XM{e zXp0~(T@k_r-!jkLwd1_Vre^v$G4|kh4}=Gi?$AaJ)3I+^m|Zyj#*?Kp@w(lQdJZf4 z#|IJW5z+S^e9@(6hW6N~{pj8|NO*>1)E=%?nNUAkmv~OY&ZV<PHdt%yO<W_%O|c-T zC%nAvgv?#h>;m-%?pQ_11)hAr0oAwILrlsGawpxx4D43J&K=n+p3WLnlDsQ$b(9+4 z?mO^hmV^F8MV{4<aA#E-8o{y-by8hR1>Lx>(Q=aHhQ1){0d*(e&s%G=i5rq3;t{JC zmgbn5Nkl)t@fPH$v;af26lyhH!k+#}_&aBK4baYPbZy$5aFx4}ka<ge$nBI}>&qxl z$=Rh$W;U)>-=S-0=?7FH9dUAd2(q#4TCAHky!$^~;Dz^j|8_wuKc*YzfdA<NJp8x7 z`_}_7!m44CG`<6nLk0r3A}8e>ht@Q&ror?91Dm!N03=4=O!a)I*0q~p0g$Fm$pmr$ zb;wD;STDIi$@M%y1>p&_>%?UP($15gou_ue1u0!4(%81;qcIW8NyxFEvXpiJ|H4wz z*mFT(qVx1FKufG11hByuX%lPk4t#WZ{>8ka2efjY`~;AL6vWyQKpJun2nRiZYDij$ zP>4jQXPaP$UC$yIVgGa)jDV;F0l^n(V=HMRB5)20V7&r$<L^Phf(W29K>jmk{UUIe zVjKroK}JAbD>B`2cwNQ&GDLx8{pg`7hbA~grk|W6LgiZ`8y`{Iq0i>t!3p2}MS6S+ zO_ruKyAElt)rdS>CtF7j{&6rP-#c=7evGMt7B6`7HG|-(WL`bDUAjyn+k$mx$C<FS ztTQ#rrhaxTX7@2TN#`pson<p6thk-4?N)^;_(Up!_V=f}<~kR)zD%o0iiqseIMZqh zGU`kZGbN)qs{;AuZP?~%PajDo&b&7)!V!+|VO<ediN}{)OvR~sQ<ZYe%O|)8-DTKw zTXmYP$VLa(Y>H;q2Dz4x;cPP$hW=`pFfLO)!jaCL@V2+F)So3}vg|%O*^T1j>C2lx zsURO-zIJC$^$g2byVbRIo^w>UxK}74^TqUiRR#7s_X$e)$6iYG1(PcW7un-va-S&u zHk9-6Zn&>T==A)lM^D~bk{&rFzCi35>UR!ZjQkdSiNX*-;l4z9j*7|q`TBl~Au`5& z+c)*8?#-tgUR$Zd%Q3bs96w6k7q@#tUn`5rj+r@_sAVVLqco|6O{ILX&U-&-cbVa3 zY?ngHR@%l{;`ri%H*0EhBWrGjv!LE4db?HEWb5mu*t@{kv|XwK8?npOshmzf=vZA@ zVSN9sL~!sn?r(AK)Q7Jk2(|M67Uy3I{eRy<vjA)m;~)jV3DFGzL)eNbs@Sy80roD> z_l&Y@A>;vjkWN5I2xvFFTLX0i+`{qz7C_@bo`ZUzDugfq4+>a3?1v%)O+YTd6@Ul7 zAfLfm=nhZ`)P~&v90$&UcF+yXm9sq!qCx3^9gzIcO|Y(js^Fj)Rvq>nQAHI92ap=P z10A4@prk+<s7nQxb0&o?puD0BStB$NLIA{pVg<pW;2=HJ11ZpVkRkF89w0s#3ef?( zka>AGWCb`2)dQYFuR$|H6iDE8p}9a?#nV2}LBCoCf(Xi2@szia7#gY>b|l!-U`c}@ zLdhvQjc!BdLJvYvzzzngnw51yRYCqh4}$oRCy-z|v3Hc*d|?^Wj=l~18*E~*cR_kU z{XsxM1i{V*4GujHQ3DBpl2w4FgFR48Nma@HPgnyKoIEY-MqmMeY=I<%oG~l!f<+FN z1ZY^;10j4M4<Vo=b&OyEfF!Y);yDCJas8bbVhK~blk}<IGME~h)6n~gdmqP>#HYXP zw5eJpA_y(>uLQ~OucgxDLuf}fVs272FaMxhn4xnDGIyLXnw>Xsd^J8XhcWIwIoQ9} z%FoSJTAGW(SRGwJwb=@pY7r$uQRK3Zd~XbxU)ts!4XsJrCycrWSI?e!IqwqIR8+Jh zlRjZ`UO1I!BtJR_2~7AbkbSm%XQqxEPkz6BTGWx8e}nQ=w7bZ|eVP4?*Tb!$(R)iC z9)&%bS*u(lXqzitAN)Oo=&Ytn>%Hzjc<5liuPi>zC_nw;Z0AE3Y$Jao_Q90R-gl~5 z_xAb2J%eArrC1CN4G$}-zVvCqF1;H;abAu6G*+PDHSYFx@Tdbfox*uEd3}BUyYY-l zTfEsOqsi#f9^FoLO;ChK<554qkri&Av~SIM*{fEYRE?vH7pTAOmu2pz3X?Wn*!ROX ztd54huAk&mFBemMooL33RV-*1f0Q3_(7hl$<#*|WF9P!;r;4_+X~k~uKEqdzZ$5Al zV63X<s4EnR@itBNL^suG_KHV!zgrw6&Bq&`dNv>N<k2!6lBSoSAvQBw$a}{Sg*d5f zJqeF6lxH}v-(s5jl(8V8Bv*((#aw(*iLTd8#?8FnMLG#}AorDTkK*%$ni#S{e-*jA zjy$_xALPmR?$A)F?XdsKy|!Ue+lIR5=csS!ZPu7h{Nc+Sd%?*WHR`S5ByDdhQAsNO zeyx0!D+fx-a_t<57fQ^<7*WTVDog0}WA0F2_h++_I?f`i|C>@)j$FN#cCD;ek1R#l zv%pGrhB~KWgoCj%GT?%{@@o(AJGt*PG#l3i>lhmb_twKH^EYvacVY-6bsCl5*^~L0 zonm@lk2UvvTKr2RS%}T>^~EYqdL1q4nD%0n&Xqr^cK^`J5W;lRRB^R-O<zOhVxo?8 zb#fjP=~|*nH<rZsU&F20QcP*BR|)$r#sFFtYi6hV=2&f<YJ%JC0IAdIRdHjO(;S%3 zC;L{EqcHO368@u|<ql>8b&HENO||mo0xaD+S=I8RTlIfVgqN@SXDr2&-)we--K7w= zJVU8?Z+7k9dy;s;^gDkQa`0nz6N{T?(A&Iz)2!DEecLyRa&FI!id#5Z7B*O2=PsR0 zEvc|8{NS^)!d)MDX(97Xw}m&kEO@5jqRaDZ!+%`wYOI<23q|&js`&o4xvjP7D_xv@ z5hEwpsp{HezI9!~6O{~)lLR@oF7?J7i>1|5a~UuoN=q&6N}EJPV_GD`&M*v8Y`^2j zKII*d_@Fi$+i*YEW+Hbz<W=zs^XxM$!;??OHDS{MUEdOi9{rF;;#a0RO>n{iQk~yP z>7N{S4)r*!NwQ`(qcN#8SRQsNK6>{)X12nbF`*7#ecO7I)Q$uZsV+xS4E7aUn+U(K baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@ literal 0 HcmV?d00001 diff --git a/im_server/frontend/public/index.html b/im_server/frontend/public/index.html new file mode 100644 index 0000000..aa069f2 --- /dev/null +++ b/im_server/frontend/public/index.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="theme-color" content="#000000" /> + <meta + name="description" + content="Web site created using create-react-app" + /> + <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> + <!-- + manifest.json provides metadata used when your web app is installed on a + user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ + --> + <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> + <!-- + Notice the use of %PUBLIC_URL% in the tags above. + It will be replaced with the URL of the `public` folder during the build. + Only files inside the `public` folder can be referenced from the HTML. + + Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will + work correctly both with client-side routing and a non-root public URL. + Learn how to configure a non-root public URL by running `npm run build`. + --> + <title>React App + + + +
+ + + diff --git a/im_server/frontend/public/logo192.png b/im_server/frontend/public/logo192.png new file mode 100644 index 0000000000000000000000000000000000000000..fc44b0a3796c0e0a64c3d858ca038bd4570465d9 GIT binary patch literal 5347 zcmZWtbyO6NvR-oO24RV%BvuJ&=?+<7=`LvyB&A_#M7mSDYw1v6DJkiYl9XjT!%$dLEBTQ8R9|wd3008in6lFF3GV-6mLi?MoP_y~}QUnaDCHI#t z7w^m$@6DI)|C8_jrT?q=f8D?0AM?L)Z}xAo^e^W>t$*Y0KlT5=@bBjT9kxb%-KNdk zeOS1tKO#ChhG7%{ApNBzE2ZVNcxbrin#E1TiAw#BlUhXllzhN$qWez5l;h+t^q#Eav8PhR2|T}y5kkflaK`ba-eoE+Z2q@o6P$)=&` z+(8}+-McnNO>e#$Rr{32ngsZIAX>GH??tqgwUuUz6kjns|LjsB37zUEWd|(&O!)DY zQLrq%Y>)Y8G`yYbYCx&aVHi@-vZ3|ebG!f$sTQqMgi0hWRJ^Wc+Ibv!udh_r%2|U) zPi|E^PK?UE!>_4`f`1k4hqqj_$+d!EB_#IYt;f9)fBOumGNyglU(ofY`yHq4Y?B%- zp&G!MRY<~ajTgIHErMe(Z8JG*;D-PJhd@RX@QatggM7+G(Lz8eZ;73)72Hfx5KDOE zkT(m}i2;@X2AT5fW?qVp?@WgN$aT+f_6eo?IsLh;jscNRp|8H}Z9p_UBO^SJXpZew zEK8fz|0Th%(Wr|KZBGTM4yxkA5CFdAj8=QSrT$fKW#tweUFqr0TZ9D~a5lF{)%-tTGMK^2tz(y2v$i%V8XAxIywrZCp=)83p(zIk6@S5AWl|Oa2hF`~~^W zI;KeOSkw1O#TiQ8;U7OPXjZM|KrnN}9arP)m0v$c|L)lF`j_rpG(zW1Qjv$=^|p*f z>)Na{D&>n`jOWMwB^TM}slgTEcjxTlUby89j1)|6ydRfWERn3|7Zd2&e7?!K&5G$x z`5U3uFtn4~SZq|LjFVrz$3iln-+ucY4q$BC{CSm7Xe5c1J<=%Oagztj{ifpaZk_bQ z9Sb-LaQMKp-qJA*bP6DzgE3`}*i1o3GKmo2pn@dj0;He}F=BgINo};6gQF8!n0ULZ zL>kC0nPSFzlcB7p41doao2F7%6IUTi_+!L`MM4o*#Y#0v~WiO8uSeAUNp=vA2KaR&=jNR2iVwG>7t%sG2x_~yXzY)7K& zk3p+O0AFZ1eu^T3s};B%6TpJ6h-Y%B^*zT&SN7C=N;g|#dGIVMSOru3iv^SvO>h4M=t-N1GSLLDqVTcgurco6)3&XpU!FP6Hlrmj}f$ zp95;b)>M~`kxuZF3r~a!rMf4|&1=uMG$;h^g=Kl;H&Np-(pFT9FF@++MMEx3RBsK?AU0fPk-#mdR)Wdkj)`>ZMl#^<80kM87VvsI3r_c@_vX=fdQ`_9-d(xiI z4K;1y1TiPj_RPh*SpDI7U~^QQ?%0&!$Sh#?x_@;ag)P}ZkAik{_WPB4rHyW#%>|Gs zdbhyt=qQPA7`?h2_8T;-E6HI#im9K>au*(j4;kzwMSLgo6u*}-K`$_Gzgu&XE)udQ zmQ72^eZd|vzI)~!20JV-v-T|<4@7ruqrj|o4=JJPlybwMg;M$Ud7>h6g()CT@wXm` zbq=A(t;RJ^{Xxi*Ff~!|3!-l_PS{AyNAU~t{h;(N(PXMEf^R(B+ZVX3 z8y0;0A8hJYp@g+c*`>eTA|3Tgv9U8#BDTO9@a@gVMDxr(fVaEqL1tl?md{v^j8aUv zm&%PX4^|rX|?E4^CkplWWNv*OKM>DxPa z!RJ)U^0-WJMi)Ksc!^ixOtw^egoAZZ2Cg;X7(5xZG7yL_;UJ#yp*ZD-;I^Z9qkP`} zwCTs0*%rIVF1sgLervtnUo&brwz?6?PXRuOCS*JI-WL6GKy7-~yi0giTEMmDs_-UX zo=+nFrW_EfTg>oY72_4Z0*uG>MnXP=c0VpT&*|rvv1iStW;*^={rP1y?Hv+6R6bxFMkxpWkJ>m7Ba{>zc_q zEefC3jsXdyS5??Mz7IET$Kft|EMNJIv7Ny8ZOcKnzf`K5Cd)&`-fTY#W&jnV0l2vt z?Gqhic}l}mCv1yUEy$%DP}4AN;36$=7aNI^*AzV(eYGeJ(Px-j<^gSDp5dBAv2#?; zcMXv#aj>%;MiG^q^$0MSg-(uTl!xm49dH!{X0){Ew7ThWV~Gtj7h%ZD zVN-R-^7Cf0VH!8O)uUHPL2mO2tmE*cecwQv_5CzWeh)ykX8r5Hi`ehYo)d{Jnh&3p z9ndXT$OW51#H5cFKa76c<%nNkP~FU93b5h-|Cb}ScHs@4Q#|}byWg;KDMJ#|l zE=MKD*F@HDBcX@~QJH%56eh~jfPO-uKm}~t7VkHxHT;)4sd+?Wc4* z>CyR*{w@4(gnYRdFq=^(#-ytb^5ESD?x<0Skhb%Pt?npNW1m+Nv`tr9+qN<3H1f<% zZvNEqyK5FgPsQ`QIu9P0x_}wJR~^CotL|n zk?dn;tLRw9jJTur4uWoX6iMm914f0AJfB@C74a;_qRrAP4E7l890P&{v<}>_&GLrW z)klculcg`?zJO~4;BBAa=POU%aN|pmZJn2{hA!d!*lwO%YSIzv8bTJ}=nhC^n}g(ld^rn#kq9Z3)z`k9lvV>y#!F4e{5c$tnr9M{V)0m(Z< z#88vX6-AW7T2UUwW`g<;8I$Jb!R%z@rCcGT)-2k7&x9kZZT66}Ztid~6t0jKb&9mm zpa}LCb`bz`{MzpZR#E*QuBiZXI#<`5qxx=&LMr-UUf~@dRk}YI2hbMsAMWOmDzYtm zjof16D=mc`^B$+_bCG$$@R0t;e?~UkF?7<(vkb70*EQB1rfUWXh$j)R2)+dNAH5%R zEBs^?N;UMdy}V};59Gu#0$q53$}|+q7CIGg_w_WlvE}AdqoS<7DY1LWS9?TrfmcvT zaypmplwn=P4;a8-%l^e?f`OpGb}%(_mFsL&GywhyN(-VROj`4~V~9bGv%UhcA|YW% zs{;nh@aDX11y^HOFXB$a7#Sr3cEtNd4eLm@Y#fc&j)TGvbbMwze zXtekX_wJqxe4NhuW$r}cNy|L{V=t#$%SuWEW)YZTH|!iT79k#?632OFse{+BT_gau zJwQcbH{b}dzKO?^dV&3nTILYlGw{27UJ72ZN){BILd_HV_s$WfI2DC<9LIHFmtyw? zQ;?MuK7g%Ym+4e^W#5}WDLpko%jPOC=aN)3!=8)s#Rnercak&b3ESRX3z{xfKBF8L z5%CGkFmGO@x?_mPGlpEej!3!AMddChabyf~nJNZxx!D&{@xEb!TDyvqSj%Y5@A{}9 zRzoBn0?x}=krh{ok3Nn%e)#~uh;6jpezhA)ySb^b#E>73e*frBFu6IZ^D7Ii&rsiU z%jzygxT-n*joJpY4o&8UXr2s%j^Q{?e-voloX`4DQyEK+DmrZh8A$)iWL#NO9+Y@!sO2f@rI!@jN@>HOA< z?q2l{^%mY*PNx2FoX+A7X3N}(RV$B`g&N=e0uvAvEN1W^{*W?zT1i#fxuw10%~))J zjx#gxoVlXREWZf4hRkgdHx5V_S*;p-y%JtGgQ4}lnA~MBz-AFdxUxU1RIT$`sal|X zPB6sEVRjGbXIP0U+?rT|y5+ev&OMX*5C$n2SBPZr`jqzrmpVrNciR0e*Wm?fK6DY& zl(XQZ60yWXV-|Ps!A{EF;=_z(YAF=T(-MkJXUoX zI{UMQDAV2}Ya?EisdEW;@pE6dt;j0fg5oT2dxCi{wqWJ<)|SR6fxX~5CzblPGr8cb zUBVJ2CQd~3L?7yfTpLNbt)He1D>*KXI^GK%<`bq^cUq$Q@uJifG>p3LU(!H=C)aEL zenk7pVg}0{dKU}&l)Y2Y2eFMdS(JS0}oZUuVaf2+K*YFNGHB`^YGcIpnBlMhO7d4@vV zv(@N}(k#REdul8~fP+^F@ky*wt@~&|(&&meNO>rKDEnB{ykAZ}k>e@lad7to>Ao$B zz<1(L=#J*u4_LB=8w+*{KFK^u00NAmeNN7pr+Pf+N*Zl^dO{LM-hMHyP6N!~`24jd zXYP|Ze;dRXKdF2iJG$U{k=S86l@pytLx}$JFFs8e)*Vi?aVBtGJ3JZUj!~c{(rw5>vuRF$`^p!P8w1B=O!skwkO5yd4_XuG^QVF z`-r5K7(IPSiKQ2|U9+`@Js!g6sfJwAHVd|s?|mnC*q zp|B|z)(8+mxXyxQ{8Pg3F4|tdpgZZSoU4P&9I8)nHo1@)9_9u&NcT^FI)6|hsAZFk zZ+arl&@*>RXBf-OZxhZerOr&dN5LW9@gV=oGFbK*J+m#R-|e6(Loz(;g@T^*oO)0R zN`N=X46b{7yk5FZGr#5&n1!-@j@g02g|X>MOpF3#IjZ_4wg{dX+G9eqS+Es9@6nC7 zD9$NuVJI}6ZlwtUm5cCAiYv0(Yi{%eH+}t)!E^>^KxB5^L~a`4%1~5q6h>d;paC9c zTj0wTCKrhWf+F#5>EgX`sl%POl?oyCq0(w0xoL?L%)|Q7d|Hl92rUYAU#lc**I&^6p=4lNQPa0 znQ|A~i0ip@`B=FW-Q;zh?-wF;Wl5!+q3GXDu-x&}$gUO)NoO7^$BeEIrd~1Dh{Tr` z8s<(Bn@gZ(mkIGnmYh_ehXnq78QL$pNDi)|QcT*|GtS%nz1uKE+E{7jdEBp%h0}%r zD2|KmYGiPa4;md-t_m5YDz#c*oV_FqXd85d@eub?9N61QuYcb3CnVWpM(D-^|CmkL z(F}L&N7qhL2PCq)fRh}XO@U`Yn<?TNGR4L(mF7#4u29{i~@k;pLsgl({YW5`Mo+p=zZn3L*4{JU;++dG9 X@eDJUQo;Ye2mwlRs?y0|+_a0zY+Zo%Dkae}+MySoIppb75o?vUW_?)>@g{U2`ERQIXV zeY$JrWnMZ$QC<=ii4X|@0H8`si75jB(ElJb00HAB%>SlLR{!zO|C9P3zxw_U8?1d8uRZ=({Ga4shyN}3 zAK}WA(ds|``G4jA)9}Bt2Hy0+f3rV1E6b|@?hpGA=PI&r8)ah|)I2s(P5Ic*Ndhn^ z*T&j@gbCTv7+8rpYbR^Ty}1AY)YH;p!m948r#%7x^Z@_-w{pDl|1S4`EM3n_PaXvK z1JF)E3qy$qTj5Xs{jU9k=y%SQ0>8E$;x?p9ayU0bZZeo{5Z@&FKX>}s!0+^>C^D#z z>xsCPvxD3Z=dP}TTOSJhNTPyVt14VCQ9MQFN`rn!c&_p?&4<5_PGm4a;WS&1(!qKE z_H$;dDdiPQ!F_gsN`2>`X}$I=B;={R8%L~`>RyKcS$72ai$!2>d(YkciA^J0@X%G4 z4cu!%Ps~2JuJ8ex`&;Fa0NQOq_nDZ&X;^A=oc1&f#3P1(!5il>6?uK4QpEG8z0Rhu zvBJ+A9RV?z%v?!$=(vcH?*;vRs*+PPbOQ3cdPr5=tOcLqmfx@#hOqX0iN)wTTO21jH<>jpmwRIAGw7`a|sl?9y9zRBh>(_%| zF?h|P7}~RKj?HR+q|4U`CjRmV-$mLW>MScKnNXiv{vD3&2@*u)-6P@h0A`eeZ7}71 zK(w%@R<4lLt`O7fs1E)$5iGb~fPfJ?WxhY7c3Q>T-w#wT&zW522pH-B%r5v#5y^CF zcC30Se|`D2mY$hAlIULL%-PNXgbbpRHgn<&X3N9W!@BUk@9g*P5mz-YnZBb*-$zMM z7Qq}ic0mR8n{^L|=+diODdV}Q!gwr?y+2m=3HWwMq4z)DqYVg0J~^}-%7rMR@S1;9 z7GFj6K}i32X;3*$SmzB&HW{PJ55kT+EI#SsZf}bD7nW^Haf}_gXciYKX{QBxIPSx2Ma? zHQqgzZq!_{&zg{yxqv3xq8YV+`S}F6A>Gtl39_m;K4dA{pP$BW0oIXJ>jEQ!2V3A2 zdpoTxG&V=(?^q?ZTj2ZUpDUdMb)T?E$}CI>r@}PFPWD9@*%V6;4Ag>D#h>!s)=$0R zRXvdkZ%|c}ubej`jl?cS$onl9Tw52rBKT)kgyw~Xy%z62Lr%V6Y=f?2)J|bZJ5(Wx zmji`O;_B+*X@qe-#~`HFP<{8$w@z4@&`q^Q-Zk8JG3>WalhnW1cvnoVw>*R@c&|o8 zZ%w!{Z+MHeZ*OE4v*otkZqz11*s!#s^Gq>+o`8Z5 z^i-qzJLJh9!W-;SmFkR8HEZJWiXk$40i6)7 zZpr=k2lp}SasbM*Nbn3j$sn0;rUI;%EDbi7T1ZI4qL6PNNM2Y%6{LMIKW+FY_yF3) zSKQ2QSujzNMSL2r&bYs`|i2Dnn z=>}c0>a}>|uT!IiMOA~pVT~R@bGlm}Edf}Kq0?*Af6#mW9f9!}RjW7om0c9Qlp;yK z)=XQs(|6GCadQbWIhYF=rf{Y)sj%^Id-ARO0=O^Ad;Ph+ z0?$eE1xhH?{T$QI>0JP75`r)U_$#%K1^BQ8z#uciKf(C701&RyLQWBUp*Q7eyn76} z6JHpC9}R$J#(R0cDCkXoFSp;j6{x{b&0yE@P7{;pCEpKjS(+1RQy38`=&Yxo%F=3y zCPeefABp34U-s?WmU#JJw23dcC{sPPFc2#J$ZgEN%zod}J~8dLm*fx9f6SpO zn^Ww3bt9-r0XaT2a@Wpw;C23XM}7_14#%QpubrIw5aZtP+CqIFmsG4`Cm6rfxl9n5 z7=r2C-+lM2AB9X0T_`?EW&Byv&K?HS4QLoylJ|OAF z`8atBNTzJ&AQ!>sOo$?^0xj~D(;kS$`9zbEGd>f6r`NC3X`tX)sWgWUUOQ7w=$TO&*j;=u%25ay-%>3@81tGe^_z*C7pb9y*Ed^H3t$BIKH2o+olp#$q;)_ zfpjCb_^VFg5fU~K)nf*d*r@BCC>UZ!0&b?AGk_jTPXaSnCuW110wjHPPe^9R^;jo3 zwvzTl)C`Zl5}O2}3lec=hZ*$JnkW#7enKKc)(pM${_$9Hc=Sr_A9Biwe*Y=T?~1CK z6eZ9uPICjy-sMGbZl$yQmpB&`ouS8v{58__t0$JP%i3R&%QR3ianbZqDs<2#5FdN@n5bCn^ZtH992~5k(eA|8|@G9u`wdn7bnpg|@{m z^d6Y`*$Zf2Xr&|g%sai#5}Syvv(>Jnx&EM7-|Jr7!M~zdAyjt*xl;OLhvW-a%H1m0 z*x5*nb=R5u><7lyVpNAR?q@1U59 zO+)QWwL8t zyip?u_nI+K$uh{y)~}qj?(w0&=SE^8`_WMM zTybjG=999h38Yes7}-4*LJ7H)UE8{mE(6;8voE+TYY%33A>S6`G_95^5QHNTo_;Ao ztIQIZ_}49%{8|=O;isBZ?=7kfdF8_@azfoTd+hEJKWE!)$)N%HIe2cplaK`ry#=pV z0q{9w-`i0h@!R8K3GC{ivt{70IWG`EP|(1g7i_Q<>aEAT{5(yD z=!O?kq61VegV+st@XCw475j6vS)_z@efuqQgHQR1T4;|-#OLZNQJPV4k$AX1Uk8Lm z{N*b*ia=I+MB}kWpupJ~>!C@xEN#Wa7V+7{m4j8c?)ChV=D?o~sjT?0C_AQ7B-vxqX30s0I_`2$in86#`mAsT-w?j{&AL@B3$;P z31G4(lV|b}uSDCIrjk+M1R!X7s4Aabn<)zpgT}#gE|mIvV38^ODy@<&yflpCwS#fRf9ZX3lPV_?8@C5)A;T zqmouFLFk;qIs4rA=hh=GL~sCFsXHsqO6_y~*AFt939UYVBSx1s(=Kb&5;j7cSowdE;7()CC2|-i9Zz+_BIw8#ll~-tyH?F3{%`QCsYa*b#s*9iCc`1P1oC26?`g<9))EJ3%xz+O!B3 zZ7$j~To)C@PquR>a1+Dh>-a%IvH_Y7^ys|4o?E%3`I&ADXfC8++hAdZfzIT#%C+Jz z1lU~K_vAm0m8Qk}K$F>|>RPK%<1SI0(G+8q~H zAsjezyP+u!Se4q3GW)`h`NPSRlMoBjCzNPesWJwVTY!o@G8=(6I%4XHGaSiS3MEBK zhgGFv6Jc>L$4jVE!I?TQuwvz_%CyO!bLh94nqK11C2W$*aa2ueGopG8DnBICVUORP zgytv#)49fVXDaR$SukloYC3u7#5H)}1K21=?DKj^U)8G;MS)&Op)g^zR2($<>C*zW z;X7`hLxiIO#J`ANdyAOJle4V%ppa*(+0i3w;8i*BA_;u8gOO6)MY`ueq7stBMJTB; z-a0R>hT*}>z|Gg}@^zDL1MrH+2hsR8 zHc}*9IvuQC^Ju)^#Y{fOr(96rQNPNhxc;mH@W*m206>Lo<*SaaH?~8zg&f&%YiOEG zGiz?*CP>Bci}!WiS=zj#K5I}>DtpregpP_tfZtPa(N<%vo^#WCQ5BTv0vr%Z{)0q+ z)RbfHktUm|lg&U3YM%lMUM(fu}i#kjX9h>GYctkx9Mt_8{@s%!K_EI zScgwy6%_fR?CGJQtmgNAj^h9B#zmaMDWgH55pGuY1Gv7D z;8Psm(vEPiwn#MgJYu4Ty9D|h!?Rj0ddE|&L3S{IP%H4^N!m`60ZwZw^;eg4sk6K{ ziA^`Sbl_4~f&Oo%n;8Ye(tiAdlZKI!Z=|j$5hS|D$bDJ}p{gh$KN&JZYLUjv4h{NY zBJ>X9z!xfDGY z+oh_Z&_e#Q(-}>ssZfm=j$D&4W4FNy&-kAO1~#3Im;F)Nwe{(*75(p=P^VI?X0GFakfh+X-px4a%Uw@fSbmp9hM1_~R>?Z8+ ziy|e9>8V*`OP}4x5JjdWp}7eX;lVxp5qS}0YZek;SNmm7tEeSF*-dI)6U-A%m6YvCgM(}_=k#a6o^%-K4{`B1+}O4x zztDT%hVb;v#?j`lTvlFQ3aV#zkX=7;YFLS$uIzb0E3lozs5`Xy zi~vF+%{z9uLjKvKPhP%x5f~7-Gj+%5N`%^=yk*Qn{`> z;xj&ROY6g`iy2a@{O)V(jk&8#hHACVDXey5a+KDod_Z&}kHM}xt7}Md@pil{2x7E~ zL$k^d2@Ec2XskjrN+IILw;#7((abu;OJii&v3?60x>d_Ma(onIPtcVnX@ELF0aL?T zSmWiL3(dOFkt!x=1O!_0n(cAzZW+3nHJ{2S>tgSK?~cFha^y(l@-Mr2W$%MN{#af8J;V*>hdq!gx=d0h$T7l}>91Wh07)9CTX zh2_ZdQCyFOQ)l(}gft0UZG`Sh2`x-w`5vC2UD}lZs*5 zG76$akzn}Xi))L3oGJ75#pcN=cX3!=57$Ha=hQ2^lwdyU#a}4JJOz6ddR%zae%#4& za)bFj)z=YQela(F#Y|Q#dp}PJghITwXouVaMq$BM?K%cXn9^Y@g43$=O)F&ZlOUom zJiad#dea;-eywBA@e&D6Pdso1?2^(pXiN91?jvcaUyYoKUmvl5G9e$W!okWe*@a<^ z8cQQ6cNSf+UPDx%?_G4aIiybZHHagF{;IcD(dPO!#=u zWfqLcPc^+7Uu#l(Bpxft{*4lv#*u7X9AOzDO z1D9?^jIo}?%iz(_dwLa{ex#T}76ZfN_Z-hwpus9y+4xaUu9cX}&P{XrZVWE{1^0yw zO;YhLEW!pJcbCt3L8~a7>jsaN{V3>tz6_7`&pi%GxZ=V3?3K^U+*ryLSb)8^IblJ0 zSRLNDvIxt)S}g30?s_3NX>F?NKIGrG_zB9@Z>uSW3k2es_H2kU;Rnn%j5qP)!XHKE zPB2mHP~tLCg4K_vH$xv`HbRsJwbZMUV(t=ez;Ec(vyHH)FbfLg`c61I$W_uBB>i^r z&{_P;369-&>23R%qNIULe=1~T$(DA`ev*EWZ6j(B$(te}x1WvmIll21zvygkS%vwG zzkR6Z#RKA2!z!C%M!O>!=Gr0(J0FP=-MN=5t-Ir)of50y10W}j`GtRCsXBakrKtG& zazmITDJMA0C51&BnLY)SY9r)NVTMs);1<=oosS9g31l{4ztjD3#+2H7u_|66b|_*O z;Qk6nalpqdHOjx|K&vUS_6ITgGll;TdaN*ta=M_YtyC)I9Tmr~VaPrH2qb6sd~=AcIxV+%z{E&0@y=DPArw zdV7z(G1hBx7hd{>(cr43^WF%4Y@PXZ?wPpj{OQ#tvc$pABJbvPGvdR`cAtHn)cSEV zrpu}1tJwQ3y!mSmH*uz*x0o|CS<^w%&KJzsj~DU0cLQUxk5B!hWE>aBkjJle8z~;s z-!A=($+}Jq_BTK5^B!`R>!MulZN)F=iXXeUd0w5lUsE5VP*H*oCy(;?S$p*TVvTxwAeWFB$jHyb0593)$zqalVlDX=GcCN1gU0 zlgU)I$LcXZ8Oyc2TZYTPu@-;7<4YYB-``Qa;IDcvydIA$%kHhJKV^m*-zxcvU4viy&Kr5GVM{IT>WRywKQ9;>SEiQD*NqplK-KK4YR`p0@JW)n_{TU3bt0 zim%;(m1=#v2}zTps=?fU5w^(*y)xT%1vtQH&}50ZF!9YxW=&7*W($2kgKyz1mUgfs zfV<*XVVIFnohW=|j+@Kfo!#liQR^x>2yQdrG;2o8WZR+XzU_nG=Ed2rK?ntA;K5B{ z>M8+*A4!Jm^Bg}aW?R?6;@QG@uQ8&oJ{hFixcfEnJ4QH?A4>P=q29oDGW;L;= z9-a0;g%c`C+Ai!UmK$NC*4#;Jp<1=TioL=t^YM)<<%u#hnnfSS`nq63QKGO1L8RzX z@MFDqs1z ztYmxDl@LU)5acvHk)~Z`RW7=aJ_nGD!mOSYD>5Odjn@TK#LY{jf?+piB5AM-CAoT_ z?S-*q7}wyLJzK>N%eMPuFgN)Q_otKP;aqy=D5f!7<=n(lNkYRXVpkB{TAYLYg{|(jtRqYmg$xH zjmq?B(RE4 zQx^~Pt}gxC2~l=K$$-sYy_r$CO(d=+b3H1MB*y_5g6WLaWTXn+TKQ|hNY^>Mp6k*$ zwkovomhu776vQATqT4blf~g;TY(MWCrf^^yfWJvSAB$p5l;jm@o#=!lqw+Lqfq>X= z$6~kxfm7`3q4zUEB;u4qa#BdJxO!;xGm)wwuisj{0y2x{R(IGMrsIzDY9LW>m!Y`= z04sx3IjnYvL<4JqxQ8f7qYd0s2Ig%`ytYPEMKI)s(LD}D@EY>x`VFtqvnADNBdeao zC96X+MxnwKmjpg{U&gP3HE}1=s!lv&D{6(g_lzyF3A`7Jn*&d_kL<;dAFx!UZ>hB8 z5A*%LsAn;VLp>3${0>M?PSQ)9s3}|h2e?TG4_F{}{Cs>#3Q*t$(CUc}M)I}8cPF6% z=+h(Kh^8)}gj(0}#e7O^FQ6`~fd1#8#!}LMuo3A0bN`o}PYsm!Y}sdOz$+Tegc=qT z8x`PH$7lvnhJp{kHWb22l;@7B7|4yL4UOOVM0MP_>P%S1Lnid)+k9{+3D+JFa#Pyf zhVc#&df87APl4W9X)F3pGS>@etfl=_E5tBcVoOfrD4hmVeTY-cj((pkn%n@EgN{0f zwb_^Rk0I#iZuHK!l*lN`ceJn(sI{$Fq6nN& zE<-=0_2WN}m+*ivmIOxB@#~Q-cZ>l136w{#TIJe478`KE7@=a{>SzPHsKLzYAyBQO zAtuuF$-JSDy_S@6GW0MOE~R)b;+0f%_NMrW(+V#c_d&U8Z9+ec4=HmOHw?gdjF(Lu zzra83M_BoO-1b3;9`%&DHfuUY)6YDV21P$C!Rc?mv&{lx#f8oc6?0?x zK08{WP65?#>(vPfA-c=MCY|%*1_<3D4NX zeVTi-JGl2uP_2@0F{G({pxQOXt_d{g_CV6b?jNpfUG9;8yle-^4KHRvZs-_2siata zt+d_T@U$&t*xaD22(fH(W1r$Mo?3dc%Tncm=C6{V9y{v&VT#^1L04vDrLM9qBoZ4@ z6DBN#m57hX7$C(=#$Y5$bJmwA$T8jKD8+6A!-IJwA{WOfs%s}yxUw^?MRZjF$n_KN z6`_bGXcmE#5e4Ym)aQJ)xg3Pg0@k`iGuHe?f(5LtuzSq=nS^5z>vqU0EuZ&75V%Z{ zYyhRLN^)$c6Ds{f7*FBpE;n5iglx5PkHfWrj3`x^j^t z7ntuV`g!9Xg#^3!x)l*}IW=(Tz3>Y5l4uGaB&lz{GDjm2D5S$CExLT`I1#n^lBH7Y zDgpMag@`iETKAI=p<5E#LTkwzVR@=yY|uBVI1HG|8h+d;G-qfuj}-ZR6fN>EfCCW z9~wRQoAPEa#aO?3h?x{YvV*d+NtPkf&4V0k4|L=uj!U{L+oLa(z#&iuhJr3-PjO3R z5s?=nn_5^*^Rawr>>Nr@K(jwkB#JK-=+HqwfdO<+P5byeim)wvqGlP-P|~Nse8=XF zz`?RYB|D6SwS}C+YQv+;}k6$-%D(@+t14BL@vM z2q%q?f6D-A5s$_WY3{^G0F131bbh|g!}#BKw=HQ7mx;Dzg4Z*bTLQSfo{ed{4}NZW zfrRm^Ca$rlE{Ue~uYv>R9{3smwATcdM_6+yWIO z*ZRH~uXE@#p$XTbCt5j7j2=86e{9>HIB6xDzV+vAo&B?KUiMP|ttOElepnl%|DPqL b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN literal 0 HcmV?d00001 diff --git a/im_server/frontend/public/manifest.json b/im_server/frontend/public/manifest.json new file mode 100644 index 0000000..080d6c7 --- /dev/null +++ b/im_server/frontend/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/im_server/frontend/public/robots.txt b/im_server/frontend/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/im_server/frontend/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/im_server/frontend/src/App.css b/im_server/frontend/src/App.css new file mode 100644 index 0000000..0b13628 --- /dev/null +++ b/im_server/frontend/src/App.css @@ -0,0 +1,5 @@ +.app-container { + display: flex; /* Arrange the chat list and chat window side-by-side */ + height: 100vh; /* Make the chat app take up the full viewport height */ + flex-direction: row; /* Specify that we want a horizontal layout */ +} diff --git a/im_server/frontend/src/App.js b/im_server/frontend/src/App.js new file mode 100644 index 0000000..23805cb --- /dev/null +++ b/im_server/frontend/src/App.js @@ -0,0 +1,181 @@ +import React, { useState, useEffect } from "react"; +import "./App.css"; +import GroupList from "./components/GroupList/GroupList"; +import ChatWindow from "./components/ChatWindow/ChatWindow"; + +function App() { + // Left panel + const [groups, setGroups] = useState([ + // { comm_id: "1", agent_names: ["asdf", "dfdfdf"] }, + // { comm_id: "2", agent_names: ["Friends"] }, + ]); + + // All right panel data + const [messages, setMessages] = useState({ + // comm_id: [{ + // comm_id: "xx", + // sender: "xx", + // content: "xx", + // goal: "xx", + // next_speaker: ["xx"], + // state: 0, + // task_abstract: "", + // task_conclusion: "", + // task_desc: "", + // task_id: "", + // team_members: [""], + // team_up_depth: 1, + // triggers: [], + // }], + }); + const [selectedGroup, setSelectedGroup] = useState(null); + + let commID2Name = {}; + + function update_message(message) { + setMessages((prevMessages) => { + const chatId = message.comm_id; + const currentMessages = prevMessages[chatId] || []; + return { + ...prevMessages, + [chatId]: [...currentMessages, message], + }; + }); + } + + useEffect(() => { + const MAX_RETRIES = 3; // Adjust the maximum retry attempts + const RETRY_INTERVAL = 3000; // Interval between retries in milliseconds + let socket; // WebSocket object + let connectionEstablished = false; // Flag to track connection status + + function connectWebSocket() { + socket = new WebSocket("ws://127.0.0.1:7788/chatlist_ws"); + + // Event Handlers + socket.onopen = () => { + console.log("WebSocket connection established!"); + connectionEstablished = true; // Update the flag on successful connection + }; + + socket.onmessage = (event) => { + const message = JSON.parse(event.data); // Assuming the message is in JSON format + console.log(message); + switch (message.frontend_type) { + case "teamup": + setGroups((prevGroups) => [ + { + comm_id: message.comm_id, + agent_names: message.agent_names, + team_name: message.team_name || message.agent_names.join(", "), + }, + ...prevGroups, + ]); + commID2Name[message.comm_id] = message.team_name; + break; + case "message": + update_message(message); + let commId = message.comm_id; + setGroups((prevGroups) => { + return prevGroups.map((group) => { + if (group.comm_id === commId) { + group.latest_message = `[${message.sender}]: ${message.content}`; + } + return group; + }); + }); + break; + + default: + break; + } + }; + + socket.onerror = (error) => { + console.error("WebSocket error:", error); + connectionEstablished = false; // Update the flag on error + }; + + socket.onclose = (event) => { + console.log("WebSocket connection closed:", event); + connectionEstablished = false; // Update the flag on close + }; + } + + let retries = 0; + const intervalId = setInterval(() => { + if (!connectionEstablished && retries < MAX_RETRIES) { + connectWebSocket(); + retries++; + } else { + clearInterval(intervalId); // Stop trying after a successful connection or max retries + } + }, RETRY_INTERVAL); + + return () => { + clearInterval(intervalId); + if (socket) { + socket.close(); // Correct method to close the WebSocket + } + }; + }, []); + + // Fetch all the chat records from the server when initialized + useEffect(() => { + fetch("http://127.0.0.1:7788/fetch_chat_record", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({}), + }) + .then((response) => response.json()) + .then((data) => { + console.log("Success:", data); + let newMessages = {}; + let newGroups = []; + for (const comm_id in data) { + let chatRecord = data[comm_id]["chat_record"]; + let agentNames = data[comm_id]["agent_names"]; + let teamName = data[comm_id]["team_name"] || agentNames.join(", "); + commID2Name[comm_id] = teamName; + chatRecord.forEach((message) => { + newMessages[comm_id] = newMessages[comm_id] || []; + newMessages[comm_id].push(message); + }); + + let latestMessage = chatRecord[chatRecord.length - 1] || null; + newGroups = [ + { + comm_id: comm_id, + agent_names: agentNames, + latest_message: latestMessage + ? `[${latestMessage.sender}]: ${latestMessage.content}` + : "", + team_name: teamName, + }, + ...newGroups, + ]; + } + setMessages(newMessages); + setGroups(newGroups); + }) + .catch((error) => { + console.error("Error:", error); + }); + }, []); + + let selectedMessages = messages[selectedGroup] || []; + + return ( +
+ + +
+ ); +} + +export default App; diff --git a/im_server/frontend/src/components/ChatWindow/ChatWindow.css b/im_server/frontend/src/components/ChatWindow/ChatWindow.css new file mode 100644 index 0000000..40ff7d9 --- /dev/null +++ b/im_server/frontend/src/components/ChatWindow/ChatWindow.css @@ -0,0 +1,55 @@ +.chat-window { + display: flex; + flex-direction: column; + height: 100%; /* Adjust based on your container */ + border: 1px solid lightgray; + width: 100%; +} + +.chat-header { + background-color: #f0f0f0; + padding: 10px; + border-bottom: 1px solid lightgray; + font-weight: bold; + font-size: 12px; /* Adjust the font size as needed */ +} + +.chat-messages { + flex-grow: 1; /* Allow message area to take up available space */ + overflow-y: auto; /* Enable scrolling for long chats */ + padding: 10px; + display: flex; + flex-direction: column; +} + +.chat-goal { + padding: 10px; + background-color: rgb(224, 240, 255); + border-radius: 15px; + border: 1px solid #ddd; + white-space: pre-wrap; +} + +.chat-goal-title { + font-weight: bold; +} + +.message-input { + display: flex; + padding: 10px; +} + +.message-input input[type="text"] { + flex-grow: 1; + padding: 10px; + border: 1px solid lightgray; + margin-right: 10px; +} + +.message-input button { + background-color: #0084ff; + color: white; + border: none; + padding: 10px 20px; + cursor: pointer; +} diff --git a/im_server/frontend/src/components/ChatWindow/ChatWindow.jsx b/im_server/frontend/src/components/ChatWindow/ChatWindow.jsx new file mode 100644 index 0000000..66cf2ae --- /dev/null +++ b/im_server/frontend/src/components/ChatWindow/ChatWindow.jsx @@ -0,0 +1,81 @@ +import React, { useState, useEffect, useRef, useCallback } from "react"; +import Message from "../Message/Message"; // Assuming you have a Message component +import "./ChatWindow.css"; // Assuming you have a CSS file +import ReactMarkdown from 'react-markdown'; + +function ChatWindow({ messages, teamName }) { + const [displayMessages, setDisplayMessages] = useState([]); + const [newMessageText, setNewMessageText] = useState(""); + const [shouldScroll, setShouldScroll] = useState(false); + const scrollRef = useRef(null); + + + useEffect(() => { + console.log(messages); + const isAtBottom = (() => { + if (!scrollRef.current) return false; + + const { scrollTop, scrollHeight, clientHeight } = scrollRef.current; + const threshold = 5; // Margin of error for the bottom check + return scrollTop >= scrollHeight - clientHeight - threshold; + }); + setShouldScroll(isAtBottom()); + if (messages) { + setDisplayMessages(messages); + } + + }, [messages]); + + useEffect(() => { + const scrollToBottom = (() => { + if (scrollRef.current) { + scrollRef.current.scrollTop = scrollRef.current.scrollHeight; + } + }); + + if (shouldScroll) { + scrollToBottom(); + } + }, [displayMessages]); + + const handleInputChange = (event) => { + setNewMessageText(event.target.value); + }; + + const handleSubmit = (event) => { + event.preventDefault(); + // Logic to send the new message (update state, API call, etc.) + setNewMessageText(""); + }; + + const title = teamName; + + return ( +
+
+ {displayMessages.length > 0 && ( +
+ Goal: + + {displayMessages[0].goal} + +
+ )} + {displayMessages.map((message, index) => ( + + ))} +
+ {/*
+ + +
*/} +
+ ); +} + +export default ChatWindow; diff --git a/im_server/frontend/src/components/GroupList/GroupList.css b/im_server/frontend/src/components/GroupList/GroupList.css new file mode 100644 index 0000000..9f271d4 --- /dev/null +++ b/im_server/frontend/src/components/GroupList/GroupList.css @@ -0,0 +1,159 @@ +.chat-list { + width: 30%; + background-color: #f7f7f7; + border-right: 1px solid lightgray; + overflow-y: auto; + overflow-x: hidden; + height: 100%; +} + +.chat-list ul { + list-style-type: none; /* Removes bullet points */ + padding: 0; /* No padding for the list */ + margin-top: 0; + margin-bottom: 0; +} + +.chat-item { + /* Style individual chat items */ + display: flex; + flex-direction: row; + cursor: pointer; + padding: 10px; + border-bottom: 1px solid lightgray; /* Divider between groups */ + white-space: pre-wrap; + overflow-x: hidden; +} + +.chat-item:hover { + background-color: lightgray; +} + +.chat-item-selected { + display: flex; + flex-direction: row; + background-color: #d2d2d2; + white-space: pre-wrap; + padding: 10px; + border-bottom: 1px solid lightgray; /* Divider between groups */ +} + +.avatar-square { + width: 50px; /* Adjust this size as needed */ + height: 50px; + display: grid; + align-items: center; + justify-content: center; + border-radius: 3px; + background-color: #dddee0; +} + +.avatar-flex { + display: flex; + align-items: center; + justify-content: center; +} + +.avatar-group-list { + width: 20px; + height: 20px; + /* border-radius: 3px; */ +} + +/* Layout for a single avatar */ +.avatar-grid-one { + width: 50px; + height: 50px; + grid-template-columns: 1fr; + grid-template-rows: 1fr; + justify-items: center; + flex-shrink: 0; + grid-template-areas: "avatar0"; +} + +/* Layout for two avatars, side by side */ +.avatar-grid-two { + width: 50px; + height: 50px; + grid-template-columns: repeat(2, 1fr); + grid-template-rows: 1fr; + justify-items: center; + flex-shrink: 0; + grid-template-areas: "avatar0 avatar1"; +} + +/* Layout for three avatars, two on top and one at the bottom */ +.avatar-grid-three { + width: 50px; + height: 50px; + grid-template-columns: repeat(2, 1fr); + grid-template-rows: 1fr 1fr; + grid-template-areas: + "avatar0 avatar1" + "avatar2 avatar2"; /* Single avatar centered at the bottom */ + justify-items: center; + flex-shrink: 0; +} + +/* Layout for four avatars in a 2x2 grid */ +.avatar-grid-four { + width: 50px; + height: 50px; + grid-template-columns: repeat(2, 1fr); + grid-template-rows: repeat(2, 1fr); + grid-template-areas: + "avatar0 avatar1" + "avatar2 avatar3"; + justify-items: center; + flex-shrink: 0; +} + +.avatar-0 { + grid-area: avatar0; +} + +.avatar-1 { + grid-area: avatar1; +} + +.avatar-2 { + grid-area: avatar2; +} + +.avatar-3 { + grid-area: avatar3; +} + +.group-info { + display: flex; + flex-direction: column; + justify-content: space-between; + margin-left: 10px; + max-width: calc(80%); +} + +.group-title { + display: flex; + justify-content: space-between; +} + +.group-name { + font-weight: bold; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.group-time { + font-size: 0.8em; + color: gray; +} + +.group-description { + display: inline-block; + max-width: calc(100%); + color: #929292; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} diff --git a/im_server/frontend/src/components/GroupList/GroupList.jsx b/im_server/frontend/src/components/GroupList/GroupList.jsx new file mode 100644 index 0000000..9331d3b --- /dev/null +++ b/im_server/frontend/src/components/GroupList/GroupList.jsx @@ -0,0 +1,59 @@ +import React, { useState } from "react"; +import "./GroupList.css"; // Assuming you have a CSS file +import getAvatar from "../../utils/avatar"; + +function AvatarGrid({ members }) { + const getGridClass = () => { + const count = members.length; + if (count === 1) return "avatar-grid-one"; + if (count === 2) return "avatar-grid-two"; + if (count === 3) return "avatar-grid-three"; + return "avatar-grid-four"; // For four or more avatars + }; + + return ( +
+ {members.slice(0, 4).map((name, index) => ( + {`Avatar + ))} +
+ ); +} + + + +function GroupList({ groups, onGroupSelect }) { + const [selectedId, setSelectedId] = useState(null); + + const handleChatClick = (chatId) => { + setSelectedId(chatId); + onGroupSelect(chatId); + }; + + return ( +
+
    + {groups.map((group) => ( +
  • handleChatClick(group.comm_id)} + className={selectedId === group.comm_id ? "chat-item-selected" : "chat-item"} + > + +
    + {group.team_name} + {group.latest_message} +
    +
  • + ))} +
+
+ ); +} + +export default GroupList; diff --git a/im_server/frontend/src/components/Message/Message.css b/im_server/frontend/src/components/Message/Message.css new file mode 100644 index 0000000..4ae15e3 --- /dev/null +++ b/im_server/frontend/src/components/Message/Message.css @@ -0,0 +1,45 @@ +.message { + padding: 10px; + margin-bottom: 10px; + border-radius: 5px; + /* background-color: antiquewhite; */ +} + +.message-header { + display: flex; + align-items: center; + margin-bottom: 5px; +} + +.avatar { + width: 40px; + height: 40px; + border-radius: 50%; + margin-right: 10px; +} + +.username { + font-weight: bold; +} + +.message-bubble { + padding: 10px; + background-color: #f1f1f1; + border-radius: 15px; + border: 1px solid #ddd; + background-color: antiquewhite; +} + +.message-own { + background-color: #e0f0ff; /* Light blue for the current user */ + align-self: flex-end; /* Align own messages to the right */ +} + +.message-key { + font-weight: bold; +} + +.message-value { + /* font-weight: bold; */ + white-space: pre-wrap; +} diff --git a/im_server/frontend/src/components/Message/Message.jsx b/im_server/frontend/src/components/Message/Message.jsx new file mode 100644 index 0000000..e957d1f --- /dev/null +++ b/im_server/frontend/src/components/Message/Message.jsx @@ -0,0 +1,50 @@ +import React from 'react'; +import './Message.css'; +import getAvatar from '../../utils/avatar'; +import ReactMarkdown from 'react-markdown'; + + +function Message({ message }) { + let type2string = { + 0: "default", + 1: "proposal", + 2: "vote", + 3: "voting result", + 4: "discussion", + 5: "sync task assignment", + 6: "async task assignment", + 7: "inform task result", + 8: "inform task progress", + 9: "pause", + 10: "conclude group discussion", + 11: "conclusion", + } + let type = type2string[message.type]; + let nextSpeaker = message.next_speaker; + if (Array.isArray(nextSpeaker) && nextSpeaker.length !== 0) { + nextSpeaker = message.next_speaker.join(", "); + } + return ( +
+
+ {`${message.sender}'s + {message.sender} +
+
+ + {message.content} + + Next Speaker: + {nextSpeaker} +

+ Type: + {type} +

+ Updated Plan: + {message.updated_plan} +
+
+ ); +} + +export default Message; diff --git a/im_server/frontend/src/index.css b/im_server/frontend/src/index.css new file mode 100644 index 0000000..4a1df4d --- /dev/null +++ b/im_server/frontend/src/index.css @@ -0,0 +1,13 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", + "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", + monospace; +} diff --git a/im_server/frontend/src/index.js b/im_server/frontend/src/index.js new file mode 100644 index 0000000..770ee7d --- /dev/null +++ b/im_server/frontend/src/index.js @@ -0,0 +1,17 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./index.css"; +import App from "./App"; +import reportWebVitals from "./reportWebVitals"; + +const root = ReactDOM.createRoot(document.getElementById("root")); +root.render( + + + +); + +// If you want to start measuring performance in your app, pass a function +// to log results (for example: reportWebVitals(console.log)) +// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals +reportWebVitals(); diff --git a/im_server/frontend/src/logo.svg b/im_server/frontend/src/logo.svg new file mode 100644 index 0000000..9dfc1c0 --- /dev/null +++ b/im_server/frontend/src/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/im_server/frontend/src/reportWebVitals.js b/im_server/frontend/src/reportWebVitals.js new file mode 100644 index 0000000..9ecd33f --- /dev/null +++ b/im_server/frontend/src/reportWebVitals.js @@ -0,0 +1,13 @@ +const reportWebVitals = (onPerfEntry) => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals; diff --git a/im_server/frontend/src/setupTests.js b/im_server/frontend/src/setupTests.js new file mode 100644 index 0000000..1dd407a --- /dev/null +++ b/im_server/frontend/src/setupTests.js @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import "@testing-library/jest-dom"; diff --git a/im_server/frontend/src/utils/avatar.js b/im_server/frontend/src/utils/avatar.js new file mode 100644 index 0000000..4329a87 --- /dev/null +++ b/im_server/frontend/src/utils/avatar.js @@ -0,0 +1,21 @@ +function stringTo1_100(text) { + // Create a hash from the text using MD5 + const hash = text.split("").reduce((acc, char) => { + return acc + char.charCodeAt(0); // Sum of char codes + }, 0); + + // Step 2: Map the hash to the range 1-100 + // Since char codes can vary greatly, use modulus to fit within a smaller range + const range = 100; // 100 is the target range + + // Map the hash to 0-(range-1) and then shift to 1-range + const mappedValue = (hash % range) + 1; + + return mappedValue; +} + +function getAvatar(name) { + return `https://avatar.iran.liara.run/public/${stringTo1_100(name)}`; +} + +export default getAvatar; diff --git a/im_server/requirements.txt b/im_server/requirements.txt new file mode 100644 index 0000000..87b7df7 --- /dev/null +++ b/im_server/requirements.txt @@ -0,0 +1,10 @@ +fastapi +uvicorn +pymilvus +colorama +openai==1.3.0 +pyyaml +sqlitedict +websockets +gunicorn +tenacity \ No newline at end of file diff --git a/scripts/gaia/gaia_merge.py b/scripts/gaia/gaia_merge.py new file mode 100644 index 0000000..8d5d992 --- /dev/null +++ b/scripts/gaia/gaia_merge.py @@ -0,0 +1,28 @@ +import os +import json +import re + +ans_pat = re.compile(r"(FINAL ANSWER|EDUCATED GUESS): (.*)") +all_results = [] + +for level in ["level1", "level2", "level3"]: + result_dir = f"results/gaia/{level}/processed" + acc = 0 + total = 0 + for file in os.listdir(result_dir): + if not file.endswith(".json"): + continue + total += 1 + with open(os.path.join(result_dir, file), "r") as f: + data = json.load(f) + task_id = file.split(".")[0] + model_answer = ans_pat.findall(data[-1])[0][1] + all_results.append({"task_id": task_id, "model_answer": model_answer}) + if model_answer.strip().lower() == data[-2].lower(): + acc += 1 + else: + pass + print(f"Level {level} accuracy: {acc / total}") + +with open("results/gaia/gaia_merged.jsonl", "w") as f: + f.writelines([json.dumps(result, ensure_ascii=False) + "\n" for result in all_results]) diff --git a/scripts/gaia/gaia_postprocess.py b/scripts/gaia/gaia_postprocess.py new file mode 100644 index 0000000..9bf5b1e --- /dev/null +++ b/scripts/gaia/gaia_postprocess.py @@ -0,0 +1,96 @@ +# Adapted from AutoGen https://github.com/microsoft/autogen/tree/gaia_multiagent_v01_march_1st/samples/tools/autogenbench/scenarios/GAIA/Templates/Orchestrator + +import sys +import os +import json +import openai +import copy + +sys.path.append(".") +sys.path.append("../") +from common.utils.database_utils import AutoStoredDict + +from argparse import ArgumentParser + +parser = ArgumentParser() +parser.add_argument("--db_path", type=str) +parser.add_argument("--level", type=int, choices=[1, 2, 3]) +args = parser.parse_args() + +client = openai.OpenAI() + +tasks = AutoStoredDict( + args.db_path, + tablename="chat", +).todict() + +STARTING_PROMPT = """Earlier you were asked the following: + +{} + +Your team then worked diligently to address that request. Here is a transcript of that conversation:""" + + +END_PROMPT = """Read the above conversation and output a FINAL ANSWER to the question. The question is repeated here for convenience: + +{} + +To output the final answer, use the following template: FINAL ANSWER: [YOUR FINAL ANSWER] +Your FINAL ANSWER should be a number OR as few words as possible OR a comma separated list of numbers and/or strings. +ADDITIONALLY, your FINAL ANSWER MUST adhere to any formatting instructions specified in the original question (e.g., alphabetization, sequencing, units, rounding, decimal places, etc.) +If you are asked for a number, express it numerically (i.e., with digits rather than words), don't use commas, and don't include units such as $ or percent signs unless specified otherwise. +If you are asked for a string, don't use articles or abbreviations (e.g. for cities), unless specified otherwise. Don't output any final sentence punctuation such as '.', '!', or '?'. +If you are asked for a comma separated list, apply the above rules depending on whether the elements are numbers or strings. +If you are unable to determine the final answer, output 'FINAL ANSWER: Unable to determine'""" + +GUESS_PROMPT = """I understand that a definitive answer could not be determined. Please make a well-informed EDUCATED GUESS based on the conversation. + +To output the educated guess, use the following template: EDUCATED GUESS: [YOUR EDUCATED GUESS] +Your EDUCATED GUESS should be a number OR as few words as possible OR a comma separated list of numbers and/or strings. DO NOT OUTPUT 'I don't know', 'Unable to determine', etc. +ADDITIONALLY, your EDUCATED GUESS MUST adhere to any formatting instructions specified in the original question (e.g., alphabetization, sequencing, units, rounding, decimal places, etc.) +If you are asked for a number, express it numerically (i.e., with digits rather than words), don't use commas, and don't include units such as $ or percent signs unless specified otherwise. +If you are asked for a string, don't use articles or abbreviations (e.g. for cities), unless specified otherwise. Don't output any final sentence punctuation such as '.', '!', or '?'. +If you are asked for a comma separated list, apply the above rules depending on whether the elements are numbers or strings.""" + +result_dir = f"results/gaia/level{args.level}" +os.makedirs(os.path.join(result_dir, "processed"), exist_ok=True) + + +def handle_unable_to_determine(messages, extracted_text): + messages = copy.deepcopy(messages) + messages += [{"role": "assistant", "content": extracted_text}, {"role": "user", "content": GUESS_PROMPT}] + response = client.chat.completions.create(messages=messages, model="gpt-4o", temperature=0) + extracted_text = response.choices[0].message.content + return extracted_text + + +for root, dirs, files in os.walk(result_dir): + for file in files: + if os.path.exists(os.path.join(result_dir, "processed", file)): + continue + if not file.endswith(".json"): + continue + with open(os.path.join(root, file), "r") as f: + data = json.load(f) + try: + comm_id, conclusion, result = data + goal = tasks[comm_id]["chat_record"][0].goal + chat_record = tasks[comm_id]["chat_record"] + except Exception as e: + print(e) + continue + + messages = ( + [{"role": "user", "content": STARTING_PROMPT.format(goal)}] + + [{"role": "assistant", "content": f"[{item.sender}]: {item.content}"} for item in chat_record] + + [{"role": "user", "content": END_PROMPT.format(goal)}] + ) + + response = client.chat.completions.create(messages=messages, model="gpt-4o", temperature=0) + extracted_text = response.choices[0].message.content + print(extracted_text) + if "Unable to determine".lower() in extracted_text.lower(): + extracted_text = handle_unable_to_determine(messages, extracted_text) + print(extracted_text) + with open(os.path.join(result_dir, "processed", file), "w") as f: + json.dump([comm_id, conclusion, result, extracted_text], f, indent=2, ensure_ascii=False) diff --git a/scripts/gaia/test_gaia.py b/scripts/gaia/test_gaia.py new file mode 100644 index 0000000..2c7d7e9 --- /dev/null +++ b/scripts/gaia/test_gaia.py @@ -0,0 +1,253 @@ +import base64 +import json +import os +import uuid +import zipfile +from argparse import ArgumentParser +from concurrent.futures import ThreadPoolExecutor, as_completed + +import openai +import pandas as pd +import pymupdf4llm +import requests +from Bio.PDB import PDBParser +from datasets import load_dataset +from docx import Document +from openpyxl import load_workbook +from pptx import Presentation +from tenacity import retry, stop_after_attempt, wait_exponential + +client = openai.OpenAI() + + +def handle_pptx(file_path) -> str: + prs = Presentation(file_path) + + text = "" + + for i, slide in enumerate(prs.slides): + text_slide = "" + for shape in slide.shapes: + if not shape.has_text_frame: + continue + for paragraph in shape.text_frame.paragraphs: + for run in paragraph.runs: + text_slide += run.text + "\n" + text += f"# Slide {i}\n{text_slide}\n\n" + return text.strip() + + +def handle_docx(file_path) -> str: + doc = Document(file_path) + + text = "" + + for paragraph in doc.paragraphs: + text += paragraph.text + "\n" + return text.strip() + + +def handle_csv(file_path) -> str: + return json.dumps(pd.read_csv(file_path).to_dict(), ensure_ascii=False)[:10000] + "..." + + +def handle_jsonld(file_path) -> str: + with open(file_path, "r") as f: + data = json.load(f) + return json.dumps(data, ensure_ascii=False) + + +def handle_xlsx(file_path) -> str: + # Function to get the color of a cell + def get_cell_color(cell): + fill = cell.fill + if fill and fill.fgColor and fill.fgColor.type == "rgb": + return fill.fgColor.rgb + return None + + # Read the Excel file using pandas + df = pd.read_excel(file_path) + + # Load the workbook and worksheet using openpyxl + with open(file_path, "rb") as f: + wb = load_workbook(f) + ws = wb.active + + # Create a copy of the DataFrame to add comments + result = df.copy() + print(df) + + for row_idx, row in enumerate(ws.iter_rows(values_only=False, min_row=2, max_row=len(df) + 1)): + for col_idx, cell in enumerate(row): + cell_color = get_cell_color(cell) + if cell_color and cell_color != "00000000": # Skip default white/empty cells + cell_value = df.iat[row_idx, col_idx] + result.iat[row_idx, col_idx] = f"{cell_value} (Color: {cell_color})" + return ( + "The Excel file has been transformed into the following format: each column's header (the first row) serves as a key, with the corresponding cells in that column serving as the associated values:\n" + + json.dumps(result.to_dict(), indent=2, ensure_ascii=False) + ) + + +def handle_zip(file_path) -> str: + uid = uuid.uuid4().hex + folder = os.path.join("temp", uid) + os.makedirs(folder, exist_ok=True) + + # Open the zip file + with zipfile.ZipFile(file_path, "r") as zip_ref: + # Extract all contents to the specified directory + zip_ref.extractall(folder) + text = "" + for root, dirs, files in os.walk(folder): + for f in files: + ext = f.split(".")[-1] + if ext in EXT_MAPPING: + text += f"# {f}\n" + EXT_MAPPING[ext](os.path.join(root, f)) + "\n\n" + return text + + +def handle_py(file_path) -> str: + with open(file_path, "r") as f: + return f"```python\n{f.read()}\n```" + + +def handle_txt(file_path) -> str: + with open(file_path, "r") as f: + return f.read() + + +@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10)) +def handle_image(file_path: str, question: str) -> str: + with open(file_path, "rb") as f: + base64_image = base64.b64encode(f.read()).decode("utf-8") + response = client.chat.completions.create( + messages=[ + { + "role": "user", + "content": [ + { + "type": "text", + "text": f'You are transforming this image to text. Here\'s a question about this image:\n"""\n{question.strip()}\n"""\n\nA team is collaborating to answer the question, but they can\'t see the image. To provide as much information as possible, you should describe this image in details (e.g., relevant text, number, element relationships, etc.). Ensure your description is complete and accurate enough for the team to do some further processing to answer the question based solely on your description! Do not try to answer the question. Only give comprehensive text description of this image.', + }, + { + "type": "image_url", + "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}, + }, + ], + }, + ], + model="gpt-4o", + max_tokens=4096, + temperature=0.5, + ) + return response.choices[0].message.content.strip() + + +def handle_audio(file_path: str) -> str: + with open(file_path, "rb") as file: + # Create a dictionary to hold the file data + files = {"file": (file_path.split("/")[-1], file, "multipart/form-data")} + + response = requests.post("http://166.111.121.22:8848/whisper", files=files) + return response.json()["text"] + + +def handle_pdf(file_path: str) -> str: + text = pymupdf4llm.to_markdown(file_path) + return text + + +def handle_pdb(file_path: str) -> str: + parser = PDBParser() + # Parse the structure + structure = parser.get_structure("protein", file_path) + + # Initialize an empty string to store all information + pdb_info = "" + + # Loop through the structure to collect information + for model in structure: + pdb_info += f"Model {model.id}\n" + for chain in model: + pdb_info += f" Chain {chain.id}\n" + for residue in chain: + pdb_info += f" Residue {residue.resname} {residue.id[1]}\n" + for atom in residue: + pdb_info += f" Atom {atom.name}, Coordinates: {atom.coord}\n" + + return pdb_info[:10000] + "..." + + +def handle_xml(file_path: str) -> str: + with open(file_path, "r") as f: + return f.read() + + +def process_data(data): + result_path = f"{result_dir}/{data['task_id']}.json" + + question = data["Question"] + additional_text = "" + goal = question + if data["file_name"].strip(): + ext = data["file_name"].split(".")[-1] + func = EXT_MAPPING[ext] + if func == handle_image: + additional_text = func(data["file_path"], question) + else: + additional_text = func(data["file_path"]) + goal += f"\n\nThe user has uploaded some files. Here are the file's contents:\n\n{additional_text}" + + print( + f"====================\nProcessing {data['task_id']}. File path: {data['file_path']}. Goal: {goal}\nLabel: {data['Final answer']}" + ) + response = requests.post( + "http://127.0.0.1:5050/launch_goal", + json={ + "goal": goal, + "team_member_names": None, + "team_up_depth": 1, # the depth limit of nested teaming up + "skip_naming": False, + "max_turns": 16, + }, + ) + + response = response.json() + response.append(data["Final answer"]) + with open(result_path, "w") as f: + f.write(json.dumps(response, ensure_ascii=False, indent=2)) + + +if __name__ == "__main__": + EXT_MAPPING = { + "pptx": handle_pptx, + "csv": handle_csv, + "jsonld": handle_jsonld, + "xlsx": handle_xlsx, + "xls": handle_xlsx, + "zip": handle_zip, + "py": handle_py, + "jpg": handle_image, + "docx": handle_docx, + "mp3": handle_audio, + "pdf": handle_pdf, + "txt": handle_txt, + "pdb": handle_pdb, + "png": handle_image, + "xml": handle_xml, + } + + parser = ArgumentParser() + parser.add_argument("--level", type=int, choices=[1, 2, 3]) + parser.add_argument("--max_workers", type=int, default=1) + args = parser.parse_args() + + result_dir = f"results/gaia/level{args.level}" + dataset = load_dataset("gaia-benchmark/GAIA", f"2023_level{args.level}") + os.makedirs(result_dir, exist_ok=True) + + with ThreadPoolExecutor(max_workers=args.max_workers) as executor: + futures = [executor.submit(process_data, data) for data in dataset["validation"]] + for future in as_completed(futures): + future.result() diff --git a/scripts/open_instruction/test_open_instruction.py b/scripts/open_instruction/test_open_instruction.py new file mode 100644 index 0000000..d366cb2 --- /dev/null +++ b/scripts/open_instruction/test_open_instruction.py @@ -0,0 +1,109 @@ +import requests +import os +import json +import concurrent.futures as conf +import traceback + +# import copy + + +def run(input_item: dict): + """ + input_item: dict, including the keys 'instruction' + """ + goal = input_item["instruction"] + try: + response = requests.post( + "http://127.0.0.1:5050/launch_goal", + json={ + "goal": goal, + "team_member_names": ["AutoGPT", "Open Interpreter"], + # "team_up_depth": 1, # the depth limit of nested teaming up + "max_turns": 40, + }, + ) + print(response.text) + + plain_text = response.text + new_item = input_item.copy() + new_item["plain_text"] = plain_text + try: + comm_id, conclusion = response.json() + new_item["conclusion"] = conclusion + new_item["task_id"] = comm_id + except Exception as e: + print(f"inner error while converting to json...: {e}") + return new_item + except Exception as e: + print(f"error: {e}...") + traceback.print_exc() + return None + + +def run_concurrently(data: list[dict], appendFilePath: str, flag_key: str = "flag", max_workers: int = 5): + if not os.path.exists(appendFilePath): + os.system(f"touch {appendFilePath}") + flags = [] + with open(appendFilePath, encoding="utf-8", mode="r") as f: + for line in f: + item = json.loads(line) + assert flag_key in item + flags.append(item[flag_key]) + print(f"existed_flags: {flags}") + data_to_run = [] + for i, item in enumerate(data): + # write + + if flag_key not in item: + item[flag_key] = i + else: + pass + # print(item[flag_key]) + if item[flag_key] not in flags: + print(item[flag_key]) + data_to_run.append(item) + + print(f"the total number of the data: {len(data)}......") + print(f"the number of data to run: {len(data_to_run)}......") + + executor = conf.ThreadPoolExecutor(max_workers=max_workers) + + try: + f = open(appendFilePath, encoding="utf-8", mode="a+") + + tasks = [executor.submit(run, item) for item in data_to_run] + + for it in conf.as_completed(tasks): + if rt := it.result(): + print("##Question") + print(rt["instruction"]) + print("##Conclusion") + try: + print(rt["plain_text"]) + print(rt["conclusion"]) + except: + pass + f.write(json.dumps(rt, ensure_ascii=False) + "\n") + f.flush() + + except Exception as e: + print(f"Exception happens when in parallel...:{e}") + finally: + f.close() + executor.shutdown(wait=True) + + +if __name__ == "__main__": + data = [] + with open("data/open_instruction.jsonl", encoding="utf-8", mode="r") as f: + for line in f: + item = json.loads(line) + data.append(item) + # sampled_data = data[:1] + os.makedirs("./results", exist_ok=True) + run_concurrently( + data, + appendFilePath="results/open_instruction_results.jsonl", + flag_key="instruction_id", + max_workers=3, + ) diff --git a/scripts/test_paper_writing.py b/scripts/test_paper_writing.py new file mode 100644 index 0000000..00e730a --- /dev/null +++ b/scripts/test_paper_writing.py @@ -0,0 +1,25 @@ +import requests + +goal = """Write the introduction section of a paper about the concept "Internet of Agents" (IoA). Note that the IoA is not the same as the conventional "IoA" in the IoA literature. +Here's the background of the IoA that we are talking about: +Large models (LMs) demonstrate remarkable capabilities. Recent research has illustrated that when LMs are equipped with specific tools and memory, they become intelligent agents capable of navigating intricate virtual environments and executing difficult tasks. For instance, these agents can utilize calculators to tackle mathematical problems or employ web browsers to gather information and produce reports. These agents function as human assistants, enhancing convenience in our lives. +Building on this concept, we foresee a promising future where every individual and internet-enabled device possesses its own agent. This will revolutionize interactions between humans, between humans and devices, and between devices themselves. We refer to this paradigm shift as the Internet of Agents (IoA), a broader concept than the Internet of Things (IoT). While IoT focuses on the connectivity of devices, IoA emphasizes the transformation in the nature of these interactions. In an IoA world, humans might not need to operate objects directly. Instead, a person's agent can interface with another object's agent to produce the desired result. The agent of that object then performs the relevant action. Furthermore, people's social interactions could evolve as agents help find potential friends based on compatibility. This paints a picture of a society where humans, objects, and their agents harmoniously coexist and bolster each other + +The paper is expected to be published in a high-impact journal like Nature or Science. Therefore, when writing the introduction section, it's crucial to adhere strictly to the formatting and citation styles typically required by these journals, which includes providing accurate citations and references for any factual statements, theories, or prior research mentioned. The introduction section should not only be polished and complete but also supported by relevant literature to establish a solid foundation for the paper's topic. +The final output should be the introduction section of the paper. +""" + +response = requests.post( + "http://127.0.0.1:5050/launch_goal", + json={ + "goal": goal, + # "team_member_names": [ + # "Weize Chen's Assistant", + # "Chen Qian's Assistant", + # "Cheng Yang's Assistant", + # "ArxivAssistant", + # ], + "team_up_depth": 1, # the depth limit of nested teaming up + }, +) +print(response)