diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 8153128144..75f7a9dcc6 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -23,14 +23,12 @@ body: - type: markdown attributes: value: | - For better global communication, Please write in English. - (为了更好的国际化交流,请您使用英语描述您的问题。) + For better global communication, please write in English. + (为了更好的国际化交流,请您使用英语描述问题。) - You can use the following translation tool to translate, but please check the translation carefully after translation to avoid misinterpretation: - (你可以使用以下翻译工具进行翻译,但是翻译完成后请仔细检查译文,以免有错误的理解:) - - [Google Translate](https://translate.google.com/) - - [Baidu Translate](https://fanyi.baidu.com/) - - [YouDao Translate](https://fanyi.baidu.com/) + You can use ChatGPT to translate your native language into English: + (您可以使用ChatGPT将您的母语翻译成英文。) + - [ChatGPT](https://chat.openai.com/) - type: checkboxes attributes: @@ -49,11 +47,12 @@ body: label: Environment description: Describe the environment. options: - - preview.laf.run + - https://laf.dev + - https://laf.run + - Linux (self-host) - Mac (self-host) - Windows (self-host) - - Linux (self-host) - - Other (self-host) + - Laf-cli validations: required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 961b6dcd04..01c20d0ca2 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -20,17 +20,18 @@ title: "[Feature] Feature title " description: I want to suggest a feature for this project. labels: [ "feature" ] body: - # - type: markdown - # attributes: - # value: | - # For better global communication, Please write in English. - # (为了更好的国际化交流,请您使用英语描述您的问题。) + - type: markdown + attributes: + value: | + For better global communication, Please write in English. + (为了更好的国际化交流,请您使用英语描述您的问题。) - # You can use the following translation tool to translate, but please check the translation carefully after translation to avoid misinterpretation: - # (你可以使用以下翻译工具进行翻译,但是翻译完成后请仔细检查译文,以免有错误的理解:) - # - [Google Translate](https://translate.google.com/) - # - [Baidu Translate](https://fanyi.baidu.com/) - # - [YouDao Translate](https://fanyi.baidu.com/) + You can use the following translation tool to translate, but please check the translation carefully after translation to avoid misinterpretation: + (你可以使用以下翻译工具进行翻译,但是翻译完成后请仔细检查译文,以免有错误的理解:) + - [Google Translate](https://translate.google.com/) + - [Baidu Translate](https://fanyi.baidu.com/) + - [YouDao Translate](https://fanyi.baidu.com/) + - ChatGPT - type: checkboxes attributes: diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml index 4bf029eb7e..4179495eb8 100644 --- a/.github/ISSUE_TEMPLATE/question.yml +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -20,17 +20,18 @@ title: "[Question] Question title " description: I have a question that isn't answered in docs or issue. labels: [ "question" ] body: - # - type: markdown - # attributes: - # value: | - # For better global communication, Please write in English. - # (为了更好的国际化交流,请您使用英语描述您的问题。) + - type: markdown + attributes: + value: | + For better global communication, Please write in English. + (为了更好的国际化交流,请您使用英语描述您的问题。) - # You can use the following translation tool to translate, but please check the translation carefully after translation to avoid misinterpretation: - # (你可以使用以下翻译工具进行翻译,但是翻译完成后请仔细检查译文,以免有错误的理解:) - # - [Google Translate](https://translate.google.com/) - # - [Baidu Translate](https://fanyi.baidu.com/) - # - [YouDao Translate](https://fanyi.baidu.com/) + You can use the following translation tool to translate, but please check the translation carefully after translation to avoid misinterpretation: + (你可以使用以下翻译工具进行翻译,但是翻译完成后请仔细检查译文,以免有错误的理解:) + - [Google Translate](https://translate.google.com/) + - [Baidu Translate](https://fanyi.baidu.com/) + - [YouDao Translate](https://fanyi.baidu.com/) + - ChatGPT - type: checkboxes attributes: diff --git a/.github/workflows/build-sealos-cluster-image.yml b/.github/workflows/build-sealos-cluster-image.yml index fcc778f7ab..24c7eede98 100644 --- a/.github/workflows/build-sealos-cluster-image.yml +++ b/.github/workflows/build-sealos-cluster-image.yml @@ -96,3 +96,13 @@ jobs: sudo buildah manifest add $IMAGE:$VERSION docker://$IMAGE:$VERSION-amd64 sudo buildah manifest add $IMAGE:$VERSION docker://$IMAGE:$VERSION-arm64 sudo buildah manifest push --all $IMAGE:$VERSION docker://$IMAGE:$VERSION + + trigger-workflow-e2e: + needs: [build_cluster_image] + runs-on: ubuntu-latest + steps: + - name: trigger cluster image workflow + uses: peter-evans/repository-dispatch@v2 + with: + event-type: cluster_image_build_success + client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}", "version": "latest"}' diff --git a/.github/workflows/deploy-doc.yml b/.github/workflows/deploy-doc.yml new file mode 100644 index 0000000000..ae649df8cd --- /dev/null +++ b/.github/workflows/deploy-doc.yml @@ -0,0 +1,44 @@ +name: deploy docs + +on: + workflow_dispatch: + push: + branches: [ main ] + paths: + - 'docs/**' + - '.github/workflows/deploy-doc.yml' +env: + LAF_CI_DOCS_PAT: ${{ secrets.LAF_CI_DOCS_PAT }} + LAF_CI_DOCS_APPID: ${{ secrets.LAF_CI_DOCS_APPID }} + LAF_CI_DOCS_BUCKET_NAME: ${{ secrets.LAF_CI_DOCS_BUCKET_NAME }} + LAF_API_URL: ${{ secrets.LAF_API_URL }} + +jobs: + linkCheckerAndDeploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set Node.js 16.x + uses: actions/setup-node@v3 + with: + node-version: 16.x + - name: Run Install + uses: borales/actions-yarn@v4 + with: + cmd: install # will run `yarn install` command in `docs` directory + dir: docs + - name: Run build + uses: borales/actions-yarn@v4 + with: + cmd: build # will run `yarn build` command in `docs` directory + dir: docs + - name: Setup laf-cli + run: npm i laf-cli -g + - name: Login laf-cli + run: laf login -r ${{ env.LAF_API_URL }} ${{ env.LAF_CI_DOCS_PAT }} + - name: Deploy to laf + working-directory: docs/.vitepress + run: | + laf app init ${{ env.LAF_CI_DOCS_APPID }} + laf storage push -f ${{ env.LAF_CI_DOCS_BUCKET_NAME }} dist/ diff --git a/.github/workflows/dockerize-runtime-nodejs.yml b/.github/workflows/dockerize-runtime-nodejs.yml index 212b003719..bb6102cdf5 100644 --- a/.github/workflows/dockerize-runtime-nodejs.yml +++ b/.github/workflows/dockerize-runtime-nodejs.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v3 with: fetch-depth: 0 - + - name: Use Node uses: actions/setup-node@v3 with: @@ -33,7 +33,7 @@ jobs: - name: Install Package working-directory: runtimes/nodejs - run: npm cache clean --force && npm install typescript -g && npm install --omit=dev + run: npm cache clean --force && npm install - name: Build Packages working-directory: runtimes/nodejs @@ -51,7 +51,7 @@ jobs: type=semver,pattern={{version}} type=raw,value=latest,enable=true type=sha,enable=true,format=short - + - name: Set up QEMU uses: docker/setup-qemu-action@v2 @@ -82,13 +82,14 @@ jobs: platforms: linux/amd64, linux/arm64 dockerize-init-image: + needs: [dockerize-main-image] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - + - name: Use Node uses: actions/setup-node@v3 with: @@ -96,7 +97,7 @@ jobs: - name: Install Package working-directory: runtimes/nodejs - run: npm cache clean --force && npm install typescript -g && npm install --omit=dev + run: npm cache clean --force && npm install - name: Build Packages working-directory: runtimes/nodejs @@ -142,4 +143,14 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - platforms: linux/amd64, linux/arm64 \ No newline at end of file + platforms: linux/amd64, linux/arm64 + + trigger-workflow-e2e: + needs: [dockerize-main-image, dockerize-init-image] + runs-on: ubuntu-latest + steps: + - name: trigger cluster image workflow + uses: peter-evans/repository-dispatch@v2 + with: + event-type: dockerize-runtime-success + client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}", "version": "latest"}' diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 0000000000..19c5c09226 --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,42 @@ +name: e2e + +on: + repository_dispatch: + types: [cluster_image_build_success, dockerize_runtime_success] + workflow_dispatch: + push: + branches: + - main + paths: + - "e2e/**" + - ".github/workflows/e2e.yml" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + DOMAIN: 127.0.0.1.nip.io + +jobs: + e2e: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Remove builtin docker + run: | + sudo apt-get remove -y moby-engine moby-cli moby-buildx moby-compose + + - name: Deploy laf + env: + DOMAIN: ${{ env.DOMAIN }} + working-directory: deploy/scripts + run: sudo sh install-on-linux.sh $DOMAIN # this script will install sealos and laf + + - name: Run E2E Test + working-directory: e2e + run: | + sudo sh e2e.sh + + diff --git a/.github/workflows/link-pr.yml b/.github/workflows/link-pr.yml index 3c7e98dfb4..b16f1855b2 100644 --- a/.github/workflows/link-pr.yml +++ b/.github/workflows/link-pr.yml @@ -19,10 +19,8 @@ jobs: with: node-version: 16.x - name: Run Install - uses: borales/actions-yarn@v4 - with: - cmd: install # will run `yarn install` command in `docs` directory - dir: docs + working-directory: docs + run: npm install - name: Run build uses: borales/actions-yarn@v4 with: diff --git a/.github/workflows/link-schedule.yml b/.github/workflows/link-schedule.yml index dbf8c325f3..92ae175a4f 100644 --- a/.github/workflows/link-schedule.yml +++ b/.github/workflows/link-schedule.yml @@ -29,7 +29,6 @@ jobs: - name: Link Checker uses: lycheeverse/lychee-action@v1.5.0 with: - fail: true # For parameter description, see https://github.com/lycheeverse/lychee#commandline-parameters # -E, --exclude-all-private Exclude all private IPs from checking. # -i, --insecure Proceed for server connections considered insecure (invalid TLS) @@ -40,6 +39,13 @@ jobs: # docs/.vitepress/dist the site directory to check # ./*.md all markdown files in the root directory - args: -E -i -n -t 45 --max-concurrency 64 -a 429,401 -- 'docs/.vitepress/dist' '*.md' + args: -E -i -n -t 45 --max-concurrency 64 -a 429,401,403 -- 'docs/.vitepress/dist' '*.md' + output: out.md env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + - name: Create Issue From File + uses: peter-evans/create-issue-from-file@v3 + with: + title: Broken Link Detected + content-filepath: out.md + assignees: nightwhite diff --git a/.lycheeignore b/.lycheeignore index 7d1abf8073..bf0674270e 100644 --- a/.lycheeignore +++ b/.lycheeignore @@ -2,4 +2,5 @@ .*xx.* https://beian.miit.gov.cn/ .*127-0-0-1.* -https://oss.lafyun.com \ No newline at end of file +https://oss.laf.run +https://github.com/labring/laf/edit/main/docs/ \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index be925eac08..32ad6dfda4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -23,7 +23,10 @@ "cSpell.words": [ "aarch", "alipay", + "alisms", "apiextensions", + "apisixtlses", + "apiv", "appid", "automount", "binded", @@ -32,11 +35,10 @@ "buildah", "buildx", "Builtins", - "casbin", - "casdoor", "chakra", "Chakra", "chatgpt", + "ciphertext", "clsx", "coll", "compat", @@ -46,12 +48,14 @@ "datasource", "datepicker", "dockerode", + "doctag", "EJSON", "entrypoint", "finalizers", "fullname", "ghaction", "healthz", + "hljs", "hokify", "hostpath", "immer", @@ -64,6 +68,7 @@ "lafyun", "languagedetector", "logtostderr", + "mchid", "millicores", "MINIO", "moby", @@ -77,6 +82,7 @@ "qrcode", "readwrite", "Referer", + "relock", "rolebinding", "roundrobin", "runc", @@ -85,6 +91,7 @@ "sealctl", "sealos", "signin", + "Signup", "statefulset", "storageclass", "tailwindcss", @@ -96,7 +103,12 @@ "upserted", "urlencode", "userid", + "videobg", + "videomobile", "vitepress", + "webchat", + "wechat", + "WECHATPAY", "withs", "xmlparser", "zcube", diff --git a/CHANGELOG.md b/CHANGELOG.md index d2ce9969d4..3d6ef08f65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,129 @@ +# [1.0.0-beta.7](https://github.com/labring/laf/compare/v1.0.0-beta.6...v1.0.0-beta.7) (2023-04-25) + + +### Bug Fixes + +* **client-sdk:** optimize invoke code prompts and documents ([#1038](https://github.com/labring/laf/issues/1038)) ([0e7d812](https://github.com/labring/laf/commit/0e7d8120c9a1225be0559a10c4ae9e6703092aea)) +* **cli:** fix function name rule, add laf-cli option to issue tpl ([#1034](https://github.com/labring/laf/issues/1034)) ([#1035](https://github.com/labring/laf/issues/1035)) ([f07fecb](https://github.com/labring/laf/commit/f07fecb7e3dfd6b4ea831617aca1a57e8827489e)) +* **runtime:** add build-base libaries in docker image to support canvas library ([c191848](https://github.com/labring/laf/commit/c191848d67eb3a4b42a791d659afd49cb5ee421b)) +* **runtime:** fix func logging order ([#1072](https://github.com/labring/laf/issues/1072)) ([dd0c3d7](https://github.com/labring/laf/commit/dd0c3d7c1811897e37bd6a9dc7959f6623fa8f21)) +* **server:** avoid acct-trans addition in free order ([#1049](https://github.com/labring/laf/issues/1049)) ([b0f7e81](https://github.com/labring/laf/commit/b0f7e81b3f2d3999a5793c167e9aa1e56328b220)) +* **server:** check env name regex for batch update ([#1065](https://github.com/labring/laf/issues/1065)) ([3ddb36f](https://github.com/labring/laf/commit/3ddb36ff8682680226cca3bea5bffc6f4cb06a96)) +* **server:** fix waiting time in instance starting task ([#1075](https://github.com/labring/laf/issues/1075)) ([fa72bb9](https://github.com/labring/laf/commit/fa72bb91085209245d412716bda168ed46c707ab)) +* **server:** Modify the installation order of APISIX ([#1022](https://github.com/labring/laf/issues/1022)) ([67cc35d](https://github.com/labring/laf/commit/67cc35dfc6e2f148dcd301c7c699879302a1c1fb)) +* **server:** remove minio alias init ([#1066](https://github.com/labring/laf/issues/1066)) ([b900f90](https://github.com/labring/laf/commit/b900f906a628633444e10ddd2c3a0972a7b6b3d7)) +* **server:** suspend cronjob after instance stopped ([#1045](https://github.com/labring/laf/issues/1045)) ([8d63403](https://github.com/labring/laf/commit/8d634039430f8b0f88c39f31f8162f1130d77edb)) +* **server:** use _id to sort logs instead of created_at ([#1073](https://github.com/labring/laf/issues/1073)) ([7a87bea](https://github.com/labring/laf/commit/7a87bea87a8918d2489cf5b2e54b37f636d93d65)) +* **web:** add spec width scrollbar ([#1046](https://github.com/labring/laf/issues/1046)) ([4bbcaa0](https://github.com/labring/laf/commit/4bbcaa0212a07bb08bd71acc373a9c787f550c2f)) +* **web:** common error handler ([#1071](https://github.com/labring/laf/issues/1071)) ([c93438b](https://github.com/labring/laf/commit/c93438bd59f24701fc5da0224f180300a3b9c01a)) +* **web:** compress png images in home site ([#1019](https://github.com/labring/laf/issues/1019)) ([f2e2c4d](https://github.com/labring/laf/commit/f2e2c4dbd9d3dfae9af76129d9f2e3f45fbdf36f)) +* **web:** fix route dashboard link ([#1020](https://github.com/labring/laf/issues/1020)) ([7ad26a0](https://github.com/labring/laf/commit/7ad26a00f3a4aeff3bbe7279827ad354c95de496)) +* **web:** opt ide typings for response & request, opt function templates ([#1059](https://github.com/labring/laf/issues/1059)) ([7cb8204](https://github.com/labring/laf/commit/7cb8204a1129d738898b43efd508e09d895c8790)) +* **web:** Repair document link address ([#1027](https://github.com/labring/laf/issues/1027)) ([f171712](https://github.com/labring/laf/commit/f17171216b11894a3d21e76480c1ba97d0650b9e)) + + +### Features + +* **cli:** add ignore file ([#1030](https://github.com/labring/laf/issues/1030)) ([3c32ced](https://github.com/labring/laf/commit/3c32ceddaa7f8d3500b889a1cce17a6cc6f48e67)) +* **doc:** improved cloud function related documents ([#1050](https://github.com/labring/laf/issues/1050)) ([9ada3d2](https://github.com/labring/laf/commit/9ada3d2bb26c18ec37a618b78df44053d7f4ae7a)) +* **runtime:** add __init__ hook in runtime ([#1081](https://github.com/labring/laf/issues/1081)) ([db62f1a](https://github.com/labring/laf/commit/db62f1af6269d4975a6c17fe102891b7c842ee31)) +* **runtime:** support process.env in runtime ([#1074](https://github.com/labring/laf/issues/1074)) ([f0f1582](https://github.com/labring/laf/commit/f0f15821b27d1a0e9680cdd69b98c3fb04b21fcc)) +* **server:** add func debug params, add envs update api ([#1055](https://github.com/labring/laf/issues/1055)) ([5f88a12](https://github.com/labring/laf/commit/5f88a1220485d88649f344dc89524cdf1659285e)) +* **server:** hot load environments for runtime instead of restarting runtime ([#1077](https://github.com/labring/laf/issues/1077)) ([feb70ae](https://github.com/labring/laf/commit/feb70aee67fd717db9a2f972023165b59da78b42)) +* **web:** add ChatGPT example ([#1052](https://github.com/labring/laf/issues/1052)) ([a46ce42](https://github.com/labring/laf/commit/a46ce42a3078f65a21639e5b897cd79e8c4b50ea)) +* **web:** add homepage darkmode ([#1043](https://github.com/labring/laf/issues/1043)) ([ade2a05](https://github.com/labring/laf/commit/ade2a05bd9e36581203798047374b4e7eb91386b)) +* **web:** add laf new homepage ([#1018](https://github.com/labring/laf/issues/1018)) ([f66e2f3](https://github.com/labring/laf/commit/f66e2f3576a8bab799b046f65753980a6879b7a0)) +* **web:** add loginpage darkmode ([#1070](https://github.com/labring/laf/issues/1070)) ([9a27bcf](https://github.com/labring/laf/commit/9a27bcfca688f8a64f009b81bb4259db330b0943)) +* **web:** add status bar ([#1054](https://github.com/labring/laf/issues/1054)) ([cd31eb8](https://github.com/labring/laf/commit/cd31eb80343f4d4a6d060f34c252b8a66ac5a4ed)) +* **web:** common error handler ([#1040](https://github.com/labring/laf/issues/1040)) ([a099568](https://github.com/labring/laf/commit/a09956825b8be3e373dbf1b52d46ef46eb349a6d)) +* **web:** support folder delete in storage ([#1047](https://github.com/labring/laf/issues/1047)) ([#1048](https://github.com/labring/laf/issues/1048)) ([367dcf0](https://github.com/labring/laf/commit/367dcf0fc8120e74e9a67f9dc2e6ee5ccdad6b5c)) +* **web:** update environment variables without app restart ([#1079](https://github.com/labring/laf/issues/1079)) ([dc25ae3](https://github.com/labring/laf/commit/dc25ae3eda45543348cb4fed32d5f48cb602f24a)) +* **web:** use laf ai to generate code ([#1029](https://github.com/labring/laf/issues/1029)) ([f1eac71](https://github.com/labring/laf/commit/f1eac71d978c6a91d7fab12401d60732f79e8d9b)) + + + +# [1.0.0-beta.6](https://github.com/labring/laf/compare/v1.0.0-beta.5...v1.0.0-beta.6) (2023-04-11) + + +### Bug Fixes + +* **deploy:** upgrade minio version to fix CVE-2023-28432 ([#960](https://github.com/labring/laf/issues/960)) ([b38c288](https://github.com/labring/laf/commit/b38c288da58b0ea6dbbb834bc8b7c69f3cc21e37)) +* fix app url protocol error & update default url ([#1006](https://github.com/labring/laf/issues/1006)) ([b79f71e](https://github.com/labring/laf/commit/b79f71edac1f84d6fb524281bbe2da59bc052a27)) +* **server:** add existing check in creating phase of tasks ([#990](https://github.com/labring/laf/issues/990)) ([8444d80](https://github.com/labring/laf/commit/8444d804edd39bd0ac7fb09133f691f7e914f419)) +* **server:** add website count limit, opt website task ([#959](https://github.com/labring/laf/issues/959)) ([7ca3364](https://github.com/labring/laf/commit/7ca33643b0d1626160f62fbb23e24d36e992a0c2)) +* **server:** bucket deletion didn't remove related website ([#983](https://github.com/labring/laf/issues/983)) ([f559764](https://github.com/labring/laf/commit/f5597649ddc7ecd14e701611666823cda4fda36b)) +* **server:** cancel namespace removal while stopping app ([#980](https://github.com/labring/laf/issues/980)) ([8213bea](https://github.com/labring/laf/commit/8213beae6e3a13c8b1c42a1f980efa4509adf0c8)) +* **server:** check site deleting state in site creation ([#997](https://github.com/labring/laf/issues/997)) ([5f4d026](https://github.com/labring/laf/commit/5f4d026fa07017697a7432fabcfffac4daa48d5a)) +* **server:** check website hosting in bucket deletion, add error handle to tasks; ([#1017](https://github.com/labring/laf/issues/1017)) ([48cad2d](https://github.com/labring/laf/commit/48cad2de3c8f8e9e0fb9af4e084e7187bcdf848e)) +* **server:** error on deleting cronjob; app stucked in starting ([#964](https://github.com/labring/laf/issues/964)) ([a1e42b1](https://github.com/labring/laf/commit/a1e42b164092718b50569ca1102815a3296ac6f1)) +* **server:** fix instance task error ([#988](https://github.com/labring/laf/issues/988)) ([63cc523](https://github.com/labring/laf/commit/63cc52308fe44ab2abe276bb4e584ad3da870d35)) +* **server:** fix tasks state handler logic ([#987](https://github.com/labring/laf/issues/987)) ([d36eab9](https://github.com/labring/laf/commit/d36eab9bcc54c829ccdbf0b261538e4318e15683)) +* **server:** fixed illegal removal of unowned trigger ([#965](https://github.com/labring/laf/issues/965)) ([260b335](https://github.com/labring/laf/commit/260b335de72c32c28a3c8f7cb4b1c7b13855443d)) +* **server:** fixed the error of repeatedly deleting website routes ([#957](https://github.com/labring/laf/issues/957)) ([46d0cce](https://github.com/labring/laf/commit/46d0ccea60e1b57317d712064b1eaab4b53c5598)) +* **server:** return notes fields in region & bundles ([#993](https://github.com/labring/laf/issues/993)) ([82b8121](https://github.com/labring/laf/commit/82b8121dfd39124437f7df4ceecf4b987f9d76e6)) +* **server:** rm minio alias init in boot, fix multi region limit; ([#976](https://github.com/labring/laf/issues/976)) ([251a3c4](https://github.com/labring/laf/commit/251a3c46ff4948759b94f54a06bb02f6562fad9c)) +* **web:** add types for ctx.request ([#963](https://github.com/labring/laf/issues/963)) ([a18c27f](https://github.com/labring/laf/commit/a18c27fb47ccbdeb14b5a5141a7e0d395b534477)) +* **web:** appid confict if open 2 tabs ([#1011](https://github.com/labring/laf/issues/1011)) ([f6c39ee](https://github.com/labring/laf/commit/f6c39ee163cd115d975a6edee27ca989192dde70)) +* **web:** fixed the path issue when clicking pathlink ([3408aca](https://github.com/labring/laf/commit/3408acac82cdef9a9e6add370c3f2eeaee1f27ac)) +* **web:** hide register button while register disabled ([#994](https://github.com/labring/laf/issues/994)) ([a12f1f5](https://github.com/labring/laf/commit/a12f1f5535e43c727077aa0885724767283177ee)) +* **web:** remove withCredentials ([#979](https://github.com/labring/laf/issues/979)) ([3300953](https://github.com/labring/laf/commit/330095346954c662f85562906c7905858898ebe5)) + + +### Features + +* **cli:** opt app list display ([#1007](https://github.com/labring/laf/issues/1007)) ([13a06df](https://github.com/labring/laf/commit/13a06df5830631d726ef20f37dd79e1bca860cd0)) +* **runtime:** impl cloud function import and cache function ([#1005](https://github.com/labring/laf/issues/1005)) ([6a96add](https://github.com/labring/laf/commit/6a96add95c83cb292f82c3fbe9339713e0ba3ecd)) +* **server:** add account transaction ([#1014](https://github.com/labring/laf/issues/1014)) ([c7e6d15](https://github.com/labring/laf/commit/c7e6d154562ac3e48e6c8c0ed5d02a6164568f3e)) +* **server:** add check if password had binded ([#951](https://github.com/labring/laf/issues/951)) ([c6b7ebc](https://github.com/labring/laf/commit/c6b7ebc57ee374bb40fc183aba448dfefb4504b9)) +* **server:** add notes field to region,bundle,pay,auth ([#986](https://github.com/labring/laf/issues/986)) ([206070a](https://github.com/labring/laf/commit/206070aed69aefe7b01c39e1b4e2894e7bd54f61)) +* **server:** support website custom domain ssl cert auto-gen ([#956](https://github.com/labring/laf/issues/956)) ([9141651](https://github.com/labring/laf/commit/914165185ebbc36eb33f0989c4aa3c635881f6f9)) +* **web:** add bundle note messages ([#992](https://github.com/labring/laf/issues/992)) ([f8adbe7](https://github.com/labring/laf/commit/f8adbe7af9e43fc4acf47f4ae57f1cf7d91f8ec8)) +* **web:** add region info on logo ([#1001](https://github.com/labring/laf/issues/1001)) ([378b0e6](https://github.com/labring/laf/commit/378b0e6c3fc7995cbd56d5a9a78f789688bf6f61)) +* **web:** fix login bg && add welcome text ([#941](https://github.com/labring/laf/issues/941)) ([6baf800](https://github.com/labring/laf/commit/6baf80037d4ccee29e9b4c7f546c5a5948f3dded)) +* **web:** format code on save ([#1002](https://github.com/labring/laf/issues/1002)) ([e970a66](https://github.com/labring/laf/commit/e970a66cdb0be1d6521a3df757f18eb62644b137)) +* **web:** generate function code with AI prompt ([#978](https://github.com/labring/laf/issues/978)) ([c68b03b](https://github.com/labring/laf/commit/c68b03b278423202798e416cbe613a6e3dfaa211)) +* **web:** reset password ([#974](https://github.com/labring/laf/issues/974)) ([13a2a9f](https://github.com/labring/laf/commit/13a2a9f2010ac872f28160ee3b33638146c16566)) + + + +# [1.0.0-beta.5](https://github.com/labring/laf/compare/v1.0.0-beta.4...v1.0.0-beta.5) (2023-03-22) + + +### Bug Fixes + +* **cli:** fix axios type error ([#881](https://github.com/labring/laf/issues/881)) ([5f8b487](https://github.com/labring/laf/commit/5f8b487590c5e12a0dbd7c756c2c8431529394c9)) +* **cli:** fix publish package ignore file ([#899](https://github.com/labring/laf/issues/899)) ([bf9c907](https://github.com/labring/laf/commit/bf9c907ff4d083c9796f5a32533609b2da9cb0f5)) +* **cli:** remove private npm mirror and replace AxiosRequestConfig to any ([#886](https://github.com/labring/laf/issues/886)) ([561fe7f](https://github.com/labring/laf/commit/561fe7fa0dbf9b9fd1126f906791c1844e367993)) +* **server:** add max renewal time in bundle; fix subscription price ([#908](https://github.com/labring/laf/issues/908)) ([6139f74](https://github.com/labring/laf/commit/6139f743f79e23dadfa56e4b9c85429745d16483)) +* **server:** add regex for environment name ([#944](https://github.com/labring/laf/issues/944)) ([1f5c300](https://github.com/labring/laf/commit/1f5c300d5f4f7de04544afe17f303614cc9379fc)) +* **server:** change password signup phone filed to optional ([#934](https://github.com/labring/laf/issues/934)) ([c35d339](https://github.com/labring/laf/commit/c35d339906d672dba821c67add714f5615363c9b)) +* **server:** deal with existed app without namespace ([#943](https://github.com/labring/laf/issues/943)) ([5ed3be5](https://github.com/labring/laf/commit/5ed3be5cec0d7dd987a9a9043bd0440e9126f701)) +* **server:** fix bucket name regex ([#924](https://github.com/labring/laf/issues/924)) ([2c84173](https://github.com/labring/laf/commit/2c84173322e414c48cb0d17795437d5fdeb913a3)) +* **server:** fix init auth provider params ([#937](https://github.com/labring/laf/issues/937)) ([796774f](https://github.com/labring/laf/commit/796774fc64515626461a79312d4388eaccf13e56)) +* **server:** stuck-starting instance blocked the task handler ([#945](https://github.com/labring/laf/issues/945)) ([f9a0f20](https://github.com/labring/laf/commit/f9a0f20d1154d0a88d6087ea9cf290e3da02dc5f)) +* **web:** fix MoreButton tooltip and npm package deletion confirm tip ([#879](https://github.com/labring/laf/issues/879)) ([3b30aec](https://github.com/labring/laf/commit/3b30aece63a5d52350ad085b4e974d9d73157712)) +* **web:** fix some dark mode ui bugs ([#919](https://github.com/labring/laf/issues/919)) ([f9e1781](https://github.com/labring/laf/commit/f9e17813677e64c1a578a041dcd90c52e1860247)) +* **web:** login page i18n word too long ([#936](https://github.com/labring/laf/issues/936)) ([0836e11](https://github.com/labring/laf/commit/0836e11751c2c16ba2ea4a57cd07f7a23cb93caa)) +* **web:** sign up provider err while refreshing page ([#938](https://github.com/labring/laf/issues/938)) ([4ad79c9](https://github.com/labring/laf/commit/4ad79c9a6a388d421c693b2a8b8729b02f9a7cf4)) +* **web:** update data use merge mode ([#940](https://github.com/labring/laf/issues/940)) ([d62fe96](https://github.com/labring/laf/commit/d62fe96346515a9083c7e828332098ae2b3b75f7)) +* **web:** web signup phone err ([#935](https://github.com/labring/laf/issues/935)) ([44b0699](https://github.com/labring/laf/commit/44b0699409f8085ba739aeceaf891732bda7b441)) + + +### Features + +* **cli:** cli invoke function support parameters ([#884](https://github.com/labring/laf/issues/884)) ([f0a6383](https://github.com/labring/laf/commit/f0a638367e04971faddff8303959949d5d8867fd)) +* **cli:** init app support sync data ([#895](https://github.com/labring/laf/issues/895)) ([449abde](https://github.com/labring/laf/commit/449abde959a3243ee29103d14f431a61a46698f9)) +* **cli:** rename name.meta.yaml to name.yaml ([#893](https://github.com/labring/laf/issues/893)) ([1dd12b2](https://github.com/labring/laf/commit/1dd12b2c16c37ae2f7724954d73a98909f3faa5f)) +* **cli:** upgrade s3 sdk version ([#922](https://github.com/labring/laf/issues/922)) ([8589126](https://github.com/labring/laf/commit/858912689388caaef672faa1021851d485fc4762)) +* **server:** add limit to update app state depends on subscription state ([39447d8](https://github.com/labring/laf/commit/39447d88752fe91b08ac99bb1db30bc201c1eb36)) +* **server:** new authentication implements ([#897](https://github.com/labring/laf/issues/897)) ([c4e3cf8](https://github.com/labring/laf/commit/c4e3cf81655ae7f2b2fcb029263dd5f4e4b9d0e8)) +* **subscription:** impl subscription and account ([#894](https://github.com/labring/laf/issues/894)) ([b8f2d47](https://github.com/labring/laf/commit/b8f2d4761140f2fecb0d7543d5faf48f2c9621e7)) +* **web:** add dark mode support ([#891](https://github.com/labring/laf/issues/891)) ([#900](https://github.com/labring/laf/issues/900)) ([99e1568](https://github.com/labring/laf/commit/99e156832a3c257af24aa04ca86c9518ff4d38f8)) +* **web:** add subscription and wechat pay ([#904](https://github.com/labring/laf/issues/904)) ([31c3a32](https://github.com/labring/laf/commit/31c3a324e66021c5ac83b2f60cd9819954a68744)) +* **web:** impl new signup & signin method ([#910](https://github.com/labring/laf/issues/910)) ([0832b1e](https://github.com/labring/laf/commit/0832b1e609e94d321028ea1d15a4cc7df0f893ef)) + + + # [1.0.0-beta.4](https://github.com/labring/laf/compare/v1.0.0-beta.3...v1.0.0-beta.4) (2023-03-09) diff --git a/README.md b/README.md index a4b160239d..aa37b9f1ed 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,16 @@ > [English](README_en.md) | 中文 +## 🚀 Quick Start + +[三分钟体验使用 laf 写一个自己的 ChatGPT (开发到上线)](https://icloudnative.io/posts/build-chatgpt-web-using-laf/) +[三分钟体验使用 laf 开发一个简单的 「Todo List」 ](./docs/guide/quick-start/Todo.md) + ## 🖥 在线体验 -🎉 [laf.dev](https://laf.dev) 可免费体验 `laf` 云开发。 +🎉 [laf.run](https://laf.run) 可免费体验 `laf` 云开发。(国内版) + +🎉 [laf.dev](https://laf.dev) 可免费体验 `laf` 云开发。(海外版) ## 👀 `laf` 是什么 @@ -73,10 +80,6 @@ laf 是开源的云开发平台,提供云函数、云数据库、云存储等 > life is short, you need laf:) -## 🚀 Quick Start - -[三分钟体验使用 laf 开发一个简单的登陆注册功能](./docs/guide/quick-start/index.md) - ## 🎉 Self-hosted Deployment [Deployment](./deploy/scripts/README.md) diff --git a/README_en.md b/README_en.md index 33262c830c..f47f5aaa20 100644 --- a/README_en.md +++ b/README_en.md @@ -162,7 +162,7 @@ Independent domain names and HTTPS licenses can be applied to your applications ## 🚀 Quick Start -[develop a register/login feature within 3 minutes](./docs/guide/quick-start/index.md) +[develop a 「Todo List」 feature within 3 minutes](./docs/guide/quick-start/Todo.md) ## 🎉 Self-hosting diff --git a/cli/README.md b/cli/README.md new file mode 100644 index 0000000000..2e9a4bde52 --- /dev/null +++ b/cli/README.md @@ -0,0 +1,88 @@ +## Project Introduction + +laf-cli is a command-line tool designed to help developers quickly create, deploy, and manage applications on laf. + +## Quick Start + +To install laf-cli, use npm: +```bash +npm install -g laf-cli +``` + +Once installation is complete, verify the installation using: +```bash +laf -v +``` + +To log in, use the login command with your personal access token (PAT), which can be obtained from User Settings -> Personal Access Tokens: +```bash +laf login +``` + +View the list of applications and initialize an application: +```bash +laf app list +laf app init +``` + +For more commands and usage: +```bash +laf -h +``` + +## Development + +To begin development, follow the steps below: + +1. Navigate to the cli directory in the terminal: +```bash +cd cli +``` + +2. Install the required dependencies: +```bash +npm install +``` + +3. Run the watch command: +```bash +npm run watch +``` + +4. Open a new terminal and run link command: +```bash +npm link +``` + +5. Finally, verify that everything is working as expected: +```bash +laf -v +``` + +## File Tree + +``` +├── src +| ├── action +| | ├── application +| | ├── auth +| | ├── dependency +| | ├── function +| | ├── policy +| | ├── storage +| | └── website +| ├── api +| | └── v1 +| ├── command +| | ├── application +| | ├── auth +| | ├── dependency +| | ├── function +| | ├── policy +| | ├── storage +| | └── website +| ├── common +| ├── config +| └── util +└── template +``` diff --git a/cli/package-lock.json b/cli/package-lock.json index 2158dcb0b9..ce59dc3118 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -1,15 +1,15 @@ { "name": "laf-cli", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "laf-cli", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "license": "ISC", "dependencies": { - "aws-sdk": "^2.1167.0", + "@aws-sdk/client-s3": "^3.45.0", "axios": "^1.2.1", "class-transformer": "^0.5.1", "cli": "^1.0.1", @@ -32,6 +32,1319 @@ "@types/node": "^17.0.31" } }, + "node_modules/@aws-crypto/crc32": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-3.0.0.tgz", + "integrity": "sha512-IzSgsrxUcsrejQbPVilIKy16kAT52EwB6zSaI+M3xxIhKh5+aldEyvI+z6erM7TCLB2BJsFrtHjp6/4/sr+3dA==", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/crc32/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/crc32c": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-3.0.0.tgz", + "integrity": "sha512-ENNPPManmnVJ4BTXlOjAgD7URidbAznURqD0KvfREyc4o20DPYdEldU1f5cQ7Jbj0CJJSPaMIk/9ZshdB3210w==", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/crc32c/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/ie11-detection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-3.0.0.tgz", + "integrity": "sha512-341lBBkiY1DfDNKai/wXM3aujNBkXR7tq1URPQDL9wi3AUbI80NR74uF1TXHMm7po1AcnFk8iu2S2IeU/+/A+Q==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/ie11-detection/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha1-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-3.0.0.tgz", + "integrity": "sha512-NJth5c997GLHs6nOYTzFKTbYdMNA6/1XlKVgnZoaZcQ7z7UJlOgj2JdbHE8tiYLS3fzXNCguct77SPGat2raSw==", + "dependencies": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-3.0.0.tgz", + "integrity": "sha512-8VLmW2B+gjFbU5uMeqtQM6Nj0/F1bro80xQXCW6CQBWgosFWXTx77aeOF5CAIAmbOK64SdMBJdNr6J41yP5mvQ==", + "dependencies": { + "@aws-crypto/ie11-detection": "^3.0.0", + "@aws-crypto/sha256-js": "^3.0.0", + "@aws-crypto/supports-web-crypto": "^3.0.0", + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-3.0.0.tgz", + "integrity": "sha512-PnNN7os0+yd1XvXAy23CFOmTbMaDxgxXtTKHybrJ39Y8kGzBATgBFibWJKH6BhytLI/Zyszs87xCOBNyBig6vQ==", + "dependencies": { + "@aws-crypto/util": "^3.0.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/sha256-js/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-3.0.0.tgz", + "integrity": "sha512-06hBdMwUAb2WFTuGG73LSC0wfPu93xWwo5vL2et9eymgmu3Id5vFAHBbajVWiGhPO37qcsdCap/FqXvJGJWPIg==", + "dependencies": { + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/supports-web-crypto/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-crypto/util": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-3.0.0.tgz", + "integrity": "sha512-2OJlpeJpCR48CC8r+uKVChzs9Iungj9wkZrl8Z041DWEWvyIHILYKCPNzJghKsivj+S3mLo6BVc7mBNzdxA46w==", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/util/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@aws-sdk/abort-controller": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.292.0.tgz", + "integrity": "sha512-lf+OPptL01kvryIJy7+dvFux5KbJ6OTwLPPEekVKZ2AfEvwcVtOZWFUhyw3PJCBTVncjKB1Kjl3V/eTS3YuPXQ==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/chunked-blob-reader": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/chunked-blob-reader/-/chunked-blob-reader-3.292.0.tgz", + "integrity": "sha512-ccFPnzBjLbDCmFjTXwhsfD58vtEiAjbor3A9tvnou+3Dj6RrMEGPaTu5tcw3mwWb2zh1K3HFJg6Bmb0no49TRw==", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/chunked-blob-reader-native": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/chunked-blob-reader-native/-/chunked-blob-reader-native-3.292.0.tgz", + "integrity": "sha512-A34sBrnggm9mXPZeeEie4jDv9zHRMS0LSm85VkfrBLuYYsfsw9DxmW59wJkuo6DIm/RK04oH5+lRMt34koBgrw==", + "dependencies": { + "@aws-sdk/util-base64": "3.292.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.293.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.293.0.tgz", + "integrity": "sha512-07Beb9mW+RX1nYf3jqW7jS77wYPWQKPcHTa9SlX7qEB2W0KKZy8Re9jZgdz7zHIi7j82TsD8wBW+MKHUujJWAQ==", + "dependencies": { + "@aws-crypto/sha1-browser": "3.0.0", + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sts": "3.293.0", + "@aws-sdk/config-resolver": "3.292.0", + "@aws-sdk/credential-provider-node": "3.293.0", + "@aws-sdk/eventstream-serde-browser": "3.292.0", + "@aws-sdk/eventstream-serde-config-resolver": "3.292.0", + "@aws-sdk/eventstream-serde-node": "3.292.0", + "@aws-sdk/fetch-http-handler": "3.292.0", + "@aws-sdk/hash-blob-browser": "3.292.0", + "@aws-sdk/hash-node": "3.292.0", + "@aws-sdk/hash-stream-node": "3.292.0", + "@aws-sdk/invalid-dependency": "3.292.0", + "@aws-sdk/md5-js": "3.292.0", + "@aws-sdk/middleware-bucket-endpoint": "3.292.0", + "@aws-sdk/middleware-content-length": "3.292.0", + "@aws-sdk/middleware-endpoint": "3.292.0", + "@aws-sdk/middleware-expect-continue": "3.292.0", + "@aws-sdk/middleware-flexible-checksums": "3.292.0", + "@aws-sdk/middleware-host-header": "3.292.0", + "@aws-sdk/middleware-location-constraint": "3.292.0", + "@aws-sdk/middleware-logger": "3.292.0", + "@aws-sdk/middleware-recursion-detection": "3.292.0", + "@aws-sdk/middleware-retry": "3.293.0", + "@aws-sdk/middleware-sdk-s3": "3.292.0", + "@aws-sdk/middleware-serde": "3.292.0", + "@aws-sdk/middleware-signing": "3.292.0", + "@aws-sdk/middleware-ssec": "3.292.0", + "@aws-sdk/middleware-stack": "3.292.0", + "@aws-sdk/middleware-user-agent": "3.293.0", + "@aws-sdk/node-config-provider": "3.292.0", + "@aws-sdk/node-http-handler": "3.292.0", + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/signature-v4-multi-region": "3.292.0", + "@aws-sdk/smithy-client": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/url-parser": "3.292.0", + "@aws-sdk/util-base64": "3.292.0", + "@aws-sdk/util-body-length-browser": "3.292.0", + "@aws-sdk/util-body-length-node": "3.292.0", + "@aws-sdk/util-defaults-mode-browser": "3.292.0", + "@aws-sdk/util-defaults-mode-node": "3.292.0", + "@aws-sdk/util-endpoints": "3.293.0", + "@aws-sdk/util-retry": "3.292.0", + "@aws-sdk/util-stream-browser": "3.292.0", + "@aws-sdk/util-stream-node": "3.292.0", + "@aws-sdk/util-user-agent-browser": "3.292.0", + "@aws-sdk/util-user-agent-node": "3.292.0", + "@aws-sdk/util-utf8": "3.292.0", + "@aws-sdk/util-waiter": "3.292.0", + "@aws-sdk/xml-builder": "3.292.0", + "fast-xml-parser": "4.1.2", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.293.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.293.0.tgz", + "integrity": "sha512-EtVgEqL4vSDAV6vi9QzeZA5M+CIQIPoy14Q6Gl7TWehakxBqGFw2xnEHBo2djWH5oJMQAGOfjICPkZLoKxJT1A==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.292.0", + "@aws-sdk/fetch-http-handler": "3.292.0", + "@aws-sdk/hash-node": "3.292.0", + "@aws-sdk/invalid-dependency": "3.292.0", + "@aws-sdk/middleware-content-length": "3.292.0", + "@aws-sdk/middleware-endpoint": "3.292.0", + "@aws-sdk/middleware-host-header": "3.292.0", + "@aws-sdk/middleware-logger": "3.292.0", + "@aws-sdk/middleware-recursion-detection": "3.292.0", + "@aws-sdk/middleware-retry": "3.293.0", + "@aws-sdk/middleware-serde": "3.292.0", + "@aws-sdk/middleware-stack": "3.292.0", + "@aws-sdk/middleware-user-agent": "3.293.0", + "@aws-sdk/node-config-provider": "3.292.0", + "@aws-sdk/node-http-handler": "3.292.0", + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/smithy-client": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/url-parser": "3.292.0", + "@aws-sdk/util-base64": "3.292.0", + "@aws-sdk/util-body-length-browser": "3.292.0", + "@aws-sdk/util-body-length-node": "3.292.0", + "@aws-sdk/util-defaults-mode-browser": "3.292.0", + "@aws-sdk/util-defaults-mode-node": "3.292.0", + "@aws-sdk/util-endpoints": "3.293.0", + "@aws-sdk/util-retry": "3.292.0", + "@aws-sdk/util-user-agent-browser": "3.292.0", + "@aws-sdk/util-user-agent-node": "3.292.0", + "@aws-sdk/util-utf8": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sso-oidc": { + "version": "3.293.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.293.0.tgz", + "integrity": "sha512-GrbcBzRxWNRc5unZ0rOe1Jzhjvf7xIiCfLDhXYKaafb38gxUc3vDPy4Uzih6Trcq525oB0fG7iiZJgstMXelcw==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.292.0", + "@aws-sdk/fetch-http-handler": "3.292.0", + "@aws-sdk/hash-node": "3.292.0", + "@aws-sdk/invalid-dependency": "3.292.0", + "@aws-sdk/middleware-content-length": "3.292.0", + "@aws-sdk/middleware-endpoint": "3.292.0", + "@aws-sdk/middleware-host-header": "3.292.0", + "@aws-sdk/middleware-logger": "3.292.0", + "@aws-sdk/middleware-recursion-detection": "3.292.0", + "@aws-sdk/middleware-retry": "3.293.0", + "@aws-sdk/middleware-serde": "3.292.0", + "@aws-sdk/middleware-stack": "3.292.0", + "@aws-sdk/middleware-user-agent": "3.293.0", + "@aws-sdk/node-config-provider": "3.292.0", + "@aws-sdk/node-http-handler": "3.292.0", + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/smithy-client": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/url-parser": "3.292.0", + "@aws-sdk/util-base64": "3.292.0", + "@aws-sdk/util-body-length-browser": "3.292.0", + "@aws-sdk/util-body-length-node": "3.292.0", + "@aws-sdk/util-defaults-mode-browser": "3.292.0", + "@aws-sdk/util-defaults-mode-node": "3.292.0", + "@aws-sdk/util-endpoints": "3.293.0", + "@aws-sdk/util-retry": "3.292.0", + "@aws-sdk/util-user-agent-browser": "3.292.0", + "@aws-sdk/util-user-agent-node": "3.292.0", + "@aws-sdk/util-utf8": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sts": { + "version": "3.293.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.293.0.tgz", + "integrity": "sha512-cNKWt9Xnv1sQvdLnzCdDJBRgavWH6g5F8TzrueaCq10cg/GanKkCgiIZFoKDv8LQ3dHzTkp/OKp4sN5N5DH/Ow==", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/config-resolver": "3.292.0", + "@aws-sdk/credential-provider-node": "3.293.0", + "@aws-sdk/fetch-http-handler": "3.292.0", + "@aws-sdk/hash-node": "3.292.0", + "@aws-sdk/invalid-dependency": "3.292.0", + "@aws-sdk/middleware-content-length": "3.292.0", + "@aws-sdk/middleware-endpoint": "3.292.0", + "@aws-sdk/middleware-host-header": "3.292.0", + "@aws-sdk/middleware-logger": "3.292.0", + "@aws-sdk/middleware-recursion-detection": "3.292.0", + "@aws-sdk/middleware-retry": "3.293.0", + "@aws-sdk/middleware-sdk-sts": "3.292.0", + "@aws-sdk/middleware-serde": "3.292.0", + "@aws-sdk/middleware-signing": "3.292.0", + "@aws-sdk/middleware-stack": "3.292.0", + "@aws-sdk/middleware-user-agent": "3.293.0", + "@aws-sdk/node-config-provider": "3.292.0", + "@aws-sdk/node-http-handler": "3.292.0", + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/smithy-client": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/url-parser": "3.292.0", + "@aws-sdk/util-base64": "3.292.0", + "@aws-sdk/util-body-length-browser": "3.292.0", + "@aws-sdk/util-body-length-node": "3.292.0", + "@aws-sdk/util-defaults-mode-browser": "3.292.0", + "@aws-sdk/util-defaults-mode-node": "3.292.0", + "@aws-sdk/util-endpoints": "3.293.0", + "@aws-sdk/util-retry": "3.292.0", + "@aws-sdk/util-user-agent-browser": "3.292.0", + "@aws-sdk/util-user-agent-node": "3.292.0", + "@aws-sdk/util-utf8": "3.292.0", + "fast-xml-parser": "4.1.2", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/config-resolver": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.292.0.tgz", + "integrity": "sha512-cB3twnNR7vYvlt2jvw8VlA1+iv/tVzl+/S39MKqw2tepU+AbJAM0EHwb/dkf1OKSmlrnANXhshx80MHF9zL4mA==", + "dependencies": { + "@aws-sdk/signature-v4": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-config-provider": "3.292.0", + "@aws-sdk/util-middleware": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.292.0.tgz", + "integrity": "sha512-YbafSG0ZEKE2969CJWVtUhh3hfOeLPecFVoXOtegCyAJgY5Ghtu4TsVhL4DgiGAgOC30ojAmUVQEXzd7xJF5xA==", + "dependencies": { + "@aws-sdk/property-provider": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-imds": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.292.0.tgz", + "integrity": "sha512-W/peOgDSRYulgzFpUhvgi1pCm6piBz6xrVN17N4QOy+3NHBXRVMVzYk6ct2qpLPgJUSEZkcpP+Gds+bBm8ed1A==", + "dependencies": { + "@aws-sdk/node-config-provider": "3.292.0", + "@aws-sdk/property-provider": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/url-parser": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.293.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.293.0.tgz", + "integrity": "sha512-Cy32aGm8Qc70Jc7VjcaxAEBfhLCS6/iewX4ZSI6MRoo0NrggnIwD9pdtO0Y0eqzEHXJvl2bycXFTJPmW4AzQIA==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.292.0", + "@aws-sdk/credential-provider-imds": "3.292.0", + "@aws-sdk/credential-provider-process": "3.292.0", + "@aws-sdk/credential-provider-sso": "3.293.0", + "@aws-sdk/credential-provider-web-identity": "3.292.0", + "@aws-sdk/property-provider": "3.292.0", + "@aws-sdk/shared-ini-file-loader": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.293.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.293.0.tgz", + "integrity": "sha512-w6NuuEiVZ5Ja2fmXbo5GiH2cykKw682HvL6bZ5Yhdj27twFL+4jUuXONxibQkXgTJbtiTx3tlcdLOa67RDq8ow==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.292.0", + "@aws-sdk/credential-provider-imds": "3.292.0", + "@aws-sdk/credential-provider-ini": "3.293.0", + "@aws-sdk/credential-provider-process": "3.292.0", + "@aws-sdk/credential-provider-sso": "3.293.0", + "@aws-sdk/credential-provider-web-identity": "3.292.0", + "@aws-sdk/property-provider": "3.292.0", + "@aws-sdk/shared-ini-file-loader": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.292.0.tgz", + "integrity": "sha512-CFVXuMuUvg/a4tknzRikEDwZBnKlHs1LZCpTXIGjBdUTdosoi4WNzDLzGp93ZRTtcgFz+4wirz2f7P3lC0NrQw==", + "dependencies": { + "@aws-sdk/property-provider": "3.292.0", + "@aws-sdk/shared-ini-file-loader": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.293.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.293.0.tgz", + "integrity": "sha512-XdZW6mgAcV20AXrQ3FYKVZAO8LuFZwZnEf34Xc1Z2MuHkbSXxixPDu+mqbUKMwru1rmy6YaZ0eNuIbZYVCq0mw==", + "dependencies": { + "@aws-sdk/client-sso": "3.293.0", + "@aws-sdk/property-provider": "3.292.0", + "@aws-sdk/shared-ini-file-loader": "3.292.0", + "@aws-sdk/token-providers": "3.293.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.292.0.tgz", + "integrity": "sha512-4DbtIEM9gGVfqYlMdYXg3XY+vBhemjB1zXIequottW8loLYM8Vuz4/uGxxKNze6evVVzowsA0wKrYclE1aj/Rg==", + "dependencies": { + "@aws-sdk/property-provider": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/eventstream-codec": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-codec/-/eventstream-codec-3.292.0.tgz", + "integrity": "sha512-P0np4vhCKf/JH6I39Id8DxZR+UZzG+Br+vOrTinerMfOhzTa2229XmL8pwlMpOoxnJLMPmEDtD1KQqLslBEXtw==", + "dependencies": { + "@aws-crypto/crc32": "3.0.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-hex-encoding": "3.292.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/eventstream-serde-browser": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-browser/-/eventstream-serde-browser-3.292.0.tgz", + "integrity": "sha512-VzRbJqqE444GOuoNTxTJ1dC1IhNhA6jfHjgsI8iDRHraaEukGqsPx1vkc+byxrDEjgxKN5IqOwZ4yJWMIAozBA==", + "dependencies": { + "@aws-sdk/eventstream-serde-universal": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/eventstream-serde-config-resolver": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.292.0.tgz", + "integrity": "sha512-Ndx+qJyWmBCW9FSm68AGLoO4AZ0AaL/wjpJEgFF2sZBWjYe9O9PB9IGR/yuqCBTElf3YtSiFMsloikQaz2ft6g==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/eventstream-serde-node": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-node/-/eventstream-serde-node-3.292.0.tgz", + "integrity": "sha512-NFCEiNCetNye7jQfRd5y/7J9dLg9+uL57698wYeXeadlwJ8Cd/Nhsz+t7RIbP05VqshU+anXARMB1avl9oAijQ==", + "dependencies": { + "@aws-sdk/eventstream-serde-universal": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/eventstream-serde-universal": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-universal/-/eventstream-serde-universal-3.292.0.tgz", + "integrity": "sha512-1gqZNx+S1EUpl3Tq6uIesiDx8gnkpXqPsFfCZT7lSWWXBpnHmnUZAh3jbiO9UlQbYuB9SfT0EBKb1iOY9z4j1Q==", + "dependencies": { + "@aws-sdk/eventstream-codec": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/fetch-http-handler": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.292.0.tgz", + "integrity": "sha512-zh3bhUJbL8RSa39ZKDcy+AghtUkIP8LwcNlwRIoxMQh3Row4D1s4fCq0KZCx98NJBEXoiTLyTQlZxxI//BOb1Q==", + "dependencies": { + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/querystring-builder": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-base64": "3.292.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/hash-blob-browser": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.292.0.tgz", + "integrity": "sha512-4+Fm4IOkxGqgx8dU0EbExCq6xx30y369ZSXz89h9YDQYdJ2Muw7iNCHAg/4VM+gfp0vo9J8zPOTsSju8LNS5Jg==", + "dependencies": { + "@aws-sdk/chunked-blob-reader": "3.292.0", + "@aws-sdk/chunked-blob-reader-native": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/hash-node": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.292.0.tgz", + "integrity": "sha512-1yLxmIsvE+eK36JXEgEIouTITdykQLVhsA5Oai//Lar6Ddgu1sFpLDbdkMtKbrh4I0jLN9RacNCkeVQjZPTCCQ==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-buffer-from": "3.292.0", + "@aws-sdk/util-utf8": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/hash-stream-node": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-stream-node/-/hash-stream-node-3.292.0.tgz", + "integrity": "sha512-p2nj9A5lZKQU45Q4Od3iZDvpziEpojAyuyAI0HPzpIuJIfzFQ0/7pMBKde1li6wq93rpyFLwNufV6FEZnKCYRg==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-utf8": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/invalid-dependency": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.292.0.tgz", + "integrity": "sha512-39OUV78CD3TmEbjhpt+V+Fk4wAGWhixqHxDSN8+4WL0uB4Fl7k5m3Z9hNY78AttHQSl2twR7WtLztnXPAFsriw==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/is-array-buffer": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.292.0.tgz", + "integrity": "sha512-kW/G5T/fzI0sJH5foZG6XJiNCevXqKLxV50qIT4B1pMuw7regd4ALIy0HwSqj1nnn9mSbRWBfmby0jWCJsMcwg==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/md5-js": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/md5-js/-/md5-js-3.292.0.tgz", + "integrity": "sha512-ngfsKLgQenXW3EbsDf47PVNys1SecTbsq6k88h7+Aa8BU49+9ZOIz4VDpWuPiNyYpeV7jJdl1dfD+ujOYvvgNw==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-utf8": "3.292.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/middleware-bucket-endpoint": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.292.0.tgz", + "integrity": "sha512-XRy9RSUIRcbxYfH504ywhQllgfdf3wVhk2k0mMPYnUbeEhAFe1/eUog2v/bi07/q5TQ4Hppi+W3nHCVualQEow==", + "dependencies": { + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-arn-parser": "3.292.0", + "@aws-sdk/util-config-provider": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-content-length": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.292.0.tgz", + "integrity": "sha512-2gMWzQus5mj14menolpPDbYBeaOYcj7KNFZOjTjjI3iQ0KqyetG6XasirNrcJ/8QX1BRmpTol8Xjp2Ue3Gbzwg==", + "dependencies": { + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-endpoint": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint/-/middleware-endpoint-3.292.0.tgz", + "integrity": "sha512-cPMkiSxpZGG6tYlW4OS+ucS6r43f9ddX9kcUoemJCY10MOuogdPjulCAjE0HTs2PLKSOrrG4CTP4Q4wWDrH4Bw==", + "dependencies": { + "@aws-sdk/middleware-serde": "3.292.0", + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/signature-v4": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/url-parser": "3.292.0", + "@aws-sdk/util-config-provider": "3.292.0", + "@aws-sdk/util-middleware": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-expect-continue": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.292.0.tgz", + "integrity": "sha512-bZ2bsBud3E6BebZWGxVcWxBSg09bP0KyX8PT0jI66JM0yTbZSJhoGhlKAqfNG46R9h4K5tCYB2uYgV/3oU/ZpQ==", + "dependencies": { + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-flexible-checksums": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.292.0.tgz", + "integrity": "sha512-AxU/Gb+TRdl/0jHmbreYh3QnB0jR25zgjPZ4/JbGBJ2SQI9jm3LCNK9XOrPUmZp/vu9wsvyxtmKQidpQ5+FX5w==", + "dependencies": { + "@aws-crypto/crc32": "3.0.0", + "@aws-crypto/crc32c": "3.0.0", + "@aws-sdk/is-array-buffer": "3.292.0", + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-utf8": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.292.0.tgz", + "integrity": "sha512-mHuCWe3Yg2S5YZ7mB7sKU6C97XspfqrimWjMW9pfV2usAvLA3R0HrB03jpR5vpZ3P4q7HB6wK3S6CjYMGGRNag==", + "dependencies": { + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-location-constraint": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.292.0.tgz", + "integrity": "sha512-WTbMyoCckdkmq7Yok0gI4226gTmxP/zM1fbFiC+liZXBJ+H5EvIFmu30tWbX+4m41LL/XQVm65olXJFwhoExGQ==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.292.0.tgz", + "integrity": "sha512-yZNY1XYmG3NG+uonET7jzKXNiwu61xm/ZZ6i/l51SusuaYN+qQtTAhOFsieQqTehF9kP4FzbsWgPDwD8ZZX9lw==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.292.0.tgz", + "integrity": "sha512-kA3VZpPko0Zqd7CYPTKAxhjEv0HJqFu2054L04dde1JLr43ro+2MTdX7vsHzeAFUVRphqatFFofCumvXmU6Mig==", + "dependencies": { + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-retry": { + "version": "3.293.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.293.0.tgz", + "integrity": "sha512-7tiaz2GzRecNHaZ6YnF+Nrtk3au8qF6oiipf11R7MJiqJ0fkMLnz/iRrlakDziS9qF/a9v+3yxb4W4NHK3f4Tw==", + "dependencies": { + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/service-error-classification": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-middleware": "3.292.0", + "@aws-sdk/util-retry": "3.292.0", + "tslib": "^2.3.1", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-retry/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.292.0.tgz", + "integrity": "sha512-kEUmh3ZM34H+2bEQfpZhVotJCNYpSbq9Q4YxlWVbnjiO/VS+S9BFEM3Fcj5+EzEgI02tNNi6/qTXj3iS8tT6hA==", + "dependencies": { + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-arn-parser": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-sts": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.292.0.tgz", + "integrity": "sha512-GN5ZHEqXZqDi+HkVbaXRX9HaW/vA5rikYpWKYsmxTUZ7fB7ijvEO3co3lleJv2C+iGYRtUIHC4wYNB5xgoTCxg==", + "dependencies": { + "@aws-sdk/middleware-signing": "3.292.0", + "@aws-sdk/property-provider": "3.292.0", + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/signature-v4": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-serde": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.292.0.tgz", + "integrity": "sha512-6hN9mTQwSvV8EcGvtXbS/MpK7WMCokUku5Wu7X24UwCNMVkoRHLIkYcxHcvBTwttuOU0d8hph1/lIX4dkLwkQw==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-signing": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.292.0.tgz", + "integrity": "sha512-GVfoSjDjEQ4TaO6x9MffyP3uRV+2KcS5FtexLCYOM9pJcnE9tqq9FJOrZ1xl1g+YjUVKxo4x8lu3tpEtIb17qg==", + "dependencies": { + "@aws-sdk/property-provider": "3.292.0", + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/signature-v4": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-middleware": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-ssec": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.292.0.tgz", + "integrity": "sha512-VfwrTEs9nYU6sCnt/cffhnJ2djGkMyMbBEysMZm2HEbFMloGKBd0Wtvk9y+SWPa6+DDRe2CqqX8jMzrO4JT4Eg==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-stack": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.292.0.tgz", + "integrity": "sha512-WdQpRkuMysrEwrkByCM1qCn2PPpFGGQ2iXqaFha5RzCdZDlxJni9cVNb6HzWUcgjLEYVTXCmOR9Wxm3CNW44Qg==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.293.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.293.0.tgz", + "integrity": "sha512-gZ7/e6XwpKk9mvgA78q4Ffc796jTn02TUKx2qMDnkLVbeJXBNN2jnvYEKq8v70+o7fd/ALRudg8gBDmkkhM/Hw==", + "dependencies": { + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-endpoints": "3.293.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/node-config-provider": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.292.0.tgz", + "integrity": "sha512-S3NnC9dQ5GIbJYSDIldZb4zdpCOEua1tM7bjYL3VS5uqCEM93kIi/o/UkIUveMp/eqTS2LJa5HjNIz5Te6je0A==", + "dependencies": { + "@aws-sdk/property-provider": "3.292.0", + "@aws-sdk/shared-ini-file-loader": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/node-http-handler": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.292.0.tgz", + "integrity": "sha512-L/E3UDSwXLXjt1XWWh0RBD55F+aZI1AEdPwdES9i1PjnZLyuxuDhEDptVibNN56+I9/4Q3SbmuVRVlOD0uzBag==", + "dependencies": { + "@aws-sdk/abort-controller": "3.292.0", + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/querystring-builder": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/property-provider": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.292.0.tgz", + "integrity": "sha512-dHArSvsiqhno/g55N815gXmAMrmN8DP7OeFNqJ4wJG42xsF2PFN3DAsjIuHuXMwu+7A3R1LHqIpvv0hA9KeoJQ==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/protocol-http": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.292.0.tgz", + "integrity": "sha512-NLi4fq3k41aXIh1I97yX0JTy+3p6aW1NdwFwdMa674z86QNfb4SfRQRZBQe9wEnAZ/eWHVnlKIuII+U1URk/Kg==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/querystring-builder": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.292.0.tgz", + "integrity": "sha512-XElIFJaReIm24eEvBtV2dOtZvcm3gXsGu/ftG8MLJKbKXFKpAP1q+K6En0Bs7/T88voKghKdKpKT+eZUWgTqlg==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-uri-escape": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/querystring-parser": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.292.0.tgz", + "integrity": "sha512-iTYpYo7a8X9RxiPbjjewIpm6XQPx2EOcF1dWCPRII9EFlmZ4bwnX+PDI36fIo9oVs8TIKXmwNGODU9nsg7CSAw==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/service-error-classification": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.292.0.tgz", + "integrity": "sha512-X1k3sixCeC45XSNHBe+kRBQBwPDyTFtFITb8O5Qw4dS9XWGhrUJT4CX0qE5aj8qP3F9U5nRizs9c2mBVVP0Caw==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/shared-ini-file-loader": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.292.0.tgz", + "integrity": "sha512-Av2TTYg1Jig2kbkD56ybiqZJB6vVrYjv1W5UQwY/q3nA/T2mcrgQ20ByCOt5Bv9VvY7FSgC+znj+L4a7RLGmBg==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.292.0.tgz", + "integrity": "sha512-+rw47VY5mvBecn13tDQTl1ipGWg5tE63faWgmZe68HoBL87ZiDzsd7bUKOvjfW21iMgWlwAppkaNNQayYRb2zg==", + "dependencies": { + "@aws-sdk/is-array-buffer": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-hex-encoding": "3.292.0", + "@aws-sdk/util-middleware": "3.292.0", + "@aws-sdk/util-uri-escape": "3.292.0", + "@aws-sdk/util-utf8": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.292.0.tgz", + "integrity": "sha512-MjWEIjbAr7n9vsFeLpoRzNSYFgWOROf1mLj6Db8TfRowaortUBO7PbleLV4n3SPujSnxhaVBzlmnCY2AjatH9g==", + "dependencies": { + "@aws-sdk/protocol-http": "3.292.0", + "@aws-sdk/signature-v4": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-arn-parser": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@aws-sdk/signature-v4-crt": "^3.118.0" + }, + "peerDependenciesMeta": { + "@aws-sdk/signature-v4-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/smithy-client": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.292.0.tgz", + "integrity": "sha512-S8PKzjPkZ6SXYZuZiU787dMsvQ0d/LFEhw2OI4Oe2An9Fc2IwJ2FYukyHoQJOV2tV0DiuMebPo7eMyQyjKElvA==", + "dependencies": { + "@aws-sdk/middleware-stack": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.293.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.293.0.tgz", + "integrity": "sha512-Ly5pdUZJcufNHTovmA0XjyUV6Qth89oK3VHSnrNbVYKFCDvApF4tuR8lBYayn7vEWrdlkGCnfJu42yN71NPfDw==", + "dependencies": { + "@aws-sdk/client-sso-oidc": "3.293.0", + "@aws-sdk/property-provider": "3.292.0", + "@aws-sdk/shared-ini-file-loader": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.292.0.tgz", + "integrity": "sha512-1teYAY2M73UXZxMAxqZxVS2qwXjQh0OWtt7qyLfha0TtIk/fZ1hRwFgxbDCHUFcdNBSOSbKH/ESor90KROXLCQ==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/url-parser": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.292.0.tgz", + "integrity": "sha512-NZeAuZCk1x6TIiWuRfbOU6wHPBhf0ly2qOHzWut4BCH+b4RrDmFF8EmXcH1auEfGhE7yRyR6XqIN0t3S+hYACA==", + "dependencies": { + "@aws-sdk/querystring-parser": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.292.0.tgz", + "integrity": "sha512-xfE4U94TfjMC2WNNDte/kDByf16GrQKaS0BKsm+Fk/PaeHUofEp8suOEz/EVdEoa3Ayy2Uc5QdhrGnlqf8MxeA==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-base64": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64/-/util-base64-3.292.0.tgz", + "integrity": "sha512-zjNCwNdy617yFvEjZorepNWXB2sQCVfsShCwFy/kIQ5iW5tT2jQKaqc0K77diU9atkooxw9p1W9m9sOgrkOFNw==", + "dependencies": { + "@aws-sdk/util-buffer-from": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-body-length-browser": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.292.0.tgz", + "integrity": "sha512-Wd/BM+JsMiKvKs/bN3z6TredVEHh2pKudGfg3CSjTRpqFpOG903KDfyHBD42yg5PuCHoHoewJvTPKwgn7/vhaw==", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-body-length-node": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.292.0.tgz", + "integrity": "sha512-BBgipZ2P6RhogWE/qj0oqpdlyd3iSBYmb+aD/TBXwB2lA/X8A99GxweBd/kp06AmcJRoMS9WIXgbWkiiBlRlSA==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-buffer-from": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.292.0.tgz", + "integrity": "sha512-RxNZjLoXNxHconH9TYsk5RaEBjSgTtozHeyIdacaHPj5vlQKi4hgL2hIfKeeNiAfQEVjaUFF29lv81xpNMzVMQ==", + "dependencies": { + "@aws-sdk/is-array-buffer": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-config-provider": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.292.0.tgz", + "integrity": "sha512-t3noYll6bPRSxeeNNEkC5czVjAiTPcsq00OwfJ2xyUqmquhLEfLwoJKmrT1uP7DjIEXdUtfoIQ2jWiIVm/oO5A==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-defaults-mode-browser": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-browser/-/util-defaults-mode-browser-3.292.0.tgz", + "integrity": "sha512-7+zVUlMGfa8/KT++9humHo6IDxTnxMCmWUj5jVNlkpk6h7Ecmppf7aXotviyVIA43lhtz0p2AErs0N0ekEUK+w==", + "dependencies": { + "@aws-sdk/property-provider": "3.292.0", + "@aws-sdk/types": "3.292.0", + "bowser": "^2.11.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@aws-sdk/util-defaults-mode-node": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-defaults-mode-node/-/util-defaults-mode-node-3.292.0.tgz", + "integrity": "sha512-SSIw85eF4BVs0fOJRyshT+R3b/UmBPhiVKCUZm2rq6+lIGkDPiSwQU3d/80AhXtiL5SFT/IzAKKgQd8qMa7q3A==", + "dependencies": { + "@aws-sdk/config-resolver": "3.292.0", + "@aws-sdk/credential-provider-imds": "3.292.0", + "@aws-sdk/node-config-provider": "3.292.0", + "@aws-sdk/property-provider": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.293.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.293.0.tgz", + "integrity": "sha512-R/99aNV49Refpv5guiUjEUrZYlvnfaNBniB+/ZtMO3ixxUopapssCrUivuJrmhccmrYaTCZw7dRzIWjU1jJhKg==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-hex-encoding": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.292.0.tgz", + "integrity": "sha512-qBd5KFIUywQ3qSSbj814S2srk0vfv8A6QMI+Obs1y2LHZFdQN5zViptI4UhXhKOHe+NnrHWxSuLC/LMH6q3SmA==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.292.0.tgz", + "integrity": "sha512-6xnFJXZI9pKw5lQCDvuWA5PnOaUtNRKWwdxvGkkLx5orboFaoVMS6zowjSQxwVNRjW82u6dYNkhmj9mZ8VSjWg==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-middleware": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-middleware/-/util-middleware-3.292.0.tgz", + "integrity": "sha512-KjhS7flfoBKDxbiBZjLjMvEizXgjfQb7GQEItgzGoI9rfGCmZtvqCcqQQoIlxb8bIzGRggAUHtBGWnlLbpb+GQ==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-retry": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-retry/-/util-retry-3.292.0.tgz", + "integrity": "sha512-JEHyF7MpVeRF5uR4LDYgpOKcFpOPiAj8TqN46SVOQQcL1K+V7cSr7O7N7J6MwJaN9XOzAcBadeIupMm7/BFbgw==", + "dependencies": { + "@aws-sdk/service-error-classification": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@aws-sdk/util-stream-browser": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-stream-browser/-/util-stream-browser-3.292.0.tgz", + "integrity": "sha512-yzwpjq18oefyp/Sv+Z0VWh7ziRPp+qM0pDUrTfuAnXg+mrlxaPDXJOhp5LoY8AVHcDPOEdIbzz0b00G48FabIg==", + "dependencies": { + "@aws-sdk/fetch-http-handler": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-base64": "3.292.0", + "@aws-sdk/util-hex-encoding": "3.292.0", + "@aws-sdk/util-utf8": "3.292.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-stream-node": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-stream-node/-/util-stream-node-3.292.0.tgz", + "integrity": "sha512-p3DHXvWo4Zdka75HwewUnWjpFp/gOT4SYYEOAsv3BwuZGxfmnojK9OVCkUBJ7s6LeHMKTgGqQPwAnVFu7iIZNg==", + "dependencies": { + "@aws-sdk/node-http-handler": "3.292.0", + "@aws-sdk/types": "3.292.0", + "@aws-sdk/util-buffer-from": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-uri-escape": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.292.0.tgz", + "integrity": "sha512-hOQtUMQ4VcQ9iwKz50AoCp1XBD5gJ9nly/gJZccAM7zSA5mOO8RRKkbdonqquVHxrO0CnYgiFeCh3V35GFecUw==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.292.0.tgz", + "integrity": "sha512-dld+lpC3QdmTQHdBWJ0WFDkXDSrJgfz03q6mQ8+7H+BC12ZhT0I0g9iuvUjolqy7QR00OxOy47Y9FVhq8EC0Gg==", + "dependencies": { + "@aws-sdk/types": "3.292.0", + "bowser": "^2.11.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.292.0.tgz", + "integrity": "sha512-f+NfIMal5E61MDc5WGhUEoicr7b1eNNhA+GgVdSB/Hg5fYhEZvFK9RZizH5rrtsLjjgcr9nPYSR7/nDKCJLumw==", + "dependencies": { + "@aws-sdk/node-config-provider": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/util-utf8": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8/-/util-utf8-3.292.0.tgz", + "integrity": "sha512-FPkj+Z59/DQWvoVu2wFaRncc3KVwe/pgK3MfVb0Lx+Ibey5KUx+sNpJmYcVYHUAe/Nv/JeIpOtYuC96IXOnI6w==", + "dependencies": { + "@aws-sdk/util-buffer-from": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-waiter": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-waiter/-/util-waiter-3.292.0.tgz", + "integrity": "sha512-+7j+mcWUY4GwU8nTK4MvLWpOzS34SJZL85qLxQ04pysoCSHkInyS51D1ejBVNlJdbUSFvIcU0WHU0y6MDDeJzg==", + "dependencies": { + "@aws-sdk/abort-controller": "3.292.0", + "@aws-sdk/types": "3.292.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.292.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.292.0.tgz", + "integrity": "sha512-0zgnhdwUy30q/1NPXi5ekdzHQqCs3ZJaUeGbvYMO54osi4K5hygAyTsyWtv6oaJggRqZrB0LAZ9xN6hG+sA8/g==", + "dependencies": { + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -66,37 +1379,6 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sdk": { - "version": "2.1333.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1333.0.tgz", - "integrity": "sha512-MvOuleNeRryJtkCGXGEWDHPqqgxuqdi4/hGzJEpn9tnjsW9LNK8UgFPpYzUZ24ZO/3S+jiUh8DMMrL5nVGnagg==", - "dependencies": { - "buffer": "4.9.2", - "events": "1.1.1", - "ieee754": "1.1.13", - "jmespath": "0.16.0", - "querystring": "0.2.0", - "sax": "1.2.1", - "url": "0.10.3", - "util": "^0.12.4", - "uuid": "8.0.0", - "xml2js": "0.4.19" - }, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/axios": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.4.tgz", @@ -112,24 +1394,10 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "node_modules/bowser": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", + "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -140,28 +1408,6 @@ "concat-map": "0.0.1" } }, - "node_modules/buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/class-transformer": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", @@ -235,14 +1481,6 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, - "node_modules/events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -251,6 +1489,21 @@ "node": ">= 0.8.0" } }, + "node_modules/fast-xml-parser": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.1.2.tgz", + "integrity": "sha512-CDYeykkle1LiA/uqQyNwYpFbyF6Axec6YapmpUP+/RHWIoR1zKjocdvNaTsxCxZzQ6v9MLXaSYm9Qq0thv0DHg==", + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + }, "node_modules/follow-redirects": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", @@ -270,14 +1523,6 @@ } } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -296,24 +1541,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -333,53 +1560,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -391,11 +1571,6 @@ "node": ">=0.10.0" } }, - "node_modules/ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -410,32 +1585,6 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -444,51 +1593,6 @@ "node": ">=8" } }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/jmespath": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", - "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -584,20 +1688,6 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, - "node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" - }, - "node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/reflect-metadata": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", @@ -608,11 +1698,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/sax": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" - }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -642,6 +1727,16 @@ "node": ">=8" } }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, + "node_modules/tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + }, "node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", @@ -654,15 +1749,6 @@ "node": ">=4.2.0" } }, - "node_modules/url": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, "node_modules/urlencode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/urlencode/-/urlencode-1.1.0.tgz", @@ -671,67 +1757,11 @@ "iconv-lite": "~0.4.11" } }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/uuid": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", - "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "node_modules/xml2js": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~9.0.1" - } - }, - "node_modules/xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha512-7YXTQc3P2l9+0rjaUbLwMKRhtmwg1M1eDf6nag7urC7pIPYLD9W/jmzQ4ptRSUbodw5S0jfoGTflLemQibSpeQ==", - "engines": { - "node": ">=4.0" - } - }, "node_modules/yaml": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.1.tgz", diff --git a/cli/package.json b/cli/package.json index e80f66cff1..082d3a6f5d 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "laf-cli", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "description": "", "main": "dist/main.js", "bin": { @@ -30,7 +30,7 @@ "@types/node": "^17.0.31" }, "dependencies": { - "aws-sdk": "^2.1167.0", + "@aws-sdk/client-s3": "^3.45.0", "axios": "^1.2.1", "class-transformer": "^0.5.1", "cli": "^1.0.1", @@ -45,4 +45,4 @@ "urlencode": "^1.1.0", "yaml": "^2.1.3" } -} \ No newline at end of file +} diff --git a/cli/src/action/application/index.ts b/cli/src/action/application/index.ts index 486c2e65ef..fe418d0762 100644 --- a/cli/src/action/application/index.ts +++ b/cli/src/action/application/index.ts @@ -22,18 +22,37 @@ import { ensureDirectory, exist } from '../../util/file' import { refreshSecretConfig } from '../../config/secret' import { getEmoji } from '../../util/print' import { formatDate } from '../../util/format' +import { regionControllerGetRegions } from '../../api/v1/public' export async function list() { const table = new Table({ - head: ['appid', 'name', 'state', 'createdAt'], + head: ['appid', 'name', 'state', 'region', 'spec', 'createdAt', 'expireAt'], }) - const data = await applicationControllerFindAll() - for (let item of data) { - table.push([item.appid, item.name, item.state, formatDate(item.createdAt)]) + const apps = await applicationControllerFindAll() + const regionMap = await getRegionMap() + for (let item of apps) { + table.push([ + item.appid, + item.name, + item.state, + regionMap.get(item.regionId)?.displayName, + `${parseFloat(item.bundle?.resource?.limitCPU) / 1000.0}C/${item.bundle?.resource?.limitMemory}MB`, + formatDate(item.subscription?.createdAt), + formatDate(item.subscription?.expiredAt), + ]) } console.log(table.toString()) } +async function getRegionMap(): Promise> { + const regionMap = new Map() + const regions = await regionControllerGetRegions() + for (let region of regions) { + regionMap.set(region.id, region) + } + return regionMap +} + export async function init(appid: string, options: { sync: boolean }) { if (existApplicationConfig()) { console.log( @@ -55,7 +74,7 @@ export async function init(appid: string, options: { sync: boolean }) { createdAt: data.createdAt, } // generate application invoke address - config.invokeUrl = 'http://' + data.domain.domain + config.invokeUrl = data.tls ? 'https://' + data.domain.domain : 'http://' + data.domain.domain writeApplicationConfig(config) diff --git a/cli/src/action/storage/index.ts b/cli/src/action/storage/index.ts index 1e5c22a408..98a728c6c8 100644 --- a/cli/src/action/storage/index.ts +++ b/cli/src/action/storage/index.ts @@ -10,13 +10,13 @@ import * as prompts from 'prompts' import { CreateBucketDto, UpdateBucketDto } from '../../api/v1/data-contracts' import { getEmoji } from '../../util/print' import { readSecretConfig } from '../../config/secret' -import { getS3Client } from './s3' +import { getS3ClientV3 } from './s3' import * as path from 'node:path' import { ensureDirectory, readDirectoryRecursive, compareFileMD5, exist } from '../../util/file' -import axios from 'axios' import * as fs from 'node:fs' -import { pipeline } from 'node:stream/promises' import * as mime from 'mime' +import { ListObjectsCommand, GetObjectCommand, PutObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3' +import { Readable } from 'node:stream' export async function list() { const appConfig = readApplicationConfig() @@ -88,9 +88,11 @@ export async function pull(bucketName: string, outPath: string, options: { force bucketName = appConfig.appid + '-' + bucketName } const secretConfig = readSecretConfig() - const client = getS3Client(secretConfig.storageSecretConfig) - const res = await client.listObjectsV2({ Bucket: bucketName, Delimiter: '' }).promise() + const client = getS3ClientV3(secretConfig.storageSecretConfig) + const listCommand = new ListObjectsCommand({ Bucket: bucketName, Delimiter: '' }) + const res = await client.send(listCommand) const bucketObjects = res.Contents || [] + const absPath = path.resolve(outPath) ensureDirectory(absPath) @@ -108,22 +110,22 @@ export async function pull(bucketName: string, outPath: string, options: { force // download files if (downloadFiles?.length > 0) { downloadFiles.forEach(async (item) => { - const fileUrl = client.getSignedUrl('getObject', { Bucket: bucketName, Key: item.Key }) const index = item.Key.lastIndexOf('/') - if (index > 0) { const newDir = item.Key.substring(0, index) const newPath = path.resolve(absPath, newDir) ensureDirectory(newPath) } - const data = await axios({ url: fileUrl, method: 'GET', responseType: 'stream' }) + const getCommand = new GetObjectCommand({ Bucket: bucketName, Key: item.Key }) + const obj = await client.send(getCommand) const filepath = path.resolve(absPath, item.Key) + let readableStream: Readable = obj.Body as Readable if (options.detail) { console.log(`${getEmoji('📥')} download file: ${filepath}`) } const writer = fs.createWriteStream(filepath) - await pipeline(data.data, writer) + readableStream.pipe(writer) }) } } @@ -134,9 +136,12 @@ export async function push(bucketName: string, inPath: string, options: { force: bucketName = appConfig.appid + '-' + bucketName } const secretConfig = readSecretConfig() - const client = getS3Client(secretConfig.storageSecretConfig) - const res = await client.listObjectsV2({ Bucket: bucketName, Delimiter: '' }).promise() + + const client = getS3ClientV3(secretConfig.storageSecretConfig) + const listCommand = new ListObjectsCommand({ Bucket: bucketName, Delimiter: '' }) + const res = await client.send(listCommand) const bucketObjects = res.Contents || [] + const absPath = path.resolve(inPath) if (!exist(absPath)) { console.log(`${getEmoji('❌')} ${absPath} not exist`) @@ -156,14 +161,14 @@ export async function push(bucketName: string, inPath: string, options: { force: console.log(`${getEmoji('📤')} upload files: ${uploadFiles.length}`) if (uploadFiles?.length > 0) { for (const file of uploadFiles) { - await client - .putObject({ - Bucket: bucketName, - Key: file.key, - Body: fs.readFileSync(path.resolve(absPath, file.absPath)), - ContentType: mime.getType(file.key), - }) - .promise() + const putCommand = new PutObjectCommand({ + Bucket: bucketName, + Key: file.key, + Body: fs.readFileSync(path.resolve(absPath, file.absPath)), + ContentType: mime.getType(file.key), + }) + await client.send(putCommand) + if (options.detail) { console.log(`${getEmoji('📤')} upload file: ${file.absPath}`) } @@ -174,12 +179,12 @@ export async function push(bucketName: string, inPath: string, options: { force: if (deletesFiles?.length > 0) { console.log(`${getEmoji('📤')} delete files: ${deletesFiles.length}`) for (const file of deletesFiles) { - await client - .deleteObject({ - Bucket: bucketName, - Key: file.Key, - }) - .promise() + const deleteCommand = new DeleteObjectCommand({ + Bucket: bucketName, + Key: file.Key, + }) + await client.send(deleteCommand) + if (options.detail) { console.log(`${getEmoji('📤')} delete file: ${file.Key}`) } diff --git a/cli/src/action/storage/s3.ts b/cli/src/action/storage/s3.ts index 43b8b7a0ca..70b0fe85c6 100644 --- a/cli/src/action/storage/s3.ts +++ b/cli/src/action/storage/s3.ts @@ -1,14 +1,14 @@ -import * as AWS from 'aws-sdk' -require('aws-sdk/lib/maintenance_mode_message').suppress = true +import { S3Client } from '@aws-sdk/client-s3' -export function getS3Client(credentials: any) { - return new AWS.S3({ - accessKeyId: credentials.accessKeyId, - secretAccessKey: credentials.accessKeySecret, - sessionToken: credentials.sessionToken, +export function getS3ClientV3(credentials: any): S3Client { + return new S3Client({ + credentials: { + accessKeyId: credentials.accessKeyId, + secretAccessKey: credentials.accessKeySecret, + sessionToken: credentials.sessionToken, + }, endpoint: credentials.endpoint, - s3ForcePathStyle: true, - signatureVersion: 'v4', + forcePathStyle: true, region: 'us-east-1', }) } diff --git a/cli/src/command/function/index.ts b/cli/src/command/function/index.ts index b61867639d..a89e559ebe 100644 --- a/cli/src/command/function/index.ts +++ b/cli/src/command/function/index.ts @@ -15,6 +15,9 @@ export function command(): Command { .option('-t --tags ', 'tags', []) .option('-d --description ', 'function description', '') .action((funcName, options) => { + if (!/^[_A-Za-z][A-Za-z0-9-_]+$/.test(funcName)) { + return console.log('Function names can only contain English letters or underscores (_).') + } create(funcName, options) }) diff --git a/cli/src/common/constant.ts b/cli/src/common/constant.ts index 0e1e32330c..c7c7525047 100644 --- a/cli/src/common/constant.ts +++ b/cli/src/common/constant.ts @@ -20,7 +20,7 @@ export const DEBUG_TOKEN_EXPIRE = 3600 * 24 * 7 export const STORAGE_TOKEN_EXPIRE = 3600 * 24 * 7 // remote server config -export const DEFAULT_REMOTE_SERVER = 'https://api.laf.dev' +export const DEFAULT_REMOTE_SERVER = 'https://api.laf.run' // template file export const TEMPLATE_DIR = 'template' diff --git a/cli/template/gitignore b/cli/template/gitignore index 6d326bb387..4dba72bc5a 100644 --- a/cli/template/gitignore +++ b/cli/template/gitignore @@ -2,4 +2,6 @@ package.json tsconfig.json types node_modules -.secret.yaml \ No newline at end of file +.secret.yaml +.laf.yaml +package-lock.json \ No newline at end of file diff --git a/contribution/zh_CN/images/change-redirect-uri.png b/contribution/zh_CN/images/change-redirect-uri.png deleted file mode 100644 index d52ecfda22..0000000000 Binary files a/contribution/zh_CN/images/change-redirect-uri.png and /dev/null differ diff --git a/contribution/zh_CN/images/configure-proxy-pattern.png b/contribution/zh_CN/images/configure-proxy-pattern.png deleted file mode 100644 index dc2f0b1390..0000000000 Binary files a/contribution/zh_CN/images/configure-proxy-pattern.png and /dev/null differ diff --git a/contribution/zh_CN/images/configure-rule-in-whistle-console.png b/contribution/zh_CN/images/configure-rule-in-whistle-console.png deleted file mode 100644 index 9d67e73175..0000000000 Binary files a/contribution/zh_CN/images/configure-rule-in-whistle-console.png and /dev/null differ diff --git a/contribution/zh_CN/images/create-proxy-pattern.png b/contribution/zh_CN/images/create-proxy-pattern.png deleted file mode 100644 index 59181121af..0000000000 Binary files a/contribution/zh_CN/images/create-proxy-pattern.png and /dev/null differ diff --git a/contribution/zh_CN/images/install-switchy-omega.png b/contribution/zh_CN/images/install-switchy-omega.png deleted file mode 100644 index 7c01caf083..0000000000 Binary files a/contribution/zh_CN/images/install-switchy-omega.png and /dev/null differ diff --git a/contribution/zh_CN/images/open-switchy-omega.png b/contribution/zh_CN/images/open-switchy-omega.png deleted file mode 100644 index f6bc2e670a..0000000000 Binary files a/contribution/zh_CN/images/open-switchy-omega.png and /dev/null differ diff --git a/contribution/zh_CN/images/translate-0.png b/contribution/zh_CN/images/translate-0.png deleted file mode 100644 index be231995b6..0000000000 Binary files a/contribution/zh_CN/images/translate-0.png and /dev/null differ diff --git a/contribution/zh_CN/images/translate-1.png b/contribution/zh_CN/images/translate-1.png deleted file mode 100644 index 22cdfcdef5..0000000000 Binary files a/contribution/zh_CN/images/translate-1.png and /dev/null differ diff --git a/contribution/zh_CN/images/translate-2.png b/contribution/zh_CN/images/translate-2.png deleted file mode 100644 index a582fc3e9f..0000000000 Binary files a/contribution/zh_CN/images/translate-2.png and /dev/null differ diff --git a/contribution/zh_CN/images/whistl-in-laf-web.png b/contribution/zh_CN/images/whistl-in-laf-web.png deleted file mode 100644 index ef91f6b533..0000000000 Binary files a/contribution/zh_CN/images/whistl-in-laf-web.png and /dev/null differ diff --git a/contribution/zh_CN/web.md b/contribution/zh_CN/web.md deleted file mode 100644 index f3ce509104..0000000000 --- a/contribution/zh_CN/web.md +++ /dev/null @@ -1,95 +0,0 @@ -# Laf web 贡献者快速上手文档 - -## Install dependencies and Start - -```bash -pnpm install -pnpm run dev -``` - -### 登陆重定向不到本地的问题 - -由于 `laf` 的登录认证是接入的 `casdoor`, 登录后的回跳地址是固定的,需要我们手动修改为 `localhost:3001`, 也即我们本地的服务器。修改完后回车,再进行登录即可跳回 `localhost:3001` - -![](./images/change-redirect-uri.png) - - - -# 相关框架简介 - -## 基础框架: react - -## 数据请求:react-query + axios - -1. 链接: - -[Overview | TanStack Query Docs](https://tanstack.com/query/v4/docs/react/overview) - -1. 为什么使用 react-query? - -[refactor: react query best practice by LeezQ · Pull Request #496 · labring/laf](https://github.com/labring/laf/pull/496#issue-1482332711) - -1. 用法参考: web\src\pages\app\functions\service.ts - - 在本项目中对于每个页面都会存在service.ts文件用于管理当前页面内的请求 - - -## 状态管理:zustand + immer - -1. 链接: - -[Zustand](https://zustand-demo.pmnd.rs/) - -1. 用法参考: web\src\pages\app\functions\store.ts - - 项目的全局状态管理: web\src\pages\globalStore.ts - - 每个页面的状态管理:存放在对应的store.ts中 - - -## UI 库:chakra - -1. 链接: - -[Installation](https://chakra-ui.com/getting-started) - -1. 自定义样式要修改:web/src/chakraTheme.ts - -## 样式: tailwind (主要)+ sass - -1. 链接: - -[Tailwind CSS - Rapidly build modern websites without ever leaving your HTML.](https://tailwindcss.com/) - -1. 自定义样式要修改:web/tailwind.config.cjs - -## 国际化:i18next - -1. 链接: - -[Introduction](https://www.i18next.com/) - -1. 国际化文案: web/public/locales -2. 使用方法: - -3.1 直接写t(”test”),鼠标hover上去后会出现如下提示框 - -![](./images/translate-1.png) - -3.2 点击zh-CN后面的编辑icon会出现如下输入框,输入后回车就完成了zh-CN文本的翻译 -![](./images/translate-2.png) - -3.3 在所有编码结束后点击编辑器的翻译插件,可以看到EN和ZH有缺失的翻译文案,点击地球icon即可完成自动翻译 -![](./images/translate-0.png) - -## ICON:react-icons + 自定义icon - -1. 链接: - -[React Icons](https://react-icons.github.io/react-icons/) - -1. 自定义 ICON 使用 @chakra-ui/icons - -# 提PR流程 - -[三分钟学会参与开源,提交 pr | 左风的博客](https://zuofeng59556.github.io/my-blog/pages/quickStart/pr/) diff --git a/deploy/build/charts/casdoor/.helmignore b/deploy/build/charts/casdoor/.helmignore deleted file mode 100644 index 0e8a0eb36f..0000000000 --- a/deploy/build/charts/casdoor/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ diff --git a/deploy/build/charts/casdoor/Chart.yaml b/deploy/build/charts/casdoor/Chart.yaml deleted file mode 100644 index c92d2b273c..0000000000 --- a/deploy/build/charts/casdoor/Chart.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: v2 -name: casdoor -description: A Helm chart for Kubernetes - -# A chart can be either an 'application' or a 'library' chart. -# -# Application charts are a collection of templates that can be packaged into versioned archives -# to be deployed. -# -# Library charts provide useful utilities or functions for the chart developer. They're included as -# a dependency of application charts to inject those utilities and functions into the rendering -# pipeline. Library charts do not define any templates and therefore cannot be deployed. -type: application - -# This is the chart version. This version number should be incremented each time you make changes -# to the chart and its templates, including the app version. -# Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 - -# This is the version number of the application being deployed. This version number should be -# incremented each time you make changes to the application. Versions are not expected to -# follow Semantic Versioning. They should reflect the version the application is using. -# It is recommended to use it with quotes. -appVersion: "1.16.0" diff --git a/deploy/build/charts/casdoor/README.md b/deploy/build/charts/casdoor/README.md deleted file mode 100644 index 66ea0b351a..0000000000 --- a/deploy/build/charts/casdoor/README.md +++ /dev/null @@ -1,22 +0,0 @@ - - - -## Prerequisites - -```shell -kubectl create namespace laf -``` - - -## Install -```shell -helm install casdoor \ - --namespace laf \ - . -``` - -## Uninstall - -```shell -helm delete casdoor -n laf -``` diff --git a/deploy/build/charts/casdoor/templates/NOTES.txt b/deploy/build/charts/casdoor/templates/NOTES.txt deleted file mode 100644 index 499bcad0a8..0000000000 --- a/deploy/build/charts/casdoor/templates/NOTES.txt +++ /dev/null @@ -1,22 +0,0 @@ -1. Get the application URL by running these commands: -{{- if .Values.ingress.enabled }} -{{- range $host := .Values.ingress.hosts }} - {{- range .paths }} - http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} - {{- end }} -{{- end }} -{{- else if contains "NodePort" .Values.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "casdoor.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" .Values.service.type }} - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "casdoor.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "casdoor.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - echo http://$SERVICE_IP:{{ .Values.service.port }} -{{- else if contains "ClusterIP" .Values.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "casdoor.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT -{{- end }} diff --git a/deploy/build/charts/casdoor/templates/_helpers.tpl b/deploy/build/charts/casdoor/templates/_helpers.tpl deleted file mode 100644 index 416a0c439f..0000000000 --- a/deploy/build/charts/casdoor/templates/_helpers.tpl +++ /dev/null @@ -1,62 +0,0 @@ -{{/* -Expand the name of the chart. -*/}} -{{- define "casdoor.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "casdoor.fullname" -}} -{{- if .Values.fullnameOverride }} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- $name := default .Chart.Name .Values.nameOverride }} -{{- if contains $name .Release.Name }} -{{- .Release.Name | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "casdoor.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "casdoor.labels" -}} -helm.sh/chart: {{ include "casdoor.chart" . }} -{{ include "casdoor.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "casdoor.selectorLabels" -}} -app.kubernetes.io/name: {{ include "casdoor.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Create the name of the service account to use -*/}} -{{- define "casdoor.serviceAccountName" -}} -{{- if .Values.serviceAccount.create }} -{{- default (include "casdoor.fullname" .) .Values.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.serviceAccount.name }} -{{- end }} -{{- end }} diff --git a/deploy/build/charts/casdoor/templates/config.yaml b/deploy/build/charts/casdoor/templates/config.yaml deleted file mode 100644 index ac24ad1d66..0000000000 --- a/deploy/build/charts/casdoor/templates/config.yaml +++ /dev/null @@ -1,31 +0,0 @@ - - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "casdoor.fullname" . }}-config - labels: - {{- include "casdoor.labels" . | nindent 4 }} -data: - app.conf: |- - appname = casdoor - httpport = 8000 - runmode = dev - SessionOn = true - copyrequestbody = true - driverName = postgres - dataSourceName = "user={{ .Values.postgresql.username }} password={{ .Values.postgresql.password }} host={{ .Values.postgresql.host }} port={{ .Values.postgresql.port }} sslmode=disable dbname={{ .Values.postgresql.database }}" - dbName = - tableNamePrefix = - showSql = false - redisEndpoint = - defaultStorageProvider = - isCloudIntranet = false - authState = "casdoor" - socks5Proxy = "127.0.0.1:10808" - verificationCodeTimeout = 10 - initScore = 2000 - logPostOnly = true - origin = - staticBaseUrl = "" \ No newline at end of file diff --git a/deploy/build/charts/casdoor/templates/deployment.yaml b/deploy/build/charts/casdoor/templates/deployment.yaml deleted file mode 100644 index fd5721558d..0000000000 --- a/deploy/build/charts/casdoor/templates/deployment.yaml +++ /dev/null @@ -1,82 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "casdoor.fullname" . }} - labels: - {{- include "casdoor.labels" . | nindent 4 }} -spec: - {{- if not .Values.autoscaling.enabled }} - replicas: {{ .Values.replicaCount }} - {{- end }} - selector: - matchLabels: - {{- include "casdoor.selectorLabels" . | nindent 6 }} - template: - metadata: - {{- with .Values.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "casdoor.selectorLabels" . | nindent 8 }} - spec: - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - serviceAccountName: {{ include "casdoor.serviceAccountName" . }} - securityContext: - {{- toYaml .Values.podSecurityContext | nindent 8 }} - containers: - - name: {{ .Chart.Name }} - securityContext: - {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} - livenessProbe: - httpGet: - path: / - port: http - readinessProbe: - httpGet: - path: / - port: http - resources: - {{- toYaml .Values.resources | nindent 12 }} - command: ["/bin/sh"] - args: ["-c", "./server --createDatabase=true"] - ports: - - name: http - containerPort: 8000 - protocol: TCP - volumeMounts: - - name: casdoor-conf-volume - mountPath: /conf/app.conf - subPath: app.conf - - name: casdoor-init-data-volume - mountPath: /init_data.json - subPath: init_data.json - env: - - name: RUNNING_IN_DOCKER - value: "true" - volumes: - - name: casdoor-conf-volume - configMap: - name: {{ template "casdoor.fullname" . }}-config - - name: casdoor-init-data-volume - configMap: - name: casdoor-init-data - {{- with .Values.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} - - diff --git a/deploy/build/charts/casdoor/templates/hpa.yaml b/deploy/build/charts/casdoor/templates/hpa.yaml deleted file mode 100644 index d4bfebcbfa..0000000000 --- a/deploy/build/charts/casdoor/templates/hpa.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.autoscaling.enabled }} -apiVersion: autoscaling/v2beta1 -kind: HorizontalPodAutoscaler -metadata: - name: {{ include "casdoor.fullname" . }} - labels: - {{- include "casdoor.labels" . | nindent 4 }} -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: {{ include "casdoor.fullname" . }} - minReplicas: {{ .Values.autoscaling.minReplicas }} - maxReplicas: {{ .Values.autoscaling.maxReplicas }} - metrics: - {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} - - type: Resource - resource: - name: cpu - targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} - {{- end }} - {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} - - type: Resource - resource: - name: memory - targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} - {{- end }} -{{- end }} diff --git a/deploy/build/charts/casdoor/templates/ingress.yaml b/deploy/build/charts/casdoor/templates/ingress.yaml deleted file mode 100644 index eb63a1e026..0000000000 --- a/deploy/build/charts/casdoor/templates/ingress.yaml +++ /dev/null @@ -1,21 +0,0 @@ - -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: casdoor-ingress -spec: - # apisix-ingress-controller is only interested in Ingress - # resources with the matched ingressClass name, in our case, - # it's apisix. - ingressClassName: apisix - rules: - - host: {{ .Values.host }} - http: - paths: - - backend: - service: - name: casdoor - port: - number: 8000 - path: / - pathType: Prefix diff --git a/deploy/build/charts/casdoor/templates/init_data.yaml b/deploy/build/charts/casdoor/templates/init_data.yaml deleted file mode 100644 index 84efcfd119..0000000000 --- a/deploy/build/charts/casdoor/templates/init_data.yaml +++ /dev/null @@ -1,89 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: casdoor-init-data -data: - init_data.json: | - { - "organizations": [ - { - "owner": "admin", - "name": "laf", - "displayName": "laf", - "websiteUrl": "https//github.com/labring/laf", - "favicon": "", - "passwordType": "plain", - "phonePrefix": "86", - "defaultAvatar": "https://www.lafyun.com/logo.png", - "tags": [] - } - ], - "applications": [ - { - "owner": "admin", - "name": "laf", - "displayName": "laf", - "logo": "https://www.lafyun.com/logo.png", - "homepageUrl": "https//github.com/labring/laf", - "organization": "laf", - "cert": "cert-laf", - "enablePassword": true, - "enableSignUp": true, - "clientId": {{ .Values.init.client_id | quote }}, - "clientSecret": {{ .Values.init.client_secret | quote }}, - "providers": [], - "signupItems": [ - { - "name": "ID", - "visible": false, - "required": true, - "prompted": false, - "rule": "Random" - }, - { - "name": "Username", - "visible": true, - "required": true, - "prompted": false, - "rule": "None" - }, - { - "name": "Password", - "visible": true, - "required": true, - "prompted": false, - "rule": "None" - }, - { - "name": "Confirm password", - "visible": true, - "required": true, - "prompted": false, - "rule": "None" - } - ], - "redirectUris": [ - "http://localhost:3001/login", - "http://localhost:3001/login_callback", - "http://localhost:3000/v1/code2token", - {{ .Values.init.redirect_uri | quote }} - ], - "expireInHours": 168 - } - ], - "certs": [ - { - "owner": "admin", - "name": "cert-laf", - "displayName": "laf cert", - "scope": "JWT", - "type": "x509", - "cryptoAlgorithm": "RS256", - "bitSize": 4096, - "expireInYears": 20, - "certificate": "{{- .Files.Get "token_jwt_key.pem"}}", - "privateKey": "{{- .Files.Get "token_jwt_key.key"}}" - } - ] - } - \ No newline at end of file diff --git a/deploy/build/charts/casdoor/templates/local-cdn-shim.yaml b/deploy/build/charts/casdoor/templates/local-cdn-shim.yaml deleted file mode 100644 index c12e294511..0000000000 --- a/deploy/build/charts/casdoor/templates/local-cdn-shim.yaml +++ /dev/null @@ -1,82 +0,0 @@ - - -apiVersion: v1 -kind: Service -metadata: - name: casdoor-local-cdn - labels: - app: casdoor-local-cdn -spec: - type: ClusterIP - ports: - - port: 80 - targetPort: http - protocol: TCP - name: http - selector: - app: casdoor-local-cdn - ---- - -apiVersion: apps/v1 -kind: Deployment -metadata: - name: casdoor-local-cdn - labels: - app: casdoor-local-cdn - {{- include "casdoor.labels" . | nindent 4 }} -spec: - replicas: 1 - selector: - matchLabels: - app: casdoor-local-cdn - template: - metadata: - {{- with .Values.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - app: casdoor-local-cdn - spec: - {{- with .Values.imagePullSecrets }} - imagePullSecrets: - {{- toYaml . | nindent 8 }} - {{- end }} - serviceAccountName: {{ include "casdoor.serviceAccountName" . }} - securityContext: - {{- toYaml .Values.podSecurityContext | nindent 8 }} - containers: - - name: docker-casbin - securityContext: - {{- toYaml .Values.securityContext | nindent 12 }} - image: labring/docker-casbin:main - imagePullPolicy: {{ .Values.image.pullPolicy }} - # livenessProbe: - # httpGet: - # path: / - # port: http - # readinessProbe: - # httpGet: - # path: / - # port: http - resources: - {{- toYaml .Values.resources | nindent 12 }} - ports: - - name: http - containerPort: 8080 - protocol: TCP - {{- with .Values.nodeSelector }} - nodeSelector: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.affinity }} - affinity: - {{- toYaml . | nindent 8 }} - {{- end }} - {{- with .Values.tolerations }} - tolerations: - {{- toYaml . | nindent 8 }} - {{- end }} - - diff --git a/deploy/build/charts/casdoor/templates/service.yaml b/deploy/build/charts/casdoor/templates/service.yaml deleted file mode 100644 index 5d333d0265..0000000000 --- a/deploy/build/charts/casdoor/templates/service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "casdoor.fullname" . }} - labels: - {{- include "casdoor.labels" . | nindent 4 }} -spec: - type: {{ .Values.service.type }} - ports: - - port: {{ .Values.service.port }} - targetPort: http - protocol: TCP - name: http - {{- if .Values.service.nodePort }} - nodePort: {{ .Values.service.nodePort }} - {{- end }} - selector: - {{- include "casdoor.selectorLabels" . | nindent 4 }} diff --git a/deploy/build/charts/casdoor/templates/serviceaccount.yaml b/deploy/build/charts/casdoor/templates/serviceaccount.yaml deleted file mode 100644 index b0db643f39..0000000000 --- a/deploy/build/charts/casdoor/templates/serviceaccount.yaml +++ /dev/null @@ -1,12 +0,0 @@ -{{- if .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ include "casdoor.serviceAccountName" . }} - labels: - {{- include "casdoor.labels" . | nindent 4 }} - {{- with .Values.serviceAccount.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- end }} diff --git a/deploy/build/charts/casdoor/templates/tests/test-connection.yaml b/deploy/build/charts/casdoor/templates/tests/test-connection.yaml deleted file mode 100644 index a0fc5ceda7..0000000000 --- a/deploy/build/charts/casdoor/templates/tests/test-connection.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: "{{ include "casdoor.fullname" . }}-test-connection" - labels: - {{- include "casdoor.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": test -spec: - containers: - - name: wget - image: "busybox:1.28" - command: ['wget'] - args: ['{{ include "casdoor.fullname" . }}:{{ .Values.service.port }}'] - restartPolicy: Never diff --git a/deploy/build/charts/casdoor/token_jwt_key.key b/deploy/build/charts/casdoor/token_jwt_key.key deleted file mode 100644 index 41f3f1c9d2..0000000000 --- a/deploy/build/charts/casdoor/token_jwt_key.key +++ /dev/null @@ -1 +0,0 @@ ------BEGIN RSA PRIVATE KEY-----\nMIIJKwIBAAKCAgEA3qr4UuXcUaR8fgsFuzXyGaSOgNAsGOIGq35n8tk7oODQSOxO\n1SuXSGAr0cBq1xhcX7iXoF4IblyS+7dDF1OQPjWvdfQ1fzz1yXuHr+2BrIe98iFV\n0vCqQeG1eq6m0lVg68cEmuHRwT2nV7v7T0PhxojzeSVP/q6ewVTP1mjGgoXPbH2D\nL/yyI9GN5APXYHswWgGD/iFfJiqrOfjBiqRb8QmN/hBlj1bkks4yVoaziqgRPC5L\nFeg43eeVkWILcSzaJFI+/9YxZt99THS0vCIqPvk84wEFszNiSVU30j2XjKGkhfu5\nu+6IhsDw8FTNUWyTasDGz9uVoY5Niyy2RGXzIC9Ho+ntBajW73eXoaHfi9xjO30f\nENl8USYSAGPCuhYMaxPBcy5+JsPKZ59H5G7W+QJfeOgoKais8veMeqtrvQxtVO2C\nMt2g/wDtF23/k8A+wNblsq/SAH1UKz+8CSVCbvXGpPq8jMPmNns38XWu4nDISEL6\nsdO8ZKBGOnysCfvvPR2pcVMPJ5T6l7GcCPZ1gvcNsmlubDzsvuWyk7WzJwUJqHFW\n++sNKX6eIRFURwKjZvV16sLhVwuANhp44Xywj7E0xG301RkpeBKTfxAmKyAP6B1w\nHLUU8J7UkKMgInCWukiytrevwfR6zl1kQ0ytC+bpxBDIVU3zWcyYJk6l/hMCAwEA\nAQKCAgEAwZFHRmlkWeTwBHJ4jQKccAZJi1lsvEThH3xHySlnWLeW2Y30CgRXAyf3\nb+Qh/NLEmsHRriuQkMARVpk9za1rG2l4GsYtK2tHD9w/XITP0bg/O5oXDcUBfTxF\nk1z40KhAFTdxnWLqAV8jdnWIRqPwRbMQVSRGolQS1mZwNyfmSdkhNGL4BGNcSR8G\nhk2AkfMFWXkv0WAZYwh8yWyic2/mLWfs9Aw0/aLAGY7+25FFyyfHs9VamLTDmsST\nlUryP3SKPkDxW15Mm+10814RL+tTZmMstvpQhjQJIU7fs/ivIiXy7Dakg+cc8GgS\nDBrsUfhdPtRPAKsXLNaUOoSn/lXSP20aJeBWdiQPJ3n+4TJCuQvAZXRbK49VIu8b\n6JPM5jGRt7MtXc84IBshP5ojW2O2dza9E+8yI2VZE1CL15/KGc37+EZ3Dfz094VX\n3mqzrHtPZ4JkvH+1GoGUwyjl1jGwJ2DxjK4iPwAVyThCEI1yRrX3RfI5E/iLzOCn\nVH/WLMJQUNRoa425Aq2wzjc0OoqM1ZL7W7hkOpzw7wMeTe60+ey+0oYEnTniqAJR\nCswhwJLBVYAPBgEopd11N5B+k28vsp/yp//AFQdG+yDUoorSeKQf4TBcdbxLDmgJ\ne3TJMI6wo1gVmLO8cs+SVNYqMbai1aChwzKz9x+CY8lk+oW+dIECggEBAPUiO2pS\ne8QJxfNYX3pffCqzUDVrMW9y1jMdVvjTYkier512FjupOpVnVXDDM0TNuGtpK7H9\nIloLk3PIqj3DrM1wU17nnqOMBhwvsnU3Na5hzJgpbO9hahBsDF9cupAjv+EX9hgz\nlp4eRCd0zUGLHIXxkaGQwiFoCTX6xE2sOykckZsgLhEff5ysp1MSbrUZbJlwTpsJ\nitcoC2jrtsz8+UOtWDfJlDEsKELnE+JhTKl4ukqv7laeULS0Ylj8HA37NoOM7Nlv\nVcK+TT7HFHfs8+p+cSLZva7ui1K//c0o8lvQHZyyQB/LlkUwZlbO0NDUafRmepgK\n2Mvu9BBJABzsoYMCggEBAOiJy89n0tZ9DifHkyy/ujfDyufvi8DPpgfvrzl7h3nH\nfMib/SVY44oHbbmILA4K7b5Jj9tkMP2Vq1IW2iLFJ+GSH8KNCvGCNukXmw+r/Zdf\nYHmP+OBDm3tg/Z4ZP9ieYe68UWMNVUEPyCI2Pdq5w2ZhnWgZlXYL7zqucBgf6AVA\nnoL622CvyysZvl3FiYJfoKyovLSaGu0c2DUgp68qJHke6xnL8HDsjaz7GFb9/h7Z\n727rIOQLfYNydQbI1h9EsuMKdtpG9piiQ5P5jR/nGJabKihy735a1Lhxzj8uU0Gd\nbM33y99r7s69VCBl/0AZWth4vLeZHgW0OD65JAZwXDECggEBAOChAN86PI31Ar8u\nkTebPjYG4Q5CbyeYjO6ECUm0stCnEXhyWIdNWRDFg0b0qQt4lHFhC5hrxUnMZ89m\n55H3uGb9cnh6OSXXT1YO4zKEaB2nIwugkmF92+q2iFPurksdZ1yGT4334CJ+y6d4\nYgqYxod7SR9LfomMQzyC0dX3aLMQqeEECRLJ0W+pyx7Vujsb1Cd7AZ0SjncBDAuW\nTInlmylINJnSj4jL1Q0RoWgGD3EQ321HcFlRc9VTove19qNdO6QqxHOvkWAGcNSB\nK6GFsjKEsXnlG+usTmGC67lPt18pA6mushIwxkAazPzpQfLLY1iBe//NmMKv8ljl\n/EOFF68CggEBAJf635Lpx3nZ9/N107HuiTXDKI1YGZ3l2RzcwUgvfUbRY7P1h4ju\nRKDE5CjbX/e5mtLAX15DaGWEeZlISD9rXfpmt40/A4T+1waXIAgpH6/cbUBmIYHp\njeggZwH6fKkGMvmGaSb04uCIAQSjMOAQgy4Z5HfSKMYjXLKcqbSKvekY58CxVcom\newHrbGj7HzlvaKMQEW10Pt7z+DcY5Z9tSrNCyuNsT/RuFtaUsb7BeGIPjBaRZEjH\nXbwYhXXus0tyafxLrYxRzv/JJaPD+UF9l6tvNCmFnROXJ+p4rxTKIS4ERsWDC+M1\nNro2MZKPNzlcmOxcVPMmBuIxfIU6Gdp/ezECggEBAJ0IUFOBN0ffxanha0TBqKMv\nk0wEoZ8HawBbg8GZNYTafu1vHDPWffb5aizeLb1OpICNmhg0nprM154uK56fzjWR\nUUIEtjg5D7sR9cPWa/GOXFyGh1qF9pg0QrZs88tzWDzLW2i/jrjsb1ye/qVdCB5a\nL4298p2N1Smm9ksnpQcHknkoSexqnVWO0t1ClPjCiZqz0e+pqRWRkjVFAAlaLsuO\ndkChSn1H6mggxRV+q8+dHTZDo6wiL/SFUUtVEeB0v0Kkm5ID0yk85OkBzRGHXvAJ\nESdc3ZnG1BtB80DWVnZR5uUohJ3sOso5ZoAGPCCEGNMvH9wglHbB7MCtfCbT/50=\n-----END RSA PRIVATE KEY-----\n \ No newline at end of file diff --git a/deploy/build/charts/casdoor/token_jwt_key.pem b/deploy/build/charts/casdoor/token_jwt_key.pem deleted file mode 100644 index d4084daf50..0000000000 --- a/deploy/build/charts/casdoor/token_jwt_key.pem +++ /dev/null @@ -1 +0,0 @@ ------BEGIN CERTIFICATE-----\nMIIE3TCCAsWgAwIBAgIDAeJAMA0GCSqGSIb3DQEBCwUAMCgxDjAMBgNVBAoTBWFk\nbWluMRYwFAYDVQQDEw1jZXJ0LWJ1aWx0LWluMB4XDTIyMTExNjEzMDc0OFoXDTQy\nMTExNjEzMDc0OFowKDEOMAwGA1UEChMFYWRtaW4xFjAUBgNVBAMTDWNlcnQtYnVp\nbHQtaW4wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDeqvhS5dxRpHx+\nCwW7NfIZpI6A0CwY4garfmfy2Tug4NBI7E7VK5dIYCvRwGrXGFxfuJegXghuXJL7\nt0MXU5A+Na919DV/PPXJe4ev7YGsh73yIVXS8KpB4bV6rqbSVWDrxwSa4dHBPadX\nu/tPQ+HGiPN5JU/+rp7BVM/WaMaChc9sfYMv/LIj0Y3kA9dgezBaAYP+IV8mKqs5\n+MGKpFvxCY3+EGWPVuSSzjJWhrOKqBE8LksV6Djd55WRYgtxLNokUj7/1jFm331M\ndLS8Iio++TzjAQWzM2JJVTfSPZeMoaSF+7m77oiGwPDwVM1RbJNqwMbP25Whjk2L\nLLZEZfMgL0ej6e0FqNbvd5ehod+L3GM7fR8Q2XxRJhIAY8K6FgxrE8FzLn4mw8pn\nn0fkbtb5Al946CgpqKzy94x6q2u9DG1U7YIy3aD/AO0Xbf+TwD7A1uWyr9IAfVQr\nP7wJJUJu9cak+ryMw+Y2ezfxda7icMhIQvqx07xkoEY6fKwJ++89HalxUw8nlPqX\nsZwI9nWC9w2yaW5sPOy+5bKTtbMnBQmocVb76w0pfp4hEVRHAqNm9XXqwuFXC4A2\nGnjhfLCPsTTEbfTVGSl4EpN/ECYrIA/oHXActRTwntSQoyAicJa6SLK2t6/B9HrO\nXWRDTK0L5unEEMhVTfNZzJgmTqX+EwIDAQABoxAwDjAMBgNVHRMBAf8EAjAAMA0G\nCSqGSIb3DQEBCwUAA4ICAQBsPjtWCLr1rqMzbkJegubKNt60lQB3mVeFLcATK9/n\n1j0J9Hy51rFE2H9cGM0etCoxCtcdYkZHlTo1qVNN8ZmYlzbmpfhCDa+rb812Bk/1\nTdaYcSMZWSMyesYUNHe05n7vxMnz5R4GTadIfFJzGYm+FkxSPAbADkW1oMU0rTbD\nzkmTa2ITgzaVFpKontuG27nnebP1JQ2TBBsYO0UBSRhOBPMfgj4udqw1Npp/XfFx\n7GlLoGezYYH7t7/ICTAG4R6bwGNJCJMwPDxpz/QmIG73xX2BSg9l8QaFlYhGrmNu\nCahXcagxxrsP/BXZuMuIkWSRA0DoSFFgqsijYK7IiUvLa1K923vr0v+a7pGug5Qk\nn69BrBPr/rzS/OVHqGe2KHDmwHz0EP/JRtT/Yz31d8+QkK0DG9wYKLyh/+VohAl8\naXuFuVJTbYPHjlqGdOCE+xQwP//BOv3HffLQm9Aloi1cTuX6BwB0L3d68QwjTiIy\nZMWDQQcDf3F+r2BOeAOtspQGlu7yYB5iHT2GJ81GU+M1OUA0ng5VV5Zix+P/gpgO\n6COWblvsjy20tZWEIQxhVHI3PKCMbRg2GcDT1/C4ax40nQVZ+gH4JW1KeE4qqWYb\nkDfa7T9LrpFdcsJeusyJwNdEHpFoVoZ2gXadvIvpQxsPEBD00ND6eL20DQ3DqiGB\n3A==\n-----END CERTIFICATE-----\n \ No newline at end of file diff --git a/deploy/build/charts/casdoor/values.yaml b/deploy/build/charts/casdoor/values.yaml deleted file mode 100644 index 737502e05c..0000000000 --- a/deploy/build/charts/casdoor/values.yaml +++ /dev/null @@ -1,99 +0,0 @@ -# Default values for casdoor. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -## app configurations -host: "" -postgresql: - host: postgresql - port: 5432 - username: adm1n - password: passw0rd - database: casdoor -init: - client_id: a71f65e93723c436027e - client_secret: 0d7e157be08055867b81456df3c222ea7c68a097 - redirect_uri: http://localhost:3001/login_callback - -## k8s resource configurations - -replicaCount: 1 - -image: - repository: casbin/casdoor - pullPolicy: IfNotPresent - # Overrides the image tag whose default is the chart appVersion. - tag: "v1.149.0" - -imagePullSecrets: [] -nameOverride: "casdoor" -fullnameOverride: "casdoor" - -serviceAccount: - # Specifies whether a service account should be created - create: false - # Annotations to add to the service account - annotations: {} - # The name of the service account to use. - # If not set and create is true, a name is generated using the fullname template - name: "" - -podAnnotations: {} - -podSecurityContext: {} - # fsGroup: 2000 - -securityContext: {} - # capabilities: - # drop: - # - ALL - # readOnlyRootFilesystem: true - # runAsNonRoot: true - # runAsUser: 1000 - -service: - type: NodePort # ClusterIP - port: 8000 - nodePort: 30070 - - -ingress: - enabled: false - className: "" - annotations: {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - hosts: - - host: chart-example.local - paths: - - path: / - pathType: ImplementationSpecific - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local - -resources: {} - # We usually recommend not to specify default resources and to leave this as a conscious - # choice for the user. This also increases chances charts run on environments with little - # resources, such as Minikube. If you do want to specify resources, uncomment the following - # lines, adjust them as necessary, and remove the curly braces after 'resources:'. - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - -autoscaling: - enabled: false - minReplicas: 1 - maxReplicas: 100 - targetCPUUtilizationPercentage: 80 - # targetMemoryUtilizationPercentage: 80 - -nodeSelector: {} - -tolerations: [] - -affinity: {} diff --git a/deploy/build/charts/laf-server/templates/cert-issuer.yaml b/deploy/build/charts/laf-server/templates/cert-issuer.yaml new file mode 100644 index 0000000000..43af9b983e --- /dev/null +++ b/deploy/build/charts/laf-server/templates/cert-issuer.yaml @@ -0,0 +1,14 @@ +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: laf-issuer +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + email: laf-deploy@{{ .Values.default_region.runtime_domain }} + privateKeySecretRef: + name: letsencrypt-prod + solvers: + - http01: + ingress: + class: apisix diff --git a/deploy/build/charts/laf-server/templates/deployment.yaml b/deploy/build/charts/laf-server/templates/deployment.yaml index 92663a6f6f..963ac7fc85 100644 --- a/deploy/build/charts/laf-server/templates/deployment.yaml +++ b/deploy/build/charts/laf-server/templates/deployment.yaml @@ -81,18 +81,8 @@ spec: value: {{ .Values.default_region.apisix_api_url }} - name: DEFAULT_REGION_APISIX_API_KEY value: {{ .Values.default_region.apisix_api_key }} - - name: CASDOOR_ENDPOINT - value: {{ .Values.casdoor.endpoint }} - - name: CASDOOR_ORG_NAME - value: {{ .Values.casdoor.org_name | quote}} - - name: CASDOOR_APP_NAME - value: {{ .Values.casdoor.app_name | quote}} - - name: CASDOOR_CLIENT_ID - value: {{ .Values.casdoor.client_id | quote}} - - name: CASDOOR_CLIENT_SECRET - value: {{ .Values.casdoor.client_secret | quote}} - - name: CASDOOR_REDIRECT_URI - value : {{ .Values.casdoor.redirect_uri | quote}} + - name: SITE_NAME + value: {{ .Values.siteName | quote}} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/deploy/build/charts/laf-server/values.yaml b/deploy/build/charts/laf-server/values.yaml index e7ba92ac75..a06aa06fba 100644 --- a/deploy/build/charts/laf-server/values.yaml +++ b/deploy/build/charts/laf-server/values.yaml @@ -5,6 +5,7 @@ apiServerHost: "" databaseUrl: "" apiServerUrl: "" +siteName: "laf" # init default region conf default_region: # db conf @@ -25,13 +26,6 @@ default_region: jwt: secret: laf_server_abc123 expires_in: 7d -casdoor: - endpoint: "" - client_id: a71f65e93723c436027e - client_secret: 0d7e157be08055867b81456df3c222ea7c68a097 - org_name: laf - app_name: laf - redirect_uri: http://localhost:3001/login_callback replicaCount: 1 diff --git a/deploy/build/charts/laf-web/templates/NOTES.txt b/deploy/build/charts/laf-web/templates/NOTES.txt index 88fb6afb2a..f2907d5ce1 100644 --- a/deploy/build/charts/laf-web/templates/NOTES.txt +++ b/deploy/build/charts/laf-web/templates/NOTES.txt @@ -2,7 +2,6 @@ Domains: - http://{{ .Values.domain }} - http://api.{{ .Values.domain }} -- http://login.{{ .Values.domain }} - http://minio.{{ .Values.domain }} > Please resolve the `*.{{ .Values.domain }}` and `{{ .Values.domain }}` to the IP address of the server. \ No newline at end of file diff --git a/deploy/build/charts/laf-web/templates/ingress.yaml b/deploy/build/charts/laf-web/templates/ingress.yaml index 9bb62728b2..66126e0c8b 100644 --- a/deploy/build/charts/laf-web/templates/ingress.yaml +++ b/deploy/build/charts/laf-web/templates/ingress.yaml @@ -1,28 +1,65 @@ - -apiVersion: networking.k8s.io/v1 -kind: Ingress +apiVersion: apisix.apache.org/v2 +kind: ApisixRoute metadata: name: laf-web-ingress spec: - # apisix-ingress-controller is only interested in Ingress - # resources with the matched ingressClass name, in our case, - # it's apisix. - ingressClassName: apisix - rules: - - host: {{ .Values.domain }} - http: - paths: - - backend: - service: - name: laf-web - port: - number: 80 - path: / - pathType: Prefix - - backend: - service: - name: laf-server - port: - number: 3000 - path: /v1/ - pathType: Prefix + http: + - name: laf-web + match: + hosts: + - {{ .Values.domain }} + paths: + - /* + backends: + - serviceName: laf-web + servicePort: 80 + plugins: + - name: gzip + enable: true + config: + comp_level: 6 + min_length: 100 + types: + - text/plain + - text/css + - text/html + - text/xml + - text/javascript + - application/json + - application/x-javascript + - application/javascript + - image/bmp + - image/png + - font/ttf + - font/otf + - font/eot + - name: laf-web-api + match: + hosts: + - {{ .Values.domain }} + paths: + - /v1/* + backends: + - serviceName: laf-server + servicePort: 3000 + websocket: true + plugins: + - name: gzip + enable: true + config: + comp_level: 6 + min_length: 100 + types: + - text/plain + - text/css + - text/html + - text/xml + - text/javascript + - application/json + - application/x-javascript + - application/javascript + - image/bmp + - image/png + - font/ttf + - font/otf + - font/eot diff --git a/deploy/build/charts/minio/templates/ingress.yaml b/deploy/build/charts/minio/templates/ingress.yaml index dee5be1e70..b3f92544a2 100644 --- a/deploy/build/charts/minio/templates/ingress.yaml +++ b/deploy/build/charts/minio/templates/ingress.yaml @@ -1,21 +1,36 @@ --- -apiVersion: networking.k8s.io/v1 -kind: Ingress +apiVersion: apisix.apache.org/v2 +kind: ApisixRoute metadata: name: oss-ingress spec: - # apisix-ingress-controller is only interested in Ingress - # resources with the matched ingressClass name, in our case, - # it's apisix. - ingressClassName: apisix - rules: - - host: {{ .Values.domain }} - http: - paths: - - backend: - service: - name: minio - port: - number: 9000 - path: / - pathType: Prefix + http: + - backends: + - serviceName: minio + servicePort: 9000 + match: + hosts: + - {{ .Values.domain }} + paths: + - /* + name: laf-oss + plugins: + - config: + comp_level: 5 + min_length: 1024 + types: + - text/plain + - text/css + - text/html + - text/xml + - text/javascript + - application/json + - application/x-javascript + - application/javascript + - image/bmp + - image/png + - font/ttf + - font/otf + - font/eot + enable: true + name: gzip diff --git a/deploy/build/charts/minio/values.yaml b/deploy/build/charts/minio/values.yaml index 30c7dea7a1..7d51a4b976 100644 --- a/deploy/build/charts/minio/values.yaml +++ b/deploy/build/charts/minio/values.yaml @@ -18,7 +18,7 @@ clusterDomain: cluster.local ## image: repository: quay.io/minio/minio - tag: RELEASE.2023-02-27T18-10-45Z + tag: RELEASE.2023-03-22T06-36-24Z pullPolicy: IfNotPresent imagePullSecrets: [] diff --git a/deploy/build/charts/postgresql/.helmignore b/deploy/build/charts/postgresql/.helmignore deleted file mode 100644 index fbdd321f57..0000000000 --- a/deploy/build/charts/postgresql/.helmignore +++ /dev/null @@ -1,26 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store - -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ - -# Common backup files -*.swp -*.bak -*.tmp -*~ - -# Various IDEs -.project -.idea/ -*.tmproj - -.circleci/ diff --git a/deploy/build/charts/postgresql/Chart.yaml b/deploy/build/charts/postgresql/Chart.yaml deleted file mode 100644 index 8322abb264..0000000000 --- a/deploy/build/charts/postgresql/Chart.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v2 -appVersion: 11.5.0 -description: PostgreSQL is an open-source object-relational database management system - (ORDBMS) emphasizing extensibility and technical standards compliance. -home: https://www.postgresql.org/ -icon: https://en.wikipedia.org/wiki/PostgreSQL#/media/File:Postgresql_elephant.svg -keywords: -- postgresql -- postgres -- database -maintainers: -- name: alexnuttinck -- name: AyadiAmen -name: postgresql -version: 0.2.3 diff --git a/deploy/build/charts/postgresql/LICENSE b/deploy/build/charts/postgresql/LICENSE deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/deploy/build/charts/postgresql/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - 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/deploy/build/charts/postgresql/README.md b/deploy/build/charts/postgresql/README.md deleted file mode 100644 index b81526c607..0000000000 --- a/deploy/build/charts/postgresql/README.md +++ /dev/null @@ -1,137 +0,0 @@ -# Helm Chart for PostgreSQL -[![CircleCI](https://circleci.com/gh/cetic/helm-postgresql.svg?style=svg)](https://circleci.com/gh/cetic/helm-postgresql/tree/master) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) ![version](https://img.shields.io/github/tag/cetic/helm-postgresql.svg?label=release) - -## Introduction - -This [Helm](https://github.com/kubernetes/helm) chart installs [postgreSQL](https://www.postgresql.org/) in a Kubernetes cluster. - -## Prerequisites - -- Kubernetes cluster 1.10+ -- Helm 3.0.0+ -- PV provisioner support in the underlying infrastructure. - -## Installation - -### Add Helm repository - -```bash -helm repo add cetic https://cetic.github.io/helm-charts -helm repo update -``` - -### Configure the chart - -The following items can be set via `--set` flag during installation or configured by editing the `values.yaml` directly (need to download the chart first). - -#### Configure the way how to expose postgreSQL service: - -- **ClusterIP**: Exposes the service on a cluster-internal IP. Choosing this value makes the service only reachable from within the cluster. -- **NodePort**: Exposes the service on each Node’s IP at a static port (the NodePort). You’ll be able to contact the NodePort service, from outside the cluster, by requesting `NodeIP:NodePort`. -- **LoadBalancer**: Exposes the service externally using a cloud provider’s load balancer. - -#### Configure the way how to persistent data: - -- **Disable**: The data does not survive the termination of a pod. -- **Persistent Volume Claim(default)**: A default `StorageClass` is needed in the Kubernetes cluster to dynamic provision the volumes. Specify another StorageClass in the `storageClass` or set `existingClaim` if you have already existing persistent volumes to use. - -#### How to use LDAP: -LDAP is used only to validate the user name/password pairs. Therefore the user must already exist in the database before LDAP can be used for authentication. If you **enable ldap** a **CronJob** will be activated, it will run the tool [pg-ldap-sync](https://github.com/cetic/pg-ldap-sync-docker) that will copy users from your ldap server to your database. - -### Install the chart - -Install the postgresql helm chart with a release name `my-release`: - -```bash -helm install my-release cetic/postgresql -``` - -## Uninstallation - -To uninstall/delete the `my-release` deployment: - -```bash -helm delete --purge my-release -``` - -## Configuration - -The following table lists the configurable parameters of the postgresql chart and the default values. - -| Parameter | Description | Default | -| --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------| ------------------------------- | -| **Image** | -| `image.repository` | postgresql Image name | `postgres` | -| `image.tag` | postgresql Image tag | `11.5` | -| `image.pullPolicy` | postgresql Image pull policy | `IfNotPresent` | -| `image.pullSecret` | postgresql Image pull secret | `nil` | -| **postgresql properties** | -| `postgresql.username` | postgresql username | `postgres` | -| `postgresql.password` | postgresql password | `postgres` | -| `postgresql.database` | postgresql database | `postgres` | -| `postgresql.port` | postgresql port | `5432` | -| `postgresql.dataDir` | PostgreSQL data dir folder | `/var/lib/postgresql/data/pgdata` | -| `postgresql.config` | Runtime Config Parameters | `nil` | -| `postgresql.pghba` | Content of pg\_hba.conf | `nil (do not create pg_hba.conf)`| -| `postgresql.initdbscripts` | Content of initdbscripts.sh ( commands to be executed at the start of postgres ) | `nil (do not create initdbscripts.sh)`| -| `postgresql.configMap` | ConfigMap with the PostgreSQL configuration files (Note: Overrides `postgresqlConfiguration` and `pgHbaConfiguration`). The value is evaluated as a template. | `nil`| -| `extraEnv` | Any extra environment variables you would like to pass on to the pod. The value is evaluated as a template. | `{}` | -| **Service** | -| `service.type` | Type of service for postgresql frontend | `CusterIP` | -| `service.loadBalancerIP` | LoadBalancerIP if service type is `LoadBalancer` | `nil` | -| `service.clusterIP` | ClusterIP if service type is `ClusterIP` | `nil` | -| `service.loadBalancerSourceRanges` | Address that are allowed when svc is `LoadBalancer` | `[]` | -| `service.annotations` | Service annotations | `{}` | -| **Volume Permissions** | -| `volumePermissions.image.registry` | Init container volume-permissions image registry | `docker.io` | -| `volumePermissions.image.repository` | Init container volume-permissions image name | `debian` | -| `volumePermissions.image.tag` | Init container volume-permissions image tag | `buster-slim` | -| `volumePermissions.image.pullPolicy` | Init container volume-permissions image pull policy | `Always` | -| `volumePermissions.securityContext.runAsUser` | User ID for the init container | `0` | -| **Security Context** | -| `securityContext.enabled` | Enable security context | `true` | -| `securityContext.fsGroup` | Group ID for the container | `1001` | -| `securityContext.runAsUser` | User ID for the container | `1001` | -| **LDAP** | -| `ldap.enabled` | Use ldap authentication | `false` | -| `ldap.pgldapconfig` | pgldap config file | `` | -| `ldap.cron.schedule` | Cron job schedule | `""` | -| `ldap.cron.repo` | Cron job Docker image | `ceticasbl/pg-ldap-sync` | -| `ldap.cron.tag` | Cron job Docker image tag | `latest` | -| `ldap.cron.restartPolicy` | Restart policy of the cron job | `Never` | -| `ldap.cron.mountPath` | Path to mount the volume at | `` | -| `ldap.cron.subPath` | Subdirectory of the volume to mount at | `` | -| **Persistence** | -| `persistence.enabled` | Use persistent volume to store data | `false` | -| `persistence.mountPath` | Path to mount the volume at | `/var/lib/postgresql` | -| `persistence.subPath` | Subdirectory of the volume to mount at | `""` | -| `persistence.storageClass` | Storage class name of PVCs | `standard` | -| `persistence.accessMode` | ReadWriteOnce or ReadOnly | `[ReadWriteOnce]` | -| `persistence.size` | Size of persistent volume claim | `10Gi` | -| **ReadinessProbe** | -| `readinessProbe` | Rediness Probe settings | `nil` | -| **LivenessProbe** | -| `livenessProbe` | Liveness Probe settings | `nil` | -| **Resources** | -| `resources` | Pod resource requests and limits for logs | `{}` | -| **nodeSelector** | -| `nodeSelector` | Node labels for pod assignment | `{}` | -| **tolerations** | -| `tolerations` | Tolerations for pod assignment | `[]` | - -## Why this PostgreSQL Helm Chart? - -* use postgres official Docker Image. -* needed LDAP support for the [FADI](https://github.com/cetic/fadi) project. -* use this Chart for other architecture (ARM, ...). -* ... - -## Contributing - -Feel free to contribute by making a [pull request](https://github.com/cetic/helm-postgresql/pull/new/master). - -Please read the official [Contribution Guide](https://github.com/helm/charts/blob/master/CONTRIBUTING.md) from Helm for more information on how you can contribute to this Chart. - -## License - -[Apache License 2.0](/LICENSE) diff --git a/deploy/build/charts/postgresql/configs/README.md b/deploy/build/charts/postgresql/configs/README.md deleted file mode 100644 index 9644730a00..0000000000 --- a/deploy/build/charts/postgresql/configs/README.md +++ /dev/null @@ -1,2 +0,0 @@ -Copy here your postgresql.conf and/or pg_hba.conf files to use it as a config map. - diff --git a/deploy/build/charts/postgresql/templates/NOTES.txt b/deploy/build/charts/postgresql/templates/NOTES.txt deleted file mode 100644 index 9df2db767f..0000000000 --- a/deploy/build/charts/postgresql/templates/NOTES.txt +++ /dev/null @@ -1,36 +0,0 @@ -** Please be patient while the chart is being deployed ** - -PostgreSQL can be accessed via port {{ .Values.postgresql.port }} on the following DNS name from within your cluster: - - {{ template "postgresql.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local - Read/Write connection - -To get the password for "{{ .Values.postgresql.username }}" run: - - export POSTGRES_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ if .Values.existingSecret }}{{ .Values.existingSecret }}{{ else }}{{ template "postgresql.fullname" . }}{{ end }} -o jsonpath="{.data.postgresql-password}" | base64 --decode) - -To connect to your database run the following command: - - kubectl run {{ template "postgresql.fullname" . }}-client --rm --tty -i --restart='Never' --namespace {{ .Release.Namespace }} --image {{ .Values.image.repository }} --env="PGPASSWORD=$POSTGRES_PASSWORD" --command -- psql --host {{ template "postgresql.fullname" . }} -U {{ .Values.postgresql.username }}{{- if .Values.postgresql.database }} -d {{ .Values.postgresql.database }}{{- end }} -p {{ .Values.postgresql.port }} - -To connect to your database from outside the cluster execute the following commands: - -{{- if contains "NodePort" .Values.service.type }} - - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "postgresql.fullname" . }}) - {{ if (.Values.postgresql.password) }}PGPASSWORD="$POSTGRES_PASSWORD" {{ end }}psql --host $NODE_IP --port $NODE_PORT -U {{ .Values.postgresql.username }}{{- if .Values.postgresql.database }} -d {{ .Values.postgresql.database }}{{- end }} - -{{- else if contains "LoadBalancer" .Values.service.type }} - - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "postgresql.fullname" . }}' - - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "postgresql.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - {{ if (.Values.postgresql.password) }}PGPASSWORD="$POSTGRES_PASSWORD" {{ end }}psql --host $SERVICE_IP --port {{ .Values.postgresql.port }} -U {{ .Values.postgresql.username }}{{- if .Values.postgresql.database }} -d {{ .Values.postgresql.database }}{{- end }} - -{{- else if contains "ClusterIP" .Values.service.type }} - - kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "postgresql.fullname" . }} {{ .Values.postgresql.port }}:{{ .Values.postgresql.port }} & - {{ if (.Values.postgresql.password) }}PGPASSWORD="$POSTGRES_PASSWORD" {{ end }}psql --host 127.0.0.1 -U {{ .Values.postgresql.username }}{{- if .Values.postgresql.database }} -d {{ .Values.postgresql.database }}{{- end }} -p {{ .Values.postgresql.port}} - -{{- end }} diff --git a/deploy/build/charts/postgresql/templates/_helpers.tpl b/deploy/build/charts/postgresql/templates/_helpers.tpl deleted file mode 100644 index 571c399945..0000000000 --- a/deploy/build/charts/postgresql/templates/_helpers.tpl +++ /dev/null @@ -1,31 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "postgresql.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -*/}} -{{- define "postgresql.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "postgresql.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} -{{- end -}} diff --git a/deploy/build/charts/postgresql/templates/configmap.yaml b/deploy/build/charts/postgresql/templates/configmap.yaml deleted file mode 100644 index a7857ba247..0000000000 --- a/deploy/build/charts/postgresql/templates/configmap.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -{{- if and (or (.Files.Glob "configs/postgresql.conf") (.Files.Glob "configs/pg_hba.conf") (.Files.Glob "configs/initdbscripts.sh") .Values.postgresql.config .Values.postgresql.pghba .Values.postgresql.initdbscripts) (not .Values.postgresql.configMap) }} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "postgresql.fullname" . }}-configuration - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -data: -{{- if (.Files.Glob "configs/postgresql.conf") }} -{{ (.Files.Glob "configs/postgresql.conf").AsConfig | indent 2 }} -{{- else if .Values.postgresql.config }} - postgresql.conf: | -{{- range $key, $value := default dict .Values.postgresql.config }} - {{ $key | snakecase }}={{ $value }} -{{- end }} -{{- end }} -{{- if (.Files.Glob "configs/pg_hba.conf") }} -{{ (.Files.Glob "configs/pg_hba.conf").AsConfig | indent 2 }} -{{- else if .Values.postgresql.pghba }} - pg_hba.conf: | -{{ .Values.postgresql.pghba | indent 4 }} -{{- end }} -{{- if (.Files.Glob "configs/initdbscripts.sh") }} -{{ (.Files.Glob "configs/initdbscripts.sh").AsConfig | indent 2 }} -{{- else if .Values.postgresql.initdbscripts }} - initdbscripts.sh: | -{{ .Values.postgresql.initdbscripts | indent 4 }} -{{- end }} -{{- end }} -# -# A ConfigMap spec for pgldap-config.yaml -# /var/lib/pglda-config.yaml -# -{{- if and .Values.ldap.enabled .Values.ldap.pgldapconfig }} ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ template "postgresql.fullname" . }}-pgldap-config - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -data: - pgldap-config.yaml: | -{{ .Values.ldap.pgldapconfig | indent 4}} -{{- end }} - - diff --git a/deploy/build/charts/postgresql/templates/cronjob.yaml b/deploy/build/charts/postgresql/templates/cronjob.yaml deleted file mode 100644 index f28c477308..0000000000 --- a/deploy/build/charts/postgresql/templates/cronjob.yaml +++ /dev/null @@ -1,33 +0,0 @@ ---- -{{- if and .Values.ldap.enabled .Values.ldap.pgldapconfig }} -apiVersion: batch/v1beta1 -kind: CronJob -metadata: - name: pg-ldap-sync -spec: - schedule: {{ .Values.ldap.cron.schedule | quote}} - jobTemplate: - metadata: - labels: - app: {{ .Release.Name | quote }} - spec: - template: - spec: - containers: - - name: pg-ldap-sync - image: {{ .Values.ldap.cron.repo }}:{{ .Values.ldap.cron.tag }} - args: [ "/workspace/pgldap-config.yaml", "-vv"] - imagePullPolicy: IfNotPresent - volumeMounts: - - name: pgldap-config - mountPath: {{ .Values.ldap.cron.mountPath | quote}} - subPath: {{ .Values.ldap.cron.subPath | quote}} - restartPolicy: {{ .Values.ldap.cron.restartPolicy }} - volumes: - - name: pgldap-config - configMap: - name: {{ template "postgresql.fullname" . }}-pgldap-config - items: - - key: pgldap-config.yaml - path: pgldap-config.yaml -{{- end}} diff --git a/deploy/build/charts/postgresql/templates/service.yaml b/deploy/build/charts/postgresql/templates/service.yaml deleted file mode 100644 index 36425827e2..0000000000 --- a/deploy/build/charts/postgresql/templates/service.yaml +++ /dev/null @@ -1,35 +0,0 @@ ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ template "postgresql.fullname" . }} - labels: - app: {{ template "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -{{- with .Values.service.annotations }} - annotations: -{{ toYaml . | indent 4 }} -{{- end }} -spec: - type: {{ .Values.service.type }} - {{- if and .Values.service.loadBalancerIP (eq .Values.service.type "LoadBalancer") }} - loadBalancerIP: {{ .Values.service.loadBalancerIP }} - {{- end }} - {{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerSourceRanges }} - loadBalancerSourceRanges: - {{ with .Values.service.loadBalancerSourceRanges }} -{{ toYaml . | indent 4 }} -{{- end }} - {{- end }} - {{- if and (eq .Values.service.type "ClusterIP") .Values.service.clusterIP }} - clusterIP: {{ .Values.service.clusterIP }} - {{- end }} - ports: - - name: postgresql - port: {{ .Values.postgresql.port }} - targetPort: postgresql - selector: - app: {{ template "postgresql.name" . }} - release: {{ .Release.Name | quote }} diff --git a/deploy/build/charts/postgresql/templates/statefulset.yaml b/deploy/build/charts/postgresql/templates/statefulset.yaml deleted file mode 100644 index f83457a6ca..0000000000 --- a/deploy/build/charts/postgresql/templates/statefulset.yaml +++ /dev/null @@ -1,184 +0,0 @@ ---- -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ template "postgresql.fullname" . }} - labels: - app: {{ include "postgresql.name" . }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} -spec: - serviceName: {{ template "postgresql.fullname" . }}-headless - replicas: 1 - selector: - matchLabels: - app: {{ template "postgresql.name" . }} - release: {{ .Release.Name | quote }} - template: - metadata: - name: {{ template "postgresql.fullname" . }} - labels: - app: {{ include "postgresql.name" . | quote }} - chart: {{ template "postgresql.chart" . }} - release: {{ .Release.Name | quote }} - heritage: {{ .Release.Service | quote }} - spec: - {{- if and .Values.volumePermissions.enabled .Values.persistence.enabled }} - initContainers: - - name: init-chmod-data - image: "{{ .Values.volumePermissions.image.repository }}:{{ .Values.volumePermissions.image.tag }}" - imagePullPolicy: "{{ .Values.volumePermissions.image.pullPolicy }}" - resources: -{{ toYaml .Values.resources | indent 10 }} - command: - - sh - - -c - - | - mkdir -p {{ .Values.persistence.mountPath }}/data - chmod 700 {{ .Values.persistence.mountPath }}/data - find {{ .Values.persistence.mountPath }} -mindepth 1 -maxdepth 1 -not -name ".snapshot" -not -name "lost+found" | \ - xargs chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }} - securityContext: - runAsUser: {{ .Values.volumePermissions.securityContext.runAsUser }} - volumeMounts: - - name: data - mountPath: {{ .Values.persistence.mountPath }} - subPath: {{ .Values.persistence.subPath }} - {{- end }} - containers: - - name: {{ template "postgresql.fullname" . }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" - {{- if and .Values.postgresql.pghba .Values.postgresql.config}} - args: ["-c", "config_file={{ .Values.persistence.mountPath }}/conf/postgresql.conf", "-c", "hba_file={{ .Values.persistence.mountPath }}/conf/pg_hba.conf"] - {{- end }} - {{- if and (not .Values.postgresql.pghba) .Values.postgresql.config}} - args: ["-c", "config_file={{ .Values.persistence.mountPath }}/conf/postgresql.conf"] - {{- end }} - {{- if and .Values.postgresql.pghba (not .Values.postgresql.config)}} - args: ["-c", "hba_file={{ .Values.persistence.mountPath }}/conf/pg_hba.conf"] - {{- end }} - imagePullPolicy: {{ .Values.image.pullPolicy | quote }} - resources: -{{ toYaml .Values.resources | indent 10 }} - env: - - name: POSTGRES_PASSWORD - value: {{ .Values.postgresql.password | quote }} - - name: POSTGRES_USER - value: {{ .Values.postgresql.username | quote }} - - name: POSTGRES_DB - value: {{ .Values.postgresql.database | quote }} - {{- if .Values.postgresql.initdbArgs }} - - name: POSTGRES_INITDB_ARGS - value: {{ .Values.postgresql.initdbArgs | quote }} - {{- end }} - {{- if .Values.postgresql.initdbWalDir }} - - name: POSTGRES_INITDB_WALDIR - value: {{ .Values.postgresql.initdbWalDir | quote }} - {{- end }} - {{- if .Values.persistence.mountPath }} - - name: PGDATA - value: {{ .Values.postgresql.dataDir | quote }} - {{- end }} -{{- if .Values.extraEnv }} -{{ tpl (toYaml .Values.extraEnv) $ | indent 8 }} -{{- end }} - ports: - - name: postgresql - containerPort: {{ .Values.postgresql.port }} - livenessProbe: -{{ toYaml .Values.livenessProbe | indent 12 }} - readinessProbe: -{{ toYaml .Values.readinessProbe | indent 12 }} - volumeMounts: - {{- if .Values.persistence.enabled }} - - name: data - mountPath: {{ .Values.persistence.mountPath }}/data - subPath: {{ .Values.persistence.subPath }} - readOnly: false - {{- end }} - {{- if or (.Files.Glob "configs/pg_hba.conf") .Values.postgresql.pghba .Values.configMap }} - - name: postgresql-config-pghba - mountPath: {{ .Values.persistence.mountPath }}/conf/pg_hba.conf - subPath: pg_hba.conf - readOnly: false - {{- end }} - {{- if or (.Files.Glob "configs/initdbscripts.sh") .Values.postgresql.initdbscripts .Values.configMap }} - - name: postgresql-config-initdbscripts - mountPath: /docker-entrypoint-initdb.d/initdbscripts.sh - subPath: initdbscripts.sh - readOnly: false - {{- end }} - {{- if or (.Files.Glob "configs/postgresql.conf") .Values.postgresql.config .Values.configMap }} - - name: postgresql-config - mountPath: {{ .Values.persistence.mountPath }}/conf/postgresql.conf - subPath: postgresql.conf - readOnly: false - {{- end }} - {{- if .Values.nodeSelector }} - nodeSelector: -{{ toYaml .Values.nodeSelector | indent 8 }} - {{- end }} - {{- if .Values.nodeName }} - nodeName: {{ .Values.nodeName | quote }} - {{- end }} - {{- if .Values.affinity }} - affinity: -{{ toYaml .Values.affinity | indent 8 }} - {{- end }} - volumes: - {{- if or (.Files.Glob "configs/pg_hba.conf") .Values.postgresql.pghba .Values.postgresql.configMap}} - - name: postgresql-config-pghba - configMap: - name: {{ template "postgresql.fullname" . }}-configuration - items: - - key: pg_hba.conf - path: pg_hba.conf - {{- end }} - {{- if or (.Files.Glob "configs/postgresql.conf") .Values.postgresql.config .Values.postgresql.configMap}} - - name: postgresql-config - configMap: - name: {{ template "postgresql.fullname" . }}-configuration - items: - - key: postgresql.conf - path: postgresql.conf - {{- end }} - {{- if or (.Files.Glob "configs/initdbscripts.sh") .Values.postgresql.initdbscripts .Values.postgresql.configMap}} - - name: postgresql-config-initdbscripts - configMap: - name: {{ template "postgresql.fullname" . }}-configuration - items: - - key: initdbscripts.sh - path: initdbscripts.sh - {{- end }} -{{- if and .Values.persistence.enabled .Values.persistence.existingClaim }} - - name: data - persistentVolumeClaim: -{{- with .Values.persistence.existingClaim }} - claimName: {{ tpl . $ }} -{{- end }} -{{- else if not .Values.persistence.enabled }} - - name: data - emptyDir: {} -{{- else if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} - volumeClaimTemplates: - - metadata: - name: data - {{- with .Values.persistence.annotations }} - annotations: - {{- range $key, $value := . }} - {{ $key }}: {{ $value }} - {{- end }} - {{- end }} - spec: - accessModes: - {{- range .Values.persistence.accessModes }} - - {{ . | quote }} - {{- end }} - {{- with .Values.persistence.storageClass }} - storageClassName: {{ tpl . $ }} - {{- end }} - resources: - requests: - storage: {{ .Values.persistence.size | quote }} -{{- end }} diff --git a/deploy/build/charts/postgresql/values.yaml b/deploy/build/charts/postgresql/values.yaml deleted file mode 100644 index aed9fd29d8..0000000000 --- a/deploy/build/charts/postgresql/values.yaml +++ /dev/null @@ -1,214 +0,0 @@ ---- -## Set default image, imageTag, and imagePullPolicy. -## ref: https://hub.docker.com/_/postgres -## -image: - repository: postgres - tag: "11.5" - pullPolicy: IfNotPresent - - ## Optionally specify an imagePullSecret. - ## Secret must be manually created in the namespace. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ - ## - # pullSecret: myRegistrKeySecretName - -## Expose the nifi service to be accessed from outside the cluster (LoadBalancer service). -## or access it from within the cluster (ClusterIP service). Set the service type and the port to serve it. -## ref: http://kubernetes.io/docs/user-guide/services/ -## -service: - type: ClusterIP - annotations: {} - ## clusterIP: - - ## Set the LoadBalancer service type to internal only. - ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer - ## - # loadBalancerIP: - - ## Load Balancer sources - ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service - ## - # loadBalancerSourceRanges: - # - 10.10.10.0/24 - -## Postgresql values -postgresql: - username: postgres - password: postgres - database: postgres - port: 5432 - # initdbArgs - # initdbWalDir - dataDir: /var/lib/postgresql/data/pgdata -# extraEnv - - ## PostgreSQL configuration - ## Specify runtime configuration parameters as a dict, using camelCase, e.g. - ## {"sharedBuffers": "500MB"} - ## Alternatively, you can put your postgresql.conf under the configs/ directory - ## ref: https://www.postgresql.org/docs/current/static/runtime-config.html - ## - # config: - - ## PostgreSQL client authentication configuration - ## Specify content for pg_hba.conf - ## Default: do not create pg_hba.conf - ## Alternatively, you can put your pg_hba.conf under the files/ directory - # pghba: |- - # local all all trust - # host all all localhost trust - # host mydatabase mysuser 192.168.0.0/24 md5 - #initdbscripts: |- - #!/bin/sh - #echo "helloworld" - ## ConfigMap with PostgreSQL configuration - ## NOTE: This will override postgresql.config and postgresql.pghba - # configMap: - -## -## Init containers parameters: -## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup -## -volumePermissions: - enabled: true - image: - registry: docker.io - repository: debian - tag: buster-slim - ## Specify a imagePullPolicy - ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' - ## ref: http://kubernetes.io/docs/user-guide/images/#pre-pulling-images - ## - pullPolicy: Always - ## Optionally specify an array of imagePullSecrets. - ## Secrets must be manually created in the namespace. - ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ - ## - # pullSecrets: - # - myRegistryKeySecretName - ## Init container Security Context - securityContext: - runAsUser: 0 - -## Pod Security Context -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ -## -securityContext: - enabled: true - fsGroup: 1001 - runAsUser: 1001 - -ldap: - enabled: false - pgldapconfig: |- - # Reference: https://github.com/larskanis/pg-ldap-sync/blob/master/config/sample-config.yaml - # Connection parameters to LDAP server - ldap_connection: - host: example.com - port: 389 - auth: - method: :simple - username: cn=admin,dc=example,dc=com - password: -password-goes-here- - - # Search parameters for LDAP users which should be synchronized - ldap_users: - base: OU=People,dc=example,dc=com - # LDAP filter (according to RFC 2254) - # defines to users in LDAP to be synchronized - filter: (&(objectClass=person)(objectClass=organizationalPerson)(givenName=*)(sn=*)) - # this attribute is used as PG role name - name_attribute: sAMAccountName - # lowercase name for use as PG role name - lowercase_name: true - ldap_groups: - base: OU=people,dc=example,dc=com - filter: (|(cn=group1)(cn=group2)(cn=group3)) - # this attribute is used as PG role name - name_attribute: cn - # this attribute must reference to all member DN's of the given group - member_attribute: member - # Connection parameters to PostgreSQL server - # see also: http://rubydoc.info/gems/pg/PG/Connection#initialize-instance_method - pg_connection: - host: - dbname: postgres # the db name is usually "postgres" - user: postgres # the user name is usually "postgres" - password: postgres # kubectl get secret --namespace fadi -o jsonpath="{.data.postgresql-password}" | base64 --decode - pg_users: - # Filter for identifying LDAP generated users in the database. - # It's the WHERE-condition to "SELECT rolname, oid FROM pg_roles" - filter: rolcanlogin AND NOT rolsuper - # Options for CREATE RULE statements - create_options: LOGIN - pg_groups: - # Filter for identifying LDAP generated groups in the database. - # It's the WHERE-condition to "SELECT rolname, oid FROM pg_roles" - filter: NOT rolcanlogin AND NOT rolsuper - # Options for CREATE RULE statements - create_options: NOLOGIN - grant_options: - - cron: - schedule: "*/1 * * * *" - repo: ceticasbl/pg-ldap-sync - tag: latest - restartPolicy: Never - mountPath: /workspace - subPath: "" - -## Enable persistence using Persistent Volume Claims -## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ -## -persistence: - enabled: true - mountPath: /var/lib/postgresql - subPath: "" - accessModes: [ReadWriteOnce] - ## Storage Capacity for persistent volume - size: 10Gi - annotations: {} - -## Configure liveness and readiness probes -## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ -## -#readinessProbe: -# httpGet: -# path: / -# port: http -# initialDelaySeconds: 60 -# periodSeconds: 15 -# timeoutSeconds: 10 -#livenessProbe: -# httpGet: -# path: / -# port: http -# initialDelaySeconds: 60 -# periodSeconds: 30 -# timeoutSeconds: 10 - -## Configure resource requests and limits -## ref: http://kubernetes.io/docs/user-guide/compute-resources/ -## - -## initdb scripts -## Specify dictionary of scripts to be run at first boot -## Alternatively, you can put your scripts under the files/docker-entrypoint-initdb.d directory -## -resources: {} - # We usually recommend not to specify default resources and to leave this as a conscious - # choice for the user. This also increases chances charts run on environments with little - # resources, such as Minikube. If you do want to specify resources, uncomment the following - # lines, adjust them as necessary, and remove the curly braces after 'resources:'. - # limits: - # cpu: 100m - # memory: 128Mi - # requests: - # cpu: 100m - # memory: 128Mi - -nodeSelector: {} - -tolerations: [] diff --git a/deploy/build/images/shim/ImageList b/deploy/build/images/shim/ImageList index 78552d504b..ebb3e2ea89 100644 --- a/deploy/build/images/shim/ImageList +++ b/deploy/build/images/shim/ImageList @@ -1,5 +1,4 @@ -docker.io/lafyun/runtime-node-init:latest -docker.io/lafyun/runtime-node:latest docker.io/apache/apisix-dashboard:2.13-alpine docker.io/apache/apisix-ingress-controller:1.5.0 -quay.io/coreos/etcd:v3.5.4 \ No newline at end of file +quay.io/minio/minio:RELEASE.2023-03-22T06-36-24Z +quay.io/minio/mc:RELEASE.2022-11-07T23-47-39Z \ No newline at end of file diff --git a/deploy/build/start.sh b/deploy/build/start.sh index 6ef584ecda..6a6e3b9d85 100644 --- a/deploy/build/start.sh +++ b/deploy/build/start.sh @@ -31,7 +31,22 @@ helm install mongodb -n ${NAMESPACE} \ ./charts/mongodb -## 2. install minio +# 2. deploy apisix +APISIX_API_URL="http://apisix-admin.${NAMESPACE}.svc.cluster.local:9180/apisix/admin" +APISIX_API_KEY=$PASSWD_OR_SECRET +helm install apisix -n ${NAMESPACE} \ + --set apisix.kind=DaemonSet \ + --set apisix.hostNetwork=true \ + --set admin.credentials.admin=${APISIX_API_KEY} \ + --set etcd.enabled=true \ + --set etcd.host[0]="http://apisix-etcd:2379" \ + --set dashboard.enabled=true \ + --set ingress-controller.enabled=true \ + --set ingress-controller.config.apisix.adminKey="${APISIX_API_KEY}" \ + ./charts/apisix + + +## 3. install minio MINIO_ROOT_ACCESS_KEY=minio-root-user MINIO_ROOT_SECRET_KEY=$PASSWD_OR_SECRET MINIO_DOMAIN=oss.${DOMAIN} @@ -47,56 +62,14 @@ helm install minio -n ${NAMESPACE} \ ./charts/minio -# 3. deploy apisix -APISIX_API_URL="http://apisix-admin.${NAMESPACE}.svc.cluster.local:9180/apisix/admin" -APISIX_API_KEY=$PASSWD_OR_SECRET -helm install apisix -n ${NAMESPACE} \ - --set apisix.kind=DaemonSet \ - --set apisix.hostNetwork=true \ - --set admin.credentials.admin=${APISIX_API_KEY} \ - --set etcd.enabled=true \ - --set etcd.host[0]="http://apisix-etcd:2379" \ - --set dashboard.enabled=true \ - --set ingress-controller.enabled=true \ - --set ingress-controller.config.apisix.adminKey="${APISIX_API_KEY}" \ - ./charts/apisix - - -## 4. install casdoor -PG_PASSWORD=$PASSWD_OR_SECRET -helm install postgresql -n ${NAMESPACE} \ - --set postgresql.username=${PG_USERNAME:-adm1n} \ - --set postgresql.password=${PG_PASSWORD} \ - --set postgresql.database=${PG_DATABASE:-casdoor} \ - ./charts/postgresql - -CASDOOR_HOST="login.${DOMAIN}" -CASDOOR_ENDPOINT="${HTTP_SCHEMA}://${CASDOOR_HOST}" -CASDOOR_CLIENT_ID=$(tr -cd 'a-f0-9' TODO diff --git a/docs/README.md b/docs/README.md index a796fc8ae6..975fc509a4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,4 @@ ### (WIP) laf documentation v0.8 -> TODO +> TODO diff --git a/docs/api/cloud.md b/docs/api/cloud.md deleted file mode 100644 index 76f4dfc9d4..0000000000 --- a/docs/api/cloud.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: 云函数Cloud SDK API文档 ---- - -# {{ $frontmatter.title }} - -## CloudSdkInterface - -````ts -export interface CloudSdkInterface { - /** - * 发送 HTTP 请求,实为 Axios 实例,使用可直接参考 axios 文档 - */ - fetch: AxiosStatic; - - /** - * 获取 database ORM 实例 - */ - database(): Db; - /** - * 调用云函数 - */ - invoke: InvokeFunctionType; - /** - * 抛出云函数事件,其它云函数可设置触发器监听此类事件 - */ - emit: EmitFunctionType; - /** - * 云函数全局内存单例对象,可跨多次调用、不同云函数之间共享数据 - * 1. 可将一些全局配置初始化到 shared 中,如微信开发信息、短信发送配置 - * 2. 可共享一些常用方法,如 checkPermission 等,以提升云函数性能 - * 3. 可做热数据的缓存,建议少量使用(此对象是在 node vm 堆中分配,因为 node vm 堆内存限制) - */ - shared: Map; - /** - * 获取 JWT Token,若缺省 `secret`,则使用当前服务器的密钥做签名 - */ - getToken: GetTokenFunctionType; - /** - * 解析 JWT Token,若缺省 `secret`,则使用当前服务器的密钥做签名 - */ - parseToken: ParseTokenFunctionType; - /** - * 当前应用的 MongoDb Node.js Driver 实例对象。 - * 由于 Laf database ORM 对象只有部分数据操作能力,故暴露此对象给云函数,让云函数拥有完整的数据库操作能力: - * 1. 事务操作 - * ```js - * const session = mongo.client.startSession() - * try { - * await session.withTransaction(async () => { - * await mongo.db.collection('xxx').updateOne({}, { session }) - * await mongo.db.collection('yyy').deleteMany({}, { session }) - * // ... - * }) - * } finally { - * await session.endSession() - * } - * ``` - * 2. 索引管理 - * ```js - * mongo.db.collection('admins').createIndex('username', { unique: true }) - * ``` - * 3. 聚合操作 - */ - mongo: MongoDriverObject; -} -```` diff --git a/docs/api/deploy-docker.md b/docs/api/deploy-docker.md deleted file mode 100644 index 5b4dd22c2b..0000000000 --- a/docs/api/deploy-docker.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Docker环境变量配置 ---- - -# {{ $frontmatter.title }} - -## MongoDB 配置 - -| 变量名称 | 默认值 | 解释 | -| ----------------------- | ------------- | -------------------- | -| `MONGODB_ROOT_PASSWORD` | `password123` | MongoDB 的 root 密码 | -| `SYS_DB` | `sys_db` | 系统数据库 | -| `SYS_DB_USER` | `sys_user` | 系统数据库用户 | -| `SYS_DB_PASSWORD` | `password123` | 系统数据库密码 | - -## 对象存储配置 - -| 变量名称 | 默认值 | 解释 | -| --------------------- | --------------------- | ------------------ | -| `MINIO_ROOT_USER` | `minio-root-user` | minio 平台初始账号 | -| `MINIO_ROOT_PASSWORD` | `minio-root-password` | minio 平台初始密码 | - -## 平台配置 - -| 变量名称 | 默认值 | 解释 | -| ---------------------------- | ------------------------------ | ------------------------ | -| `INIT_ROOT_ACCOUNT` | `root` | Laf 平台初始账号 | -| `INIT_ROOT_ACCOUNT_PASSWORD` | `password123` | Laf 平台初始密码 | -| `SYS_SERVER_SECRET_SALT` | `system-server-abcdefg1234567` | 系统密钥,用于生成 Token | -| `SYSTEM_EXTENSION_APPID` | `000000` | 系统扩展应用 APPID | -| `DEPLOY_DOMAIN` | `127-0-0-1.nip.io` | 部署域名 | -| `SYS_CLIENT_HOST` | `console.127-0-0-1.nip.io` | 控制台访问域名 | -| `OSS_DOMAIN` | `oss.127-0-0-1.nip.io` | 对象存储访问域名 | -| `APP_SERVICE_IMAGE` | `lafyun/app-service:latest` | 云函数服务使用的镜像 | diff --git a/docs/api/function.md b/docs/api/function.md deleted file mode 100644 index d305525e40..0000000000 --- a/docs/api/function.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: 云函数API文档 ---- - -# {{ $frontmatter.title }} - -## 云函数签名 - -```ts -(ctx: FunctionContext) => any; -``` - -## FunctionContext - -云函数执行时提供的上下文 - -| 属性 | 类型 | 介绍 | -| --------------- | ------------------------------------------------------------------------- | ------------------------------------------------ | -| `ctx.requestId` | `string` | 当前请求的唯一 ID | -| `ctx?.method` | `string` | 当前请求的方法,如`GET`、`POST` | -| `ctx?.headers` | `import('http').IncomingHttpHeaders` | 所有请求的 headers | -| `ctx?.auth` | `{ uid: string }` | 使用 Http Bearer Token 认证时,解析出的 token 值 | -| `ctx.query` | `import('qs').ParsedQs` | 当前请求的 query 参数 | -| `ctx.body` | `any` | 当前请求的 body 参数 | -| `ctx.response` | `import('express').Response` | HTTP 响应,和`express`的`Response`实例保持一致 | -| `ctx.socket` | [`WebSocket`](https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket) | WebSocket 实例 | -| `ctx.files` | [`File[]`](https://developer.mozilla.org/zh-CN/docs/Web/API/File) | 上传的文件对象数组) | diff --git a/docs/diagrams/laf-arch-full.excalidraw b/docs/diagrams/laf-arch-full.excalidraw index eb133ece7b..3d72167320 100644 --- a/docs/diagrams/laf-arch-full.excalidraw +++ b/docs/diagrams/laf-arch-full.excalidraw @@ -5,81 +5,8 @@ "elements": [ { "type": "rectangle", - "version": 2016, - "versionNonce": 1115561779, - "isDeleted": false, - "id": "CWJVfUily2HQrkrrhGWVB", - "fillStyle": "hachure", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 789.6579973884218, - "y": 31.55495249606804, - "strokeColor": "#000000", - "backgroundColor": "#ced4da", - "width": 238, - "height": 74, - "seed": 956432943, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [ - { - "type": "text", - "id": "G6myBAdfgZgo6d2Oa3rIj" - }, - { - "id": "8fGBOXNk8bCIy6Zk7y-De", - "type": "arrow" - }, - { - "id": "F0l5EdS9JdyYqN5Lmjb8Q", - "type": "arrow" - } - ], - "updated": 1664572206635, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 1844, - "versionNonce": 147320700, - "isDeleted": false, - "id": "G6myBAdfgZgo6d2Oa3rIj", - "fillStyle": "solid", - "strokeWidth": 4, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 794.6579973884218, - "y": 46.55495249606804, - "strokeColor": "#000000", - "backgroundColor": "#40c057", - "width": 213, - "height": 44, - "seed": 887303503, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1668084241168, - "link": null, - "locked": false, - "fontSize": 36, - "fontFamily": 3, - "text": "laf server", - "baseline": 35, - "textAlign": "left", - "verticalAlign": "middle", - "containerId": "CWJVfUily2HQrkrrhGWVB", - "originalText": "laf server" - }, - { - "type": "rectangle", - "version": 727, - "versionNonce": 1470850309, + "version": 729, + "versionNonce": 743764033, "isDeleted": false, "id": "yIaxuM7PTc3JyYygAVlow", "fillStyle": "hachure", @@ -89,28 +16,28 @@ "opacity": 100, "angle": 0, "x": 482.70861820892173, - "y": -86.97645210442369, + "y": -87.18785794781246, "strokeColor": "#000000", "backgroundColor": "#dee4ea", "width": 176, "height": 66, "seed": 2125013043, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "type": "text", "id": "m7YtI68vy8BrAI9456Lx0" } ], - "updated": 1667988583501, + "updated": 1682390147044, "link": null, "locked": false }, { "type": "rectangle", - "version": 824, - "versionNonce": 878802411, + "version": 825, + "versionNonce": 602009679, "isDeleted": false, "id": "iFdhpoqG-8cvlt635sWly", "fillStyle": "hachure", @@ -127,25 +54,21 @@ "height": 66, "seed": 645415389, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "j7AFmXdWx8ncL-sByBxr1", "type": "text" - }, - { - "type": "text", - "id": "j7AFmXdWx8ncL-sByBxr1" } ], - "updated": 1667988582804, + "updated": 1682390147044, "link": null, "locked": false }, { "type": "rectangle", - "version": 879, - "versionNonce": 1362650283, + "version": 880, + "versionNonce": 2007973921, "isDeleted": false, "id": "LEtOq_GNzdK06yv6FCUaL", "fillStyle": "hachure", @@ -162,29 +85,21 @@ "height": 38, "seed": 1649448179, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "2i_OC0N5CymL1Gm3XGJ51", "type": "text" - }, - { - "id": "2i_OC0N5CymL1Gm3XGJ51", - "type": "text" - }, - { - "type": "text", - "id": "2i_OC0N5CymL1Gm3XGJ51" } ], - "updated": 1667988581981, + "updated": 1682390147044, "link": null, "locked": false }, { "type": "rectangle", - "version": 1063, - "versionNonce": 1757802853, + "version": 1064, + "versionNonce": 234688111, "isDeleted": false, "id": "tKjzaQgey4YRa-W0mOpBk", "fillStyle": "hachure", @@ -201,33 +116,21 @@ "height": 66, "seed": 1583443869, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "c3_dC4IS__cnRYxHXTdrp", "type": "text" - }, - { - "id": "c3_dC4IS__cnRYxHXTdrp", - "type": "text" - }, - { - "id": "c3_dC4IS__cnRYxHXTdrp", - "type": "text" - }, - { - "type": "text", - "id": "c3_dC4IS__cnRYxHXTdrp" } ], - "updated": 1667988581262, + "updated": 1682390147044, "link": null, "locked": false }, { "type": "rectangle", - "version": 1119, - "versionNonce": 1212021643, + "version": 1121, + "versionNonce": 1266359919, "isDeleted": false, "id": "C16_cp7Kvs98I3yC1wEzB", "fillStyle": "hachure", @@ -236,45 +139,29 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 483.74377445892173, - "y": 201.08431178446517, + "x": 483.53230667417824, + "y": 200.8860994496149, "strokeColor": "#000000", "backgroundColor": "#dee4ea", "width": 178, "height": 66, "seed": 706811581, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "VCtvQy5TQteGcX2VgctFr", "type": "text" - }, - { - "id": "VCtvQy5TQteGcX2VgctFr", - "type": "text" - }, - { - "id": "VCtvQy5TQteGcX2VgctFr", - "type": "text" - }, - { - "id": "VCtvQy5TQteGcX2VgctFr", - "type": "text" - }, - { - "type": "text", - "id": "VCtvQy5TQteGcX2VgctFr" } ], - "updated": 1667988580485, + "updated": 1682390179627, "link": null, "locked": false }, { "type": "rectangle", - "version": 1220, - "versionNonce": 1304590245, + "version": 1221, + "versionNonce": 1599039631, "isDeleted": false, "id": "m_-FpYnKNljgOKf_7OTgJ", "fillStyle": "hachure", @@ -291,41 +178,21 @@ "height": 66, "seed": 609703069, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "WDu98khDATYV08tGQWau5", "type": "text" - }, - { - "id": "WDu98khDATYV08tGQWau5", - "type": "text" - }, - { - "id": "WDu98khDATYV08tGQWau5", - "type": "text" - }, - { - "id": "WDu98khDATYV08tGQWau5", - "type": "text" - }, - { - "id": "WDu98khDATYV08tGQWau5", - "type": "text" - }, - { - "type": "text", - "id": "WDu98khDATYV08tGQWau5" } ], - "updated": 1667988591670, + "updated": 1682390147044, "link": null, "locked": false }, { "type": "rectangle", - "version": 710, - "versionNonce": 520071109, + "version": 711, + "versionNonce": 237267937, "isDeleted": false, "id": "i_oL4vx3IxwwV65ndHvXG", "fillStyle": "hachure", @@ -342,37 +209,21 @@ "height": 66, "seed": 40928669, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "6dYVn41EPXSYABfzG93KG", "type": "text" - }, - { - "type": "text", - "id": "6dYVn41EPXSYABfzG93KG" - }, - { - "id": "P--KqBqhusuV65Jfm9e9S", - "type": "arrow" - }, - { - "id": "edEYS7LQQXgHqVU4gRSMi", - "type": "arrow" - }, - { - "id": "omfoNBHlSi-C65seG3joz", - "type": "arrow" } ], - "updated": 1667988584051, + "updated": 1682390147044, "link": null, "locked": false }, { "type": "text", - "version": 718, - "versionNonce": 1458379211, + "version": 725, + "versionNonce": 1623580265, "isDeleted": false, "id": "m7YtI68vy8BrAI9456Lx0", "fillStyle": "hachure", @@ -381,32 +232,33 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 511.20861820892173, - "y": -81.97645210442369, + "x": 523.8336182089217, + "y": -66.18785794781246, "strokeColor": "#000000", "backgroundColor": "#dee4ea", - "width": 119, - "height": 48, + "width": 93.75, + "height": 24, "seed": 371639347, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988583506, + "updated": 1683235807884, "link": null, "locked": false, "fontSize": 20, "fontFamily": 3, - "text": "instance \ncontroller", - "baseline": 44, + "text": "instance", "textAlign": "center", "verticalAlign": "middle", "containerId": "yIaxuM7PTc3JyYygAVlow", - "originalText": "instance controller" + "originalText": "instance", + "lineHeight": 1.2, + "baseline": 19 }, { "type": "text", - "version": 850, - "versionNonce": 1882292363, + "version": 856, + "versionNonce": 1574721703, "isDeleted": false, "id": "j7AFmXdWx8ncL-sByBxr1", "fillStyle": "hachure", @@ -415,32 +267,33 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 511.50983348669945, - "y": -8.629211412934296, + "x": 524.1348334866994, + "y": 7.370788587065704, "strokeColor": "#000000", "backgroundColor": "#dee4ea", - "width": 119, - "height": 48, + "width": 93.75, + "height": 24, "seed": 1300960883, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988582810, + "updated": 1683235807884, "link": null, "locked": false, "fontSize": 20, "fontFamily": 3, - "text": "database \ncontroller", - "baseline": 44, + "text": "database", "textAlign": "center", "verticalAlign": "middle", "containerId": "iFdhpoqG-8cvlt635sWly", - "originalText": "database controller" + "originalText": "database", + "lineHeight": 1.2, + "baseline": 19 }, { "type": "text", - "version": 886, - "versionNonce": 1215156101, + "version": 897, + "versionNonce": 1060120905, "isDeleted": false, "id": "2i_OC0N5CymL1Gm3XGJ51", "fillStyle": "hachure", @@ -449,32 +302,33 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 488.42997237558836, - "y": 69.40071803446517, + "x": 530.4143473755884, + "y": 71.40071803446517, "strokeColor": "#000000", "backgroundColor": "#dee4ea", - "width": 166, + "width": 82.03125, "height": 24, "seed": 409315261, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988581986, + "updated": 1683235807885, "link": null, "locked": false, "fontSize": 20, "fontFamily": 3, - "text": "oss controller", - "baseline": 20, + "text": "storage", "textAlign": "center", "verticalAlign": "middle", "containerId": "LEtOq_GNzdK06yv6FCUaL", - "originalText": "oss controller" + "originalText": "storage", + "lineHeight": 1.2, + "baseline": 19 }, { "type": "text", - "version": 1063, - "versionNonce": 1747745989, + "version": 1075, + "versionNonce": 708357063, "isDeleted": false, "id": "c3_dC4IS__cnRYxHXTdrp", "fillStyle": "hachure", @@ -483,32 +337,33 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 510.32797584781065, - "y": 122.54481525668734, + "x": 528.8123508478106, + "y": 138.54481525668734, "strokeColor": "#000000", "backgroundColor": "#dee4ea", - "width": 119, - "height": 48, + "width": 82.03125, + "height": 24, "seed": 1181000883, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988581268, + "updated": 1683235807885, "link": null, "locked": false, "fontSize": 20, "fontFamily": 3, - "text": "gateway \ncontroller", - "baseline": 44, + "text": "gateway", "textAlign": "center", "verticalAlign": "middle", "containerId": "tKjzaQgey4YRa-W0mOpBk", - "originalText": "gateway controller" + "originalText": "gateway", + "lineHeight": 1.2, + "baseline": 19 }, { "type": "text", - "version": 1138, - "versionNonce": 229397035, + "version": 1158, + "versionNonce": 869144617, "isDeleted": false, "id": "VCtvQy5TQteGcX2VgctFr", "fillStyle": "hachure", @@ -517,32 +372,33 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 513.2437744589217, - "y": 206.08431178446517, + "x": 537.3760566741782, + "y": 221.8860994496149, "strokeColor": "#000000", "backgroundColor": "#dee4ea", - "width": 119, - "height": 48, + "width": 70.3125, + "height": 24, "seed": 1429110675, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988580491, + "updated": 1683235807885, "link": null, "locked": false, "fontSize": 20, "fontFamily": 3, - "text": "runtime \ncontroller", - "baseline": 44, + "text": "region", "textAlign": "center", "verticalAlign": "middle", "containerId": "C16_cp7Kvs98I3yC1wEzB", - "originalText": "runtime controller" + "originalText": "region", + "lineHeight": 1.2, + "baseline": 19 }, { "type": "text", - "version": 1247, - "versionNonce": 4078341, + "version": 1259, + "versionNonce": 1239259879, "isDeleted": false, "id": "WDu98khDATYV08tGQWau5", "fillStyle": "hachure", @@ -551,32 +407,33 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 513.6352675144774, - "y": 286.10080484002066, + "x": 532.1196425144774, + "y": 302.10080484002066, "strokeColor": "#000000", "backgroundColor": "#dee4ea", - "width": 119, - "height": 48, + "width": 82.03125, + "height": 24, "seed": 1860931507, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988591677, + "updated": 1683235807885, "link": null, "locked": false, "fontSize": 20, "fontFamily": 3, - "text": "trigger \ncontroller", - "baseline": 44, + "text": "trigger", "textAlign": "center", "verticalAlign": "middle", "containerId": "m_-FpYnKNljgOKf_7OTgJ", - "originalText": "trigger controller" + "originalText": "trigger", + "lineHeight": 1.2, + "baseline": 19 }, { "type": "text", - "version": 702, - "versionNonce": 268657419, + "version": 718, + "versionNonce": 9120521, "isDeleted": false, "id": "6dYVn41EPXSYABfzG93KG", "fillStyle": "hachure", @@ -585,32 +442,33 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 498.295857792255, - "y": -158.43304932664591, + "x": 504.842732792255, + "y": -142.43304932664591, "strokeColor": "#000000", "backgroundColor": "#dee4ea", - "width": 142, - "height": 48, + "width": 128.90625, + "height": 24, "seed": 2130308787, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988584057, + "updated": 1683235807886, "link": null, "locked": false, "fontSize": 20, "fontFamily": 3, - "text": "application \ncontroller", - "baseline": 44, + "text": "application", "textAlign": "center", "verticalAlign": "middle", "containerId": "i_oL4vx3IxwwV65ndHvXG", - "originalText": "application controller" + "originalText": "application", + "lineHeight": 1.2, + "baseline": 19 }, { "type": "rectangle", - "version": 1981, - "versionNonce": 1635857939, + "version": 1984, + "versionNonce": 184984847, "isDeleted": false, "id": "ErO6-0lIVDUhdmtZ9_T_2", "fillStyle": "hachure", @@ -627,33 +485,29 @@ "height": 613.5189887152779, "seed": 882339581, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { - "id": "8fGBOXNk8bCIy6Zk7y-De", - "type": "arrow" - }, - { - "id": "yGPWxY9FQKpmjOKLu_fmc", + "id": "I1nGdnOz_CgahA-y7cGbM", "type": "arrow" }, { - "id": "I1nGdnOz_CgahA-y7cGbM", + "id": "nrxhhHB-9wXQK_qHT3bSs", "type": "arrow" }, { - "id": "nrxhhHB-9wXQK_qHT3bSs", + "id": "F0l5EdS9JdyYqN5Lmjb8Q", "type": "arrow" } ], - "updated": 1664572076691, + "updated": 1682390213581, "link": null, "locked": false }, { "type": "rectangle", - "version": 862, - "versionNonce": 1777423172, + "version": 863, + "versionNonce": 1764831023, "isDeleted": false, "id": "BPTHaB1d7bTkLwjf3WSq8", "fillStyle": "solid", @@ -670,21 +524,21 @@ "height": 49, "seed": 1136602525, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "type": "text", "id": "q7HTshLHNpAnsIF3aIfuN" } ], - "updated": 1668084253789, + "updated": 1682390147045, "link": null, "locked": false }, { "type": "text", - "version": 692, - "versionNonce": 654316924, + "version": 701, + "versionNonce": 22521351, "isDeleted": false, "id": "q7HTshLHNpAnsIF3aIfuN", "fillStyle": "hachure", @@ -693,32 +547,33 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 507.70373539642185, + "x": 492.17248539642185, "y": -225.71451634053506, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 133, + "width": 164.0625, "height": 34, "seed": 150916339, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1668084257150, + "updated": 1683235807886, "link": null, "locked": false, "fontSize": 28, "fontFamily": 3, - "text": "laf core", - "baseline": 27, + "text": "laf server", "textAlign": "center", "verticalAlign": "middle", "containerId": "BPTHaB1d7bTkLwjf3WSq8", - "originalText": "laf core" + "originalText": "laf server", + "lineHeight": 1.2142857142857142, + "baseline": 27 }, { "type": "ellipse", - "version": 1338, - "versionNonce": 286133501, + "version": 1339, + "versionNonce": 683766095, "isDeleted": false, "id": "heV518HpIRbsnPscnw7cc", "fillStyle": "solid", @@ -737,16 +592,16 @@ "groupIds": [ "AV5QK58pag-XAYecGDqOn" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076691, + "updated": 1682390147045, "link": null, "locked": false }, { "type": "ellipse", - "version": 1380, - "versionNonce": 1482886483, + "version": 1381, + "versionNonce": 1396985633, "isDeleted": false, "id": "JaSR5BP7Hqq2Q2zmoWw9f", "fillStyle": "solid", @@ -765,16 +620,16 @@ "groupIds": [ "AV5QK58pag-XAYecGDqOn" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076691, + "updated": 1682390147045, "link": null, "locked": false }, { "type": "ellipse", - "version": 1421, - "versionNonce": 488465757, + "version": 1422, + "versionNonce": 759459695, "isDeleted": false, "id": "UXp2CK2SQnozdBGdZevDS", "fillStyle": "solid", @@ -793,69 +648,16 @@ "groupIds": [ "AV5QK58pag-XAYecGDqOn" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076691, + "updated": 1682390147045, "link": null, "locked": false }, { "type": "arrow", - "version": 2330, - "versionNonce": 1818793117, - "isDeleted": false, - "id": "8fGBOXNk8bCIy6Zk7y-De", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 775.7628956061426, - "y": 76.44124819218145, - "strokeColor": "#000000", - "backgroundColor": "#228be6", - "width": 61.089460687561996, - "height": 0.26659395427897437, - "seed": 1596869139, - "groupIds": [], - "strokeSharpness": "round", - "boundElements": [], - "updated": 1664572303000, - "link": null, - "locked": false, - "startBinding": { - "elementId": "CWJVfUily2HQrkrrhGWVB", - "gap": 13.895101782279227, - "focus": -0.1729085514225781 - }, - "endBinding": { - "elementId": "ErO6-0lIVDUhdmtZ9_T_2", - "focus": -0.041063454394831514, - "gap": 14.258074515353002 - }, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - -10.549047622402213, - 0.10232634380973593 - ], - [ - -61.089460687561996, - 0.26659395427897437 - ] - ] - }, - { - "type": "arrow", - "version": 3528, - "versionNonce": 1536053171, + "version": 3801, + "versionNonce": 574923279, "isDeleted": false, "id": "F0l5EdS9JdyYqN5Lmjb8Q", "fillStyle": "solid", @@ -864,28 +666,28 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 901.5900766874938, - "y": 173.93165658795988, + "x": 817.9268057301465, + "y": 111.79038534717182, "strokeColor": "#000000", "backgroundColor": "#228be6", - "width": 0.4023256050325017, - "height": 52.540233263301246, + "width": 100.787226919001, + "height": 0.5986806575956791, "seed": 1607502237, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572303000, + "updated": 1682390216744, "link": null, "locked": false, "startBinding": { "elementId": "xeTZSFRJPria6_fCTJ7si", - "gap": 12.00204575635525, - "focus": -0.029921827695954292 + "focus": -0.3781336467486217, + "gap": 12.002045756355358 }, "endBinding": { - "elementId": "CWJVfUily2HQrkrrhGWVB", - "gap": 15.836470828590585, - "focus": 0.05248848464725526 + "elementId": "ErO6-0lIVDUhdmtZ9_T_2", + "focus": 0.06684415025193227, + "gap": 16.724218407918016 }, "lastCommittedPoint": null, "startArrowhead": null, @@ -896,15 +698,15 @@ 0 ], [ - 0.4023256050325017, - -52.540233263301246 + -100.787226919001, + -0.5986806575956791 ] ] }, { "type": "rectangle", - "version": 4248, - "versionNonce": 46777427, + "version": 4262, + "versionNonce": 1157741281, "isDeleted": false, "id": "tSpu5H8lblwlnn13Wz8Rl", "fillStyle": "solid", @@ -923,21 +725,21 @@ "groupIds": [ "nqaclVxUzCgraM1EQ9VuF" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "I1nGdnOz_CgahA-y7cGbM", "type": "arrow" } ], - "updated": 1664572076692, + "updated": 1682390147045, "link": null, "locked": false }, { "type": "rectangle", - "version": 5456, - "versionNonce": 1954809701, + "version": 5493, + "versionNonce": 1877951841, "isDeleted": false, "id": "RqWzbG9cswTR5MEjnZHb0", "fillStyle": "hachure", @@ -947,42 +749,34 @@ "opacity": 100, "angle": 0, "x": 152.82037364005788, - "y": -183.61071972864167, + "y": -183.9675019313722, "strokeColor": "#000000", "backgroundColor": "#ced4da", "width": 181, - "height": 44, + "height": 39, "seed": 992812285, "groupIds": [ "nqaclVxUzCgraM1EQ9VuF" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "-3QRDzc7uFeAnkql3NZCD", "type": "text" }, - { - "id": "8fGBOXNk8bCIy6Zk7y-De", - "type": "arrow" - }, { "id": "F0l5EdS9JdyYqN5Lmjb8Q", "type": "arrow" - }, - { - "type": "text", - "id": "-3QRDzc7uFeAnkql3NZCD" } ], - "updated": 1667988587988, + "updated": 1682390164541, "link": null, "locked": false }, { "type": "rectangle", - "version": 5479, - "versionNonce": 133341669, + "version": 5493, + "versionNonce": 27899585, "isDeleted": false, "id": "seQu8_J3CL9Lt8R3bL22H", "fillStyle": "hachure", @@ -1001,37 +795,25 @@ "groupIds": [ "nqaclVxUzCgraM1EQ9VuF" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "55FiARpPQE_zho5x-ZUO8", "type": "text" }, - { - "id": "8fGBOXNk8bCIy6Zk7y-De", - "type": "arrow" - }, { "id": "F0l5EdS9JdyYqN5Lmjb8Q", "type": "arrow" - }, - { - "id": "55FiARpPQE_zho5x-ZUO8", - "type": "text" - }, - { - "type": "text", - "id": "55FiARpPQE_zho5x-ZUO8" } ], - "updated": 1667988586459, + "updated": 1682390147045, "link": null, "locked": false }, { "type": "rectangle", - "version": 5542, - "versionNonce": 192880971, + "version": 5579, + "versionNonce": 2037763233, "isDeleted": false, "id": "svcbltv9b-WzYyB5ktXMS", "fillStyle": "hachure", @@ -1045,46 +827,30 @@ "strokeColor": "#000000", "backgroundColor": "#ced4da", "width": 181, - "height": 44, + "height": 39, "seed": 632272893, "groupIds": [ "nqaclVxUzCgraM1EQ9VuF" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "5yat8wLf-J_xYX46ZzGln", "type": "text" }, - { - "id": "8fGBOXNk8bCIy6Zk7y-De", - "type": "arrow" - }, { "id": "F0l5EdS9JdyYqN5Lmjb8Q", "type": "arrow" - }, - { - "id": "5yat8wLf-J_xYX46ZzGln", - "type": "text" - }, - { - "id": "5yat8wLf-J_xYX46ZzGln", - "type": "text" - }, - { - "type": "text", - "id": "5yat8wLf-J_xYX46ZzGln" } ], - "updated": 1667988589756, + "updated": 1682390156184, "link": null, "locked": false }, { "type": "rectangle", - "version": 5620, - "versionNonce": 185404307, + "version": 5634, + "versionNonce": 61290145, "isDeleted": false, "id": "xpCiUeVBSQd9r39Y9pMJF", "fillStyle": "cross-hatch", @@ -1103,49 +869,29 @@ "groupIds": [ "nqaclVxUzCgraM1EQ9VuF" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "374mHHnI1qdq-3vCk5mIG", "type": "text" }, - { - "id": "8fGBOXNk8bCIy6Zk7y-De", - "type": "arrow" - }, { "id": "F0l5EdS9JdyYqN5Lmjb8Q", "type": "arrow" }, - { - "id": "374mHHnI1qdq-3vCk5mIG", - "type": "text" - }, - { - "id": "374mHHnI1qdq-3vCk5mIG", - "type": "text" - }, - { - "id": "374mHHnI1qdq-3vCk5mIG", - "type": "text" - }, - { - "type": "text", - "id": "374mHHnI1qdq-3vCk5mIG" - }, { "id": "ZQbEf5yZUkOtPwD_rAbZB", "type": "arrow" } ], - "updated": 1664572076692, + "updated": 1682390147045, "link": null, "locked": false }, { "type": "text", - "version": 5300, - "versionNonce": 187583851, + "version": 5352, + "versionNonce": 501408233, "isDeleted": false, "id": "-3QRDzc7uFeAnkql3NZCD", "fillStyle": "solid", @@ -1154,34 +900,35 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 165.32037364005788, - "y": -178.61071972864167, + "x": 166.46002207755788, + "y": -178.9675019313722, "strokeColor": "#000000", "backgroundColor": "#40c057", - "width": 156, + "width": 153.720703125, "height": 29, "seed": 796720467, "groupIds": [ "nqaclVxUzCgraM1EQ9VuF" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988587993, + "updated": 1683235807886, "link": null, "locked": false, "fontSize": 23.854444858222056, "fontFamily": 3, "text": "app cluster", - "baseline": 23, "textAlign": "center", "verticalAlign": "middle", "containerId": "RqWzbG9cswTR5MEjnZHb0", - "originalText": "app cluster" + "originalText": "app cluster", + "lineHeight": 1.2157063462327606, + "baseline": 23 }, { "type": "text", - "version": 5379, - "versionNonce": 527211243, + "version": 5395, + "versionNonce": 1336102183, "isDeleted": false, "id": "55FiARpPQE_zho5x-ZUO8", "fillStyle": "solid", @@ -1190,34 +937,35 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 173.2330242105445, + "x": 174.3599773355445, "y": -125.21245689497809, "strokeColor": "#000000", "backgroundColor": "#40c057", - "width": 142, + "width": 139.74609375, "height": 29, "seed": 1495363987, "groupIds": [ "nqaclVxUzCgraM1EQ9VuF" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988586465, + "updated": 1683235807886, "link": null, "locked": false, "fontSize": 23.854444858222056, "fontFamily": 3, "text": "db cluster", - "baseline": 23, "textAlign": "center", "verticalAlign": "middle", "containerId": "seQu8_J3CL9Lt8R3bL22H", - "originalText": "db cluster" + "originalText": "db cluster", + "lineHeight": 1.2157063462327606, + "baseline": 23 }, { "type": "text", - "version": 5444, - "versionNonce": 1215737061, + "version": 5496, + "versionNonce": 1759558857, "isDeleted": false, "id": "5yat8wLf-J_xYX46ZzGln", "fillStyle": "solid", @@ -1226,34 +974,35 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 167.14266098145544, + "x": 168.28230941895544, "y": -71.63766588153507, "strokeColor": "#000000", "backgroundColor": "#40c057", - "width": 156, + "width": 153.720703125, "height": 29, "seed": 407212627, "groupIds": [ "nqaclVxUzCgraM1EQ9VuF" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988589761, + "updated": 1683235807887, "link": null, "locked": false, "fontSize": 23.854444858222056, "fontFamily": 3, "text": "oss cluster", - "baseline": 23, "textAlign": "center", "verticalAlign": "middle", "containerId": "svcbltv9b-WzYyB5ktXMS", - "originalText": "oss cluster" + "originalText": "oss cluster", + "lineHeight": 1.2157063462327606, + "baseline": 23 }, { "type": "text", - "version": 5514, - "versionNonce": 773292755, + "version": 5530, + "versionNonce": 539824199, "isDeleted": false, "id": "374mHHnI1qdq-3vCk5mIG", "fillStyle": "solid", @@ -1262,34 +1011,35 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 196.49031723145544, + "x": 197.57918441895544, "y": -18.68942369403507, "strokeColor": "#000000", "backgroundColor": "#40c057", - "width": 100, + "width": 97.822265625, "height": 29, "seed": 2040542611, "groupIds": [ "nqaclVxUzCgraM1EQ9VuF" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076692, + "updated": 1683235807887, "link": null, "locked": false, "fontSize": 23.854444858222056, "fontFamily": 3, "text": "gateway", - "baseline": 23, "textAlign": "center", "verticalAlign": "middle", "containerId": "xpCiUeVBSQd9r39Y9pMJF", - "originalText": "gateway" + "originalText": "gateway", + "lineHeight": 1.2157063462327606, + "baseline": 23 }, { "type": "rectangle", - "version": 2478, - "versionNonce": 53807069, + "version": 2492, + "versionNonce": 767283247, "isDeleted": false, "id": "huP2FrJ-wkcr6vlJtQjNo", "fillStyle": "solid", @@ -1308,21 +1058,21 @@ "groupIds": [ "nqaclVxUzCgraM1EQ9VuF" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "type": "text", "id": "gDXZG2VZnjGqGW4DcKFlQ" } ], - "updated": 1664572076692, + "updated": 1682390147045, "link": null, "locked": false }, { "type": "text", - "version": 2376, - "versionNonce": 1013297267, + "version": 2392, + "versionNonce": 287325097, "isDeleted": false, "id": "gDXZG2VZnjGqGW4DcKFlQ", "fillStyle": "solid", @@ -1331,34 +1081,35 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 144.55516696645316, + "x": 145.33641696645316, "y": -238.98515094605668, "strokeColor": "#000000", "backgroundColor": "#ced4da", - "width": 100, + "width": 98.4375, "height": 34, "seed": 166841683, "groupIds": [ "nqaclVxUzCgraM1EQ9VuF" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076692, + "updated": 1683235807887, "link": null, "locked": false, "fontSize": 28, "fontFamily": 3, "text": "region", - "baseline": 27, "textAlign": "center", "verticalAlign": "middle", "containerId": "huP2FrJ-wkcr6vlJtQjNo", - "originalText": "region" + "originalText": "region", + "lineHeight": 1.2142857142857142, + "baseline": 27 }, { "type": "rectangle", - "version": 4673, - "versionNonce": 1784808509, + "version": 4674, + "versionNonce": 625996367, "isDeleted": false, "id": "p0D15L-nr8QhX-zbskk8_", "fillStyle": "solid", @@ -1377,21 +1128,21 @@ "groupIds": [ "UFRQGUFnpiKOVq5Iy6XUA" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "nrxhhHB-9wXQK_qHT3bSs", "type": "arrow" } ], - "updated": 1664572076692, + "updated": 1682390147045, "link": null, "locked": false }, { "type": "rectangle", - "version": 5869, - "versionNonce": 467336485, + "version": 5870, + "versionNonce": 228220449, "isDeleted": false, "id": "k57klHHO_yd_U8HZLzii9", "fillStyle": "hachure", @@ -1410,37 +1161,25 @@ "groupIds": [ "UFRQGUFnpiKOVq5Iy6XUA" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "SrrJ6B-uIpzDjqa31vB49", "type": "text" }, - { - "id": "8fGBOXNk8bCIy6Zk7y-De", - "type": "arrow" - }, { "id": "F0l5EdS9JdyYqN5Lmjb8Q", "type": "arrow" - }, - { - "id": "SrrJ6B-uIpzDjqa31vB49", - "type": "text" - }, - { - "type": "text", - "id": "SrrJ6B-uIpzDjqa31vB49" } ], - "updated": 1667988595088, + "updated": 1682390147045, "link": null, "locked": false }, { "type": "rectangle", - "version": 5893, - "versionNonce": 1759110699, + "version": 5894, + "versionNonce": 1985663087, "isDeleted": false, "id": "6vsz4Dw2TmbW1sk47VZs9", "fillStyle": "hachure", @@ -1459,41 +1198,25 @@ "groupIds": [ "UFRQGUFnpiKOVq5Iy6XUA" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "PfE5kBDG7XS-eflDWVWb2", "type": "text" }, - { - "id": "8fGBOXNk8bCIy6Zk7y-De", - "type": "arrow" - }, { "id": "F0l5EdS9JdyYqN5Lmjb8Q", "type": "arrow" - }, - { - "id": "PfE5kBDG7XS-eflDWVWb2", - "type": "text" - }, - { - "id": "PfE5kBDG7XS-eflDWVWb2", - "type": "text" - }, - { - "type": "text", - "id": "PfE5kBDG7XS-eflDWVWb2" } ], - "updated": 1667988597192, + "updated": 1682390147045, "link": null, "locked": false }, { "type": "rectangle", - "version": 5956, - "versionNonce": 807432715, + "version": 5957, + "versionNonce": 1305211393, "isDeleted": false, "id": "cW4jdENz1hf0K4l0PTQp-", "fillStyle": "hachure", @@ -1512,45 +1235,25 @@ "groupIds": [ "UFRQGUFnpiKOVq5Iy6XUA" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "EamthWT66S2hXL08TUdTY", "type": "text" }, - { - "id": "8fGBOXNk8bCIy6Zk7y-De", - "type": "arrow" - }, { "id": "F0l5EdS9JdyYqN5Lmjb8Q", "type": "arrow" - }, - { - "id": "EamthWT66S2hXL08TUdTY", - "type": "text" - }, - { - "id": "EamthWT66S2hXL08TUdTY", - "type": "text" - }, - { - "id": "EamthWT66S2hXL08TUdTY", - "type": "text" - }, - { - "type": "text", - "id": "EamthWT66S2hXL08TUdTY" } ], - "updated": 1667988598621, + "updated": 1682390147045, "link": null, "locked": false }, { "type": "rectangle", - "version": 6035, - "versionNonce": 1041357053, + "version": 6036, + "versionNonce": 983886479, "isDeleted": false, "id": "atGfK9Ka_jA7EbGAQUhV3", "fillStyle": "cross-hatch", @@ -1569,49 +1272,25 @@ "groupIds": [ "UFRQGUFnpiKOVq5Iy6XUA" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "U1Nj4qJ8lKgvug1V0iBjz", "type": "text" }, - { - "id": "8fGBOXNk8bCIy6Zk7y-De", - "type": "arrow" - }, { "id": "F0l5EdS9JdyYqN5Lmjb8Q", "type": "arrow" - }, - { - "id": "U1Nj4qJ8lKgvug1V0iBjz", - "type": "text" - }, - { - "id": "U1Nj4qJ8lKgvug1V0iBjz", - "type": "text" - }, - { - "id": "U1Nj4qJ8lKgvug1V0iBjz", - "type": "text" - }, - { - "id": "U1Nj4qJ8lKgvug1V0iBjz", - "type": "text" - }, - { - "type": "text", - "id": "U1Nj4qJ8lKgvug1V0iBjz" } ], - "updated": 1664572076692, + "updated": 1682390147045, "link": null, "locked": false }, { "type": "text", - "version": 5683, - "versionNonce": 1631228843, + "version": 5686, + "versionNonce": 1020358503, "isDeleted": false, "id": "SrrJ6B-uIpzDjqa31vB49", "fillStyle": "solid", @@ -1620,34 +1299,35 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 167.0947045908557, + "x": 168.2343530283557, "y": 191.4800174721562, "strokeColor": "#000000", "backgroundColor": "#40c057", - "width": 156, + "width": 153.720703125, "height": 29, "seed": 1227194771, "groupIds": [ "UFRQGUFnpiKOVq5Iy6XUA" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988595093, + "updated": 1683235807887, "link": null, "locked": false, "fontSize": 23.854444858222056, "fontFamily": 3, "text": "app cluster", - "baseline": 23, "textAlign": "center", "verticalAlign": "middle", "containerId": "k57klHHO_yd_U8HZLzii9", - "originalText": "app cluster" + "originalText": "app cluster", + "lineHeight": 1.2157063462327606, + "baseline": 23 }, { "type": "text", - "version": 5763, - "versionNonce": 381625861, + "version": 5766, + "versionNonce": 1187831433, "isDeleted": false, "id": "PfE5kBDG7XS-eflDWVWb2", "fillStyle": "solid", @@ -1656,34 +1336,35 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 175.00735516134228, + "x": 176.13430828634228, "y": 244.62828030581977, "strokeColor": "#000000", "backgroundColor": "#40c057", - "width": 142, + "width": 139.74609375, "height": 29, "seed": 1729844509, "groupIds": [ "UFRQGUFnpiKOVq5Iy6XUA" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988597198, + "updated": 1683235807887, "link": null, "locked": false, "fontSize": 23.854444858222056, "fontFamily": 3, "text": "db cluster", - "baseline": 23, "textAlign": "center", "verticalAlign": "middle", "containerId": "6vsz4Dw2TmbW1sk47VZs9", - "originalText": "db cluster" + "originalText": "db cluster", + "lineHeight": 1.2157063462327606, + "baseline": 23 }, { "type": "text", - "version": 5828, - "versionNonce": 903858213, + "version": 5831, + "versionNonce": 2145184391, "isDeleted": false, "id": "EamthWT66S2hXL08TUdTY", "fillStyle": "solid", @@ -1692,34 +1373,35 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 168.91699193225327, + "x": 170.05664036975327, "y": 298.2030713192628, "strokeColor": "#000000", "backgroundColor": "#40c057", - "width": 156, + "width": 153.720703125, "height": 29, "seed": 717608755, "groupIds": [ "UFRQGUFnpiKOVq5Iy6XUA" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988598626, + "updated": 1683235807887, "link": null, "locked": false, "fontSize": 23.854444858222056, "fontFamily": 3, "text": "oss cluster", - "baseline": 23, "textAlign": "center", "verticalAlign": "middle", "containerId": "cW4jdENz1hf0K4l0PTQp-", - "originalText": "oss cluster" + "originalText": "oss cluster", + "lineHeight": 1.2157063462327606, + "baseline": 23 }, { "type": "text", - "version": 5898, - "versionNonce": 1910734269, + "version": 5901, + "versionNonce": 681715049, "isDeleted": false, "id": "U1Nj4qJ8lKgvug1V0iBjz", "fillStyle": "solid", @@ -1728,34 +1410,35 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 198.26464818225327, + "x": 199.35351536975327, "y": 351.1513135067628, "strokeColor": "#000000", "backgroundColor": "#40c057", - "width": 100, + "width": 97.822265625, "height": 29, "seed": 780970365, "groupIds": [ "UFRQGUFnpiKOVq5Iy6XUA" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076693, + "updated": 1683235807888, "link": null, "locked": false, "fontSize": 23.854444858222056, "fontFamily": 3, "text": "gateway", - "baseline": 23, "textAlign": "center", "verticalAlign": "middle", "containerId": "atGfK9Ka_jA7EbGAQUhV3", - "originalText": "gateway" + "originalText": "gateway", + "lineHeight": 1.2157063462327606, + "baseline": 23 }, { "type": "rectangle", - "version": 2893, - "versionNonce": 778700947, + "version": 2894, + "versionNonce": 117294497, "isDeleted": false, "id": "W4ChEm505TWn1WpfW8HNW", "fillStyle": "solid", @@ -1774,29 +1457,25 @@ "groupIds": [ "UFRQGUFnpiKOVq5Iy6XUA" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "u2MkqS2S7SXAokNV71lph", "type": "text" }, - { - "type": "text", - "id": "u2MkqS2S7SXAokNV71lph" - }, { "id": "nrxhhHB-9wXQK_qHT3bSs", "type": "arrow" } ], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false }, { "type": "text", - "version": 2760, - "versionNonce": 1267121693, + "version": 2763, + "versionNonce": 1175191975, "isDeleted": false, "id": "u2MkqS2S7SXAokNV71lph", "fillStyle": "solid", @@ -1805,34 +1484,35 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 146.32949791725105, + "x": 147.11074791725105, "y": 130.85558625474118, "strokeColor": "#000000", "backgroundColor": "#ced4da", - "width": 100, + "width": 98.4375, "height": 34, "seed": 966029789, "groupIds": [ "UFRQGUFnpiKOVq5Iy6XUA" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076693, + "updated": 1683235807888, "link": null, "locked": false, "fontSize": 28, "fontFamily": 3, "text": "region", - "baseline": 27, "textAlign": "center", "verticalAlign": "middle", "containerId": "W4ChEm505TWn1WpfW8HNW", - "originalText": "region" + "originalText": "region", + "lineHeight": 1.2142857142857142, + "baseline": 27 }, { "type": "arrow", - "version": 3318, - "versionNonce": 1010528861, + "version": 3332, + "versionNonce": 626420097, "isDeleted": false, "id": "I1nGdnOz_CgahA-y7cGbM", "fillStyle": "solid", @@ -1849,9 +1529,11 @@ "height": 67.37285218755672, "seed": 1944148413, "groupIds": [], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572242260, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": { @@ -1884,8 +1566,8 @@ }, { "type": "arrow", - "version": 4305, - "versionNonce": 1371038749, + "version": 4306, + "versionNonce": 1354738447, "isDeleted": false, "id": "nrxhhHB-9wXQK_qHT3bSs", "fillStyle": "solid", @@ -1902,9 +1584,11 @@ "height": 58.513881284219565, "seed": 2054861757, "groupIds": [], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": { @@ -1937,8 +1621,8 @@ }, { "type": "ellipse", - "version": 1750, - "versionNonce": 260388915, + "version": 1751, + "versionNonce": 1555009889, "isDeleted": false, "id": "NEAT3eMDTiiE7pephvT-l", "fillStyle": "solid", @@ -1958,16 +1642,16 @@ "kJUfOxO1MS73tdxUj7gLO", "Kjd8DzMT9qLTxKD-6VoJD" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false }, { "type": "ellipse", - "version": 1792, - "versionNonce": 11524221, + "version": 1793, + "versionNonce": 886403375, "isDeleted": false, "id": "gJxGIku4cDRAq8pRRovoP", "fillStyle": "solid", @@ -1987,16 +1671,16 @@ "kJUfOxO1MS73tdxUj7gLO", "Kjd8DzMT9qLTxKD-6VoJD" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false }, { "type": "ellipse", - "version": 1833, - "versionNonce": 87407059, + "version": 1834, + "versionNonce": 1113111873, "isDeleted": false, "id": "V-tCUIzZzoaLsFF5WBkzh", "fillStyle": "solid", @@ -2016,16 +1700,16 @@ "kJUfOxO1MS73tdxUj7gLO", "Kjd8DzMT9qLTxKD-6VoJD" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false }, { "type": "arrow", - "version": 764, - "versionNonce": 547686259, + "version": 778, + "versionNonce": 982348623, "isDeleted": false, "id": "ZQbEf5yZUkOtPwD_rAbZB", "fillStyle": "solid", @@ -2042,9 +1726,11 @@ "height": 36.62083381418845, "seed": 1610118803, "groupIds": [], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": { @@ -2077,8 +1763,8 @@ }, { "type": "arrow", - "version": 1022, - "versionNonce": 1839701309, + "version": 1023, + "versionNonce": 363949345, "isDeleted": false, "id": "aAKa09DjRg0mEhlWYHR5u", "fillStyle": "solid", @@ -2095,9 +1781,11 @@ "height": 189.57335937117904, "seed": 1064598845, "groupIds": [], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": { @@ -2126,8 +1814,8 @@ }, { "type": "line", - "version": 1496, - "versionNonce": 1709250579, + "version": 1497, + "versionNonce": 1782591855, "isDeleted": false, "id": "ENjm2KAXIlTkeFJ4JUNAx", "fillStyle": "solid", @@ -2146,9 +1834,9 @@ "groupIds": [ "Xap4MeFI6FrBeVoCuInyh" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -2193,8 +1881,8 @@ }, { "type": "line", - "version": 3918, - "versionNonce": 912942749, + "version": 3919, + "versionNonce": 2116624641, "isDeleted": false, "id": "9-L3yte_SBFhQl2glk0Nl", "fillStyle": "solid", @@ -2213,9 +1901,11 @@ "groupIds": [ "Xap4MeFI6FrBeVoCuInyh" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -2456,8 +2146,8 @@ }, { "type": "line", - "version": 1431, - "versionNonce": 147496371, + "version": 1432, + "versionNonce": 758524815, "isDeleted": false, "id": "z3m1W0H4jyNAfw-DU3-hY", "fillStyle": "solid", @@ -2476,9 +2166,11 @@ "groupIds": [ "Xap4MeFI6FrBeVoCuInyh" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -2523,8 +2215,8 @@ }, { "type": "line", - "version": 1550, - "versionNonce": 889031421, + "version": 1551, + "versionNonce": 155146465, "isDeleted": false, "id": "kofCliHy9ymke9jTDJOsP", "fillStyle": "solid", @@ -2543,9 +2235,11 @@ "groupIds": [ "Xap4MeFI6FrBeVoCuInyh" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -2590,8 +2284,8 @@ }, { "type": "line", - "version": 1555, - "versionNonce": 1269985107, + "version": 1556, + "versionNonce": 799531439, "isDeleted": false, "id": "GuqNKIEHNKRWg6hzqfNP0", "fillStyle": "solid", @@ -2610,9 +2304,11 @@ "groupIds": [ "Xap4MeFI6FrBeVoCuInyh" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -2657,8 +2353,8 @@ }, { "type": "line", - "version": 1735, - "versionNonce": 1382884189, + "version": 1736, + "versionNonce": 1753453761, "isDeleted": false, "id": "59L2E8oZajCQdHB5pcT3L", "fillStyle": "solid", @@ -2677,9 +2373,11 @@ "groupIds": [ "Xap4MeFI6FrBeVoCuInyh" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -2724,8 +2422,8 @@ }, { "type": "line", - "version": 1866, - "versionNonce": 820972787, + "version": 1867, + "versionNonce": 45994959, "isDeleted": false, "id": "R39r_T3RGjwq80QNW2z5U", "fillStyle": "solid", @@ -2744,9 +2442,11 @@ "groupIds": [ "Xap4MeFI6FrBeVoCuInyh" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -2791,8 +2491,8 @@ }, { "type": "line", - "version": 1929, - "versionNonce": 1661644733, + "version": 1930, + "versionNonce": 1872057505, "isDeleted": false, "id": "mZCXsRHQ3xk7WQA0qwUcU", "fillStyle": "solid", @@ -2811,9 +2511,11 @@ "groupIds": [ "Xap4MeFI6FrBeVoCuInyh" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -2858,8 +2560,8 @@ }, { "type": "line", - "version": 2057, - "versionNonce": 738653843, + "version": 2058, + "versionNonce": 2123399663, "isDeleted": false, "id": "unOPkBZIxaB1Pgvs_OBu9", "fillStyle": "solid", @@ -2878,9 +2580,11 @@ "groupIds": [ "Xap4MeFI6FrBeVoCuInyh" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -2925,8 +2629,8 @@ }, { "type": "ellipse", - "version": 876, - "versionNonce": 888647709, + "version": 877, + "versionNonce": 1378097281, "isDeleted": false, "id": "LsyCJlwYv7_DXvxdEObRF", "fillStyle": "solid", @@ -2945,16 +2649,16 @@ "groupIds": [ "Xap4MeFI6FrBeVoCuInyh" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076693, + "updated": 1682390147046, "link": null, "locked": false }, { "type": "line", - "version": 2252, - "versionNonce": 1822403667, + "version": 2253, + "versionNonce": 1680370703, "isDeleted": false, "id": "bOrXyZj9OMnDGhz1v7h0H", "fillStyle": "solid", @@ -2973,9 +2677,9 @@ "groupIds": [ "1TlngZZWxu19iKmY05Qwg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -3020,8 +2724,8 @@ }, { "type": "line", - "version": 4674, - "versionNonce": 1874736733, + "version": 4675, + "versionNonce": 569335905, "isDeleted": false, "id": "tFrXMLLOM0fG7UgojMMXW", "fillStyle": "solid", @@ -3040,9 +2744,11 @@ "groupIds": [ "1TlngZZWxu19iKmY05Qwg" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -3283,8 +2989,8 @@ }, { "type": "line", - "version": 2187, - "versionNonce": 455911923, + "version": 2188, + "versionNonce": 1065226799, "isDeleted": false, "id": "_03j2sy3L4conj6PCz2sK", "fillStyle": "solid", @@ -3303,9 +3009,11 @@ "groupIds": [ "1TlngZZWxu19iKmY05Qwg" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -3350,8 +3058,8 @@ }, { "type": "line", - "version": 2306, - "versionNonce": 2059494077, + "version": 2307, + "versionNonce": 214346817, "isDeleted": false, "id": "Ja8Vc0fG4N7MxVmnlXEIA", "fillStyle": "solid", @@ -3370,9 +3078,11 @@ "groupIds": [ "1TlngZZWxu19iKmY05Qwg" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -3417,8 +3127,8 @@ }, { "type": "line", - "version": 2311, - "versionNonce": 378074003, + "version": 2312, + "versionNonce": 158987343, "isDeleted": false, "id": "PkOjNnIbMYltuiixUP06f", "fillStyle": "solid", @@ -3437,9 +3147,11 @@ "groupIds": [ "1TlngZZWxu19iKmY05Qwg" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -3484,8 +3196,8 @@ }, { "type": "line", - "version": 2491, - "versionNonce": 694158109, + "version": 2492, + "versionNonce": 1518959649, "isDeleted": false, "id": "pR_1IHE-bDhvaXjCBze1G", "fillStyle": "solid", @@ -3504,9 +3216,11 @@ "groupIds": [ "1TlngZZWxu19iKmY05Qwg" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147046, "link": null, "locked": false, "startBinding": null, @@ -3551,8 +3265,8 @@ }, { "type": "line", - "version": 2622, - "versionNonce": 518719795, + "version": 2623, + "versionNonce": 167023215, "isDeleted": false, "id": "mt9kn51mVehBtw7CgSvBK", "fillStyle": "solid", @@ -3571,9 +3285,11 @@ "groupIds": [ "1TlngZZWxu19iKmY05Qwg" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false, "startBinding": null, @@ -3618,8 +3334,8 @@ }, { "type": "line", - "version": 2685, - "versionNonce": 1611372413, + "version": 2686, + "versionNonce": 723996673, "isDeleted": false, "id": "VgbIhsxaQ8qjFIj6xHwVk", "fillStyle": "solid", @@ -3638,9 +3354,11 @@ "groupIds": [ "1TlngZZWxu19iKmY05Qwg" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false, "startBinding": null, @@ -3685,8 +3403,8 @@ }, { "type": "line", - "version": 2813, - "versionNonce": 700017363, + "version": 2814, + "versionNonce": 2041998479, "isDeleted": false, "id": "oRzP3X-24Zmb0TzqfkKPI", "fillStyle": "solid", @@ -3705,9 +3423,11 @@ "groupIds": [ "1TlngZZWxu19iKmY05Qwg" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false, "startBinding": null, @@ -3752,8 +3472,8 @@ }, { "type": "ellipse", - "version": 1632, - "versionNonce": 2030411741, + "version": 1633, + "versionNonce": 1956620257, "isDeleted": false, "id": "rAkiUi5e2cti74pxvE85G", "fillStyle": "solid", @@ -3772,16 +3492,16 @@ "groupIds": [ "1TlngZZWxu19iKmY05Qwg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false }, { "type": "line", - "version": 2216, - "versionNonce": 998938739, + "version": 2217, + "versionNonce": 1685586607, "isDeleted": false, "id": "ow7K33erLRsTrZvrVFTbW", "fillStyle": "solid", @@ -3800,9 +3520,9 @@ "groupIds": [ "A1yQIiz7mzmYfVaaTsjNO" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false, "startBinding": null, @@ -3847,8 +3567,8 @@ }, { "type": "line", - "version": 4638, - "versionNonce": 174038077, + "version": 4639, + "versionNonce": 1090651073, "isDeleted": false, "id": "YR5DHIe93wREkj6EC1sWw", "fillStyle": "solid", @@ -3867,9 +3587,11 @@ "groupIds": [ "A1yQIiz7mzmYfVaaTsjNO" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false, "startBinding": null, @@ -4110,8 +3832,8 @@ }, { "type": "line", - "version": 2151, - "versionNonce": 35983891, + "version": 2152, + "versionNonce": 1256314063, "isDeleted": false, "id": "pMBJry41FzhNgnXSlJT88", "fillStyle": "solid", @@ -4130,9 +3852,11 @@ "groupIds": [ "A1yQIiz7mzmYfVaaTsjNO" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false, "startBinding": null, @@ -4177,8 +3901,8 @@ }, { "type": "line", - "version": 2270, - "versionNonce": 1811614877, + "version": 2271, + "versionNonce": 745399201, "isDeleted": false, "id": "6WjyphA7oKlryRoN4dhG0", "fillStyle": "solid", @@ -4197,9 +3921,11 @@ "groupIds": [ "A1yQIiz7mzmYfVaaTsjNO" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false, "startBinding": null, @@ -4244,8 +3970,8 @@ }, { "type": "line", - "version": 2275, - "versionNonce": 780097459, + "version": 2276, + "versionNonce": 76309231, "isDeleted": false, "id": "NqD9783Kmjx73TclhDEVh", "fillStyle": "solid", @@ -4264,9 +3990,11 @@ "groupIds": [ "A1yQIiz7mzmYfVaaTsjNO" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false, "startBinding": null, @@ -4311,8 +4039,8 @@ }, { "type": "line", - "version": 2455, - "versionNonce": 2106159357, + "version": 2456, + "versionNonce": 588433281, "isDeleted": false, "id": "mnGQbo4NSeTRDAXIj-9KS", "fillStyle": "solid", @@ -4331,9 +4059,11 @@ "groupIds": [ "A1yQIiz7mzmYfVaaTsjNO" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false, "startBinding": null, @@ -4378,8 +4108,8 @@ }, { "type": "line", - "version": 2586, - "versionNonce": 247458131, + "version": 2587, + "versionNonce": 1644178703, "isDeleted": false, "id": "j61ENMslzWUVHpZmv8Sgp", "fillStyle": "solid", @@ -4398,9 +4128,11 @@ "groupIds": [ "A1yQIiz7mzmYfVaaTsjNO" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false, "startBinding": null, @@ -4445,8 +4177,8 @@ }, { "type": "line", - "version": 2649, - "versionNonce": 747391325, + "version": 2650, + "versionNonce": 1596993377, "isDeleted": false, "id": "nlF3HST4S1-mqCeV6Wycr", "fillStyle": "solid", @@ -4465,9 +4197,11 @@ "groupIds": [ "A1yQIiz7mzmYfVaaTsjNO" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false, "startBinding": null, @@ -4512,8 +4246,8 @@ }, { "type": "line", - "version": 2777, - "versionNonce": 1748846323, + "version": 2778, + "versionNonce": 246788911, "isDeleted": false, "id": "nEeu04ObgcVoPbMfbWOad", "fillStyle": "solid", @@ -4532,9 +4266,11 @@ "groupIds": [ "A1yQIiz7mzmYfVaaTsjNO" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false, "startBinding": null, @@ -4579,8 +4315,8 @@ }, { "type": "ellipse", - "version": 1596, - "versionNonce": 978654653, + "version": 1597, + "versionNonce": 655727425, "isDeleted": false, "id": "9fu4-Y-EE8r68y42dPcUa", "fillStyle": "solid", @@ -4599,16 +4335,16 @@ "groupIds": [ "A1yQIiz7mzmYfVaaTsjNO" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147047, "link": null, "locked": false }, { "type": "rectangle", - "version": 1988, - "versionNonce": 740151613, + "version": 2150, + "versionNonce": 695957487, "isDeleted": false, "id": "xeTZSFRJPria6_fCTJ7si", "fillStyle": "hachure", @@ -4617,8 +4353,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 793.9996448444456, - "y": 185.93370234431512, + "x": 829.9288514865018, + "y": 71.05646079003355, "strokeColor": "#000000", "backgroundColor": "#ced4da", "width": 221, @@ -4627,7 +4363,7 @@ "groupIds": [ "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "type": "text", @@ -4638,14 +4374,14 @@ "type": "arrow" } ], - "updated": 1664572195318, + "updated": 1682390216744, "link": null, "locked": false }, { "type": "text", - "version": 1799, - "versionNonce": 75469491, + "version": 1963, + "versionNonce": 1911263305, "isDeleted": false, "id": "ISq37rN3pAjk5bat7bMln", "fillStyle": "hachure", @@ -4654,34 +4390,35 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 813.4996448444456, - "y": 190.93370234431512, + "x": 850.1944764865018, + "y": 76.05646079003355, "strokeColor": "#000000", "backgroundColor": "#ced4da", - "width": 182, + "width": 180.46875, "height": 34, "seed": 689640513, "groupIds": [ "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572195318, + "updated": 1683235807888, "link": null, "locked": false, "fontSize": 28, "fontFamily": 3, "text": "laf clients", - "baseline": 27, "textAlign": "center", "verticalAlign": "top", "containerId": "xeTZSFRJPria6_fCTJ7si", - "originalText": "laf clients" + "originalText": "laf clients", + "lineHeight": 1.2142857142857142, + "baseline": 27 }, { "type": "rectangle", - "version": 1538, - "versionNonce": 855533053, + "version": 1700, + "versionNonce": 413370415, "isDeleted": false, "id": "JiK4zccqUEJ2ZD3eexlcA", "fillStyle": "solid", @@ -4690,8 +4427,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 907.0799663486237, - "y": 234.14186560975975, + "x": 943.00917299068, + "y": 119.26462405547818, "strokeColor": "#000000", "backgroundColor": "transparent", "width": 73.05349278983334, @@ -4702,21 +4439,16 @@ "0M-3yz4yS6w2gyIgaJ2mq", "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "sharp", - "boundElements": [ - { - "type": "arrow", - "id": "9RT6Uw_WUaOTrDl9MY1Gv" - } - ], - "updated": 1664572195318, + "roundness": null, + "boundElements": [], + "updated": 1682390216744, "link": null, "locked": false }, { "type": "rectangle", - "version": 1550, - "versionNonce": 1325450323, + "version": 1712, + "versionNonce": 1532728897, "isDeleted": false, "id": "1V9kLTxu1tHQB7WwtdpT3", "fillStyle": "solid", @@ -4725,8 +4457,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 909.8833735211464, - "y": 237.76980430361147, + "x": 945.8125801632026, + "y": 122.8925627493299, "strokeColor": "#000000", "backgroundColor": "#000000", "width": 67.44667844478977, @@ -4737,16 +4469,16 @@ "0M-3yz4yS6w2gyIgaJ2mq", "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572195318, + "updated": 1682390216744, "link": null, "locked": false }, { "type": "line", - "version": 1556, - "versionNonce": 832216669, + "version": 1718, + "versionNonce": 1249946191, "isDeleted": false, "id": "wmGkfQMuNo4DicGS-lqpl", "fillStyle": "solid", @@ -4755,8 +4487,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 904.1291960956946, - "y": 279.656005587173, + "x": 940.058402737751, + "y": 164.77876403289144, "strokeColor": "#000000", "backgroundColor": "#000000", "width": 79.13748282381697, @@ -4767,9 +4499,9 @@ "0M-3yz4yS6w2gyIgaJ2mq", "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572195318, + "updated": 1682390216744, "link": null, "locked": false, "startBinding": null, @@ -4790,8 +4522,8 @@ }, { "type": "line", - "version": 1596, - "versionNonce": 1101709811, + "version": 1758, + "versionNonce": 452011553, "isDeleted": false, "id": "YXy3EX-Lp2oNFP6I_G9j4", "fillStyle": "solid", @@ -4800,8 +4532,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 906.2753853816101, - "y": 283.19084688575396, + "x": 942.2045920236664, + "y": 168.3136053314724, "strokeColor": "#000000", "backgroundColor": "#000000", "width": 75.45340581361945, @@ -4812,9 +4544,9 @@ "0M-3yz4yS6w2gyIgaJ2mq", "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572195318, + "updated": 1682390216744, "link": null, "locked": false, "startBinding": null, @@ -4835,8 +4567,8 @@ }, { "type": "line", - "version": 1542, - "versionNonce": 349227709, + "version": 1704, + "versionNonce": 615811183, "isDeleted": false, "id": "uuL_-AFdFzanX9Tv4tbnD", "fillStyle": "solid", @@ -4845,8 +4577,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 981.7626847037236, - "y": 283.3070532005895, + "x": 1017.6918913457798, + "y": 168.42981164630794, "strokeColor": "#000000", "backgroundColor": "#000000", "width": 1.592994899209459, @@ -4857,9 +4589,11 @@ "0M-3yz4yS6w2gyIgaJ2mq", "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572195318, + "updated": 1682390216744, "link": null, "locked": false, "startBinding": null, @@ -4884,8 +4618,8 @@ }, { "type": "line", - "version": 1566, - "versionNonce": 1971587987, + "version": 1728, + "versionNonce": 352958977, "isDeleted": false, "id": "046oiwxDUc8tFBo2CND8c", "fillStyle": "solid", @@ -4894,8 +4628,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 906.209212341219, - "y": 283.3070532005896, + "x": 942.1384189832753, + "y": 168.42981164630805, "strokeColor": "#000000", "backgroundColor": "#000000", "width": 1.8205655990965262, @@ -4906,9 +4640,11 @@ "0M-3yz4yS6w2gyIgaJ2mq", "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572195318, + "updated": 1682390216744, "link": null, "locked": false, "startBinding": null, @@ -4933,8 +4669,8 @@ }, { "type": "rectangle", - "version": 1555, - "versionNonce": 490892061, + "version": 1717, + "versionNonce": 1694999183, "isDeleted": false, "id": "ZayR-KJtJVAkO2U-XWMzM", "fillStyle": "solid", @@ -4943,8 +4679,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 938.0382030199171, - "y": 279.69823698331476, + "x": 973.9674096619733, + "y": 164.8209954290332, "strokeColor": "#000000", "backgroundColor": "#000000", "width": 10.836699994622158, @@ -4955,16 +4691,16 @@ "0M-3yz4yS6w2gyIgaJ2mq", "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572195318, + "updated": 1682390216744, "link": null, "locked": false }, { "type": "text", - "version": 1055, - "versionNonce": 516104499, + "version": 1219, + "versionNonce": 545993927, "isDeleted": false, "id": "Bo00P1FC02NoEwp1ysrPO", "fillStyle": "solid", @@ -4973,35 +4709,36 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 925.6784100774155, - "y": 244.33724198496208, + "x": 962.3966792194716, + "y": 129.4600004306805, "strokeColor": "#ffffff", "backgroundColor": "#495057", - "width": 38, + "width": 36.421875, "height": 25, "seed": 395530845, "groupIds": [ "0M-3yz4yS6w2gyIgaJ2mq", "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572195318, + "updated": 1683235807888, "link": null, "locked": false, "fontSize": 20.724303817271576, "fontFamily": 3, "text": "cli", - "baseline": 20, "textAlign": "center", "verticalAlign": "top", "containerId": null, - "originalText": "cli" + "originalText": "cli", + "lineHeight": 1.2063131394148483, + "baseline": 20 }, { "type": "text", - "version": 1689, - "versionNonce": 2069954429, + "version": 1853, + "versionNonce": 1753521961, "isDeleted": false, "id": "9y9UXBQAck1TKCGDVjvPg", "fillStyle": "solid", @@ -5010,35 +4747,36 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 853.2411465531247, - "y": 284.6929714411967, + "x": 889.1703531951808, + "y": 169.8157298869151, "strokeColor": "#000", "backgroundColor": "transparent", - "width": 38, + "width": 35.947265625, "height": 25, "seed": 1505309139, "groupIds": [ "eMduRRAABtjtgcoMCENBV", "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572195318, + "updated": 1683235807888, "link": null, "locked": false, "fontSize": 20.45309724991167, "fontFamily": 3, "text": "Web", - "baseline": 20, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "Web" + "originalText": "Web", + "lineHeight": 1.222308763046045, + "baseline": 20 }, { "type": "rectangle", - "version": 3352, - "versionNonce": 651068115, + "version": 3514, + "versionNonce": 1892806081, "isDeleted": false, "id": "GBV4ibMyR3xKCvwkOpPMy", "fillStyle": "solid", @@ -5047,8 +4785,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 850.9168315294087, - "y": 231.95504790957295, + "x": 886.846038171465, + "y": 117.07780635529139, "strokeColor": "#000000", "backgroundColor": "#ff7353", "width": 37.79600275559777, @@ -5059,16 +4797,16 @@ "eMduRRAABtjtgcoMCENBV", "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572195318, + "updated": 1682390216744, "link": null, "locked": false }, { "type": "rectangle", - "version": 2854, - "versionNonce": 1433274333, + "version": 3016, + "versionNonce": 803048143, "isDeleted": false, "id": "azxhpnErbVO2nOeDV_Muo", "fillStyle": "solid", @@ -5077,8 +4815,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 862.5371354743497, - "y": 238.185327717856, + "x": 898.466342116406, + "y": 123.30808616357444, "strokeColor": "#000000", "backgroundColor": "#fff", "width": 30.398903493209932, @@ -5089,16 +4827,16 @@ "eMduRRAABtjtgcoMCENBV", "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572195318, + "updated": 1682390216744, "link": null, "locked": false }, { "type": "text", - "version": 2054, - "versionNonce": 104640627, + "version": 2218, + "versionNonce": 1190593511, "isDeleted": false, "id": "mj16Zn5jjc_LHrLeLLAzH", "fillStyle": "solid", @@ -5107,11 +4845,11 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 866.3662583438094, - "y": 240.25148310703776, + "x": 902.2954649858656, + "y": 125.37424155275619, "strokeColor": "#000000", "backgroundColor": "#c5bcdd", - "width": 25, + "width": 23.3919677734375, "height": 11, "seed": 267822397, "groupIds": [ @@ -5119,24 +4857,25 @@ "eMduRRAABtjtgcoMCENBV", "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572195318, + "updated": 1683235807889, "link": null, "locked": false, "fontSize": 8.603859583296448, "fontFamily": 1, "text": "HTML", - "baseline": 8, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "HTML" + "originalText": "HTML", + "lineHeight": 1.2784959928164594, + "baseline": 8 }, { "type": "text", - "version": 1684, - "versionNonce": 226165821, + "version": 1848, + "versionNonce": 181981705, "isDeleted": false, "id": "LqLlTuna3S27mAzeVh8DI", "fillStyle": "solid", @@ -5145,11 +4884,11 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 857.9363080539305, - "y": 262.5428444697911, + "x": 893.8655146959867, + "y": 147.6656029155095, "strokeColor": "#000", "backgroundColor": "transparent", - "width": 27, + "width": 24.613174438476562, "height": 20, "seed": 203364627, "groupIds": [ @@ -5157,24 +4896,25 @@ "eMduRRAABtjtgcoMCENBV", "lDeAg5xcR2r5EziP7leHg" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572195318, + "updated": 1683235807889, "link": null, "locked": false, "fontSize": 15.486947249933605, "fontFamily": 1, "text": "", - "baseline": 14, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "" + "originalText": "", + "lineHeight": 1.2914100937539994, + "baseline": 14 }, { "type": "rectangle", - "version": 3574, - "versionNonce": 508731475, + "version": 3575, + "versionNonce": 1615170113, "isDeleted": false, "id": "rw2QNRirrhZsKeemh1AFj", "fillStyle": "hachure", @@ -5193,7 +4933,7 @@ "groupIds": [ "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "6K6iRG81BfUtlnRql2IXP", @@ -5203,10 +4943,6 @@ "id": "F0l5EdS9JdyYqN5Lmjb8Q", "type": "arrow" }, - { - "type": "text", - "id": "6K6iRG81BfUtlnRql2IXP" - }, { "id": "aAKa09DjRg0mEhlWYHR5u", "type": "arrow" @@ -5216,14 +4952,14 @@ "type": "arrow" } ], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false }, { "type": "text", - "version": 3479, - "versionNonce": 893517989, + "version": 3482, + "versionNonce": 1230761735, "isDeleted": false, "id": "6K6iRG81BfUtlnRql2IXP", "fillStyle": "hachure", @@ -5232,34 +4968,35 @@ "roughness": 1, "opacity": 100, "angle": 0.01556190171898919, - "x": -133.47963428080544, + "x": -132.71400928080544, "y": 51.61694110489756, "strokeColor": "#000000", "backgroundColor": "#ced4da", - "width": 182, + "width": 180.46875, "height": 34, "seed": 954803453, "groupIds": [ "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1667988576992, + "updated": 1683235807889, "link": null, "locked": false, "fontSize": 28, "fontFamily": 3, "text": "app clients", - "baseline": 27, "textAlign": "center", "verticalAlign": "top", "containerId": "rw2QNRirrhZsKeemh1AFj", - "originalText": "app clients" + "originalText": "app clients", + "lineHeight": 1.2142857142857142, + "baseline": 27 }, { "type": "text", - "version": 1104, - "versionNonce": 39919091, + "version": 1107, + "versionNonce": 2112071913, "isDeleted": false, "id": "gedDdnx4slUq1LVe1z9qa", "fillStyle": "solid", @@ -5272,31 +5009,32 @@ "y": 163.4015284278193, "strokeColor": "#000", "backgroundColor": "#fbbd9b", - "width": 20, + "width": 18.180587768554688, "height": 12, "seed": 434595379, "groupIds": [ "dtlnkA_NP2PqR0LQZNLOI", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1683235807889, "link": null, "locked": false, "fontSize": 9.427717025298142, "fontFamily": 1, "text": "APK", - "baseline": 9, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "APK" + "originalText": "APK", + "lineHeight": 1.2728426158527506, + "baseline": 8 }, { "type": "rectangle", - "version": 3089, - "versionNonce": 641609405, + "version": 3090, + "versionNonce": 1355437167, "isDeleted": false, "id": "8B8CnbJU0O9k4FSnEwLBe", "fillStyle": "solid", @@ -5317,16 +5055,16 @@ "dtlnkA_NP2PqR0LQZNLOI", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false }, { "type": "rectangle", - "version": 2566, - "versionNonce": 118417299, + "version": 2567, + "versionNonce": 923184641, "isDeleted": false, "id": "rusP1D-v_-a7jXXXvXeff", "fillStyle": "solid", @@ -5347,16 +5085,16 @@ "dtlnkA_NP2PqR0LQZNLOI", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false }, { "type": "text", - "version": 1672, - "versionNonce": 1667452701, + "version": 1675, + "versionNonce": 37123623, "isDeleted": false, "id": "LTWXKzCJwXZhsTjYBICfW", "fillStyle": "solid", @@ -5369,7 +5107,7 @@ "y": 113.05973277270347, "strokeColor": "#000000", "backgroundColor": "#c5bcdd", - "width": 20, + "width": 18.180587768554688, "height": 12, "seed": 2035495645, "groupIds": [ @@ -5377,24 +5115,25 @@ "dtlnkA_NP2PqR0LQZNLOI", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1683235807889, "link": null, "locked": false, "fontSize": 9.427717025298142, "fontFamily": 1, "text": "APK", - "baseline": 9, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "APK" + "originalText": "APK", + "lineHeight": 1.2728426158527506, + "baseline": 8 }, { "type": "line", - "version": 1231, - "versionNonce": 1922202931, + "version": 1232, + "versionNonce": 1222854113, "isDeleted": false, "id": "BiQl4RF0rMuRSZIOMM684", "fillStyle": "solid", @@ -5416,9 +5155,9 @@ "dtlnkA_NP2PqR0LQZNLOI", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false, "startBinding": null, @@ -5439,8 +5178,8 @@ }, { "type": "line", - "version": 1253, - "versionNonce": 331703165, + "version": 1254, + "versionNonce": 507856047, "isDeleted": false, "id": "otvvPPs1_brFIhmeJdiiW", "fillStyle": "solid", @@ -5462,9 +5201,9 @@ "dtlnkA_NP2PqR0LQZNLOI", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false, "startBinding": null, @@ -5485,8 +5224,8 @@ }, { "type": "line", - "version": 1652, - "versionNonce": 5398227, + "version": 1653, + "versionNonce": 1193402817, "isDeleted": false, "id": "4PDA0bVNAcoAB7zMgrx3Q", "fillStyle": "solid", @@ -5508,9 +5247,11 @@ "dtlnkA_NP2PqR0LQZNLOI", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false, "startBinding": null, @@ -5587,8 +5328,8 @@ }, { "type": "ellipse", - "version": 1375, - "versionNonce": 732294109, + "version": 1376, + "versionNonce": 498521807, "isDeleted": false, "id": "9hDu2pzMH2nE29dyWpHm7", "fillStyle": "solid", @@ -5610,16 +5351,16 @@ "dtlnkA_NP2PqR0LQZNLOI", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false }, { "type": "ellipse", - "version": 1497, - "versionNonce": 988089459, + "version": 1498, + "versionNonce": 1591869857, "isDeleted": false, "id": "E32AdE46_GOS8bfgMRyW_", "fillStyle": "solid", @@ -5641,16 +5382,16 @@ "dtlnkA_NP2PqR0LQZNLOI", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false }, { "type": "text", - "version": 1514, - "versionNonce": 454453309, + "version": 1517, + "versionNonce": 993043401, "isDeleted": false, "id": "CIhfWZyOlf5kD63Q5GzGD", "fillStyle": "solid", @@ -5663,31 +5404,32 @@ "y": 162.9273325388957, "strokeColor": "#000", "backgroundColor": "#edf2f9", - "width": 33, + "width": 31.326980590820312, "height": 12, "seed": 593543763, "groupIds": [ "77XHXVZ-aslCUWd_tkdRc", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1683235807889, "link": null, "locked": false, "fontSize": 8.927305135629158, "fontFamily": 1, "text": "Flutter", - "baseline": 8, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "Flutter" + "originalText": "Flutter", + "lineHeight": 1.3441906395814365, + "baseline": 8 }, { "type": "rectangle", - "version": 3500, - "versionNonce": 370214419, + "version": 3501, + "versionNonce": 1834165633, "isDeleted": false, "id": "59MpQzwCB722w9JG2z7Gl", "fillStyle": "solid", @@ -5709,21 +5451,21 @@ "77XHXVZ-aslCUWd_tkdRc", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "aAKa09DjRg0mEhlWYHR5u", "type": "arrow" } ], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false }, { "type": "rectangle", - "version": 3050, - "versionNonce": 1408784541, + "version": 3051, + "versionNonce": 553430799, "isDeleted": false, "id": "QI-v2FDxDV2cU0_nruqdD", "fillStyle": "solid", @@ -5745,16 +5487,16 @@ "77XHXVZ-aslCUWd_tkdRc", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false }, { "type": "text", - "version": 2208, - "versionNonce": 1221381043, + "version": 2211, + "versionNonce": 1215502663, "isDeleted": false, "id": "JGTSXQle9sAiJ-D0O2Z3W", "fillStyle": "solid", @@ -5767,7 +5509,7 @@ "y": 114.8028934412314, "strokeColor": "#000000", "backgroundColor": "#fff", - "width": 33, + "width": 31.326980590820312, "height": 12, "seed": 298544317, "groupIds": [ @@ -5776,24 +5518,25 @@ "77XHXVZ-aslCUWd_tkdRc", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1683235807889, "link": null, "locked": false, "fontSize": 8.927305135629158, "fontFamily": 1, "text": "Flutter", - "baseline": 8, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "Flutter" + "originalText": "Flutter", + "lineHeight": 1.3441906395814365, + "baseline": 8 }, { "type": "line", - "version": 2065, - "versionNonce": 268254461, + "version": 2066, + "versionNonce": 2127689007, "isDeleted": false, "id": "7j5yXJ9c87Is3B8FPeseO", "fillStyle": "solid", @@ -5815,9 +5558,9 @@ "77XHXVZ-aslCUWd_tkdRc", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false, "startBinding": null, @@ -5850,8 +5593,8 @@ }, { "type": "line", - "version": 1483, - "versionNonce": 1732173139, + "version": 1484, + "versionNonce": 123107649, "isDeleted": false, "id": "7DKYVZ8m5NE32dQsW9WOf", "fillStyle": "solid", @@ -5873,9 +5616,9 @@ "77XHXVZ-aslCUWd_tkdRc", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false, "startBinding": null, @@ -5908,8 +5651,8 @@ }, { "type": "line", - "version": 1487, - "versionNonce": 1453757789, + "version": 1488, + "versionNonce": 442070863, "isDeleted": false, "id": "2iZfbrrLpCsr1VyCO2Ndi", "fillStyle": "solid", @@ -5931,9 +5674,9 @@ "77XHXVZ-aslCUWd_tkdRc", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false, "startBinding": null, @@ -5966,8 +5709,8 @@ }, { "type": "rectangle", - "version": 2933, - "versionNonce": 1019067123, + "version": 2934, + "versionNonce": 1805101345, "isDeleted": false, "id": "0gvLFIIMb58ofxtgZYLUT", "fillStyle": "solid", @@ -5988,16 +5731,16 @@ "x73pZB4zDV5T9hqT3liFY", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false }, { "type": "rectangle", - "version": 2339, - "versionNonce": 1128653245, + "version": 2340, + "versionNonce": 2045490543, "isDeleted": false, "id": "ejdayrz8A8pKNh6ZrPBuP", "fillStyle": "solid", @@ -6018,16 +5761,16 @@ "x73pZB4zDV5T9hqT3liFY", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false }, { "type": "text", - "version": 1444, - "versionNonce": 1708123283, + "version": 1447, + "versionNonce": 2128298665, "isDeleted": false, "id": "oiqMx0JIwPFvGsGK6GV2J", "fillStyle": "solid", @@ -6040,7 +5783,7 @@ "y": 108.92013075750509, "strokeColor": "#000000", "backgroundColor": "#c5bcdd", - "width": 20, + "width": 17.830780029296875, "height": 12, "seed": 830003891, "groupIds": [ @@ -6048,24 +5791,25 @@ "x73pZB4zDV5T9hqT3liFY", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1683235807890, "link": null, "locked": false, "fontSize": 9.360388407600311, "fontFamily": 1, "text": "VUE", - "baseline": 9, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "VUE" + "originalText": "VUE", + "lineHeight": 1.281998083568457, + "baseline": 8 }, { "type": "line", - "version": 1389, - "versionNonce": 184328733, + "version": 1390, + "versionNonce": 1154559887, "isDeleted": false, "id": "bFL5iIXaH1r-I7ZcZ45Ty", "fillStyle": "solid", @@ -6087,9 +5831,9 @@ "x73pZB4zDV5T9hqT3liFY", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false, "startBinding": null, @@ -6118,8 +5862,8 @@ }, { "type": "line", - "version": 1761, - "versionNonce": 707516979, + "version": 1762, + "versionNonce": 264672481, "isDeleted": false, "id": "_kvP7X8-0wSe0W_hVISPi", "fillStyle": "solid", @@ -6141,9 +5885,9 @@ "x73pZB4zDV5T9hqT3liFY", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false, "startBinding": null, @@ -6172,8 +5916,8 @@ }, { "type": "line", - "version": 2901, - "versionNonce": 1119639165, + "version": 2902, + "versionNonce": 625108399, "isDeleted": false, "id": "mWdDbrXSdunx1F5sWoQQy", "fillStyle": "solid", @@ -6195,9 +5939,9 @@ "x73pZB4zDV5T9hqT3liFY", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false, "startBinding": null, @@ -6226,8 +5970,8 @@ }, { "type": "line", - "version": 1239, - "versionNonce": 381164499, + "version": 1240, + "versionNonce": 314790081, "isDeleted": false, "id": "zXtE_tHk5kO5vywcHCsbV", "fillStyle": "solid", @@ -6249,9 +5993,9 @@ "x73pZB4zDV5T9hqT3liFY", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false, "startBinding": null, @@ -6276,8 +6020,8 @@ }, { "type": "text", - "version": 604, - "versionNonce": 1699118813, + "version": 607, + "versionNonce": 1634621543, "isDeleted": false, "id": "O1mqnsTqZDlQ4UprPYFlf", "fillStyle": "solid", @@ -6290,31 +6034,32 @@ "y": 159.9298979900603, "strokeColor": "#000", "backgroundColor": "#edf2f9", - "width": 17, + "width": 15.275497436523438, "height": 12, "seed": 1082262205, "groupIds": [ "x73pZB4zDV5T9hqT3liFY", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1683235807890, "link": null, "locked": false, "fontSize": 9.360388407600311, "fontFamily": 1, "text": "Vue", - "baseline": 9, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "Vue" + "originalText": "Vue", + "lineHeight": 1.281998083568457, + "baseline": 8 }, { "type": "text", - "version": 1222, - "versionNonce": 1468737907, + "version": 1225, + "versionNonce": 1972307337, "isDeleted": false, "id": "TbEzGrZWhlADy_PuHBQkP", "fillStyle": "solid", @@ -6327,31 +6072,32 @@ "y": 158.43840649433812, "strokeColor": "#000", "backgroundColor": "#edf2f9", - "width": 29, + "width": 27.370712280273438, "height": 12, "seed": 883695731, "groupIds": [ "DJjPjwFB_M5LqZMR6Riwe", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1683235807890, "link": null, "locked": false, "fontSize": 9.250786025523743, "fontFamily": 1, "text": "React", - "baseline": 8, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "React" + "originalText": "React", + "lineHeight": 1.297187067876279, + "baseline": 8 }, { "type": "rectangle", - "version": 3209, - "versionNonce": 422353725, + "version": 3210, + "versionNonce": 1784284655, "isDeleted": false, "id": "lkLknEN0tEcALN765sz5R", "fillStyle": "solid", @@ -6373,16 +6119,16 @@ "DJjPjwFB_M5LqZMR6Riwe", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false }, { "type": "rectangle", - "version": 2725, - "versionNonce": 1374389011, + "version": 2726, + "versionNonce": 77911169, "isDeleted": false, "id": "x1rGbGXUwAsokooJnVvc3", "fillStyle": "solid", @@ -6404,16 +6150,16 @@ "DJjPjwFB_M5LqZMR6Riwe", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147048, "link": null, "locked": false }, { "type": "text", - "version": 1872, - "versionNonce": 919612317, + "version": 1875, + "versionNonce": 854897543, "isDeleted": false, "id": "7yzIwHGPQnhUkD1fJ1A78", "fillStyle": "solid", @@ -6426,7 +6172,7 @@ "y": 108.2346073441382, "strokeColor": "#000000", "backgroundColor": "#fff", - "width": 29, + "width": 27.370712280273438, "height": 12, "seed": 930546845, "groupIds": [ @@ -6435,24 +6181,25 @@ "DJjPjwFB_M5LqZMR6Riwe", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1683235807890, "link": null, "locked": false, "fontSize": 9.250786025523743, "fontFamily": 1, "text": "React", - "baseline": 8, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "React" + "originalText": "React", + "lineHeight": 1.297187067876279, + "baseline": 8 }, { "type": "ellipse", - "version": 1143, - "versionNonce": 2119149747, + "version": 1144, + "versionNonce": 1022925921, "isDeleted": false, "id": "W18s7gWIoBHF85Pi7ag0L", "fillStyle": "solid", @@ -6474,16 +6221,16 @@ "DJjPjwFB_M5LqZMR6Riwe", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147049, "link": null, "locked": false }, { "type": "ellipse", - "version": 1260, - "versionNonce": 241348605, + "version": 1261, + "versionNonce": 565614127, "isDeleted": false, "id": "VxTVi2G6Xj4oYS6nRbl9w", "fillStyle": "solid", @@ -6505,16 +6252,16 @@ "DJjPjwFB_M5LqZMR6Riwe", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147049, "link": null, "locked": false }, { "type": "ellipse", - "version": 1283, - "versionNonce": 39721555, + "version": 1284, + "versionNonce": 1799907393, "isDeleted": false, "id": "dGZFgU_QaMmPnJzz1I4GJ", "fillStyle": "solid", @@ -6536,16 +6283,16 @@ "DJjPjwFB_M5LqZMR6Riwe", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076694, + "updated": 1682390147049, "link": null, "locked": false }, { "type": "ellipse", - "version": 780, - "versionNonce": 1843767389, + "version": 781, + "versionNonce": 436336719, "isDeleted": false, "id": "BrUDc3SIIeaR0gMeNP9zc", "fillStyle": "solid", @@ -6567,9 +6314,9 @@ "DJjPjwFB_M5LqZMR6Riwe", "icWb81AmMBtok_h9W-7F7" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664572076695, + "updated": 1682390147049, "link": null, "locked": false } diff --git a/docs/diagrams/laf-arch-simple.excalidraw b/docs/diagrams/laf-arch-simple.excalidraw index 2c06408acc..37af210c36 100644 --- a/docs/diagrams/laf-arch-simple.excalidraw +++ b/docs/diagrams/laf-arch-simple.excalidraw @@ -5,8 +5,8 @@ "elements": [ { "type": "rectangle", - "version": 1828, - "versionNonce": 596727967, + "version": 1830, + "versionNonce": 2018580382, "isDeleted": false, "id": "9UnJOgDqkaJktInMVo47r", "fillStyle": "solid", @@ -23,102 +23,31 @@ "height": 157, "seed": 1483473887, "groupIds": [], - "strokeSharpness": "round", + "roundness": { + "type": 1 + }, "boundElements": [ { "type": "text", "id": "Z809WNYMBMTJkJuXxrV2f" }, - { - "id": "kqj5BjInSDGoAuV2NWQC1", - "type": "arrow" - }, { "id": "BKtrNR7ahqNp_W0JX5yYz", "type": "arrow" - } - ], - "updated": 1664546888283, - "link": null, - "locked": false - }, - { - "type": "rectangle", - "version": 2409, - "versionNonce": 1227033591, - "isDeleted": false, - "id": "TMMDu5oiiccd-lZLzPZJ1", - "fillStyle": "cross-hatch", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 337.34089158488155, - "y": -717.5280783925962, - "strokeColor": "#000000", - "backgroundColor": "#40c057", - "width": 438, - "height": 141, - "seed": 1037531185, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [ - { - "type": "text", - "id": "oBfeWalO5ee6UnDijMdzq" - }, - { - "id": "kqj5BjInSDGoAuV2NWQC1", - "type": "arrow" }, { - "id": "AzJlXlpiAOpjWfG6hCefX", + "id": "IXGLaKwvNWM7iA7SwPJbz", "type": "arrow" } ], - "updated": 1668084820656, + "updated": 1682390356102, "link": null, "locked": false }, { "type": "text", - "version": 2510, - "versionNonce": 1783691927, - "isDeleted": false, - "id": "oBfeWalO5ee6UnDijMdzq", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 405.34089158488155, - "y": -712.5280783925962, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 302, - "height": 77, - "seed": 318769375, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1668084837016, - "link": null, - "locked": false, - "fontSize": 63.94116082054938, - "fontFamily": 3, - "text": "laf core", - "baseline": 62, - "textAlign": "center", - "verticalAlign": "top", - "containerId": "TMMDu5oiiccd-lZLzPZJ1", - "originalText": "laf core" - }, - { - "type": "text", - "version": 1735, - "versionNonce": 354331065, + "version": 1737, + "versionNonce": 1697434895, "isDeleted": false, "id": "Z809WNYMBMTJkJuXxrV2f", "fillStyle": "solid", @@ -127,138 +56,33 @@ "roughness": 2, "opacity": 100, "angle": 0, - "x": 664.9176487971549, + "x": 666.1676487971549, "y": -306.1187054323188, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 460, + "width": 457.5, "height": 94, "seed": 322762385, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1668084159361, + "updated": 1683235809304, "link": null, "locked": false, "fontSize": 78.0868293956231, "fontFamily": 3, "text": "laf server", - "baseline": 76, "textAlign": "center", "verticalAlign": "middle", "containerId": "9UnJOgDqkaJktInMVo47r", - "originalText": "laf server" - }, - { - "type": "arrow", - "version": 3295, - "versionNonce": 1726772503, - "isDeleted": false, - "id": "kqj5BjInSDGoAuV2NWQC1", - "fillStyle": "solid", - "strokeWidth": 4, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 6.279247880108075, - "x": 883.8995138780068, - "y": -338.41030154144244, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 106.22484141611312, - "height": 207.19979631724772, - "seed": 336290367, - "groupIds": [], - "strokeSharpness": "round", - "boundElements": [], - "updated": 1668084820656, - "link": null, - "locked": false, - "startBinding": { - "elementId": "pwFa_JsY4UC6EwKz1z0bE", - "focus": -0.8295575145153079, - "gap": 10.551370110599635 - }, - "endBinding": { - "elementId": "TMMDu5oiiccd-lZLzPZJ1", - "focus": -0.5465803449233135, - "gap": 31.189159943192863 - }, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - -46.877432913366306, - -124.34028999189604 - ], - [ - -106.22484141611312, - -207.19979631724772 - ] - ] - }, - { - "type": "arrow", - "version": 2643, - "versionNonce": 605178841, - "isDeleted": false, - "id": "AzJlXlpiAOpjWfG6hCefX", - "fillStyle": "solid", - "strokeWidth": 4, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 317.98727024740316, - "y": -551.9926112904379, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 80.4487949742257, - "height": 181.2387351702194, - "seed": 238665841, - "groupIds": [], - "strokeSharpness": "round", - "boundElements": [], - "updated": 1668084820656, - "link": null, - "locked": false, - "startBinding": { - "elementId": "TMMDu5oiiccd-lZLzPZJ1", - "gap": 31.249828876260878, - "focus": 0.6213304482698953 - }, - "endBinding": { - "elementId": "sFE8hJbB0-zakUa7U66ZI", - "gap": 32, - "focus": -0.010070174556607147 - }, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "points": [ - [ - 0, - 0 - ], - [ - -47.82515686521541, - 64.91849133349608 - ], - [ - -80.4487949742257, - 181.2387351702194 - ] - ] + "originalText": "laf server", + "lineHeight": 1.20378815131235, + "baseline": 75 }, { "type": "text", - "version": 3207, - "versionNonce": 570621375, + "version": 3209, + "versionNonce": 1788710753, "isDeleted": false, "id": "XBwYr-Ggufku0RrL4QBXi", "fillStyle": "solid", @@ -267,29 +91,32 @@ "roughness": 0, "opacity": 100, "angle": 0.04454966694106055, - "x": 481.49874187899337, - "y": 653.1835841987612, + "x": 481.4999744187205, + "y": 653.128260064777, "strokeColor": "#000000", "backgroundColor": "white", - "width": 149, + "width": 146.51547241210938, "height": 39, "seed": 32540977, "groupIds": [ "-elfsLPKjTB42IroSjeyr" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664546888283, + "updated": 1683235809304, "link": null, "locked": false, "fontSize": 31.289487449163044, "fontFamily": 1, "text": "Developer", - "baseline": 28, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "Developer" + "originalText": "Developer", + "lineHeight": 1.2464250193731825, + "baseline": 27 }, { "type": "line", @@ -314,7 +141,9 @@ "MmDhGpV7gD0dufHdOn7Xs", "-elfsLPKjTB42IroSjeyr" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], "updated": 1664546888283, "link": null, @@ -374,7 +203,9 @@ "MmDhGpV7gD0dufHdOn7Xs", "-elfsLPKjTB42IroSjeyr" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [ { "id": "qT3ZXcKZMAQ2PIdL4Jn_V", @@ -391,8 +222,8 @@ }, { "type": "arrow", - "version": 4686, - "versionNonce": 2098300511, + "version": 4774, + "versionNonce": 991184642, "isDeleted": false, "id": "BKtrNR7ahqNp_W0JX5yYz", "fillStyle": "solid", @@ -401,17 +232,19 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 897.9153932980781, - "y": 153.136457137969, + "x": 897.9108450761719, + "y": 129.21380563052475, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 2.2131452341895965, - "height": 285.3857280915365, + "width": 2.196352546919343, + "height": 261.4630765840923, "seed": 333875071, "groupIds": [], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664546888283, + "updated": 1682390388180, "link": null, "locked": false, "startBinding": { @@ -433,15 +266,15 @@ 0 ], [ - 2.2131452341895965, - -285.3857280915365 + 2.196352546919343, + -261.4630765840923 ] ] }, { "type": "arrow", - "version": 5016, - "versionNonce": 997708561, + "version": 5068, + "versionNonce": 481874498, "isDeleted": false, "id": "qT3ZXcKZMAQ2PIdL4Jn_V", "fillStyle": "solid", @@ -454,13 +287,15 @@ "y": 544.4213481896425, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 303.06333505234153, - "height": 145.99831010245418, + "width": 305.79945738001095, + "height": 167.6264549868415, "seed": 1289142047, "groupIds": [], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664546888283, + "updated": 1682390374323, "link": null, "locked": false, "startBinding": { @@ -486,15 +321,15 @@ -77.41405726701726 ], [ - -303.06333505234153, - -145.99831010245418 + -305.79945738001095, + -167.6264549868415 ] ] }, { "type": "arrow", - "version": 4609, - "versionNonce": 921657983, + "version": 4653, + "versionNonce": 1133194846, "isDeleted": false, "id": "I-Gae0eQW3HFmaEMCgWe6", "fillStyle": "solid", @@ -507,13 +342,15 @@ "y": 535.3090103404702, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 235.71372702516783, - "height": 121.05443966744548, + "width": 239.00702346745686, + "height": 144.97709117488972, "seed": 1995353727, "groupIds": [], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664546888283, + "updated": 1682390388180, "link": null, "locked": false, "startBinding": { @@ -535,846 +372,19 @@ 0 ], [ - 170.00189426585837, - -61.134539965866566 - ], - [ - 235.71372702516783, - -121.05443966744548 - ] - ] - }, - { - "type": "line", - "version": 2215, - "versionNonce": 2081245425, - "isDeleted": false, - "id": "SoJ9FPEYeuMLfhGecRWQK", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 557.3303448791635, - "y": -597.859321040327, - "strokeColor": "#000000", - "backgroundColor": "#326ce5", - "width": 317.3553341276203, - "height": 310.62630033039557, - "seed": 457011679, - "groupIds": [ - "eArZb9ZBlnfWJEMQQV4z9" - ], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1664546888283, - "link": null, - "locked": false, - "startBinding": null, - "endBinding": null, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": null, - "points": [ - [ - 0, - 0 - ], - [ - -130.99347834203905, - 62.65852410098101 - ], - [ - -158.00244294864507, - 196.64111287010007 - ], - [ - -67.52241151651502, - 310.62630033039557 - ], - [ - 84.40301439564368, - 309.95972028676795 - ], - [ - 159.3528911789753, - 187.97557230294285 - ], - [ - 129.64303011170867, - 55.992723664706475 - ], - [ - 0, - 0 - ] - ] - }, - { - "type": "line", - "version": 4637, - "versionNonce": 217889439, - "isDeleted": false, - "id": "yqWQvvbP3Y_Q3HAI3PmYg", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0.010125045471368388, - "x": 532.5847865706936, - "y": -520.7948388771216, - "strokeColor": "#000000", - "backgroundColor": "#ffff", - "width": 238.4426469128351, - "height": 237.4885659417879, - "seed": 1458724753, - "groupIds": [ - "eArZb9ZBlnfWJEMQQV4z9" - ], - "strokeSharpness": "round", - "boundElements": [], - "updated": 1664546888283, - "link": null, - "locked": false, - "startBinding": null, - "endBinding": null, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": null, - "points": [ - [ - 0, - 0 - ], - [ - 17.000665349035607, - -5.46968171336234 - ], - [ - 18.574891576791547, - -14.209705556448927 - ], - [ - 16.336458120775223, - -39.07613244008722 - ], - [ - 27.630763746335127, - -40.00821487145517 - ], - [ - 27.122265299164923, - -13.87654221580623 - ], - [ - 31.342243841439927, - -5.793579763136908 - ], - [ - 49.713275366017314, - -2.003746515933498 - ], - [ - 75.31067377467866, - 7.7518678343689045 - ], - [ - 93.45931155316691, - 20.32082325249709 - ], - [ - 100.4142316995715, - 18.782593603901674 - ], - [ - 116.95788790581241, - 5.829080773624646 - ], - [ - 122.18436635902779, - 10.585448765992016 - ], - [ - 105.72301690008176, - 23.84255955322866 - ], - [ - 103.00689423935576, - 30.90627201848909 - ], - [ - 114.24176524508646, - 52.11764927806777 - ], - [ - 121.11437864419639, - 76.44596556243188 - ], - [ - 121.87571605667272, - 100.34924470705245 - ], - [ - 127.10219450988795, - 104.82225460625753 - ], - [ - 148.35791199875223, - 107.1700788067454 - ], - [ - 147.18504084980248, - 115.73154119300645 - ], - [ - 125.92932336093808, - 111.72404816113946 - ], - [ - 119.30363020371247, - 113.3027575373295 - ], - [ - 109.24163034693157, - 133.13782405869122 - ], - [ - 94.879102944001, - 150.4024278777948 - ], - [ - 74.5493363622024, - 166.65503850703305 - ], - [ - 77.100845528339, - 173.55683206191515 - ], - [ - 90.39338521643808, - 192.62278375897918 - ], - [ - 81.52483319543084, - 197.48035107033272 - ], - [ - 71.91552044877115, - 176.43089272113284 - ], - [ - 63.70542240612155, - 170.54109235611628 - ], - [ - 40.165692679828666, - 176.9368893160654 - ], - [ - 8.086637921707267, - 176.30945353834903 - ], - [ - -12.119668539149142, - 167.78847087968236 - ], - [ - -18.107484404840793, - 172.30196050648206 - ], - [ - -28.848514926803176, - 192.29894593822192 - ], - [ - -36.21496880968159, - 187.25921985269252 - ], - [ - -23.560306413116777, - 168.6790248867638 - ], - [ - -22.51089538510894, - 161.5748326939089 - ], - [ - -38.31379086569722, - 149.45115427932134 - ], - [ - -52.820355076393554, - 129.45416884758123 - ], - [ - -59.137397931264246, - 115.6708216016145 - ], - [ - -67.4915327816793, - 114.82074732212754 - ], - [ - -88.80898033101465, - 120.64982809575231 - ], - [ - -90.08473491408286, - 111.46092993177446 - ], - [ - -68.68498061745302, - 108.74878818293537 - ], - [ - -62.6765880649376, - 103.50666345943256 - ], - [ - -62.58056352642709, - 75.16185864818047 - ], - [ - -57.015712889888874, - 53.4557291624454 - ], - [ - -46.75023246340719, - 35.13640355212646 - ], - [ - -51.56517718014895, - 28.052451223068687 - ], - [ - -72.16244069065534, - 17.102684908725127 - ], - [ - -66.93596223743988, - 8.460263067274663 - ], - [ - -48.519827530243845, - 23.17464404791755 - ], - [ - -38.86936140993669, - 24.04495819120175 - ], - [ - -22.408011950990563, - 10.808087267762392 - ], - [ - 0, - 0 - ] - ] - }, - { - "type": "line", - "version": 2150, - "versionNonce": 1513685713, - "isDeleted": false, - "id": "XaE7GXCT4GwJ2nhMwtlWg", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 505.27945011367774, - "y": -486.788630728042, - "strokeColor": "#000000", - "backgroundColor": "#326ce5", - "width": 48.47469376071386, - "height": 48.47469376071386, - "seed": 261217791, - "groupIds": [ - "eArZb9ZBlnfWJEMQQV4z9" - ], - "strokeSharpness": "round", - "boundElements": [], - "updated": 1664546888283, - "link": null, - "locked": false, - "startBinding": null, - "endBinding": null, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": null, - "points": [ - [ - 0, - 0 - ], - [ - 14.430327911426346, - -13.068830780054945 - ], - [ - 29.280956635806834, - -22.13699907641955 - ], - [ - 46.653390237912426, - -23.47055323764966 - ], - [ - 48.47469376071386, - 0.6667770806150289 - ], - [ - 45.252387528065256, - 25.004140523064205 - ], - [ - 21.855642273616635, - 13.73560786066992 - ], - [ - 0, - 0 - ] - ] - }, - { - "type": "line", - "version": 2269, - "versionNonce": 1139412671, - "isDeleted": false, - "id": "mvV2dD4yTJcDKdAYmx3FF", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0.9881310661508964, - "x": 556.7059617723021, - "y": -492.54942582191745, - "strokeColor": "#000000", - "backgroundColor": "#326ce5", - "width": 49.13117540263562, - "height": 50.11506909221825, - "seed": 1367491953, - "groupIds": [ - "eArZb9ZBlnfWJEMQQV4z9" - ], - "strokeSharpness": "round", - "boundElements": [], - "updated": 1664546888283, - "link": null, - "locked": false, - "startBinding": null, - "endBinding": null, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": null, - "points": [ - [ - 0, - 0 - ], - [ - 14.182288505688028, - -12.844193818214828 - ], - [ - 28.777653375619405, - -21.75649156962916 - ], - [ - 44.04720172849084, - -24.256112534712983 - ], - [ - 49.13117540263562, - -0.9507938675839573 - ], - [ - 47.07841964402909, - 25.858956557505266 - ], - [ - 21.479970940653768, - 13.499509829348174 - ], - [ - 0, - 0 - ] - ] - }, - { - "type": "line", - "version": 2274, - "versionNonce": 1385332913, - "isDeleted": false, - "id": "cigEvAYM5C2n4TajcqSg6", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 1.880863085334429, - "x": 594.3780293494175, - "y": -455.55455559786367, - "strokeColor": "#000000", - "backgroundColor": "#326ce5", - "width": 48.29807726718517, - "height": 50.67219549209237, - "seed": 851691039, - "groupIds": [ - "eArZb9ZBlnfWJEMQQV4z9" - ], - "strokeSharpness": "round", - "boundElements": [], - "updated": 1664546888283, - "link": null, - "locked": false, - "startBinding": null, - "endBinding": null, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": null, - "points": [ - [ - 0, - 0 - ], - [ - 14.377751325202478, - -13.021214779048572 - ], - [ - 28.8313107159284, - -21.94645818921957 - ], - [ - 46.48340962419841, - -23.38503878686273 - ], - [ - 48.29807726718517, - 0.664347692808582 - ], - [ - 43.57916915410944, - 27.28715670522964 - ], - [ - 21.52962978284186, - 15.27717845811122 - ], - [ - 0, - 0 - ] - ] - }, - { - "type": "line", - "version": 2454, - "versionNonce": 911728351, - "isDeleted": false, - "id": "hccjRHlL1ZaE1-wS8I9lB", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 2.8469082809423476, - "x": 586.7431828114449, - "y": -404.11188875655375, - "strokeColor": "#000000", - "backgroundColor": "#326ce5", - "width": 46.26123147054415, - "height": 52.5857593702524, - "seed": 551186257, - "groupIds": [ - "eArZb9ZBlnfWJEMQQV4z9" - ], - "strokeSharpness": "round", - "boundElements": [], - "updated": 1664546888283, - "link": null, - "locked": false, - "startBinding": null, - "endBinding": null, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": null, - "points": [ - [ - 0, - 0 - ], - [ - 8.98725650698632, - -10.141044492218427 - ], - [ - 24.966812833594844, - -21.61398255978931 - ], - [ - 41.79427231468136, - -24.055575815943136 - ], - [ - 46.26123147054415, - 1.1751965535672875 - ], - [ - 43.95460067977341, - 28.530183554309254 - ], - [ - 21.00664550546962, - 17.000233688329192 - ], - [ - 0, - 0 - ] - ] - }, - { - "type": "line", - "version": 2585, - "versionNonce": 1656832657, - "isDeleted": false, - "id": "XHU2OwqBOrlxwbE59OFhp", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 3.774871714878671, - "x": 541.407570331417, - "y": -377.5946520230925, - "strokeColor": "#000000", - "backgroundColor": "#326ce5", - "width": 47.357643859194916, - "height": 54.39985471610307, - "seed": 1136896575, - "groupIds": [ - "eArZb9ZBlnfWJEMQQV4z9" - ], - "strokeSharpness": "round", - "boundElements": [], - "updated": 1664546888283, - "link": null, - "locked": false, - "startBinding": null, - "endBinding": null, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": null, - "points": [ - [ - 0, - 0 - ], - [ - 11.971026379833722, - -11.749470191690138 - ], - [ - 26.862786904361528, - -22.78640428704829 - ], - [ - 43.0452144052358, - -27.06661877900955 - ], - [ - 46.00053463162567, - -0.0045456574213424885 - ], - [ - 47.357643859194916, - 27.33323593709352 - ], - [ - 23.38715276490379, - 14.669574937152335 - ], - [ - 0, - 0 - ] - ] - }, - { - "type": "line", - "version": 2648, - "versionNonce": 383167231, - "isDeleted": false, - "id": "2uHGrUT2YNXCCSed_5Z6T", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 4.759646000521123, - "x": 491.5849780148061, - "y": -397.93793368475764, - "strokeColor": "#000000", - "backgroundColor": "#326ce5", - "width": 46.887285571853354, - "height": 46.1026794771245, - "seed": 189947185, - "groupIds": [ - "eArZb9ZBlnfWJEMQQV4z9" - ], - "strokeSharpness": "round", - "boundElements": [], - "updated": 1664546888283, - "link": null, - "locked": false, - "startBinding": null, - "endBinding": null, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": null, - "points": [ - [ - 0, - 0 - ], - [ - 9.324476433685488, - -13.142771725173525 - ], - [ - 24.035693385592612, - -24.243425847069968 - ], - [ - 37.02827557858398, - -25.1011099227724 - ], - [ - 45.935528209756825, - -3.5503731155861638 - ], - [ - 46.887285571853354, - 21.00156955435209 - ], - [ - 21.52962978284186, - 15.27717845811122 - ], - [ - 0, - 0 - ] - ] - }, - { - "type": "line", - "version": 2776, - "versionNonce": 1736231025, - "isDeleted": false, - "id": "gGs2qQi5c6FOrr45ntp7f", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 5.645190933495279, - "x": 477.96611328172173, - "y": -446.0378195776641, - "strokeColor": "#000000", - "backgroundColor": "#326ce5", - "width": 52.66324158134681, - "height": 50.90620499382871, - "seed": 1332873823, - "groupIds": [ - "eArZb9ZBlnfWJEMQQV4z9" - ], - "strokeSharpness": "round", - "boundElements": [], - "updated": 1664546888283, - "link": null, - "locked": false, - "startBinding": null, - "endBinding": null, - "lastCommittedPoint": null, - "startArrowhead": null, - "endArrowhead": null, - "points": [ - [ - 0, - 0 - ], - [ - 9.32447643368549, - -13.142771725173526 - ], - [ - 24.035693385592616, - -24.243425847069975 - ], - [ - 38.74420553451078, - -27.41545864349239 - ], - [ - 47.08278677781014, - -4.4930562314554505 - ], - [ - 52.66324158134681, - 23.490746350336323 - ], - [ - 25.77439970397941, - 14.389466103227798 + 170.00189426585837, + -61.134539965866566 ], [ - 0, - 0 + 239.00702346745686, + -144.97709117488972 ] ] }, - { - "type": "ellipse", - "version": 1595, - "versionNonce": 1910960927, - "isDeleted": false, - "id": "S497XWVRl4wRHDkU0JMet", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 553.2460323407352, - "y": -446.8979002433115, - "strokeColor": "#000000", - "backgroundColor": "#326ce5", - "width": 21.20795466073014, - "height": 21.20795466073014, - "seed": 542215953, - "groupIds": [ - "eArZb9ZBlnfWJEMQQV4z9" - ], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1664546888283, - "link": null, - "locked": false - }, { "type": "arrow", - "version": 5021, - "versionNonce": 982291025, + "version": 5125, + "versionNonce": 1958503810, "isDeleted": false, "id": "tBVa_Dx6tqTSgAtdQRH9n", "fillStyle": "solid", @@ -1383,17 +393,19 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 217.94382403697253, - "y": 134.4044053313339, + "x": 218.31107044909433, + "y": 112.77626044694657, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 0.7819181801259845, - "height": 198.24054861171592, + "width": 0.0808345908460808, + "height": 176.6124037273286, "seed": 1837979281, "groupIds": [], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664546888283, + "updated": 1682390374323, "link": null, "locked": false, "startBinding": { @@ -1415,15 +427,15 @@ 0 ], [ - 0.7819181801259845, - -198.24054861171592 + 0.0808345908460808, + -176.6124037273286 ] ] }, { "type": "rectangle", - "version": 2027, - "versionNonce": 1212474705, + "version": 2079, + "versionNonce": 1932225986, "isDeleted": false, "id": "_-BKWrSu7p3gamORvlowF", "fillStyle": "cross-hatch", @@ -1432,8 +444,8 @@ "roughness": 2, "opacity": 100, "angle": 0, - "x": -39.193306977127804, - "y": 136.27210267117488, + "x": -38.60811286654416, + "y": 114.64395778678755, "strokeColor": "#000000", "backgroundColor": "#ced4da", "width": 542, @@ -1442,7 +454,7 @@ "groupIds": [ "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "type": "text", @@ -1457,14 +469,14 @@ "type": "arrow" } ], - "updated": 1664546888286, + "updated": 1682390374322, "link": null, "locked": false }, { "type": "text", - "version": 2579, - "versionNonce": 1994626111, + "version": 2633, + "versionNonce": 1129206575, "isDeleted": false, "id": "8r7_rZGi0MKvtcC2DrjNA", "fillStyle": "solid", @@ -1473,34 +485,35 @@ "roughness": 2, "opacity": 100, "angle": 0, - "x": 36.806693022872196, - "y": 141.27210267117488, + "x": 38.51688713345584, + "y": 119.64395778678755, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 390, + "width": 387.75, "height": 72, "seed": 583060785, "groupIds": [ "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1683235809305, "link": null, "locked": false, "fontSize": 60.163616257419534, "fontFamily": 3, "text": "app clients", - "baseline": 58, "textAlign": "center", "verticalAlign": "top", "containerId": "_-BKWrSu7p3gamORvlowF", - "originalText": "app clients" + "originalText": "app clients", + "lineHeight": 1.1967365740107214, + "baseline": 58 }, { "type": "rectangle", - "version": 4113, - "versionNonce": 167646001, + "version": 4165, + "versionNonce": 1356358978, "isDeleted": false, "id": "ESnUKVgDaXsKkWE3zAW7H", "fillStyle": "solid", @@ -1509,8 +522,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 84.63663329145731, - "y": 238.66306243787574, + "x": 85.22182740204096, + "y": 217.0349175534884, "strokeColor": "#000000", "backgroundColor": "#eaeafa", "width": 87.85825103183927, @@ -1521,16 +534,16 @@ "FPhas0gBc4s_HVOEg2MrJ", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "rectangle", - "version": 3519, - "versionNonce": 721728607, + "version": 3571, + "versionNonce": 322766814, "isDeleted": false, "id": "pUscOls9kEohQdM1IZ8uZ", "fillStyle": "solid", @@ -1539,8 +552,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 123.97379029770661, - "y": 253.14558565426694, + "x": 124.55898440829026, + "y": 231.5174407698796, "strokeColor": "#000000", "backgroundColor": "#fff", "width": 58.3359375, @@ -1551,16 +564,16 @@ "FPhas0gBc4s_HVOEg2MrJ", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "text", - "version": 2624, - "versionNonce": 2081850641, + "version": 2678, + "versionNonce": 500628289, "isDeleted": false, "id": "u7mJMpi8DHWwSgzpefRI0", "fillStyle": "solid", @@ -1569,11 +582,11 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 133.26429961791962, - "y": 257.5675375676361, + "x": 133.84949372850326, + "y": 235.9393926832488, "strokeColor": "#000000", "backgroundColor": "#c5bcdd", - "width": 40, + "width": 38.09999084472656, "height": 25, "seed": 2065883327, "groupIds": [ @@ -1581,24 +594,25 @@ "FPhas0gBc4s_HVOEg2MrJ", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1683235809305, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, "text": "VUE", - "baseline": 18, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "VUE" + "originalText": "VUE", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "line", - "version": 2569, - "versionNonce": 1514983551, + "version": 2621, + "versionNonce": 1145855006, "isDeleted": false, "id": "o67sbkREmRktODZjahRdX", "fillStyle": "solid", @@ -1607,8 +621,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 99.42708175513837, - "y": 302.0463369163764, + "x": 100.01227586572202, + "y": 280.41819203198907, "strokeColor": "#000", "backgroundColor": "#41b883", "width": 57.726740684381255, @@ -1620,9 +634,9 @@ "FPhas0gBc4s_HVOEg2MrJ", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1682390374323, "link": null, "locked": false, "startBinding": null, @@ -1651,8 +665,8 @@ }, { "type": "line", - "version": 2941, - "versionNonce": 1510324977, + "version": 2993, + "versionNonce": 978156738, "isDeleted": false, "id": "IziU7uuKUzp-EmONcYom-", "fillStyle": "solid", @@ -1661,8 +675,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 110.23343345148953, - "y": 302.6154183949085, + "x": 110.81862756207317, + "y": 280.98727351052116, "strokeColor": "#000", "backgroundColor": "#34485e", "width": 36.97684919225588, @@ -1674,9 +688,9 @@ "FPhas0gBc4s_HVOEg2MrJ", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1682390374323, "link": null, "locked": false, "startBinding": null, @@ -1705,8 +719,8 @@ }, { "type": "line", - "version": 4081, - "versionNonce": 2122082463, + "version": 4133, + "versionNonce": 2028415070, "isDeleted": false, "id": "PWahcUHKty0CbsTUlK73i", "fillStyle": "solid", @@ -1715,8 +729,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 117.4538822427902, - "y": 298.8863703945889, + "x": 118.03907635337384, + "y": 277.25822551020156, "strokeColor": "#ff00", "backgroundColor": "#eaeafa", "width": 21.971236623429228, @@ -1728,9 +742,9 @@ "FPhas0gBc4s_HVOEg2MrJ", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1682390374323, "link": null, "locked": false, "startBinding": null, @@ -1759,8 +773,8 @@ }, { "type": "line", - "version": 2419, - "versionNonce": 72561873, + "version": 2471, + "versionNonce": 1254397058, "isDeleted": false, "id": "EJHLJm7hnutgI4gXi20Zf", "fillStyle": "solid", @@ -1769,8 +783,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 116.89703712605808, - "y": 300.0522158293119, + "x": 117.48223123664172, + "y": 278.42407094492455, "strokeColor": "#000", "backgroundColor": "#edf2f9", "width": 21.2946266891332, @@ -1782,9 +796,9 @@ "FPhas0gBc4s_HVOEg2MrJ", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1682390374323, "link": null, "locked": false, "startBinding": null, @@ -1809,8 +823,8 @@ }, { "type": "text", - "version": 1784, - "versionNonce": 88341695, + "version": 1838, + "versionNonce": 194647375, "isDeleted": false, "id": "EvaoyoFLkdnLOpvUx20CK", "fillStyle": "solid", @@ -1819,35 +833,36 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 112.64064555263701, - "y": 366.5582439599842, + "x": 113.22583966322065, + "y": 344.9300990755969, "strokeColor": "#000", "backgroundColor": "#edf2f9", - "width": 35, + "width": 32.63996887207031, "height": 25, "seed": 1006016113, "groupIds": [ "FPhas0gBc4s_HVOEg2MrJ", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1683235809305, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, "text": "Vue", - "baseline": 18, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "Vue" + "originalText": "Vue", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "text", - "version": 2231, - "versionNonce": 1586918065, + "version": 2285, + "versionNonce": 582478625, "isDeleted": false, "id": "VdHeC0OvW_97WbhXDcgej", "fillStyle": "solid", @@ -1856,35 +871,36 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 7.252637980973532, - "y": 361.40719851148924, + "x": 7.837832091557175, + "y": 339.7790536271019, "strokeColor": "#000", "backgroundColor": "#edf2f9", - "width": 61, + "width": 59.179962158203125, "height": 25, "seed": 1401331007, "groupIds": [ "KVisCmg1GFZmWL8P4Tbhv", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1683235809305, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, "text": "React", - "baseline": 18, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "React" + "originalText": "React", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "rectangle", - "version": 4218, - "versionNonce": 1380191455, + "version": 4270, + "versionNonce": 165882078, "isDeleted": false, "id": "xK0foML1IrEFExHM1eyNF", "fillStyle": "solid", @@ -1893,8 +909,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": -11.73163271087219, - "y": 235.4807745530377, + "x": -11.146438600288548, + "y": 213.85262966865037, "strokeColor": "#000000", "backgroundColor": "#454c5a", "width": 87.85825103183927, @@ -1906,16 +922,16 @@ "KVisCmg1GFZmWL8P4Tbhv", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "rectangle", - "version": 3734, - "versionNonce": 1836512401, + "version": 3786, + "versionNonce": 1474747394, "isDeleted": false, "id": "EF1lYZJZMcVxUveR5ehgU", "fillStyle": "solid", @@ -1924,8 +940,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 13.167564417711901, - "y": 249.9632977694289, + "x": 13.752758528295544, + "y": 228.33515288504157, "strokeColor": "#000000", "backgroundColor": "#fff", "width": 72.77605438232425, @@ -1937,16 +953,16 @@ "KVisCmg1GFZmWL8P4Tbhv", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "text", - "version": 2881, - "versionNonce": 17635583, + "version": 2935, + "versionNonce": 1969787759, "isDeleted": false, "id": "yriaCvOKBCs7SYSop1qw7", "fillStyle": "solid", @@ -1955,11 +971,11 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 22.812892051747667, - "y": 252.86766681832682, + "x": 23.39808616233131, + "y": 231.2395219339395, "strokeColor": "#000000", "backgroundColor": "#fff", - "width": 61, + "width": 59.179962158203125, "height": 25, "seed": 1080798225, "groupIds": [ @@ -1968,24 +984,25 @@ "KVisCmg1GFZmWL8P4Tbhv", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1683235809305, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, "text": "React", - "baseline": 18, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "React" + "originalText": "React", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "ellipse", - "version": 2152, - "versionNonce": 883702385, + "version": 2204, + "versionNonce": 74451906, "isDeleted": false, "id": "RG75y65RDKd7nkmoCWblm", "fillStyle": "solid", @@ -1994,8 +1011,8 @@ "roughness": 1, "opacity": 100, "angle": 1.566715780553067, - "x": 26.14479844975108, - "y": 294.1658148819017, + "x": 26.729992560334722, + "y": 272.5376699975144, "strokeColor": "#00bbd4", "backgroundColor": "#ff00", "width": 16.325228482441457, @@ -2007,16 +1024,16 @@ "KVisCmg1GFZmWL8P4Tbhv", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "ellipse", - "version": 2269, - "versionNonce": 1730126111, + "version": 2321, + "versionNonce": 1127811422, "isDeleted": false, "id": "QOdPzB1fnoj2aI7pOaSS1", "fillStyle": "solid", @@ -2025,8 +1042,8 @@ "roughness": 1, "opacity": 100, "angle": 0.5133050667589325, - "x": 25.433164767982362, - "y": 294.1443220949345, + "x": 26.018358878566005, + "y": 272.5161772105472, "strokeColor": "#00bbd4", "backgroundColor": "#ff00", "width": 16.325228482441457, @@ -2038,16 +1055,16 @@ "KVisCmg1GFZmWL8P4Tbhv", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "ellipse", - "version": 2292, - "versionNonce": 1425917009, + "version": 2344, + "versionNonce": 1874674562, "isDeleted": false, "id": "pn2OiIwDX9FleezNOHBbp", "fillStyle": "solid", @@ -2056,8 +1073,8 @@ "roughness": 1, "opacity": 100, "angle": 2.5193659458493443, - "x": 26.189461892294048, - "y": 294.23276664064633, + "x": 26.77465600287769, + "y": 272.604621756259, "strokeColor": "#00bbd4", "backgroundColor": "#ff00", "width": 16.325228482441457, @@ -2069,16 +1086,16 @@ "KVisCmg1GFZmWL8P4Tbhv", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "ellipse", - "version": 1789, - "versionNonce": 1441539391, + "version": 1841, + "versionNonce": 1749822878, "isDeleted": false, "id": "bq4quacnLwxfn65nEnlIf", "fillStyle": "solid", @@ -2087,8 +1104,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 31.86330776959835, - "y": 318.1363114315718, + "x": 32.44850188018199, + "y": 296.5081665471845, "strokeColor": "#00bbd4", "backgroundColor": "#00bbd4", "width": 3.8855987810294716, @@ -2100,16 +1117,16 @@ "KVisCmg1GFZmWL8P4Tbhv", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "text", - "version": 2288, - "versionNonce": 1782780465, + "version": 2342, + "versionNonce": 1638915841, "isDeleted": false, "id": "QKST9zA7BOBmctPW3qu7Z", "fillStyle": "solid", @@ -2118,35 +1135,36 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 289.10158140727606, - "y": 362.5964956957989, + "x": 289.6867755178597, + "y": 340.9683508114116, "strokeColor": "#000", "backgroundColor": "#edf2f9", - "width": 72, + "width": 70.23992919921875, "height": 25, "seed": 227470257, "groupIds": [ "ciMTMixWnwvt0JakDJmyq", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888286, + "updated": 1683235809305, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, "text": "Flutter", - "baseline": 18, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "Flutter" + "originalText": "Flutter", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "rectangle", - "version": 4274, - "versionNonce": 483599711, + "version": 4326, + "versionNonce": 2146486750, "isDeleted": false, "id": "z8S9OTLJ8tCw4f2D3u9OD", "fillStyle": "solid", @@ -2155,8 +1173,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 276.6082110391277, - "y": 237.01283153539475, + "x": 277.19340514971134, + "y": 215.38468665100743, "strokeColor": "#000000", "backgroundColor": "#edf2f9", "width": 87.85825103183927, @@ -2168,21 +1186,21 @@ "ciMTMixWnwvt0JakDJmyq", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "qT3ZXcKZMAQ2PIdL4Jn_V", "type": "arrow" } ], - "updated": 1664546888286, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "rectangle", - "version": 3826, - "versionNonce": 694395921, + "version": 3878, + "versionNonce": 1270860546, "isDeleted": false, "id": "fWEGOCgoor-pCn8fKbzdf", "fillStyle": "solid", @@ -2191,8 +1209,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 292.2746863370427, - "y": 251.49535475178595, + "x": 292.8598804476263, + "y": 229.86720986739863, "strokeColor": "#000000", "backgroundColor": "#fff", "width": 82.00877621299335, @@ -2204,16 +1222,16 @@ "ciMTMixWnwvt0JakDJmyq", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "text", - "version": 2982, - "versionNonce": 1260724607, + "version": 3036, + "versionNonce": 956452239, "isDeleted": false, "id": "dCdRkC8-C_Zz6j2PTt3m_", "fillStyle": "solid", @@ -2222,11 +1240,11 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 298.01788183638985, - "y": 254.78246141215345, + "x": 298.6030759469735, + "y": 233.15431652776613, "strokeColor": "#000000", "backgroundColor": "#fff", - "width": 72, + "width": 70.23992919921875, "height": 25, "seed": 1806290943, "groupIds": [ @@ -2235,24 +1253,25 @@ "ciMTMixWnwvt0JakDJmyq", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1683235809306, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, "text": "Flutter", - "baseline": 18, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "Flutter" + "originalText": "Flutter", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "line", - "version": 2839, - "versionNonce": 1045887473, + "version": 2891, + "versionNonce": 223550146, "isDeleted": false, "id": "owZ8K-S1kTyufhR-jLISn", "fillStyle": "solid", @@ -2261,8 +1280,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 323.98098245620406, - "y": 302.68670176249816, + "x": 324.5661765667877, + "y": 281.05855687811083, "strokeColor": "#44d1fd", "backgroundColor": "#44d1fd", "width": 33.32480821095047, @@ -2274,9 +1293,9 @@ "ciMTMixWnwvt0JakDJmyq", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false, "startBinding": null, @@ -2309,8 +1328,8 @@ }, { "type": "line", - "version": 2257, - "versionNonce": 841128351, + "version": 2309, + "versionNonce": 2031250014, "isDeleted": false, "id": "Hc9WMem3QVIK-5-AUg8qc", "fillStyle": "solid", @@ -2319,8 +1338,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 311.93647432667365, - "y": 333.9337353949004, + "x": 312.5216684372573, + "y": 312.30559051051307, "strokeColor": "#065a9d", "backgroundColor": "#065a9d", "width": 24.06937282447777, @@ -2332,9 +1351,9 @@ "ciMTMixWnwvt0JakDJmyq", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false, "startBinding": null, @@ -2367,8 +1386,8 @@ }, { "type": "line", - "version": 2262, - "versionNonce": 1780782033, + "version": 2314, + "versionNonce": 661025410, "isDeleted": false, "id": "h3tL87Z7EvuLMED-MQTiM", "fillStyle": "solid", @@ -2377,8 +1396,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 312.0710066803389, - "y": 333.5908571141679, + "x": 312.6562007909225, + "y": 311.96271222978055, "strokeColor": "#41d0fd", "backgroundColor": "#41d0fd", "width": 24.495086769147004, @@ -2390,9 +1409,9 @@ "ciMTMixWnwvt0JakDJmyq", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false, "startBinding": null, @@ -2425,8 +1444,8 @@ }, { "type": "text", - "version": 1945, - "versionNonce": 654052799, + "version": 1999, + "versionNonce": 155080417, "isDeleted": false, "id": "QAjYW3mBlpmVneZe3EXdK", "fillStyle": "solid", @@ -2435,40 +1454,41 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 202.46712165876977, - "y": 362.4067319800322, + "x": 203.0523157693534, + "y": 340.77858709564487, "strokeColor": "#000", "backgroundColor": "#fbbd9b", - "width": 41, + "width": 38.5999755859375, "height": 25, "seed": 270565073, "groupIds": [ "LNvdY8TFeQxuY1KgXMRCr", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "qT3ZXcKZMAQ2PIdL4Jn_V", "type": "arrow" } ], - "updated": 1664546888287, + "updated": 1683235809306, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, "text": "APK", - "baseline": 18, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "APK" + "originalText": "APK", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "rectangle", - "version": 3924, - "versionNonce": 1625551281, + "version": 3976, + "versionNonce": 1168501470, "isDeleted": false, "id": "TYD9JErqDImy8gkbx2MXG", "fillStyle": "solid", @@ -2477,8 +1497,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 179.62651364647297, - "y": 236.75467858449747, + "x": 180.21170775705662, + "y": 215.12653370011014, "strokeColor": "#000000", "backgroundColor": "#f48284", "width": 87.85825103183927, @@ -2489,16 +1509,16 @@ "LNvdY8TFeQxuY1KgXMRCr", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "rectangle", - "version": 3401, - "versionNonce": 80870879, + "version": 3453, + "versionNonce": 1076443650, "isDeleted": false, "id": "fnobSdbsTWzfZbXmg6q0w", "fillStyle": "solid", @@ -2507,8 +1527,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 218.95786827602967, - "y": 251.18947528602587, + "x": 219.54306238661331, + "y": 229.56133040163854, "strokeColor": "#000000", "backgroundColor": "#fff", "width": 58.3359375, @@ -2519,16 +1539,16 @@ "LNvdY8TFeQxuY1KgXMRCr", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "text", - "version": 2509, - "versionNonce": 1740411793, + "version": 2563, + "versionNonce": 1906295727, "isDeleted": false, "id": "hTag8egMzfK5pem0VOe5L", "fillStyle": "solid", @@ -2537,11 +1557,11 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 228.24837759624268, - "y": 255.61142719939505, + "x": 228.83357170682632, + "y": 233.98328231500773, "strokeColor": "#000000", "backgroundColor": "#c5bcdd", - "width": 41, + "width": 38.5999755859375, "height": 25, "seed": 1431151327, "groupIds": [ @@ -2549,24 +1569,25 @@ "LNvdY8TFeQxuY1KgXMRCr", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1683235809306, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, "text": "APK", - "baseline": 18, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "APK" + "originalText": "APK", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "line", - "version": 2066, - "versionNonce": 1857350143, + "version": 2118, + "versionNonce": 817277378, "isDeleted": false, "id": "JUgQd_KcJA2Qic5Fnr4Wi", "fillStyle": "solid", @@ -2575,8 +1596,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 200.36584607650582, - "y": 301.25791199426055, + "x": 200.95104018708946, + "y": 279.6297671098732, "strokeColor": "#000", "backgroundColor": "#aed796", "width": 7.5923919677734375, @@ -2588,9 +1609,9 @@ "LNvdY8TFeQxuY1KgXMRCr", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false, "startBinding": null, @@ -2611,8 +1632,8 @@ }, { "type": "line", - "version": 2088, - "versionNonce": 853932401, + "version": 2140, + "versionNonce": 1521699678, "isDeleted": false, "id": "Z_zY2SOwkwrHDtX0GXRSl", "fillStyle": "solid", @@ -2621,8 +1642,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 245.2735708851793, - "y": 310.36165393201475, + "x": 245.85876499576295, + "y": 288.7335090476274, "strokeColor": "#000", "backgroundColor": "#aed796", "width": 6.975860595703125, @@ -2634,9 +1655,9 @@ "LNvdY8TFeQxuY1KgXMRCr", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false, "startBinding": null, @@ -2657,8 +1678,8 @@ }, { "type": "line", - "version": 2487, - "versionNonce": 1369788959, + "version": 2539, + "versionNonce": 1434460546, "isDeleted": false, "id": "zux3sNR05IS-4S3hGDeo4", "fillStyle": "solid", @@ -2667,8 +1688,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 197.47642820746012, - "y": 335.8807088181071, + "x": 198.06162231804376, + "y": 314.2525639337198, "strokeColor": "#000", "backgroundColor": "#aed796", "width": 58.24350785235947, @@ -2680,9 +1701,11 @@ "LNvdY8TFeQxuY1KgXMRCr", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false, "startBinding": null, @@ -2759,8 +1782,8 @@ }, { "type": "ellipse", - "version": 2210, - "versionNonce": 61317969, + "version": 2262, + "versionNonce": 1529753502, "isDeleted": false, "id": "ayMFRUCfykbQYWa1T7lMw", "fillStyle": "solid", @@ -2769,8 +1792,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 211.20289731240598, - "y": 317.34381344926396, + "x": 211.78809142298962, + "y": 295.71566856487664, "strokeColor": "#000", "backgroundColor": "#aed796", "width": 3.3739471435546875, @@ -2782,16 +1805,16 @@ "LNvdY8TFeQxuY1KgXMRCr", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "ellipse", - "version": 2332, - "versionNonce": 647214655, + "version": 2384, + "versionNonce": 1506058562, "isDeleted": false, "id": "s0xVIfGqHVL9RheEufZWL", "fillStyle": "solid", @@ -2800,8 +1823,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 234.7368363625743, - "y": 317.5692231321801, + "x": 235.32203047315795, + "y": 295.9410782477928, "strokeColor": "#000", "backgroundColor": "#aed796", "width": 3.3739471435546875, @@ -2813,16 +1836,16 @@ "LNvdY8TFeQxuY1KgXMRCr", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "text", - "version": 2280, - "versionNonce": 106500401, + "version": 2334, + "versionNonce": 1274204865, "isDeleted": false, "id": "dPNePcQpFV_yl4boehg50", "fillStyle": "solid", @@ -2831,35 +1854,36 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 403.407463934636, - "y": 365.60348978548564, + "x": 403.9926580452196, + "y": 343.9753449010983, "strokeColor": "#000", "backgroundColor": "#edf2f9", - "width": 52, + "width": 49.73994445800781, "height": 25, "seed": 1792558527, "groupIds": [ "I8XWYTUn08wlcXvEs72sE", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1683235809306, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, "text": "Swift", - "baseline": 18, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "Swift" + "originalText": "Swift", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "rectangle", - "version": 4228, - "versionNonce": 1952487007, + "version": 4280, + "versionNonce": 685975810, "isDeleted": false, "id": "jCrB9HQo1TYbql4MMUnNF", "fillStyle": "solid", @@ -2868,8 +1892,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 380.9441485391304, - "y": 239.04489994571077, + "x": 381.52934264971407, + "y": 217.41675506132344, "strokeColor": "#000000", "backgroundColor": "#868e96", "width": 87.85825103183927, @@ -2881,16 +1905,16 @@ "I8XWYTUn08wlcXvEs72sE", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "rectangle", - "version": 3751, - "versionNonce": 1885455121, + "version": 3803, + "versionNonce": 687955998, "isDeleted": false, "id": "BpiYgnpWqpgMEKezddORB", "fillStyle": "solid", @@ -2899,8 +1923,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 415.08839419066373, - "y": 253.52742316210197, + "x": 415.6735883012474, + "y": 231.89927827771464, "strokeColor": "#000000", "backgroundColor": "#fff", "width": 63.53100585937503, @@ -2912,16 +1936,16 @@ "I8XWYTUn08wlcXvEs72sE", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "text", - "version": 2885, - "versionNonce": 299659903, + "version": 2939, + "versionNonce": 1063876047, "isDeleted": false, "id": "qW2ZcISUytR3-bOm5nrLS", "fillStyle": "solid", @@ -2930,11 +1954,11 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 423.1901198349534, - "y": 257.03979773468154, + "x": 423.77531394553705, + "y": 235.41165285029422, "strokeColor": "#000000", "backgroundColor": "#fff", - "width": 52, + "width": 49.73994445800781, "height": 25, "seed": 355916689, "groupIds": [ @@ -2943,24 +1967,25 @@ "I8XWYTUn08wlcXvEs72sE", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1683235809306, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, "text": "Swift", - "baseline": 18, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "Swift" + "originalText": "Swift", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "rectangle", - "version": 1398, - "versionNonce": 1580808433, + "version": 1450, + "versionNonce": 140225630, "isDeleted": false, "id": "br53QokYDJxLRUsjPhCwy", "fillStyle": "solid", @@ -2969,8 +1994,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 401.9401034286399, - "y": 298.29111147776825, + "x": 402.5252975392235, + "y": 276.66296659338093, "strokeColor": "#ef5139", "backgroundColor": "#ef5139", "width": 48.496691645408184, @@ -2982,16 +2007,18 @@ "I8XWYTUn08wlcXvEs72sE", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "round", + "roundness": { + "type": 1 + }, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false }, { "type": "line", - "version": 1468, - "versionNonce": 667404959, + "version": 1520, + "versionNonce": 2110410882, "isDeleted": false, "id": "p8w32VzdSrLF86ACDRXp8", "fillStyle": "solid", @@ -3000,8 +2027,8 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 432.16572596611616, - "y": 322.0919307445047, + "x": 432.7509200766998, + "y": 300.46378586011735, "strokeColor": "#fff", "backgroundColor": "#fff", "width": 37.039122762559145, @@ -3013,9 +2040,11 @@ "I8XWYTUn08wlcXvEs72sE", "JbFUCMpOHEHN3NyvSrPdT" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1664546888287, + "updated": 1682390374323, "link": null, "locked": false, "startBinding": null, @@ -3188,8 +2217,8 @@ }, { "type": "rectangle", - "version": 1881, - "versionNonce": 666005169, + "version": 1885, + "versionNonce": 1405645790, "isDeleted": false, "id": "sFE8hJbB0-zakUa7U66ZI", "fillStyle": "solid", @@ -3206,25 +2235,27 @@ "height": 148, "seed": 1526121535, "groupIds": [], - "strokeSharpness": "round", + "roundness": { + "type": 1 + }, "boundElements": [ { "type": "text", "id": "rLnghxDF0hu3jeUQUOcjY" }, { - "id": "AzJlXlpiAOpjWfG6hCefX", + "id": "IXGLaKwvNWM7iA7SwPJbz", "type": "arrow" } ], - "updated": 1664546888287, + "updated": 1682390356102, "link": null, "locked": false }, { "type": "text", - "version": 1823, - "versionNonce": 905302239, + "version": 1825, + "versionNonce": 1584190113, "isDeleted": false, "id": "rLnghxDF0hu3jeUQUOcjY", "fillStyle": "solid", @@ -3233,27 +2264,28 @@ "roughness": 2, "opacity": 100, "angle": 0, - "x": -20.383601408884147, + "x": -19.308406096384147, "y": -301.25387612021854, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 462, + "width": 459.849609375, "height": 73, "seed": 1168708113, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888287, + "updated": 1683235809306, "link": null, "locked": false, "fontSize": 60.37149825737669, "fontFamily": 3, "text": "app resources", - "baseline": 59, "textAlign": "center", "verticalAlign": "middle", "containerId": "sFE8hJbB0-zakUa7U66ZI", - "originalText": "app resources" + "originalText": "app resources", + "lineHeight": 1.2091798631331838, + "baseline": 58 }, { "type": "freedraw", @@ -3278,7 +2310,9 @@ "HEAUma5p3ll4isR0VQ7cr", "eSa1mG-tgsa-M-bEVkGgd" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], "updated": 1668084793565, "link": null, @@ -4451,7 +3485,7 @@ "groupIds": [ "eSa1mG-tgsa-M-bEVkGgd" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1668084793565, "link": null, @@ -4519,7 +3553,7 @@ "gXTOyhHtXV0fwkdOzla3X", "eSa1mG-tgsa-M-bEVkGgd" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1668084793565, "link": null, @@ -4576,7 +3610,7 @@ "gXTOyhHtXV0fwkdOzla3X", "eSa1mG-tgsa-M-bEVkGgd" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1668084793565, "link": null, @@ -4633,7 +3667,7 @@ "gXTOyhHtXV0fwkdOzla3X", "eSa1mG-tgsa-M-bEVkGgd" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1668084793565, "link": null, @@ -4678,7 +3712,7 @@ "gXTOyhHtXV0fwkdOzla3X", "eSa1mG-tgsa-M-bEVkGgd" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1668084793565, "link": null, @@ -4701,8 +3735,8 @@ }, { "type": "text", - "version": 1222, - "versionNonce": 252418873, + "version": 1224, + "versionNonce": 695722991, "isDeleted": false, "id": "7NdHRosUGfJjhS_0gpsIg", "fillStyle": "solid", @@ -4715,25 +3749,26 @@ "y": -152.70454893413927, "strokeColor": "#000000", "backgroundColor": "#552f99", - "width": 82, + "width": 80.44355773925781, "height": 41, "seed": 813810897, "groupIds": [ "eSa1mG-tgsa-M-bEVkGgd" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1668084793565, + "updated": 1683235809307, "link": null, "locked": false, "fontSize": 16.602151713597063, "fontFamily": 1, "text": "Container\nInstances", - "baseline": 35, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "Container\nInstances" + "originalText": "Container\nInstances", + "lineHeight": 1.2347797052842628, + "baseline": 35 }, { "type": "line", @@ -4758,7 +3793,9 @@ "NMLUUP8IftNJb1tb79wga", "nBc0YIskB39Ba9lzkDVrG" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], "updated": 1668084797457, "link": null, @@ -4866,7 +3903,7 @@ "NMLUUP8IftNJb1tb79wga", "nBc0YIskB39Ba9lzkDVrG" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1668084797457, "link": null, @@ -4874,8 +3911,8 @@ }, { "type": "text", - "version": 806, - "versionNonce": 21604697, + "version": 808, + "versionNonce": 895211137, "isDeleted": false, "id": "P7nq8xZ3Gz4YhJ0jN-Y46", "fillStyle": "hachure", @@ -4884,30 +3921,31 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 54.344421562151396, + "x": 55.49485796351858, "y": -122.80685829283304, "strokeColor": "#000000", "backgroundColor": "#228be6", - "width": 73, + "width": 70.69912719726562, "height": 18, "seed": 1375689055, "groupIds": [ "tmJTxLP-C9tFCk2RYxENl", "nBc0YIskB39Ba9lzkDVrG" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1668084797457, + "updated": 1683235809307, "link": null, "locked": false, "fontSize": 14.301911527166304, "fontFamily": 1, "text": "Database", - "baseline": 13, "textAlign": "center", "verticalAlign": "top", "containerId": null, - "originalText": "Database" + "originalText": "Database", + "lineHeight": 1.2585730212223185, + "baseline": 13 }, { "type": "rectangle", @@ -4932,7 +3970,7 @@ "c61pafqq2DoyaQk7S7rdQ", "dRHiZS_p9blXC3Ng6hQG8" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1668084772978, "link": null, @@ -4961,7 +3999,7 @@ "c61pafqq2DoyaQk7S7rdQ", "dRHiZS_p9blXC3Ng6hQG8" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1668084772978, "link": null, @@ -4969,8 +4007,8 @@ }, { "type": "text", - "version": 2382, - "versionNonce": 1505854425, + "version": 2384, + "versionNonce": 1070829071, "isDeleted": false, "id": "BjtrAhl09kN7oKEBaL6bn", "fillStyle": "solid", @@ -4983,31 +4021,32 @@ "y": -197.48072848360022, "strokeColor": "#000000", "backgroundColor": "#fff", - "width": 59, - "height": 14, + "width": 56.532501220703125, + "height": 13.999999999999998, "seed": 759863167, "groupIds": [ "c61pafqq2DoyaQk7S7rdQ", "dRHiZS_p9blXC3Ng6hQG8" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1668084772978, + "updated": 1683235809307, "link": null, "locked": false, "fontSize": 11.026657954006614, "fontFamily": 1, "text": "TypeScript", - "baseline": 10, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "TypeScript" + "originalText": "TypeScript", + "lineHeight": 1.2696503381528217, + "baseline": 10 }, { "type": "text", - "version": 2452, - "versionNonce": 1072431671, + "version": 2454, + "versionNonce": 58678881, "isDeleted": false, "id": "n5-vmTGQWUd_p9usIdRUn", "fillStyle": "solid", @@ -5020,31 +4059,32 @@ "y": -165.65083540033294, "strokeColor": "#fff", "backgroundColor": "#fff", - "width": 37, - "height": 32, + "width": 35.01759338378906, + "height": 31.999999999999996, "seed": 334226417, "groupIds": [ "c61pafqq2DoyaQk7S7rdQ", "dRHiZS_p9blXC3Ng6hQG8" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1668084772978, + "updated": 1683235809307, "link": null, "locked": false, "fontSize": 24.80998039651488, "fontFamily": 1, "text": "TS", - "baseline": 22, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "TS" + "originalText": "TS", + "lineHeight": 1.2898035181235015, + "baseline": 22 }, { "type": "text", - "version": 1781, - "versionNonce": 108372153, + "version": 1783, + "versionNonce": 2104816687, "isDeleted": false, "id": "PcsOmu30L_rud3Fnl4PTt", "fillStyle": "solid", @@ -5057,30 +4097,31 @@ "y": -121.44556646430952, "strokeColor": "#000", "backgroundColor": "#edf2f9", - "width": 73, + "width": 70.69134521484375, "height": 17, "seed": 1546211231, "groupIds": [ "dRHiZS_p9blXC3Ng6hQG8" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1668084772978, + "updated": 1683235809307, "link": null, "locked": false, "fontSize": 13.783322442508265, "fontFamily": 1, "text": "TypeScript", - "baseline": 12, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "TypeScript" + "originalText": "TypeScript", + "lineHeight": 1.2333746142055986, + "baseline": 12 }, { "type": "text", - "version": 1374, - "versionNonce": 1249681305, + "version": 1376, + "versionNonce": 2007427649, "isDeleted": false, "id": "mLuZ7f1DeaNzeP_Sh9kqz", "fillStyle": "solid", @@ -5093,25 +4134,28 @@ "y": -122.65910574530965, "strokeColor": "#000", "backgroundColor": "#fff", - "width": 61, + "width": 59.357696533203125, "height": 19, "seed": 466522577, "groupIds": [ "R4x12rk5t_zG4oOuD4tXV" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], - "updated": 1668084795932, + "updated": 1683235809307, "link": null, "locked": false, "fontSize": 15.332661163750746, "fontFamily": 1, "text": "Storage", - "baseline": 14, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "Storage" + "originalText": "Storage", + "lineHeight": 1.2391847571065826, + "baseline": 13 }, { "type": "rectangle", @@ -5136,7 +4180,7 @@ "IlnJLkvE8VOzsRJoGaPA_", "R4x12rk5t_zG4oOuD4tXV" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1668084795932, "link": null, @@ -5165,7 +4209,7 @@ "IlnJLkvE8VOzsRJoGaPA_", "R4x12rk5t_zG4oOuD4tXV" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1668084795932, "link": null, @@ -5173,8 +4217,8 @@ }, { "type": "text", - "version": 1874, - "versionNonce": 1585978263, + "version": 1876, + "versionNonce": 1782879823, "isDeleted": false, "id": "kiyKl8-8fMrcRFeTjU3S6", "fillStyle": "solid", @@ -5187,26 +4231,27 @@ "y": -207.7552445122546, "strokeColor": "#000000", "backgroundColor": "#c5bcdd", - "width": 35, + "width": 32.95948791503906, "height": 19, "seed": 2070061023, "groupIds": [ "IlnJLkvE8VOzsRJoGaPA_", "R4x12rk5t_zG4oOuD4tXV" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1668084795932, + "updated": 1683235809307, "link": null, "locked": false, "fontSize": 15.332661163750746, "fontFamily": 1, "text": "DOC", - "baseline": 14, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "DOC" + "originalText": "DOC", + "lineHeight": 1.2391847571065826, + "baseline": 13 }, { "type": "line", @@ -5232,7 +4277,9 @@ "IlnJLkvE8VOzsRJoGaPA_", "R4x12rk5t_zG4oOuD4tXV" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], "updated": 1668084795932, "link": null, @@ -5277,7 +4324,9 @@ "IlnJLkvE8VOzsRJoGaPA_", "R4x12rk5t_zG4oOuD4tXV" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], "updated": 1668084795932, "link": null, @@ -5322,7 +4371,9 @@ "IlnJLkvE8VOzsRJoGaPA_", "R4x12rk5t_zG4oOuD4tXV" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], "updated": 1668084795932, "link": null, @@ -5367,7 +4418,9 @@ "IlnJLkvE8VOzsRJoGaPA_", "R4x12rk5t_zG4oOuD4tXV" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], "updated": 1668084795932, "link": null, @@ -5390,8 +4443,8 @@ }, { "type": "text", - "version": 2542, - "versionNonce": 537680479, + "version": 2544, + "versionNonce": 984742433, "isDeleted": false, "id": "tNK7h97Dn-OfY07IGfRCr", "fillStyle": "hachure", @@ -5404,30 +4457,31 @@ "y": -99.21244366676899, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 175, + "width": 173.1598663330078, "height": 25, "seed": 1141251455, "groupIds": [ "-sNFEAHViAfchO6_MWFao" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "tBVa_Dx6tqTSgAtdQRH9n", "type": "arrow" } ], - "updated": 1664546888288, + "updated": 1683235809308, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, "text": "Internet gateway", - "baseline": 18, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "Internet gateway" + "originalText": "Internet gateway", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "ellipse", @@ -5452,7 +4506,7 @@ "6FERP11otZouFXGo3kss3", "-sNFEAHViAfchO6_MWFao" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1664546888288, "link": null, @@ -5482,7 +4536,9 @@ "6FERP11otZouFXGo3kss3", "-sNFEAHViAfchO6_MWFao" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], "updated": 1664546888288, "link": null, @@ -5539,7 +4595,9 @@ "6FERP11otZouFXGo3kss3", "-sNFEAHViAfchO6_MWFao" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], "updated": 1664546888288, "link": null, @@ -5596,7 +4654,9 @@ "6FERP11otZouFXGo3kss3", "-sNFEAHViAfchO6_MWFao" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], "updated": 1664546888288, "link": null, @@ -5641,7 +4701,9 @@ "6FERP11otZouFXGo3kss3", "-sNFEAHViAfchO6_MWFao" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], "updated": 1664546888288, "link": null, @@ -5664,8 +4726,8 @@ }, { "type": "rectangle", - "version": 2048, - "versionNonce": 459629247, + "version": 2092, + "versionNonce": 859930434, "isDeleted": false, "id": "wT6zbcxTh2394WWbu094O", "fillStyle": "cross-hatch", @@ -5674,8 +4736,8 @@ "roughness": 2, "opacity": 100, "angle": 0, - "x": 674.2422263047413, - "y": 154.136457137969, + "x": 674.196028669269, + "y": 130.21380563052475, "strokeColor": "#000000", "backgroundColor": "#ced4da", "width": 461, @@ -5684,7 +4746,7 @@ "groupIds": [ "iae2_WmdvEgM8v_reLLV8" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "type": "text", @@ -5695,14 +4757,14 @@ "type": "arrow" } ], - "updated": 1664546888288, + "updated": 1682390388180, "link": null, "locked": false }, { "type": "text", - "version": 2349, - "versionNonce": 1109814449, + "version": 2395, + "versionNonce": 2098918511, "isDeleted": false, "id": "vrCHtx-q8_aRadMYJycWC", "fillStyle": "solid", @@ -5711,34 +4773,35 @@ "roughness": 2, "opacity": 100, "angle": 0, - "x": 705.7422263047413, - "y": 159.136457137969, + "x": 706.889388044269, + "y": 135.21380563052475, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 398, + "width": 395.61328125, "height": 74, "seed": 1623014289, "groupIds": [ "iae2_WmdvEgM8v_reLLV8" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888288, + "updated": 1683235809308, "link": null, "locked": false, "fontSize": 61.38050137320138, "fontFamily": 3, "text": "laf clients", - "baseline": 60, "textAlign": "center", "verticalAlign": "top", "containerId": "wT6zbcxTh2394WWbu094O", - "originalText": "laf clients" + "originalText": "laf clients", + "lineHeight": 1.2055945836947541, + "baseline": 59 }, { "type": "text", - "version": 1807, - "versionNonce": 726184671, + "version": 1853, + "versionNonce": 764415489, "isDeleted": false, "id": "z2pCxegSVApSkkYf7si7k", "fillStyle": "solid", @@ -5747,40 +4810,41 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 786.3662863712673, - "y": 378.0463915604954, + "x": 786.320088735795, + "y": 354.12374005305116, "strokeColor": "#000", "backgroundColor": "transparent", - "width": 56, + "width": 54.39996337890625, "height": 25, "seed": 135864113, "groupIds": [ "5p1vbEZAXknROdLCm6RJJ", "iae2_WmdvEgM8v_reLLV8" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "I-Gae0eQW3HFmaEMCgWe6", "type": "arrow" } ], - "updated": 1664546888288, + "updated": 1683235809308, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, "text": "HTML", - "baseline": 18, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "HTML" + "originalText": "HTML", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "rectangle", - "version": 3504, - "versionNonce": 284667537, + "version": 3548, + "versionNonce": 1892413058, "isDeleted": false, "id": "AQ8qIJz4KhYT6QQzz4K8A", "fillStyle": "solid", @@ -5789,8 +4853,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 768.8422140153214, - "y": 243.56907406355697, + "x": 768.7960163798491, + "y": 219.64642255611273, "strokeColor": "#000000", "backgroundColor": "#ff7353", "width": 87.85825103183927, @@ -5801,16 +4865,16 @@ "5p1vbEZAXknROdLCm6RJJ", "iae2_WmdvEgM8v_reLLV8" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888288, + "updated": 1682390388180, "link": null, "locked": false }, { "type": "rectangle", - "version": 3006, - "versionNonce": 1586298623, + "version": 3050, + "versionNonce": 1158787742, "isDeleted": false, "id": "-jN9gTEn3ms81qV7qCNsg", "fillStyle": "solid", @@ -5819,8 +4883,8 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 795.8540540678966, - "y": 258.05159727994817, + "x": 795.8078564324244, + "y": 234.12894577250393, "strokeColor": "#000000", "backgroundColor": "#fff", "width": 70.66341145833303, @@ -5831,16 +4895,16 @@ "5p1vbEZAXknROdLCm6RJJ", "iae2_WmdvEgM8v_reLLV8" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888288, + "updated": 1682390388180, "link": null, "locked": false }, { "type": "text", - "version": 2206, - "versionNonce": 1543877745, + "version": 2252, + "versionNonce": 1036029583, "isDeleted": false, "id": "wrjV5tISBRetKQmKbKTdA", "fillStyle": "solid", @@ -5849,11 +4913,11 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 804.7549963308168, - "y": 262.85445434468454, + "x": 804.7087986953445, + "y": 238.9318028372403, "strokeColor": "#000000", "backgroundColor": "#c5bcdd", - "width": 56, + "width": 54.39996337890625, "height": 25, "seed": 1487012991, "groupIds": [ @@ -5861,24 +4925,25 @@ "5p1vbEZAXknROdLCm6RJJ", "iae2_WmdvEgM8v_reLLV8" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888288, + "updated": 1683235809308, "link": null, "locked": false, "fontSize": 20, "fontFamily": 1, "text": "HTML", - "baseline": 18, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "HTML" + "originalText": "HTML", + "lineHeight": 1.25, + "baseline": 18 }, { "type": "text", - "version": 1836, - "versionNonce": 397592351, + "version": 1882, + "versionNonce": 1732290017, "isDeleted": false, "id": "Wy7ujfL8of09I5Np59siL", "fillStyle": "solid", @@ -5887,11 +4952,11 @@ "roughness": 0, "opacity": 100, "angle": 0, - "x": 785.1592551212673, - "y": 314.67157466596416, + "x": 785.113057485795, + "y": 290.7489231585199, "strokeColor": "#000", "backgroundColor": "transparent", - "width": 59, + "width": 57.239990234375, "height": 46, "seed": 2110637809, "groupIds": [ @@ -5899,19 +4964,20 @@ "5p1vbEZAXknROdLCm6RJJ", "iae2_WmdvEgM8v_reLLV8" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888288, + "updated": 1683235809308, "link": null, "locked": false, "fontSize": 36, "fontFamily": 1, "text": "", - "baseline": 32, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "" + "originalText": "", + "lineHeight": 1.2777777777777777, + "baseline": 32 }, { "type": "rectangle", @@ -5936,13 +5002,8 @@ "52h6ZYPpEkAfthNpb7iMr", "E5rLiJESzfEqlGFa-rvfQ" ], - "strokeSharpness": "sharp", - "boundElements": [ - { - "type": "arrow", - "id": "9RT6Uw_WUaOTrDl9MY1Gv" - } - ], + "roundness": null, + "boundElements": [], "updated": 1664546888288, "link": null, "locked": false @@ -5970,7 +5031,7 @@ "52h6ZYPpEkAfthNpb7iMr", "E5rLiJESzfEqlGFa-rvfQ" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1664546888288, "link": null, @@ -5999,7 +5060,7 @@ "52h6ZYPpEkAfthNpb7iMr", "E5rLiJESzfEqlGFa-rvfQ" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1664546888288, "link": null, @@ -6043,7 +5104,7 @@ "52h6ZYPpEkAfthNpb7iMr", "E5rLiJESzfEqlGFa-rvfQ" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1664546888288, "link": null, @@ -6087,7 +5148,9 @@ "52h6ZYPpEkAfthNpb7iMr", "E5rLiJESzfEqlGFa-rvfQ" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], "updated": 1664546888288, "link": null, @@ -6135,7 +5198,9 @@ "52h6ZYPpEkAfthNpb7iMr", "E5rLiJESzfEqlGFa-rvfQ" ], - "strokeSharpness": "round", + "roundness": { + "type": 2 + }, "boundElements": [], "updated": 1664546888288, "link": null, @@ -6183,7 +5248,7 @@ "52h6ZYPpEkAfthNpb7iMr", "E5rLiJESzfEqlGFa-rvfQ" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], "updated": 1664546888288, "link": null, @@ -6191,8 +5256,8 @@ }, { "type": "text", - "version": 873, - "versionNonce": 1693630367, + "version": 875, + "versionNonce": 653124783, "isDeleted": false, "id": "jd9JkvH_iBjZmEyY8adrE", "fillStyle": "solid", @@ -6205,94 +5270,26 @@ "y": 276.5847975441686, "strokeColor": "#fff", "backgroundColor": "#40c057", - "width": 65, + "width": 63.28125, "height": 44, "seed": 1090563729, "groupIds": [ "E5rLiJESzfEqlGFa-rvfQ" ], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888288, + "updated": 1683235809309, "link": null, "locked": false, "fontSize": 36, "fontFamily": 3, "text": "cli", - "baseline": 35, "textAlign": "left", "verticalAlign": "top", "containerId": null, - "originalText": "cli" - }, - { - "type": "diamond", - "version": 1132, - "versionNonce": 1113786321, - "isDeleted": false, - "id": "pwFa_JsY4UC6EwKz1z0bE", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 863.1527750386329, - "y": -406.58903058083035, - "strokeColor": "#000000", - "backgroundColor": "#edf2f9", - "width": 132, - "height": 84, - "seed": 1474917169, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [ - { - "type": "text", - "id": "3opB-I7IvrQxx0SlamakC" - }, - { - "id": "kqj5BjInSDGoAuV2NWQC1", - "type": "arrow" - } - ], - "updated": 1664546888289, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 1084, - "versionNonce": 1326373311, - "isDeleted": false, - "id": "3opB-I7IvrQxx0SlamakC", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 2, - "opacity": 100, - "angle": 0, - "x": 896.6527750386329, - "y": -386.58903058083035, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 65, - "height": 44, - "seed": 1304687551, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1664546888289, - "link": null, - "locked": false, - "fontSize": 36, - "fontFamily": 3, - "text": "crd", - "baseline": 35, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "pwFa_JsY4UC6EwKz1z0bE", - "originalText": "crd" + "originalText": "cli", + "lineHeight": 1.2222222222222223, + "baseline": 35 }, { "type": "rectangle", @@ -6314,7 +5311,7 @@ "height": 54, "seed": 562864735, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "type": "text", @@ -6331,8 +5328,8 @@ }, { "type": "text", - "version": 758, - "versionNonce": 1911424913, + "version": 760, + "versionNonce": 1926447553, "isDeleted": false, "id": "YI9lnxxXBeeVSOaQWwyhh", "fillStyle": "solid", @@ -6341,32 +5338,33 @@ "roughness": 2, "opacity": 100, "angle": 0, - "x": 782.5213576279182, + "x": 783.5057326279182, "y": -187.4774234379728, "strokeColor": "#000000", "backgroundColor": "#edf2f9", - "width": 234, + "width": 232.03125, "height": 44, "seed": 628287743, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888289, + "updated": 1683235809309, "link": null, "locked": false, "fontSize": 36, "fontFamily": 3, "text": "tenant auth", - "baseline": 35, "textAlign": "center", "verticalAlign": "middle", "containerId": "bDbiIjoiWoEF_-QIL1pl6", - "originalText": "tenant auth" + "originalText": "tenant auth", + "lineHeight": 1.2222222222222223, + "baseline": 35 }, { "type": "rectangle", - "version": 1157, - "versionNonce": 1904522751, + "version": 1176, + "versionNonce": 861191042, "isDeleted": false, "id": "94pL6u1LZ9bj5i7fV9faW", "fillStyle": "solid", @@ -6375,29 +5373,29 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 146.63491789577586, - "y": 83.46286674059866, + "x": 147.6204433912486, + "y": 75.70166398126094, "strokeColor": "#000000", "backgroundColor": "#edf2f9", "width": 70, "height": 34, "seed": 1660914559, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "type": "text", "id": "z4XZS_B7IC5Hcbq32LNOh" } ], - "updated": 1664546888289, + "updated": 1682390376840, "link": null, "locked": false }, { "type": "rectangle", - "version": 1092, - "versionNonce": 1590226289, + "version": 1142, + "versionNonce": 304143326, "isDeleted": false, "id": "NII3JqUhpr9hNElI5QR0U", "fillStyle": "solid", @@ -6406,33 +5404,29 @@ "roughness": 2, "opacity": 100, "angle": 0, - "x": 848.1876522707755, - "y": 114.54378191916999, + "x": 852.1759518881388, + "y": 95.34101289707564, "strokeColor": "#000000", "backgroundColor": "#edf2f9", "width": 97, "height": 44, "seed": 1676330079, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "vvQcKQSjOBH3b9Jl-JzdT", "type": "text" - }, - { - "type": "text", - "id": "vvQcKQSjOBH3b9Jl-JzdT" } ], - "updated": 1664546888289, + "updated": 1682390393704, "link": null, "locked": false }, { "type": "text", - "version": 1136, - "versionNonce": 10198559, + "version": 1157, + "versionNonce": 1212905167, "isDeleted": false, "id": "z4XZS_B7IC5Hcbq32LNOh", "fillStyle": "solid", @@ -6441,32 +5435,33 @@ "roughness": 2, "opacity": 100, "angle": 0, - "x": 157.13491789577586, - "y": 88.46286674059866, + "x": 159.1829433912486, + "y": 80.70166398126094, "strokeColor": "#000000", "backgroundColor": "#edf2f9", - "width": 49, + "width": 46.875, "height": 24, "seed": 1084474143, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888289, + "updated": 1683235809309, "link": null, "locked": false, "fontSize": 20, "fontFamily": 3, "text": "http", - "baseline": 20, "textAlign": "center", "verticalAlign": "middle", "containerId": "94pL6u1LZ9bj5i7fV9faW", - "originalText": "http" + "originalText": "http", + "lineHeight": 1.2, + "baseline": 19 }, { "type": "text", - "version": 1074, - "versionNonce": 520886097, + "version": 1126, + "versionNonce": 1298620833, "isDeleted": false, "id": "vvQcKQSjOBH3b9Jl-JzdT", "fillStyle": "solid", @@ -6475,32 +5470,33 @@ "roughness": 2, "opacity": 100, "angle": 0, - "x": 862.6876522707755, - "y": 119.54378191916999, + "x": 867.8634518881388, + "y": 100.34101289707564, "strokeColor": "#000000", "backgroundColor": "#edf2f9", - "width": 68, + "width": 65.625, "height": 34, "seed": 945386769, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888289, + "updated": 1683235809309, "link": null, "locked": false, "fontSize": 28, "fontFamily": 3, "text": "http", - "baseline": 27, "textAlign": "center", "verticalAlign": "middle", "containerId": "NII3JqUhpr9hNElI5QR0U", - "originalText": "http" + "originalText": "http", + "lineHeight": 1.2142857142857142, + "baseline": 27 }, { "type": "rectangle", - "version": 2225, - "versionNonce": 386018545, + "version": 2245, + "versionNonce": 330922654, "isDeleted": false, "id": "3b_CUyIro58tYnO8BXHy7", "fillStyle": "solid", @@ -6509,33 +5505,29 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 220.68402503863263, - "y": 44.75778861559877, + "x": 220.86881558052164, + "y": 36.580807137010765, "strokeColor": "#000000", "backgroundColor": "#edf2f9", "width": 102, "height": 30, "seed": 540872767, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "Y_pMhovsOA0XaxQv0ZJjF", "type": "text" - }, - { - "type": "text", - "id": "Y_pMhovsOA0XaxQv0ZJjF" } ], - "updated": 1664546888289, + "updated": 1682390378527, "link": null, "locked": false }, { "type": "text", - "version": 2132, - "versionNonce": 1933055647, + "version": 2154, + "versionNonce": 678544623, "isDeleted": false, "id": "Y_pMhovsOA0XaxQv0ZJjF", "fillStyle": "solid", @@ -6544,161 +5536,28 @@ "roughness": 2, "opacity": 100, "angle": 0, - "x": 228.68402503863263, - "y": 49.75778861559877, + "x": 229.68131558052164, + "y": 41.580807137010765, "strokeColor": "#000000", "backgroundColor": "#edf2f9", - "width": 86, + "width": 84.375, "height": 20, "seed": 1817996497, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1664546888289, + "updated": 1683235809309, "link": null, "locked": false, "fontSize": 16, "fontFamily": 3, "text": "websocket", - "baseline": 16, "textAlign": "center", "verticalAlign": "middle", "containerId": "3b_CUyIro58tYnO8BXHy7", - "originalText": "websocket" - }, - { - "id": "H08zFlUaSxFLTRVqx9-uH", - "type": "rectangle", - "x": 285.5241090621514, - "y": -592.4904520428331, - "width": 157, - "height": 40, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "#228be6", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 2004336599, - "version": 1478, - "versionNonce": 929812569, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "Uxzlb_yD-RgqglTRXUQ-c" - } - ], - "updated": 1668084862896, - "link": null, - "locked": false - }, - { - "id": "Uxzlb_yD-RgqglTRXUQ-c", - "type": "text", - "x": 322.0241090621514, - "y": -584.4904520428331, - "width": 84, - "height": 24, - "angle": 0, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "groupIds": [], - "strokeSharpness": "sharp", - "seed": 1354007993, - "version": 1472, - "versionNonce": 574274999, - "isDeleted": false, - "boundElements": null, - "updated": 1668084862896, - "link": null, - "locked": false, - "text": "k8s crd", - "fontSize": 20, - "fontFamily": 3, - "textAlign": "center", - "verticalAlign": "middle", - "baseline": 20, - "containerId": "H08zFlUaSxFLTRVqx9-uH", - "originalText": "k8s crd" - }, - { - "type": "rectangle", - "version": 1098, - "versionNonce": 1427361591, - "isDeleted": false, - "id": "G2Oa1ANDGy2b0RgrAep_I", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 653.0202028121514, - "y": -590.5021707928331, - "strokeColor": "#000000", - "backgroundColor": "#228be6", - "width": 182, - "height": 38, - "seed": 106884025, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [ - { - "id": "NFRVm8Y3PjHUQJuwyC7EP", - "type": "text" - }, - { - "type": "text", - "id": "NFRVm8Y3PjHUQJuwyC7EP" - } - ], - "updated": 1668084858874, - "link": null, - "locked": false - }, - { - "type": "text", - "version": 1110, - "versionNonce": 305996729, - "isDeleted": false, - "id": "NFRVm8Y3PjHUQJuwyC7EP", - "fillStyle": "hachure", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 1, - "opacity": 100, - "angle": 0, - "x": 661.0202028121514, - "y": -583.5021707928331, - "strokeColor": "#000000", - "backgroundColor": "transparent", - "width": 166, - "height": 24, - "seed": 1143048279, - "groupIds": [], - "strokeSharpness": "sharp", - "boundElements": [], - "updated": 1668084858874, - "link": null, - "locked": false, - "fontSize": 20, - "fontFamily": 3, - "text": "k8s-api-server", - "baseline": 20, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "G2Oa1ANDGy2b0RgrAep_I", - "originalText": "k8s-api-server" + "originalText": "websocket", + "lineHeight": 1.25, + "baseline": 15 }, { "type": "rectangle", @@ -6720,15 +5579,11 @@ "height": 37, "seed": 279999705, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [ { "id": "Kj05CpUJANSwy-OtOW12G", "type": "text" - }, - { - "type": "text", - "id": "Kj05CpUJANSwy-OtOW12G" } ], "updated": 1668084744609, @@ -6737,8 +5592,8 @@ }, { "type": "text", - "version": 912, - "versionNonce": 310101113, + "version": 914, + "versionNonce": 606897537, "isDeleted": false, "id": "Kj05CpUJANSwy-OtOW12G", "fillStyle": "hachure", @@ -6747,27 +5602,79 @@ "roughness": 1, "opacity": 100, "angle": 0, - "x": 147.7350465621514, + "x": 148.6412965621514, "y": -347.3224832928331, "strokeColor": "#000000", "backgroundColor": "transparent", - "width": 119, + "width": 117.1875, "height": 24, "seed": 1751163191, "groupIds": [], - "strokeSharpness": "sharp", + "roundness": null, "boundElements": [], - "updated": 1668084744609, + "updated": 1683235809309, "link": null, "locked": false, "fontSize": 20, "fontFamily": 3, "text": "kubernetes", - "baseline": 20, "textAlign": "center", "verticalAlign": "middle", "containerId": "6fsRLl1rBFRMPfralCRWJ", - "originalText": "kubernetes" + "originalText": "kubernetes", + "lineHeight": 1.2, + "baseline": 19 + }, + { + "type": "arrow", + "version": 67, + "versionNonce": 1118058818, + "isDeleted": false, + "id": "IXGLaKwvNWM7iA7SwPJbz", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 615.9595016138026, + "y": -266.22505587984483, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 138.95476383334267, + "height": 3.6342380517520496, + "seed": 209595230, + "groupIds": [], + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1682390356102, + "link": null, + "locked": false, + "startBinding": { + "elementId": "9UnJOgDqkaJktInMVo47r", + "focus": 0.1685321674877726, + "gap": 12.958147183352423 + }, + "endBinding": { + "elementId": "sFE8hJbB0-zakUa7U66ZI", + "focus": 0.11307072739803732, + "gap": 8.388339189344038 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -138.95476383334267, + 3.6342380517520496 + ] + ] } ], "appState": { diff --git a/docs/diagrams/laf-arch-simple.png b/docs/diagrams/laf-arch-simple.png deleted file mode 100644 index 1cc97d3c15..0000000000 Binary files a/docs/diagrams/laf-arch-simple.png and /dev/null differ diff --git a/docs/doc-images/AppID.png b/docs/doc-images/AppID.png new file mode 100644 index 0000000000..6b4cd6af08 Binary files /dev/null and b/docs/doc-images/AppID.png differ diff --git a/docs/doc-images/add-env-step1.png b/docs/doc-images/add-env-step1.png index d59aae1eaa..e59bcbf11d 100644 Binary files a/docs/doc-images/add-env-step1.png and b/docs/doc-images/add-env-step1.png differ diff --git a/docs/doc-images/add-env-step2.png b/docs/doc-images/add-env-step2.png index 53eca044cf..415f061139 100644 Binary files a/docs/doc-images/add-env-step2.png and b/docs/doc-images/add-env-step2.png differ diff --git a/docs/doc-images/add-env-step3.png b/docs/doc-images/add-env-step3.png index 44fe4698f2..daf0c3691e 100644 Binary files a/docs/doc-images/add-env-step3.png and b/docs/doc-images/add-env-step3.png differ diff --git a/docs/doc-images/add-env.png b/docs/doc-images/add-env.png new file mode 100644 index 0000000000..9af5525e5d Binary files /dev/null and b/docs/doc-images/add-env.png differ diff --git a/docs/doc-images/add-packages.png b/docs/doc-images/add-packages.png index d2eeff65a6..2247b12cb3 100644 Binary files a/docs/doc-images/add-packages.png and b/docs/doc-images/add-packages.png differ diff --git a/docs/doc-images/add-polocy.png b/docs/doc-images/add-polocy.png new file mode 100644 index 0000000000..6bde41e193 Binary files /dev/null and b/docs/doc-images/add-polocy.png differ diff --git a/docs/doc-images/app-list.png b/docs/doc-images/app-list.png new file mode 100644 index 0000000000..c66eb249d9 Binary files /dev/null and b/docs/doc-images/app-list.png differ diff --git a/docs/doc-images/appList.png b/docs/doc-images/appList.png new file mode 100644 index 0000000000..489052d5ba Binary files /dev/null and b/docs/doc-images/appList.png differ diff --git a/docs/doc-images/application-list.png b/docs/doc-images/application-list.png index 552b491b29..d0545ce98e 100644 Binary files a/docs/doc-images/application-list.png and b/docs/doc-images/application-list.png differ diff --git a/docs/doc-images/auto-build1.png b/docs/doc-images/auto-build1.png new file mode 100644 index 0000000000..314aeb2b42 Binary files /dev/null and b/docs/doc-images/auto-build1.png differ diff --git a/docs/doc-images/auto-build2.png b/docs/doc-images/auto-build2.png new file mode 100644 index 0000000000..39cd3a9f92 Binary files /dev/null and b/docs/doc-images/auto-build2.png differ diff --git a/docs/doc-images/change-package-version.png b/docs/doc-images/change-package-version.png new file mode 100644 index 0000000000..c6537d2ff0 Binary files /dev/null and b/docs/doc-images/change-package-version.png differ diff --git a/docs/doc-images/cli-mind.png b/docs/doc-images/cli-mind.png new file mode 100644 index 0000000000..8ea6005479 Binary files /dev/null and b/docs/doc-images/cli-mind.png differ diff --git a/docs/doc-images/creat-polocy.png b/docs/doc-images/creat-polocy.png new file mode 100644 index 0000000000..3094797579 Binary files /dev/null and b/docs/doc-images/creat-polocy.png differ diff --git a/docs/doc-images/creat-token.png b/docs/doc-images/creat-token.png new file mode 100644 index 0000000000..f0b14fe98f Binary files /dev/null and b/docs/doc-images/creat-token.png differ diff --git a/docs/doc-images/create-application.png b/docs/doc-images/create-application.png index 7d4f4643ee..33637995fb 100644 Binary files a/docs/doc-images/create-application.png and b/docs/doc-images/create-application.png differ diff --git a/docs/doc-images/create-bucket-1.png b/docs/doc-images/create-bucket-1.png new file mode 100644 index 0000000000..dad0aa04c3 Binary files /dev/null and b/docs/doc-images/create-bucket-1.png differ diff --git a/docs/doc-images/create-bucket.png b/docs/doc-images/create-bucket.png new file mode 100644 index 0000000000..f7eb407840 Binary files /dev/null and b/docs/doc-images/create-bucket.png differ diff --git a/docs/doc-images/create-cloudfunction.png b/docs/doc-images/create-cloudfunction.png index 473ba3a8da..096a68d8d0 100644 Binary files a/docs/doc-images/create-cloudfunction.png and b/docs/doc-images/create-cloudfunction.png differ diff --git a/docs/doc-images/create-function.jpg b/docs/doc-images/create-function.jpg index 00f1845461..43e487b9bf 100644 Binary files a/docs/doc-images/create-function.jpg and b/docs/doc-images/create-function.jpg differ diff --git a/docs/doc-images/create-function.png b/docs/doc-images/create-function.png new file mode 100644 index 0000000000..ed777e388e Binary files /dev/null and b/docs/doc-images/create-function.png differ diff --git a/docs/doc-images/create-gather.png b/docs/doc-images/create-gather.png new file mode 100644 index 0000000000..e6b7e0666b Binary files /dev/null and b/docs/doc-images/create-gather.png differ diff --git a/docs/doc-images/create-injector.png b/docs/doc-images/create-injector.png index 9c20da1051..43b42d2226 100644 Binary files a/docs/doc-images/create-injector.png and b/docs/doc-images/create-injector.png differ diff --git a/docs/doc-images/create-laf-app.jpg b/docs/doc-images/create-laf-app.jpg new file mode 100644 index 0000000000..a4a547070f Binary files /dev/null and b/docs/doc-images/create-laf-app.jpg differ diff --git a/docs/doc-images/db.png b/docs/doc-images/db.png new file mode 100644 index 0000000000..1c2c3580bd Binary files /dev/null and b/docs/doc-images/db.png differ diff --git a/docs/doc-images/dblist.jpg b/docs/doc-images/dblist.jpg new file mode 100644 index 0000000000..845cebe2db Binary files /dev/null and b/docs/doc-images/dblist.jpg differ diff --git a/docs/doc-images/delete-package.png b/docs/doc-images/delete-package.png new file mode 100644 index 0000000000..ff69f50d25 Binary files /dev/null and b/docs/doc-images/delete-package.png differ diff --git a/docs/doc-images/doc-app-list.png b/docs/doc-images/doc-app-list.png new file mode 100644 index 0000000000..4e8c522b90 Binary files /dev/null and b/docs/doc-images/doc-app-list.png differ diff --git a/docs/doc-images/doc-db.png b/docs/doc-images/doc-db.png new file mode 100644 index 0000000000..5124dbb058 Binary files /dev/null and b/docs/doc-images/doc-db.png differ diff --git a/docs/doc-images/doc-function-list.png b/docs/doc-images/doc-function-list.png new file mode 100644 index 0000000000..38e0cf9b60 Binary files /dev/null and b/docs/doc-images/doc-function-list.png differ diff --git a/docs/doc-images/doc-policy.png b/docs/doc-images/doc-policy.png new file mode 100644 index 0000000000..edcc5a67a8 Binary files /dev/null and b/docs/doc-images/doc-policy.png differ diff --git a/docs/doc-images/doc-storage.png b/docs/doc-images/doc-storage.png new file mode 100644 index 0000000000..8173a586c5 Binary files /dev/null and b/docs/doc-images/doc-storage.png differ diff --git a/docs/doc-images/edit-cloudfunction.png b/docs/doc-images/edit-cloudfunction.png index 1b29cb3ab5..478cb69027 100644 Binary files a/docs/doc-images/edit-cloudfunction.png and b/docs/doc-images/edit-cloudfunction.png differ diff --git a/docs/doc-images/file.png b/docs/doc-images/file.png new file mode 100644 index 0000000000..aa88488627 Binary files /dev/null and b/docs/doc-images/file.png differ diff --git a/docs/doc-images/function-body.png b/docs/doc-images/function-body.png new file mode 100644 index 0000000000..f29ce9cafe Binary files /dev/null and b/docs/doc-images/function-body.png differ diff --git a/docs/doc-images/function-log.png b/docs/doc-images/function-log.png new file mode 100644 index 0000000000..b10595c90f Binary files /dev/null and b/docs/doc-images/function-log.png differ diff --git a/docs/doc-images/function-query.png b/docs/doc-images/function-query.png new file mode 100644 index 0000000000..46197ae91c Binary files /dev/null and b/docs/doc-images/function-query.png differ diff --git a/docs/doc-images/function-url.png b/docs/doc-images/function-url.png new file mode 100644 index 0000000000..afbcde73f0 Binary files /dev/null and b/docs/doc-images/function-url.png differ diff --git a/docs/doc-images/function.png b/docs/doc-images/function.png new file mode 100644 index 0000000000..c21904e868 Binary files /dev/null and b/docs/doc-images/function.png differ diff --git a/docs/doc-images/getToken-parseToken.png b/docs/doc-images/getToken-parseToken.png new file mode 100644 index 0000000000..a39fd68dec Binary files /dev/null and b/docs/doc-images/getToken-parseToken.png differ diff --git a/docs/doc-images/index.png b/docs/doc-images/index.png new file mode 100644 index 0000000000..e5852130f2 Binary files /dev/null and b/docs/doc-images/index.png differ diff --git a/docs/doc-images/open-website.png b/docs/doc-images/open-website.png new file mode 100644 index 0000000000..f2272520bb Binary files /dev/null and b/docs/doc-images/open-website.png differ diff --git a/docs/doc-images/package-list.png b/docs/doc-images/package-list.png index 308bc3ca92..63b68e72c6 100644 Binary files a/docs/doc-images/package-list.png and b/docs/doc-images/package-list.png differ diff --git a/docs/doc-images/pakcage-list.jpg b/docs/doc-images/pakcage-list.jpg index 922e311b9c..348f7b075d 100644 Binary files a/docs/doc-images/pakcage-list.jpg and b/docs/doc-images/pakcage-list.jpg differ diff --git a/docs/doc-images/polocy-db-data.png b/docs/doc-images/polocy-db-data.png new file mode 100644 index 0000000000..95e647c6f0 Binary files /dev/null and b/docs/doc-images/polocy-db-data.png differ diff --git a/docs/doc-images/publish-cloudfunction.png b/docs/doc-images/publish-cloudfunction.png index 2f9e519341..ac1499c251 100644 Binary files a/docs/doc-images/publish-cloudfunction.png and b/docs/doc-images/publish-cloudfunction.png differ diff --git a/docs/doc-images/register.png b/docs/doc-images/register.png new file mode 100644 index 0000000000..cf9ab88694 Binary files /dev/null and b/docs/doc-images/register.png differ diff --git a/docs/doc-images/run-cloudfunction.png b/docs/doc-images/run-cloudfunction.png index 30c16d7ce8..9adf18e682 100644 Binary files a/docs/doc-images/run-cloudfunction.png and b/docs/doc-images/run-cloudfunction.png differ diff --git a/docs/doc-images/select-package-version.png b/docs/doc-images/select-package-version.png index 290bd03f4e..9c9bfe0c6c 100644 Binary files a/docs/doc-images/select-package-version.png and b/docs/doc-images/select-package-version.png differ diff --git a/docs/doc-images/specification.jpg b/docs/doc-images/specification.jpg new file mode 100644 index 0000000000..12e8680d97 Binary files /dev/null and b/docs/doc-images/specification.jpg differ diff --git a/docs/doc-images/todo-demo.png b/docs/doc-images/todo-demo.png new file mode 100644 index 0000000000..8d38230e7a Binary files /dev/null and b/docs/doc-images/todo-demo.png differ diff --git a/docs/doc-images/upload.png b/docs/doc-images/upload.png new file mode 100644 index 0000000000..2a5ba2b4ec Binary files /dev/null and b/docs/doc-images/upload.png differ diff --git a/docs/doc-images/use-injector.png b/docs/doc-images/use-injector.png index a16cc059a4..b5c3e2576c 100644 Binary files a/docs/doc-images/use-injector.png and b/docs/doc-images/use-injector.png differ diff --git a/docs/doc-images/web-ide-index.png b/docs/doc-images/web-ide-index.png new file mode 100644 index 0000000000..29ec5c0f65 Binary files /dev/null and b/docs/doc-images/web-ide-index.png differ diff --git a/docs/doc-images/website-hosting.png b/docs/doc-images/website-hosting.png new file mode 100644 index 0000000000..a462ba28dd Binary files /dev/null and b/docs/doc-images/website-hosting.png differ diff --git a/docs/examples/3min-login.md b/docs/examples/3min-login.md deleted file mode 100644 index 69f9dd65e2..0000000000 --- a/docs/examples/3min-login.md +++ /dev/null @@ -1,4 +0,0 @@ - -## 正在编写中,即将发布 - -> TODO \ No newline at end of file diff --git a/docs/examples/alipay-pay.md b/docs/examples/alipay-pay.md deleted file mode 100644 index 1479ea9059..0000000000 --- a/docs/examples/alipay-pay.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: 支付宝支付云函数 ---- - -# {{ $frontmatter.title }} - -创建 `aliPay` 云函数,添加依赖 alipay-sdk ,编写以下代码: - -```ts -import cloud from "@lafjs/cloud"; -import alipay from "alipay-sdk"; -const AlipayFormData = require("alipay-sdk/lib/form").default; - -exports.main = async function (ctx) { - const { totalFee, goodsName, goodsDetail, payOrderId } = ctx.body; - - const ali = new alipay({ - appId: "2016091800536572", - signType: "RSA2", - privateKey: "MIIEow......Yf2Mlz6xqG/Aq", - alipayPublicKey: "MIIBI......IDAQAB", - gateway: "https://openapi.alipaydev.com/gateway.do", //沙箱测试网关 - }); - - const formData = new AlipayFormData(); - formData.setMethod("get"); - formData.addField( - "notifyUrl", - "https://APPID.lafyun.com/alipay_notify_callback" - ); - formData.addField("bizContent", { - subject: goodsName, - body: goodsDetail, - outTradeNo: payOrderId, - totalAmount: totalFee, - }); - - const result = await ali.exec( - "alipay.trade.app.pay", - {}, - { formData: formData } - ); - - return { - code: 0, - data: result, - }; -}; -``` diff --git a/docs/examples/aliyun-sms.md b/docs/examples/aliyun-sms.md deleted file mode 100644 index a3075da532..0000000000 --- a/docs/examples/aliyun-sms.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: 阿里云短信服务发验证码的云函数 ---- - -# {{ $frontmatter.title }} - -使用阿里云短信接口,编写发送短信验证码的云函数。 -需要你提供阿里云短信服务的 `AccessKey` 和 `SecretKey`,以及短信模板 ID。 - -创建 `sendsms` 云函数,添加依赖 @alicloud/dysmsapi20170525,编写以下代码: - -```ts -import Dysmsapi, * as dysmsapi from "@alicloud/dysmsapi20170525"; -import * as OpenApi from "@alicloud/openapi-client"; -import * as Util from "@alicloud/tea-util"; - -const accessKeyId = "xxxxxxxxxxxxxx"; -const accessKeySecret = "xxxxxxxxxxxxxx"; -const signName = "XXXX"; -const templateCode = "SMS_xxxxx"; -const endpoint = "dysmsapi.aliyuncs.com"; - -exports.main = async function (ctx: FunctionContext) { - const { phone, code } = ctx.body; - - const sendSmsRequest = new dysmsapi.SendSmsRequest({ - phoneNumbers: phone, - signName, - templateCode, - templateParam: `{"code":${code}}`, - }); - - const config = new OpenApi.Config({ accessKeyId, accessKeySecret, endpoint }); - const client = new Dysmsapi(config); - const runtime = new Util.RuntimeOptions({}); - const res = await client.sendSmsWithOptions(sendSmsRequest, runtime); - return res.body; -}; -``` diff --git a/docs/examples/github-actions-blog.md b/docs/examples/github-actions-blog.md deleted file mode 100644 index 69f9dd65e2..0000000000 --- a/docs/examples/github-actions-blog.md +++ /dev/null @@ -1,4 +0,0 @@ - -## 正在编写中,即将发布 - -> TODO \ No newline at end of file diff --git a/docs/examples/health-check.md b/docs/examples/health-check.md deleted file mode 100644 index 69f9dd65e2..0000000000 --- a/docs/examples/health-check.md +++ /dev/null @@ -1,4 +0,0 @@ - -## 正在编写中,即将发布 - -> TODO \ No newline at end of file diff --git a/docs/examples/polkadot-transaction.md b/docs/examples/polkadot-transaction.md deleted file mode 100644 index 69f9dd65e2..0000000000 --- a/docs/examples/polkadot-transaction.md +++ /dev/null @@ -1,4 +0,0 @@ - -## 正在编写中,即将发布 - -> TODO \ No newline at end of file diff --git a/docs/examples/send-mail.md b/docs/examples/send-mail.md deleted file mode 100644 index 55958fe0c4..0000000000 --- a/docs/examples/send-mail.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: 发送邮件 ---- - -# {{ $frontmatter.title }} - -使用 SMTP 服务发送邮件。 - -创建 `sendmail` 云函数,添加依赖 `nodemailer`,编写以下代码: - -```ts -import from 'nodemailer' - -// 邮件服务器配置 -const transportConfig = { - host: 'smtp.exmail.qq.com', // smtp 服务地址,示例腾讯企业邮箱地址 - port: 465, // smtp 服务端口,一般服务器未开此端口,需要手动开启 - secureConnection: true, // 使用了 SSL - auth: { - user: 'sender@xx.com', // 发件人邮箱,写你的邮箱地址即可 - pass: 'your password', // 你设置的smtp专用密码或登录密码,每家服务不相同,QQ邮箱需要开启并配置授权码,即这里的pass - } -} - -// 邮件配置 -const mailOptions = { - from: '"SenderName" ', // 发件人 - to: 'hi@xx.com', // 收件人 - subject: 'Hello', // 邮件主题 - html: 'Hello world?' // html 格式邮件正文 - // text: 'hello' // 文本格式有限正文 -} - -exports.main = async function (ctx) { - const transporter = nodemailer.createTransport(transportConfig) - - transporter.sendMail(mailOptions, (error, info) => { - if (error) { - return console.log(error); - } - console.log('Message sent: %s', info.messageId); - return info.messageId - }) -}; -``` diff --git a/docs/examples/todo-list.md b/docs/examples/todo-list.md deleted file mode 100644 index a503af324e..0000000000 --- a/docs/examples/todo-list.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: laf.js 前端使用演示 Demo ---- - -# {{ $frontmatter.title }} - -## Demo: Todo List - -> CodeSandBox 在线 Demo,由于网络原因加载会比较慢 - - diff --git a/docs/examples/websocket.md b/docs/examples/websocket.md deleted file mode 100644 index 0fd425d8dd..0000000000 --- a/docs/examples/websocket.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: 使用WebSocket长连接 ---- - -# {{ $frontmatter.title }} - -正在编写中,即将发布 - -> TODO diff --git a/docs/examples/wechat-notify.md b/docs/examples/wechat-notify.md deleted file mode 100644 index 69f9dd65e2..0000000000 --- a/docs/examples/wechat-notify.md +++ /dev/null @@ -1,4 +0,0 @@ - -## 正在编写中,即将发布 - -> TODO \ No newline at end of file diff --git a/docs/examples/wechat-pay.md b/docs/examples/wechat-pay.md deleted file mode 100644 index 9e8e785a91..0000000000 --- a/docs/examples/wechat-pay.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: 发起微信支付云函数 ---- - -# {{ $frontmatter.title }} - -本案例以微信 native 支付为例,native 支付服务端下单之后微信支付会返回一个 code-url, 然后前端接收这个返回值,直接把这个 code-url 在前端 -生成一个二维码即可用微信扫描支付,适合 PC 网站支付。 - -code-url 类似:`weixin://wxpay/bizpayurl?pr=aIQrOYOzz` - -notify_url 也可以写一个 laf 云函数来接受支付结果的通知。 - -创建 `wx-pay` 云函数,添加依赖 [wxpay-v3](https://github.com/yangfuhe/node-wxpay),编写以下代码: - -```ts -import cloud from "@lafjs/cloud"; -const Payment = require("wxpay-v3"); - -exports.main = async function (ctx: any) { - const { goodsName, totalFee, payOrderId } = ctx.body; - - // create payment instance - const payment = new Payment({ - appid: "应用ID", - mchid: "商户id", - private_key: getPrivateKey(), - serial_no: "序列号", - apiv3_private_key: "api v3密钥", - notify_url: "付退款结果通知的回调地址", - }); - - // 下单 - const result = await payment.native({ - description: goodsName, - out_trade_no: payOrderId, - amount: { - total: totalFee, - }, - }); - return result; -}; - -function getPrivateKey() { - const key = `-----BEGIN PRIVATE KEY----- -HOBHEk+4cdiPcvhowhC8ii7838DP4qC+18ibL/KAySWyZjUC/keOr4MxhxQ1T+OV -... -... -475J8ALCRltkgTSxicoXS7SpjLqvIH2FPpv2BI+qQ3nOmAugsRkeH9lZdC/nSC0m -uI205SwTsTaT70/vF90AwQ== ------END PRIVATE KEY----- -`; - return key; -} -``` diff --git a/docs/guide/cases/index.md b/docs/guide/cases/index.md index 69f9dd65e2..f4573e006f 100644 --- a/docs/guide/cases/index.md +++ b/docs/guide/cases/index.md @@ -1,4 +1,4 @@ ## 正在编写中,即将发布 -> TODO \ No newline at end of file +> TODO diff --git a/docs/guide/cli/index.md b/docs/guide/cli/index.md index 772f9253d6..f222f24768 100644 --- a/docs/guide/cli/index.md +++ b/docs/guide/cli/index.md @@ -4,139 +4,205 @@ title: laf-cli 命令行工具 # {{ $frontmatter.title }} - ## 简介 -`laf-cli` 提供本地开发环境相关能力的支持: - -- 云函数:支持在本地运行、拉取、部署云函数 -- 云存储:支持从本地上传、下载云存储文件 -- 应用:初始化、查看、启动、停止应用服务 +`laf-cli` 可以让你实现本地开发同步 Web 端,用你最熟悉的开发工具,更加高效。 +我们先预览一下 cli 为我们提供的所有操作。 +![](../../doc-images/cli-mind.png) ## 安装 -```bash +```shell # 要求 node 版本 >= 16 npm i laf-cli -g ``` +cli 的主要功能就是把在 laf web 上的操作集成到命令行里,下面我们根据 web 端的操作来一个个演示。 ## 登录 -```bash -laf login -u username -p password +想要执行登录操作我们需要先拿到我们的 PAT(访问凭证)。 + +![](../../doc-images/creat-token.png) + +生成 token 之后我们复制放在 laf login 后面执行此命令即可登录。 + +```shell +laf login [pat] ``` -默认登录 `lafyun.com`,如果要登录私有部署的 laf 可通过 `-r` 参数指定: +默认登录 `laf.run`,如果要登录私有部署的 laf 可通过 `-r` 参数指定: -`laf login -u username -p password -r https://console.lafyun.com` +`laf login [pat] -r https://api.laf.run` +::: tip +这里要注意,https 后面需要加上 api +::: + +### 退出登录 + +```shell +laf logout +``` +## App -## 查看应用列表 +在 web 端登录之后我们会看到我们的 app 列表,那么在 cli 中想查看 app 列表只需要执行。 -```bash -laf list +```shell +laf app list ``` +### 初始化 app -## 启停应用 +初始化需要用到 appid ,我们可以在 web 端首页拿到。 +这里稍微解释一下,初始化 app 是指在你运行这个命令的目录下生成模版文件,默认是空的,如果想把 web 端的东西同步过来需要加上 -s 。 +::: tip +建议在一个空的目录下尝试此命令。 +::: -```bash -# 启动应用 -laf start APPID +```shell +laf app init [appid] +``` + +## 依赖 -# 停止应用 -laf stop APPID +我们可以通过 pull 命令把 web 端的依赖拉到本地,然后 npm i 即可。 -# 重启应用 -laf restart APPID +```shell +laf dep pull ``` +如果我们想添加依赖可以使用 add ,注意这里的 add 是在 web 端和本地同时添加这个依赖,添加之后 npm i 即可使用。 -## 在本地初始化应用 +```shell +laf dep add [dependencyName] +``` -在你的本地项目目录下执行: +如果我们的依赖文件,或者说整个本地文件都是从其他地方拷贝过来的,可以通过 push 命令把 dependency.yaml 文件中的所有依赖都安装到 web 端。 -```bash -laf init -s APPID +```shell +laf dep push ``` -执行后会在当前目录生成一个文件夹 `@laf`,该文件夹下包含了 laf 应用的云函数代码等文件。 +## 云函数 + +新建云函数,此命令是在本地和 web 同时创建云函数。 -`-s` 参数指定初始化时从远程拉取云函数代码,如果不指定,则只会同步应用的基本信息。 +```shell + laf func create [funcName] +``` -`APPID` 应是你已经创建应用的 ID,可通过 `laf list` 查看。 +删除云函数,同新建一样本地和 web 同时删除。 +```shell +laf func del [funcName] +``` -## 拉取云函数 +查看云函数列表。 -从远程拉取云函数到本地: +```shell +laf func list +``` -```bash +更新 web 端云函数代码到本地。 -# 拉取所有云函数 -laf fn pull +```shell +laf func pull [funcName] +``` -# 拉取一个云函数 -laf fn pull FUNCTION_NAME +推送本地云函数代码到 web 。 +```shell +laf func push [funcName] ``` +执行云函数,执行结果会打印在命令行,日志需要在 web 上查看。 -## 推送云函数 +```shell +laf func exec [funcName] +``` -推送本地云函数到远程: +## 存储 -```bash +查看 bucket 列表。 -# 推送所有云函数 -laf fn push +```shell +laf storage list +``` -# 推送一个云函数 -laf fn push FUNCTION_NAME +新建 bucket 。 +```shell +laf storage create [bucketName] ``` +删除 bucket 。 + +```shell +laf storage del [bucketName] +``` -## 调试云函数 +更新 bucket 权限。 -用于调试「未保存」「未发布」的云函数: +```shell +laf storage update [bucketName] +``` -```bash +下载 bucket 文件到本地。 -```bash -laf fn invoke FUNCTION_NAME --param '{"name": "laf"}' +```shell +laf storage pull [bucketName] [outPath] ``` +上传本地文件到 bucket 。 + +```shell +laf storage push [bucketName] [inPath] +``` -## 发布云函数 +## 访问策略 -发布云函数: +查看所有访问策略。 -```bash -laf fn publish FUNCTION_NAME +```shell +laf policy list ``` -## 上传云存储文件 +拉取访问策略到本地,参数 policyName 是可选,不填代表拉取全部。 -将本地目录 `./dist/` 内的文件上传到 `www` Bucket 中: +```shell +laf policy pull [policyName] +``` -```bash -laf oss push ./dist/ www +推送访问策略到 web,参数 policyName 是可选,不填代表推送全部。 + +```shell +laf policy push [policyName] ``` -## 下载云存储文件 +## 网站托管 -下载云存储 bucket 内的文件到本地: +查看托管列表。 -```bash -laf oss pull www ./dist/ +```shell +laf website list ``` +开启网站托管,此命令是开启 [bucketName] 的网站托管。 + +```shell +laf website create [bucketName] +``` -## 其它说明 +关闭网站托管,此命令是关闭 [bucketName] 的网站托管。 -1. laf cli 还不支持查看应用/云函数日志,正在开发中; -2. laf cli 版本不稳定,以上文档可能更新并不及时,可通过 `laf -h` `laf fn pull -h` 来查看具体说明; -3. laf cli 从 laf 0.8.5 开始支持,`system-server` 服务版本低于 0.8.5 不支持 laf cli; \ No newline at end of file +```shell +laf website del [bucketName] +``` + +自定义域名,此命令是为已开启网站托管的 [bucketName] 设置自定义域名。 + +```shell +laf website custom [bucketName] [domain] +``` diff --git a/docs/guide/client-sdk/index.md b/docs/guide/client-sdk/index.md new file mode 100644 index 0000000000..e98c2c5014 --- /dev/null +++ b/docs/guide/client-sdk/index.md @@ -0,0 +1,157 @@ +--- +title: laf-client-sdk +--- + +# {{ $frontmatter.title }} + +## 介绍 + +laf 为前端提供了 `laf-client-sdk` 适用于前端 js 运行环境。 + +## 安装 + +```bash + npm install laf-client-sdk +``` + +## 使用示例 + +```js +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + // 这里 APPID 需要换成对应的 APPID + baseUrl: "https://APPID.laf.run", + // 这里是访问策略的入口地址,如果没有访问策略可不填 + dbProxyUrl: "/proxy/app", + // 请求时带的 token,可空 + getAccessToken: () => localStorage.getItem("access_token"), +}); +``` + +## 参数 + +`baseUrl` Laf 应用链接,格式为 `https://APPID.laf.run`,APPID 为你的 Laf 应用的 appid + +`dbProxyUrl` 数据库访问策略入口,格式为 `/proxy/` 开头加上你新建策略名,如果不需要操作数据库,可不填此参数 + +`getAccessToken` 请求时带的 token,token 为 JWT token,如果不涉及权限可空 + +`environment` 目前兼容三种环境 `wxmp` `uniapp` `h5`,`wxmp` 为微信小程序 + +## 微信小程序中使用 + +```js +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + baseUrl: "https://APPID.laf.run", + dbProxyUrl: "/proxy/app", + getAccessToken: () => wx.getStorageSync('access_token'), + environment: "wxmp", +}); +``` + +::: warning +微信小程序中使用 NPM 依赖,需要 `构建NPM` +::: + +### `Typescript` 版微信小程序构建方法 + +1、终端 npm 初始化,在小程序项目文件夹中执行 `npm init -y` + +2、安装客户端 SDK,在小程序项目文件夹中执行 `npm i laf-client-sdk` + +3、修改 project.config.json + +setting 下新增: + +```typescript +"packNpmManually": true, +"packNpmRelationList": [ + { + "packageJsonPath": "./package.json", + "miniprogramNpmDistDir": "miniprogram/" + } +] +``` + +4、构建 NPM,微信开发者工具中,点击"工具"-"构建 npm" + +5、页面中调用 SDK 的功能 + +### `Javascript` 版微信小程序构建方法 + +1、终端 npm 初始化,在小程序项目文件夹中执行 `npm init -y` + +2、安装客户端 SDK,在小程序项目文件夹中执行 `npm i laf-client-sdk` + +3、构建 NPM,微信开发者工具中,点击"工具"-"构建 npm" + +6、页面中调用 SDK 的功能 + +## UNI-APP 中使用 + +```js +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + baseUrl: "https://APPID.laf.run", + dbProxyUrl: "/proxy/app", + getAccessToken: () => uni.getStorageSync("access_token"), + environment: "uniapp", +}); +``` + +## H5 中使用 + +```js +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + baseUrl: "https://APPID.laf.run", + dbProxyUrl: "/proxy/app", + getAccessToken: () => localStorage.getItem("access_token"), + environment: "h5", +}); +``` + +## 调用云函数 + +::: tip +`laf-client-sdk` 调用云函数只支持 POST 请求云函数 +::: + +```typescript +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + baseUrl: "https://APPID.laf.run", + dbProxyUrl: "/proxy/app", + getAccessToken: () => localStorage.getItem("access_token"), +}); + +// 调用 getCode 云函数,并且传入参数 +const res = await cloud.invoke("getCode", { phone: phone.value }); +``` + +## 操作数据库 + +:::tip +通过 `laf-client-sdk` 我们可以像在云函数中一样操作数据库,更多操作情参考 [云数据库](/guide/db/) 章节。 +还有就是需要配合相对应的访问策略。 +::: + +```typescript +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + baseUrl: "https://APPID.laf.run", + dbProxyUrl: "/proxy/app", //数据库访问策略 + getAccessToken: () => localStorage.getItem("access_token"), +}); +const db = cloud.database() + +// 获取用户表中的数据。 +const res = await db.collection('user').get() +``` diff --git a/docs/guide/db/actions.md b/docs/guide/db/actions.md deleted file mode 100644 index 7cd4b648cb..0000000000 --- a/docs/guide/db/actions.md +++ /dev/null @@ -1,217 +0,0 @@ ---- -title: 云数据库操作 ---- - -# {{ $frontmatter.title }} - -## 新增文档 - -### 方法 1: `collection.add(data)` - -示例: - -| 参数 | 类型 | 必填 | 说明 | -| ---- | ------ | ---- | ------------------------------------------ | -| data | object | 是 | {\_id: '10001', 'name': 'Ben'} \_id 非必填 | - -```js -//promise -collection - .add({ - name: "Ben", - }) - .then((res) => {}); -``` - -### 方法 2: `collection.doc().set(data)` - -也可通过 `set` 方法新增一个文档,需先取得文档引用再调用 `set` 方法。 -如果文档不存在,`set` 方法会创建一个新文档。 - -```js -//promise -collection.doc().set({ - name: "Hey", -}); -``` - -## 删除文档 - -### 方式 1 通过指定文档 ID - -`collection.doc(\_id).remove()` - -```js -// 清理全部数据 -collection - .get() - .then((res) => { - const promiseList = res.data.map((document) => { - return collection.doc(document._id).remove(); - }); - Promise.all(promiseList); - }) - .catch((e) => {}); -``` - -### 方式 2 条件查找文档然后直接批量删除 - -`collection.where().remove()` - -```js -// 删除字段a的值大于2的文档 -// 批量删除需要在 remove() 中添加 {multi: true} -//promise -collection - .where({ - a: _.gt(2), - }) - .remove({multi: true}) - .then(function (res) {}); -``` - -## 更新文档 - -### 更新指定文档 - -`collection.doc().update()` - -```js -collection.doc("doc-id").update({ - name: "Hey", -}); -``` - -### 更新文档,如果不存在则创建 - -`collection.doc().set()` - -```js -//promise -collection - .doc("doc-id") - .set({ - name: "Hey", - }) - .then(function (res) {}); -``` - -### 批量更新文档 - -`collection.update()` - -```js -//promise -collection - .where({ name: _.eq("hey") }) - .update({ - age: 18, - }) - .then(function (res) {}); -``` - -## 更新指令 - -### set - -更新指令。用于设定字段等于指定值。这种方法相比传入纯 JS 对象的好处是能够指定字段等于一个对象: - -```js -// 以下方法只会更新 property.location 和 property.size,如果 property 对象中有 -//promise -db.collection("photo") - .doc("doc-id") - .update({ - data: { - property: { - location: "guangzhou", - size: 8, - }, - }, - }) - .then(function (res) {}); -``` - -### inc - -更新指令。用于指示字段自增某个值,这是个原子操作,使用这个操作指令而不是先读数据、再加、再写回的好处是: - -1. 原子性:多个用户同时写,对数据库来说都是将字段加一,不会有后来者覆写前者的情况 -2. 减少一次网络请求:不需先读再写 - -之后的 mul 指令同理。 - -如给收藏的商品数量加一: - -```js -const _ = db.command; -//promise -db.collection("user") - .where({ - _openid: "my-open-id", - }) - .update({ - count: { - favorites: _.inc(1), - }, - }) - .then(function (res) {}); -``` - -### mul - -更新指令。用于指示字段自乘某个值。 - -### remove - -更新指令。用于表示删除某个字段。如某人删除了自己一条商品评价中的评分: - -```js -//promise -const _ = db.command; -db.collection("comments") - .doc("comment-id") - .update({ - rating: _.remove(), - }) - .then(function (res) {}); -``` - -### push - -向数组尾部追加元素,支持传入单个元素或数组 - -```js -const _ = db.command; -//promise -db.collection("comments") - .doc("comment-id") - .update({ - // users: _.push('aaa') - users: _.push(["aaa", "bbb"]), - }) - .then(function (res) {}); -``` - -### pop - -删除数组尾部元素 - -```js -const _ = db.command; -//promise -db.collection("comments") - .doc("comment-id") - .update({ - users: _.pop(), - }) - .then(function (res) {}); -``` - -### unshift - -向数组头部添加元素,支持传入单个元素或数组。使用同 push - -### shift - -删除数组头部元素。使用同 pop diff --git a/docs/guide/db/add.md b/docs/guide/db/add.md new file mode 100644 index 0000000000..5bb7f91b67 --- /dev/null +++ b/docs/guide/db/add.md @@ -0,0 +1,64 @@ +--- +title: 新增数据 +--- + +# {{ $frontmatter.title }} + +Laf 云函数库中,新增数据非常简单,正规说法为插入文档。以下是插入单个文档和批量插入文档的写法。 + +同时 Laf 云数据库是 `Schema Free` 的,意味着你可以插入任意的字段和数据类型。 + +::: tip +使用 `cloud.database()`新增数据的方法无法自定义 id,所有新增的数据,都会自动生成 id,生成的 id 类型为为 `string` + +使用 `mongodb 原生写法` ,可以自定义 id,也可以自动生成 id,生成的 id 类型为 `ObjectId` +::: + +## 插入单个文档 + +下例向 user 集合中添加了一条记录。 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export default async function (ctx: FunctionContext) { + // 向 user 集合中添加一条记录 + const res = await db.collection('user').add({ name: "jack" }) + console.log(res) +} +``` + +## 批量新增文档 + +当然我们也可以批量添加多条记录,只需要多传入一个对象`{ multi: true }`即可。 + +```typescript +const list = [ + { name: "jack" }, + { name: "rose" } +] +// 向 user 集合中加入多条记录 +const res = await db.collection('user').add(list, { multi: true }) +console.log(res) +``` + +## mongodb 原生写法 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.mongo.db + +export async function main(ctx: FunctionContext) { + // 向 user 集合中插入单个文档 + const result1 = db.collection('user').insertOne({ name: "jack" }) + console.log(result1) + // 向 user 集合中批量插入文档 + const documents = [ + { name: "Jane Doe", age: 25 }, + { name: "Bob Smith", age: 40 } + ]; + const result2 = db.collection('user').insertMany(documents); + console.log(result2) +} +``` diff --git a/docs/guide/db/aggregate.md b/docs/guide/db/aggregate.md new file mode 100644 index 0000000000..10274a32ed --- /dev/null +++ b/docs/guide/db/aggregate.md @@ -0,0 +1,2329 @@ +--- +title: 数据库聚合操作 +--- + +# {{ $frontmatter.title }} + +在进行复杂的数据查询时,需要用到聚合操作。 + +## 获取数据库集合的聚合操作实例 + +```js +db.collection('scores').aggregate() +``` + +**注意:** + +- 聚合操作实例仅用于查询,不可执行增删改操作。在聚合操作实例上只能使用聚合操作方法,不能使用 `where/orderBy` 等基础方法,`where` 需改为 `match`,`orderBy` 应使用 `sort` 实现,细节请阅读下方聚合操作文档。 +- 聚合操作在大数据量下性能不如简单查询,请根据自身业务选择合适的用法 + +云函数中使用时切勿复用 aggregate 实例,容易引发 Bug。 + +以下两种写法均为错误示例: + +```js +const db = cloud.database() +const collection = db.collection('test') +const aggregate = collection.aggregate() // 云函数实例复用时,此聚合实例也会复用,导致 Bug +export default async function (ctx: FunctionContext) { + const res = await aggregate.match({a:1}).end() + return {res} +} +``` + +```js +const db = cloud.database() +const collection = db.collection('test') +export default async function (ctx: FunctionContext) { + const aggregate = collection.aggregate() // 此聚合实例分别在两个请求内使用,导致 Bug + const res1 = await aggregate.match({a:1}).end() + const res2 = await aggregate.match({a:2}).end() + return {res1, res2} +} +``` + +将上述两个用法修正为正确用法分别如下: + +```js +const db = cloud.database() +const collection = db.collection('test') +export default async function (ctx: FunctionContext) { + const aggregate = collection.aggregate() // 每次执行云函数会有独立的聚合实例 + const res = await aggregate.match({a:1}).end() + return {res} +} +``` + +```js +const db = cloud.database() +const collection = db.collection('test') +export default async function (ctx: FunctionContext) { + const res1 = await collection.aggregate().match({a:1}).end() // 两个请求分别调用 aggregate 方法产生聚合实例 + const res2 = await collection.aggregate().match({a:2}).end() + return {res1, res2} +} +``` + +## 聚合表达式 + +表达式可以是字段路径、常量、或数据库运算方法。表达式可以嵌套表达式。 + +**字段路径** + +表达式用字段路径表示法来指定记录中的字段。字段路径的表示由一个 `$` 符号加上字段名或嵌套字段名。嵌套字段名用点将嵌套的各级字段连接起来。如 `$profile` 就表示 `profile` 的字段路径,`$profile.name` 就表示 `profile.name` 的字段路径(`profile` 字段中嵌套的 `name` 字段)。 + +例如:现有以下数据 + +```json +[{ + "profile": { + "name": "Chloe" + }, + "status": 0 +}] +``` + +```js +// 执行以下操作 +let res = await db.collection('scores').aggregate() + .addFields({ + name: '$profile.name' + }) + .end() + +// 返回值为 +{ + "data": [{ + "profile": { + "name": "Chloe" + }, + "status": 0, + "name": "Chloe" + }] +} +``` + +**常量** + +常量可以是任意类型。默认情况下 $ 开头的字符串都会被当做字段路径处理,如果想要避免这种行为,使用 `db.command.aggregate.literal` 声明为常量。 + +**数据库运算方法** + + + +参考数据库运算方法 + +## addFields + +聚合阶段。添加新字段到输出的记录。经过 `addFields` 聚合阶段,输出的所有记录中除了输入时带有的字段外,还将带有 `addFields` 指定的字段。 + +**API 说明** + +`addFields` 等同于同时指定了所有已有字段和新增字段的 `project` 阶段。 + +**`addFields` 的形式如下:** + +```js +addFields({ + <新字段>: <表达式> +}) +``` + +`addFields` 可指定多个新字段,每个新字段的值由使用的表达式决定。 + +如果指定的新字段与原有字段重名,则新字段的值会覆盖原有字段的值。注意 `addFields` 不能用来给数组字段添加元素。 + +**示例 1:连续两次 addFields** + +假设集合 scores 有如下记录: + +```js +{ + _id: 1, + student: "Maya", + homework: [ 10, 5, 10 ], + quiz: [ 10, 8 ], + extraCredit: 0 +} +{ + _id: 2, + student: "Ryan", + homework: [ 5, 6, 5 ], + quiz: [ 8, 8 ], + extraCredit: 8 +} +``` + +应用两次 `addFields`,第一次增加两个字段分别为 `homework` 和 `quiz` 的和值,第二次增加一个字段再基于上两个和值求一次和值。 + +```js +const $ = db.command.aggregate +let res = await db.collection('scores').aggregate() + .addFields({ + totalHomework: $.sum('$homework'), + totalQuiz: $.sum('$quiz') + }) + .addFields({ + totalScore: $.add(['$totalHomework', '$totalQuiz', '$extraCredit']) + }) + .end() +``` + +返回结果如下: + +```js +{ + "_id" : 1, + "student" : "Maya", + "homework" : [ 10, 5, 10 ], + "quiz" : [ 10, 8 ], + "extraCredit" : 0, + "totalHomework" : 25, + "totalQuiz" : 18, + "totalScore" : 43 +} +{ + "_id" : 2, + "student" : "Ryan", + "homework" : [ 5, 6, 5 ], + "quiz" : [ 8, 8 ], + "extraCredit" : 8, + "totalHomework" : 16, + "totalQuiz" : 16, + "totalScore" : 40 +} +``` + +**示例 2:在嵌套记录里增加字段** + +可以用点表示法在嵌套记录里增加字段。假设 vehicles 集合含有如下记录: + +```js +{ _id: 1, type: "car", specs: { doors: 4, wheels: 4 } } +{ _id: 2, type: "motorcycle", specs: { doors: 0, wheels: 2 } } +{ _id: 3, type: "jet ski" } +``` + +可以用如下操作在 `specs` 字段下增加一个新的字段 `fuel_type`,值都设为固定字符串 `unleaded`: + +```js +let res = await db.collection('vehicles').aggregate() + .addFields({ + 'specs.fuel_type': 'unleaded' + }) + .end() +``` + +返回结果如下: + +```js +{ _id: 1, type: "car", + specs: { doors: 4, wheels: 4, fuel_type: "unleaded" } } +{ _id: 2, type: "motorcycle", + specs: { doors: 0, wheels: 2, fuel_type: "unleaded" } } +{ _id: 3, type: "jet ski", + specs: { fuel_type: "unleaded" } } +``` + +**示例 3:设置字段值为另一个字段** + +可以通过 `$` 加字段名组成的字符串作为值的表达式来设置字段的值为另一个字段的值。 + +同样用上一个集合示例,可以用如下操作添加一个字段 `vehicle_type`,将其值设置为 `type` 字段的值: + +```js +let res = await db.collection('vehicles').aggregate() + .addFields({ + vehicle_type: '$type' + }) + .end() +``` + +返回结果如下: + +```js +{ _id: 1, type: "car", vehicle_type: "car", + specs: { doors: 4, wheels: 4, fuel_type: "unleaded" } } +{ _id: 2, type: "motorcycle", vehicle_type: "motorcycle", + specs: { doors: 0, wheels: 2, fuel_type: "unleaded" } } +{ _id: 3, type: "jet ski", vehicle_type: "jet ski", + specs: { fuel_type: "unleaded" } } +``` + +## bucket + +聚合阶段。将输入记录根据给定的条件和边界划分成不同的组,每组即一个 `bucket`。 + +**API 说明** + +每组分别作为一个记录输出,包含一个以下界为值的 `_id` 字段和一个以组中记录数为值的 `count` 字段。`count` 在没有指定 `output` 的时候是默认输出的。 + +`bucket` 只会在组内有至少一个记录的时候输出。 + +**bucket 的形式如下:** + +```js +bucket({ + groupBy: , + boundaries: [, , ...], + default: , + output: { + : , + ... + : + } +}) +``` + +`groupBy` 是一个用以决定分组的表达式,会应用在各个输入记录上。可以用 `$` 前缀加上要用以分组的字段路径来作为表达式。除非用 `default` 指定了默认值,否则每个记录都需要包含指定的字段,且字段值必须在 `boundaries` 指定的范围之内。 + +`boundaries` 是一个数组,每个元素分别是每组的下界。必须至少指定两个边界值。数组值必须是同类型递增的值。 + +`default` 可选,指定之后,没有进入任何分组的记录将都进入一个默认分组,这个分组记录的 `_id` 即由 `default` 决定。`default` 的值必须小于 `boundaries` 中的最小值或大于等于其中的最大值。`default` 的值可以与 `boundaries` 元素值类型不同。 + +`output` 可选,用以决定输出记录除了 `_id` 外还要包含哪些字段,各个字段的值必须用累加器表达式指定。当 `output` 指定时,默认的 `count` 是不会被默认输出的,必须手动指定: + +```js +output: { + count: $.sum(1), + ... + : +} +``` + +使用 bucket 需要满足以下至少一个条件,否则会抛出错误: + +每一个输入记录应用 groupBy 表达式获取的值都必须是一个在 boundaries 内的值 + +指定一个 default 值,该值在 boundaries 以外,或与 boundaries 元素的值不同的类型。 + +**示例** + +假设集合 items 有如下记录: + +```js +{ + _id: "1", + price: 10 +} +{ + _id: "2", + price: 50 +} +{ + _id: "3", + price: 20 +} +{ + _id: "4", + price: 80 +} +{ + _id: "5", + price: 200 +} +``` + +对上述记录进行分组,将 [0, 50) 分为一组,[50, 100) 分为一组,其他分为一组: + +```js +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .bucket({ + groupBy: '$price', + boundaries: [0, 50, 100], + default: 'other', + output: { + count: $.sum(1), + ids: $.push('$_id') + } + }) + .end() +``` + +返回结果如下: + +```js +[ + { + "_id": 0, + "count": 2, + "ids": [ + "1", + "3" + ] + }, + { + "_id": 50, + "count": 2, + "ids": [ + "2", + "4" + ] + }, + { + "_id": "other", + "count": 1, + "ids": [ + "5" + ] + } +] +``` + +## bucketAuto + +聚合阶段。将输入记录根据给定的条件划分成不同的组,每组即一个 `bucket`。与 `bucket` 的其中一个不同之处在于无需指定 `boundaries`,`bucketAuto` 会自动尝试将记录尽可能平均的分散到每组中。 + +**API 说明** +每组分别作为一个记录输出,包含一个以包含组中最大值和最小值两个字段的对象为值的 _id 字段和一个以组中记录数为值的 count 字段。count 在没有指定 output 的时候是默认输出的。 + +**bucketAuto 的形式如下:** + +```js +bucketAuto({ + groupBy: , + buckets: , + granularity: , + output: { + : , + ... + : + } +}) +``` + +`groupBy` 是一个用以决定分组的表达式,会应用在各个输入记录上。可以用 $ 前缀加上要用以分组的字段路径来作为表达式。除非用 `default` 指定了默认值,否则每个记录都需要包含指定的字段,且字段值必须在 `boundaries` 指定的范围之内。 + +`buckets` 是一个用于指定划分组数的正整数。 + +`granularity` 是可选枚举值字符串,用于保证自动计算出的边界符合给定的规则。这个字段仅可在所有 `groupBy` 值都是数字并且没有 `NaN` 的情况下使用。枚举值包括:`R5、R10、R20、R40、R80、1-2-5、E6、E12、E24、E48、E96、E192、POWERSOF2`。 + +`output` 可选,用以决定输出记录除了 `_id` 外还要包含哪些字段,各个字段的值必须用累加器表达式指定。当 `output` 指定时,默认的 `count` 是不会被默认输出的,必须手动指定: + +```js +output: { + count: $.sum(1), + ... + : +} +``` + +在以下情况中,输出的分组可能会小于给定的组数: + +输入记录数少于分组数 + +- `groupBy` 计算得到的唯一值少于分组数 +- `granularity` 的间距少于分组数 +- `granularity` 不够精细以至于不能平均分配到各组 + +**granularity 详细说明** + +`granularity` 用于保证边界值属于一个给定的数字序列。 + +**Renard 序列** + +Renard 序列是以 10 的 5 / 10 / 20 / 40 / 80 次方根来推导的、在 1.0 到 10.0 (如果是 R80 则是 10.3) 之间的数字序列。 + +设置 granularity 为 R5 / R10 / R20 / R40 / R80 就把边界值限定在序列内。如果 groupBy 的值不在 1.0 到 10.0 (如果是 R80 则是 10.3) 内,则序列数字会自动乘以 10。 + +**E 序列** + +E 序列是以 10 的 6 / 12 / 24 / 48 / 96 / 192 次方跟来推导的、带有一个特定误差的、在 1.0 到 10.0 之间的数字序列。 + +**1-2-5 序列** + +1-2-5 序列 表现与三值 Renard 序列一样。 + +**2的次方序列** + +由 2 的各次方组成的序列数字。 + +**示例** + +假设集合 items 有如下记录: + +```js +{ + _id: "1", + price: 10.5 +} +{ + _id: "2", + price: 50.3 +} +{ + _id: "3", + price: 20.8 +} +{ + _id: "4", + price: 80.2 +} +{ + _id: "5", + price: 200.3 +} +``` + +对上述记录进行自动分组,分成三组: + +```js +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .bucketAuto({ + groupBy: '$price', + buckets: 3, + }) + .end() +``` + +返回结果如下: + +```js +{ + "_id": { + "min": 10.5, + "max": 50.3 + }, + "count": 2 +} +{ + "_id": { + "min": 50.3, + "max": 200.3 + }, + "count": 2 +} +{ + "_id": { + "min": 200.3, + "max": 200.3 + }, + "count": 1 +} +``` + +## count + +聚合阶段。计算上一聚合阶段输入到本阶段的记录数,输出一个记录,其中指定字段的值为记录数。 + +**API 说明** + +**count 的形式如下:** + +```js +count() +``` + +`` 是输出记录数的字段的名字,不能是空字符串,不能以 $ 开头,不能包含 . 字符。 + +count 阶段等同于 group + project 的操作: + +```js +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .group({ + _id: null, + count: $.sum(1), + }) + .project({ + _id: 0, + }) + .end() +``` + +上述操作会输出一个包含 count 字段的记录。 + +**示例** + +假设集合 items 有如下记录: + +```js +{ + _id: "1", + price: 10.5 +} +{ + _id: "2", + price: 50.3 +} +{ + _id: "3", + price: 20.8 +} +{ + _id: "4", + price: 80.2 +} +{ + _id: "5", + price: 200.3 +} +``` + +找出价格大于 50 的记录数: + +```js +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .match({ + price: $.gt(50) + }) + .count('expensiveCount') + .end() +``` + +返回结果如下: + +```js +{ + "expensiveCount": 3 +} +``` + +## geoNear + +聚合阶段。将记录按照离给定点从近到远输出。 + +|属性 |类型 |默认值 |必填 |说明 | +|---- |---- |---- |---- |---- | +|near |GeoPoint | |是 |GeoJSON Point,用于判断距离的点 | +|spherical |true | |是 |必填,值为 true | +|maxDistance |number | |否 |距离最大值 | +|minDistance |number | |否 |距离最小值 | +|query |Object | |否 |要求记录必须同时满足该条件(语法同 where) | +|distanceMultiplier |number | |否 |返回时在距离上乘以该数字 | +|distanceField |string | |是 |存放距离的输出字段名,可以用点表示法表示一个嵌套字段 | +|includeLocs |string | |否 |列出要用于距离计算的字段,如果记录中有多个字段都是地理位置时有用 | +|key |string | |否 |选择要用的地理位置索引。如果集合由多个地理位置索引,则必须指定一个,指定的方式是指定对应的字段 | + +**API 说明** + +- `geoNear` 必须为第一个聚合阶段 +- 必须有地理位置索引。如果有多个,必须用 `key` 参数指定要使用的索引。 + +**示例** + +假设集合 attractions 有如下记录: + +```js +{ + "_id": "geoNear.0", + "city": "Guangzhou", + "docType": "geoNear", + "location": { + "type": "Point", + "coordinates": [ + 113.30593, + 23.1361155 + ] + }, + "name": "Canton Tower" +}, +{ + "_id": "geoNear.1", + "city": "Guangzhou", + "docType": "geoNear", + "location": { + "type": "Point", + "coordinates": [ + 113.306789, + 23.1564721 + ] + }, + "name": "Baiyun Mountain" +}, +{ + "_id": "geoNear.2", + "city": "Beijing", + "docType": "geoNear", + "location": { + "type": "Point", + "coordinates": [ + 116.3949659, + 39.9163447 + ] + }, + "name": "The Palace Museum" +}, +{ + "_id": "geoNear.3", + "city": "Beijing", + "docType": "geoNear", + "location": { + "type": "Point", + "coordinates": [ + 116.2328567, + 40.242373 + ] + }, + "name": "Great Wall" +} +``` + +```js +const $ = db.command.aggregate +let res = await db.collection('attractions').aggregate() + .geoNear({ + distanceField: 'distance', // 输出的每个记录中 distance 即是与给定点的距离 + spherical: true, + near: new db.Geo.Point(113.3089506, 23.0968251), + query: { + docType: 'geoNear', + }, + key: 'location', // 若只有 location 一个地理位置索引的字段,则不需填 + includeLocs: 'location', // 若只有 location 一个是地理位置,则不需填 + }) + .end() +``` + +返回结果如下: + +```js +{ + "_id": "geoNear.0", + "location": { + "type": "Point", + "coordinates": [ + 113.30593, + 23.1361155 + ] + }, + "docType": "geoNear", + "name": "Canton Tower", + "city": "Guangzhou", + "distance": 4384.68131486958 +}, +{ + "_id": "geoNear.1", + "city": "Guangzhou", + "location": { + "type": "Point", + "coordinates": [ + 113.306789, + 23.1564721 + ] + }, + "docType": "geoNear", + "name": "Baiyun Mountain", + "distance": 6643.521654040738 +}, +{ + "_id": "geoNear.2", + "docType": "geoNear", + "name": "The Palace Museum", + "city": "Beijing", + "location": { + "coordinates": [ + 116.3949659, + 39.9163447 + ], + "type": "Point" + }, + "distance": 1894750.4414538583 +}, +{ + "_id": "geoNear.3", + "docType": "geoNear", + "name": "Great Wall", + "city": "Beijing", + "location": { + "type": "Point", + "coordinates": [ + 116.2328567, + 40.242373 + ] + }, + "distance": 1928300.3308822548 +} +``` + +## group + +聚合阶段。将输入记录按给定表达式分组,输出时每个记录代表一个分组,每个记录的 _id 是区分不同组的 key。输出记录中也可以包括累计值,将输出字段设为累计值即会从该分组中计算累计值。 + +使用group可以很方便的实现类似SQL的distinct功能 + +**API 说明** + +**group 的形式如下:** + +```js +group({ + _id: , + : , + ... + : +}) +``` + +`_id` 参数是必填的,如果填常量则只有一组。其他字段是可选的,都是累计值,用 `$.sum` 等累计器(`const $ = db.command.aggregate`),但也可以使用其他表达式。 + +累计器必须是以下操作符之一: + +详细使用方法见[累计器操作符](#累计器操作符) + +|操作符 |说明 | +|---- |---- | +|addToSet |向数组中添加值,如果数组中已存在该值,不执行任何操作 | +|avg |返回一组集合中,指定字段对应数据的平均值 | +|sum |计算并且返回一组字段所有数值的总和 | +|first |返回指定字段在一组集合的第一条记录对应的值。仅当这组集合是按照某种定义排序( sort )后,此操作才有意义。 | +|last |返回指定字段在一组集合的最后一条记录对应的值。仅当这组集合是按照某种定义排序( sort )后,此操作才有意义。 | +|max |返回一组数值的最大值 | +|min |返回一组数值的最小值 | +|push |在 group 阶段,返回一组中表达式指定列与对应的值,一起组成的数组 | +|stdDevPop |返回一组字段对应值的标准差 | +|stdDevSamp |计算输入值的样本标准偏差。如果输入值代表数据总体,或者不概括更多的数据,请改用 db.command.aggregate.stdDevPop| +|mergeObjects |将多个文档合并为单个文档 | + +**内存限制** + +该阶段有 100M 内存使用限制。 + +**示例 1:按字段值分组** + +假设集合 avatar 有如下记录: + +```js +{ + _id: "1", + alias: "john", + region: "asia", + scores: [40, 20, 80], + coins: 100 +} +{ + _id: "2", + alias: "arthur", + region: "europe", + scores: [60, 90], + coins: 20 +} +{ + _id: "3", + alias: "george", + region: "europe", + scores: [50, 70, 90], + coins: 50 +} +{ + _id: "4", + alias: "john", + region: "asia", + scores: [30, 60, 100, 90], + coins: 40 +} +{ + _id: "5", + alias: "george", + region: "europe", + scores: [20], + coins: 60 +} +{ + _id: "6", + alias: "john", + region: "asia", + scores: [40, 80, 70], + coins: 120 +} +``` + +```js +const $ = db.command.aggregate +let res = await db.collection('avatar').aggregate() + .group({ + _id: '$alias', + num: $.sum(1) + }) + .end() +``` + +返回结果如下: + +```js +{ + "_id": "john", + "num": 3 +} +{ + "_id": "authur", + "num": 1 +} +{ + "_id": "george", + "num": 2 +} +``` + +**示例 2:按多个值分组** + +可以给 _id 传入记录的方式按多个值分组。还是沿用上面的示例数据,按各个区域(region)获得相同最高分(score)的来分组,并求出各组虚拟币(coins)的总量: + +```js +const $ = db.command.aggregate +let res = await db.collection('avatar').aggregate() + .group({ + _id: { + region: '$region', + maxScore: $.max('$scores') + }, + totalCoins: $.sum('$coins') + }) + .end() +``` + +返回结果如下: + +```js +{ + "_id": { + "region": "asia", + "maxScore": 80 + }, + "totalCoins": 220 +} +{ + "_id": { + "region": "asia", + "maxScore": 100 + }, + "totalCoins": 40 +} +{ + "_id": { + "region": "europe", + "maxScore": 90 + }, + "totalCoins": 70 +} +{ + "_id": { + "region": "europe", + "maxScore": 20 + }, + "totalCoins": 60 +} +``` + +## limit + +聚合阶段。限制输出到下一阶段的记录数。 + +**示例** + +假设集合 items 有如下记录: + +```js +{ + _id: "1", + price: 10 +} +{ + _id: "2", + price: 50 +} +{ + _id: "3", + price: 20 +} +{ + _id: "4", + price: 80 +} +{ + _id: "5", + price: 200 +} +``` + +返回价格大于 20 的记录的最小的两个记录: + +```js +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .match({ + price: $.gt(20) + }) + .sort({ + price: 1, + }) + .limit(2) + .end() +``` + +返回结果如下: + +```js +{ + "_id": "2", + "price": 50 +} +{ + "_id": "4", + "price": 80 +} +``` + +## lookup + +聚合阶段。联表查询。与同个数据库下的一个指定的集合做 left outer join(左外连接)。对该阶段的每一个输入记录,lookup 会在该记录中增加一个数组字段,该数组是被联表中满足匹配条件的记录列表。lookup 会将连接后的结果输出给下个阶段。 + +**API 说明** + +`lookup` 有两种使用方式 + +### 相等匹配 + +将输入记录的一个字段和被连接集合的一个字段进行相等匹配时,采用以下定义: + +```js +lookup({ + from: <要连接的集合名>, + localField: <输入记录的要进行相等匹配的字段>, + foreignField: <被连接集合的要进行相等匹配的字段>, + as: <输出的数组字段名> +}) +``` + +**参数详细说明** + +|参数字段 |说明 | +|---- |---- | +|from |要进行连接的另外一个集合的名字 | +|localField |当前流水线的输入记录的字段名,该字段将被用于与 from 指定的集合的 foreignField 进行相等匹配。如果输入记录中没有该字段,则该字段的值在匹配时会被视作 null| +|foreignField |被连接集合的字段名,该字段会被用于与 localField 进行相等匹配。如果被连接集合的记录中没有该字段,该字段的值将在匹配时被视作 null | +|as |指定连接匹配出的记录列表要存放的字段名,这个数组包含的是匹配出的来自 from 集合的记录。如果输入记录中本来就已有该字段,则该字段会被覆写 | + +这个操作等价于以下伪 SQL 操作: + +``` +SELECT *, +FROM collection +WHERE IN (SELECT * + FROM + WHERE = ); +``` + +**例子:** + +- 指定一个相等匹配条件 +- 对数组字段应用相等匹配 +- 组合 mergeObjects 应用相等匹配 + +### 自定义连接条件、拼接子查询 + +如果需要指定除相等匹配之外的连接条件,或指定多个相等匹配条件,或需要拼接被连接集合的子查询结果,那可以使用如下定义: + +```js +lookup({ + from: <要连接的集合名>, + let: { <变量 1>: <表达式 1>, ..., <变量 n>: <表达式 n> }, + pipeline: [ <在要连接的集合上进行的流水线操作> ], + as: <输出的数组字段名> +}) +``` + +**参数详细说明** + +|参数字段 |说明 | +|---- |---- | +|from |要进行连接的另外一个集合的名字 | +|let |可选。指定在 pipeline 中可以使用的变量,变量的值可以引用输入记录的字段,比如 let: { userName: '$name' } 就代表将输入记录的 name 字段作为变量 userName 的值。在 pipeline 中无法直接访问输入记录的字段,必须通过 let 定义之后才能访问,访问的方式是在 expr 操作符中用 $$变量名 的方式访问,比如 $$userName。 | +|pipeline |指定要在被连接集合中运行的聚合操作。如果要返回整个集合,则该字段取值空数组 []。在 pipeline 中无法直接访问输入记录的字段,必须通过 let 定义之后才能访问,访问的方式是在 expr 操作符中用 $$变量名 的方式访问,比如 $$userName。 | +|as |指定连接匹配出的记录列表要存放的字段名,这个数组包含的是匹配出的来自 from 集合的记录。如果输入记录中本来就已有该字段,则该字段会被覆写 | + +该操作等价于以下伪 SQL 语句: + +``` +SELECT *, +FROM collection +WHERE IN (SELECT + FROM + WHERE ); +``` + +**例子** + +- 指定多个连接条件 +- 拼接被连接集合的子查询 + +**示例** + +**指定一个相等匹配条件** + +假设 orders 集合有以下记录: + +```js +[ + {"_id":4,"book":"novel 1","price":30,"quantity":2}, + {"_id":5,"book":"science 1","price":20,"quantity":1}, + {"_id":6} +] +``` + +books 集合有以下记录: + +```js +[ + {"_id":"book1","author":"author 1","category":"novel","stock":10,"time":1564456048486,"title":"novel 1"}, + {"_id":"book3","author":"author 3","category":"science","stock":30,"title":"science 1"}, + {"_id":"book4","author":"author 3","category":"science","stock":40,"title":"science 2"}, + {"_id":"book2","author":"author 2","category":"novel","stock":20,"title":"novel 2"}, + {"_id":"book5","author":"author 4","category":"science","stock":50,"title":null}, + {"_id":"book6","author":"author 5","category":"novel","stock":"60"} +] +``` + +以下聚合操作可以通过一个相等匹配条件连接 `orders` 和 `books` 集合,匹配的字段是 `orders` 集合的 `book` 字段和 `books` 集合的 title 字段: + +```js +const db = cloud.database() +let res = await db.collection('orders').aggregate() + .lookup({ + from: 'books', + localField: 'book', + foreignField: 'title', + as: 'bookList', + }) + .end() +``` + +结果: + +```js +[ + { + "_id": 4, + "book": "novel 1", + "price": 30, + "quantity": 2, + "bookList": [ + { + "_id": "book1", + "title": "novel 1", + "author": "author 1", + "category": "novel", + "stock": 10 + } + ] + }, + { + "_id": 5, + "book": "science 1", + "price": 20, + "quantity": 1, + "bookList": [ + { + "_id": "book3", + "category": "science", + "title": "science 1", + "author": "author 3", + "stock": 30 + } + ] + }, + { + "_id": 6, + "bookList": [ + { + "_id": "book5", + "category": "science", + "author": "author 4", + "stock": 50, + "title": null + }, + { + "_id": "book6", + "author": "author 5", + "stock": "60", + "category": "novel" + } + ] + } +] +``` + +对数组字段应用相等匹配 +假设 authors 集合有以下记录: + +```js +[ + {"_id": 1, "name": "author 1", "intro": "Two-time best-selling sci-fiction novelist"}, + {"_id": 3, "name": "author 3", "intro": "UCB assistant professor"}, + {"_id": 4, "name": "author 4", "intro": "major in CS"} +] +``` + +books 集合有以下记录: + +```js +[ + {"_id":"book1","authors":["author 1"],"category":"novel","stock":10,"time":1564456048486,"title":"novel 1"}, + {"_id":"book3","authors":["author 3", "author 4"],"category":"science","stock":30,"title":"science 1"}, + {"_id":"book4","authors":["author 3"],"category":"science","stock":40,"title":"science 2"} +] +``` + +以下操作获取作者信息及他们分别发表的书籍,使用了 lookup 操作匹配 authors 集合的 name 字段和 books 集合的 authors 数组字段: + +```js +const db = cloud.database() +let res = await db.collection('authors').aggregate() + .lookup({ + from: 'books', + localField: 'name', + foreignField: 'authors', + as: 'publishedBooks', + }) + .end() +``` + +结果 + +```js +[ + { + "_id": 1, + "intro": "Two-time best-selling sci-fiction novelist", + "name": "author 1", + "publishedBooks": [ + { + "_id": "book1", + "title": "novel 1", + "category": "novel", + "stock": 10, + "authors": [ + "author 1" + ] + } + ] + }, + { + "_id": 3, + "name": "author 3", + "intro": "UCB assistant professor", + "publishedBooks": [ + { + "_id": "book3", + "category": "science", + "title": "science 1", + "stock": 30, + "authors": [ + "author 3", + "author 4" + ] + }, + { + "_id": "book4", + "title": "science 2", + "category": "science", + "stock": 40, + "authors": [ + "author 3" + ] + } + ] + }, + { + "_id": 4, + "intro": "major in CS", + "name": "author 4", + "publishedBooks": [ + { + "_id": "book3", + "category": "science", + "title": "science 1", + "stock": 30, + "authors": [ + "author 3", + "author 4" + ] + } + ] + } +] +``` + +**组合 mergeObjects 应用相等匹配** + +假设 `orders` 集合有以下记录: + +```js +[ + {"_id":4,"book":"novel 1","price":30,"quantity":2}, + {"_id":5,"book":"science 1","price":20,"quantity":1}, + {"_id":6} +] +``` + +`books` 集合有以下记录: + +```js +[ + {"_id":"book1","author":"author 1","category":"novel","stock":10,"time":1564456048486,"title":"novel 1"}, + {"_id":"book3","author":"author 3","category":"science","stock":30,"title":"science 1"}, + {"_id":"book4","author":"author 3","category":"science","stock":40,"title":"science 2"}, + {"_id":"book2","author":"author 2","category":"novel","stock":20,"title":"novel 2"}, + {"_id":"book5","author":"author 4","category":"science","stock":50,"title":null}, + {"_id":"book6","author":"author 5","category":"novel","stock":"60"} +] +``` + +以下操作匹配 orders 的 book 字段和 books 的 title 字段,并将 books 匹配结果直接 merge 到 orders 记录中。 + +```js +var db = cloud.database() +var $ = db.command.aggregate +let res = await db.collection('orders').aggregate() + .lookup({ + from: "books", + localField: "book", + foreignField: "title", + as: "bookList" + }) + .replaceRoot({ + newRoot: $.mergeObjects([ $.arrayElemAt(['$bookList', 0]), '$$ROOT' ]) + }) + .project({ + bookList: 0 + }) + .end() +``` + +结果 + +```js +[ + { + "_id": 4, + "title": "novel 1", + "author": "author 1", + "time": 1564456048486, + "category": "novel", + "stock": 10, + "book": "novel 1", + "price": 30, + "quantity": 2 + }, + { + "_id": 5, + "category": "science", + "title": "science 1", + "author": "author 3", + "stock": 30, + "book": "science 1", + "price": 20, + "quantity": 1 + }, + { + "_id": 6, + "category": "science", + "author": "author 4", + "stock": 50, + "title": null + } +] +``` + +**指定多个连接条件** + +假设 `orders` 集合有以下记录: + +```js +[ + {"_id":4,"book":"novel 1","price":300,"quantity":20}, + {"_id":5,"book":"science 1","price":20,"quantity":1} +] +``` + +`books` 集合有以下记录: + +```js +[ + {"_id":"book1","author":"author 1","category":"novel","stock":10,"time":1564456048486,"title":"novel 1"}, + {"_id":"book3","author":"author 3","category":"science","stock":30,"title":"science 1"} +] +``` + +以下操作连接 `orders` 和 `books` 集合,要求两个条件: + +- orders 的 book 字段与 books 的 title 字段相等 +- books 的 stock 字段 大于或等于 orders 的 quantity 字段 + +```js +const db = cloud.database() +const dbCmd = db.command +const $ = dbCmd.aggregate +let res = await db.collection('orders').aggregate() + .lookup({ + from: 'books', + let: { + order_book: '$book', + order_quantity: '$quantity' + }, + pipeline: $.pipeline() + .match(dbCmd.expr($.and([ + $.eq(['$title', '$$order_book']), + $.gte(['$stock', '$$order_quantity']) + ]))) + .project({ + _id: 0, + title: 1, + author: 1, + stock: 1 + }) + .done(), + as: 'bookList', + }) + .end() +``` + +结果: + +```js +[ + { + "_id": 4, + "book": "novel 1", + "price": 300, + "quantity": 20, + "bookList": [] + }, + { + "_id": 5, + "book": "science 1", + "price": 20, + "quantity": 1, + "bookList": [ + { + "title": "science 1", + "author": "author 3", + "stock": 30 + } + ] + } +] +``` + +**拼接被连接集合的子查询** + +假设 `orders` 集合有以下记录: + +```js +[ + {"_id":4,"book":"novel 1","price":30,"quantity":2}, + {"_id":5,"book":"science 1","price":20,"quantity":1} +] +``` + +`books` 集合有以下记录: + +```js +[ + {"_id":"book1","author":"author 1","category":"novel","stock":10,"time":1564456048486,"title":"novel 1"}, + {"_id":"book3","author":"author 3","category":"science","stock":30,"title":"science 1"}, + {"_id":"book4","author":"author 3","category":"science","stock":40,"title":"science 2"} +] +``` + +在每条输出记录上加上一个数组字段,该数组字段的值是对 books 集合的一个查询语句的结果: + +```js +const db = cloud.database() +const $ = db.command.aggregate +let res = await db.collection('orders').aggregate() + .lookup({ + from: 'books', + let: { + order_book: '$book', + order_quantity: '$quantity' + }, + pipeline: $.pipeline() + .match({ + author: 'author 3' + }) + .project({ + _id: 0, + title: 1, + author: 1, + stock: 1 + }) + .done(), + as: 'bookList', + }) + .end() +``` + +结果 + +```js +[ + { + "_id": 4, + "book": "novel 1", + "price": 30, + "quantity": 20, + "bookList": [ + { + "title": "science 1", + "author": "author 3", + "stock": 30 + }, + { + "title": "science 2", + "author": "author 3", + "stock": 40 + } + ] + }, + { + "_id": 5, + "book": "science 1", + "price": 20, + "quantity": 1, + "bookList": [ + { + "title": "science 1", + "author": "author 3", + "stock": 30 + }, + { + "title": "science 2", + "author": "author 3", + "stock": 40 + } + ] + } +] +``` + +**多表联表查询** + +假设 `orders` 集合有以下记录: + +```js +[ + {"_id":4,"book":"book1","price":30,"quantity":2}, + {"_id":5,"book":"book2","price":20,"quantity":1} +] +``` + +`books` 集合有以下记录: + +```js +[ + {"_id":"book1","author":"author1","title":"novel 1"}, + {"_id":"book2","author":"author2","title":"science 1"}, +] +``` + +`authors` 集合有以下记录: + +```js +[ + {"_id":"author1","name":"A1"}, + {"_id":"author2","author":"A2"} +] +``` + +如需orders关联books,book再关联authors查询,可以在pipeline内再使用lookup + +```js +const db = cloud.database() +const dbCmd = db.command +const $ = db.command.aggregate +let res = await db.collection('orders').aggregate() + .lookup({ + from: 'books', + let: { + book_id: '$book' + }, + pipeline: $.pipeline() + .match( + dbCmd.expr($.eq(['$_id', '$$book_id'])) + ) + .lookup({ + from: 'authors', + let: { + author_id: '$author' + }, + pipeline: $.pipeline() + .match( + dbCmd.expr($.eq(['$_id', '$$author_id'])) + ) + .done(), + as: 'authorList' + }) + .done(), + as: 'bookList', + }) + .end() + +``` + +结果如下 + +```js +[ + { + "_id":4, + "book":"book1", + "price":30, + "quantity":2, + "bookList": [{ + "_id":"book1", + "author":"author1", + "title":"novel 1", + authorList: [{ + "_id":"author1", + "name":"A1" + }] + }] + }, + { + "_id":5, + "book":"book2", + "price":20, + "quantity":1, + "bookList": [{ + "_id":"book2", + "author":"author2", + "title":"science 1", + authorList: [{ + "_id":"author2", + "name":"A2" + }] + }] + } +] +``` + +## match + +聚合阶段。根据条件过滤文档,并且把符合条件的文档传递给下一个流水线阶段。 + +**API 说明** + +**match 的形式如下:** + +```js +match(<查询条件>) +``` + +查询条件与普通查询一致,可以用普通查询操作符,注意 match 阶段和其他聚合阶段不同,不可使用数据库运算方法,只能使用查询操作符。 + +```js +// 直接使用字符串 +match({ + name: 'Tony Stark' +}) +``` + +```js +// 使用操作符 +const dbCmd = db.command +match({ + age: dbCmd.gt(18) +}) +``` + +**示例** + +假设集合 articles 有如下记录: + +```js +{ "_id" : "1", "author" : "stark", "score" : 80 } +{ "_id" : "2", "author" : "stark", "score" : 85 } +{ "_id" : "3", "author" : "bob", "score" : 60 } +{ "_id" : "4", "author" : "li", "score" : 55 } +{ "_id" : "5", "author" : "jimmy", "score" : 60 } +{ "_id" : "6", "author" : "li", "score" : 94 } +{ "_id" : "7", "author" : "justan", "score" : 95 } +``` + +**匹配** + +下面是一个直接匹配的例子: + +```js +let res = await db.collection('articles') + .aggregate() + .match({ + author: 'stark' + }) + .end() +``` + +这里的代码尝试找到所有 author 字段是 stark 的文章,那么匹配如下: + +```js +{ "_id" : "1", "author" : "stark", "score" : 80 } +{ "_id" : "2", "author" : "stark", "score" : 85 } +``` + +**计数** + +match 过滤出文档后,还可以与其他流水线阶段配合使用。 + +比如下面这个例子,我们使用 group 进行搭配,计算 score 字段大于 80 的文档数量: + +```js +const dbCmd = db.command +const $ = dbCmd.aggregate +let res = await db.collection('articles') + .aggregate() + .match({ + score: dbCmd.gt(80) + }) + .group({ + _id: null, + count: $.sum(1) + }) + .end() +``` + +返回值如下: + +```js +{ "_id" : null, "count" : 3 } +``` + +## project + +聚合阶段。把指定的字段传递给下一个流水线,指定的字段可以是某个已经存在的字段,也可以是计算出来的新字段。 + +**API 说明** + +**project 的形式如下:** + +```js +project({ + <表达式> +}) +``` + +表达式可以有以下格式: + +|格式 |说明 | +|---- |---- | +|<字段>: <1 或 true> |指定包含某个已有字段 | +|_id: <0 或 false> |舍弃 _id 字段 | +|<字段>: <表达式> |加入一个新字段,或者重置某个已有字段 | +|<字段>: <0 或 false> |舍弃某个字段(如果你指定舍弃了某个非 _id 字段,那么在此次 project 中,你不能再使用其它表达式) | + +**指定包含字段** + +_id 字段是默认包含在输出中的,除此之外其他任何字段,如果想要在输出中体现的话,必须在 project 中指定; 如果指定包含一个尚不存在的字段,那么 project 会忽略这个字段,不会加入到输出的文档中; + +**指定排除字段** + +如果你在 project 中指定排除某个字段,那么其它字段都会体现在输出中; 如果指定排除的是非 _id 字段,那么在本次 project 中,不能再使用其它表达式; + +**加入新的字段或重置某个已有字段** + +你可以使用一些特殊的表达式加入新的字段,或重置某个已有字段。 + +**多层嵌套的字段** + +有时有些字段处于多层嵌套的底层,我们可以使用点记法: + +```js +"contact.phone.number": <1 or 0 or 表达式> +``` + +也可以直接使用嵌套的格式: + +```js +contact: { phone: { number: <1 or 0 or 表达式> } } +``` + +**示例** + +假设我们有一个 articles 集合,其中含有以下文档: + +```js +{ + "_id": 666, + "title": "This is title", + "author": "Nobody", + "isbn": "123456789", + "introduction": "......" +} +``` + +**指定包含某些字段** + +下面的代码使用 project,让输出只包含 _id、title 和 author 字段: + +```js +let res = await db.collection('articles') + .aggregate() + .project({ + title: 1, + author: 1 + }) + .end() +``` + +输出如下: + +```js +{ "_id" : 666, "title" : "This is title", "author" : "Nobody" } +``` + +**去除输出中的 _id 字段** + +_id 是默认包含在输出中的,如果不想要它,可以指定去除它: + +```js +let res = await db.collection('articles') + .aggregate() + .project({ + _id: 0, // 指定去除 _id 字段 + title: 1, + author: 1 + }) + .end() +``` + +输出如下: + +```js +{ "title" : "This is title", "author" : "Nobody" } +``` + +**去除某个非 _id 字段** + +我们还可以指定在输出中去掉某个非 _id 字段,这样其它字段都会被输出: + +```js +let res = await db.collection('articles') + .aggregate() + .project({ + isbn: 0, // 指定去除 isbn 字段 + }) + .end() +``` + +输出如下,相比输入,没有了 isbn 字段: + +```js +{ + "_id" : 666, + "title" : "This is title", + "author" : "Nobody", + "introduction": "......" +} +``` + +**加入计算出的新字段** + +假设我们有一个 students 集合,其中包含以下文档: + +```js +{ + "_id": 1, + "name": "小明", + "scores": { + "chinese": 80, + "math": 90, + "english": 70 + } +} +``` + +下面的代码,我们使用 project,在输出中加入了一个新的字段 totalScore: + +```js +const { sum } = db.command.aggregate +let res = await db.collection('students') + .aggregate() + .project({ + _id: 0, + name: 1, + totalScore: sum([ + "$scores.chinese", + "$scores.math", + "$scores.english" + ]) + }) + .end() +``` + +输出为: + +```js +{ "name": "小明", "totalScore": 240 } +``` + +**加入新的数组字段** + +假设我们有一个 points 集合,包含以下文档: + +```js +{ "_id": 1, "x": 1, "y": 1 } +{ "_id": 2, "x": 2, "y": 2 } +{ "_id": 3, "x": 3, "y": 3 } +``` + +下面的代码,我们使用 project,把 x 和 y 字段,放入到一个新的数组字段 coordinate 中: + +```js +let res = await db.collection('points') + .aggregate() + .project({ + coordinate: ["$x", "$y"] + }) + .end() +``` + +输出如下: + +```js +{ "_id": 1, "coordinate": [1, 1] } +{ "_id": 2, "coordinate": [2, 2] } +{ "_id": 3, "coordinate": [3, 3] } +``` + +## replaceRoot + +聚合阶段。指定一个已有字段作为输出的根节点,也可以指定一个计算出的新字段作为根节点。 + +**API 说明** + +**replaceRoot 使用形式如下:** + +```js +replaceRoot({ + newRoot: <表达式> +}) +``` + +表达式格式如下: + +|格式 |说明 | +|---- |---- | +|<字段名> |指定一个已有字段作为输出的根节点(如果字段不存在则报错) | +|<对象> |计算一个新字段,并且把这个新字段作为根节点 | + +**示例** + +**使用已有字段作为根节点** + +假设我们有一个 schools 集合,内容如下: + +```js +{ + "_id": 1, + "name": "SFLS", + "teachers": { + "chinese": 22, + "math": 18, + "english": 21, + "other": 123 + } +} +``` + +下面的代码使用 replaceRoot,把 teachers 字段作为根节点输出: + +```js +let res = await db.collection('schools') + .aggregate() + .replaceRoot({ + newRoot: '$teachers' + }) + .end() +``` + +输出如下: + +```js +{ + "chinese": 22, + "math": 18, + "english": 21, + "other": 123 +} +``` + +**使用计算出的新字段作为根节点** + +假设我们有一个 roles 集合,内容如下: + +```js +{ "_id": 1, "first_name": "四郎", "last_name": "黄" } +{ "_id": 2, "first_name": "邦德", "last_name": "马" } +{ "_id": 3, "first_name": "牧之", "last_name": "张" } +``` + +下面的代码使用 replaceRoot,把 first_name 和 last_name 拼在一起: + +```js +const { concat } = db.command.aggregate +let res = await db.collection('roles') + .aggregate() + .replaceRoot({ + newRoot: { + full_name: concat(['$last_name', '$first_name']) + } + }) + .end() +``` + +输出如下: + +```js +{ "full_name": "黄四郎" } +{ "full_name": "马邦德" } +{ "full_name": "张牧之" } +``` + +## sample + +**注意** + +- 此方法在数据量大的集合高频调用时可能会导致响应缓慢 +- 腾讯云数据库操作有默认20的limit,如需使用sample返回20条以上数据,请额外指定limit,例:`sample({size:40}).limit(40)` + +聚合阶段。随机从文档中选取指定数量的记录。 + +**API 说明** + +**sample 的形式如下:** + +```js +sample({ + size: <正整数> +}) +``` + +请注意:size 是正整数,否则会出错。 + +**示例** + +假设文档 users 有以下记录: + +```js +{ "name": "a" } +{ "name": "b" } +``` + +**随机选取** + +如果现在进行抽奖活动,需要选出一名幸运用户。那么 sample 的调用方式如下: + +```js +let res = await db.collection('users') + .aggregate() + .sample({ + size: 1 + }) + .end() +``` + +返回了随机选中的一个用户对应的记录,结果如下: + +```js +{ "_id": "696529e4-7e82-4e7f-812e-5144714edff6", "name": "b" } +``` + +## skip + +聚合阶段。指定一个正整数,跳过对应数量的文档,输出剩下的文档。 + +**示例** + +```js +let res = await db.collection('users') + .aggregate() + .skip(5) + .end() +``` + +这段代码会跳过查找到的前 5 个文档,并且把剩余的文档输出。 + +## sort + +聚合阶段。根据指定的字段,对输入的文档进行排序。 + +**API 说明** + +**形式如下:** + +```js +sort({ + <字段名 1>: <排序规则>, + <字段名 2>: <排序规则>, +}) +``` + +<排序规则>可以是以下取值: + +- 1 代表升序排列(从小到大); +- -1 代表降序排列(从大到小); + +**示例** + +升序/降序排列 + +假设我们有集合 articles,其中包含数据如下: + +```js +{ "_id": "1", "author": "stark", "score": 80, "age": 18 } +{ "_id": "2", "author": "bob", "score": 60, "age": 18 } +{ "_id": "3", "author": "li", "score": 55, "age": 19 } +{ "_id": "4", "author": "jimmy", "score": 60, "age": 22 } +{ "_id": "5", "author": "justan", "score": 95, "age": 33 } +``` + +```js +let res = await db.collection('articles') + .aggregate() + .sort({ + age: -1, + score: -1 + }) + .end() +``` + +上面的代码在 students 集合中进行聚合搜索,并且将结果排序,首先根据 age 字段降序排列,然后再根据 score 字段进行降序排列。 + +输出结果如下: + +```js +{ "_id": "5", "author": "justan", "score": 95, "age": 33 } +{ "_id": "4", "author": "jimmy", "score": 60, "age": 22 } +{ "_id": "3", "author": "li", "score": 55, "age": 19 } +{ "_id": "1", "author": "stark", "score": 80, "age": 18 } +{ "_id": "2", "author": "bob", "score": 60, "age": 18 } +``` + +## sortByCount + +聚合阶段。根据传入的表达式,将传入的集合进行分组(group)。然后计算不同组的数量,并且将这些组按照它们的数量进行排序,返回排序后的结果。 + +**API 说明** + +**sortByCount 的调用方式如下:** + +```js +sortByCount(<表达式>) +``` + +表达式的形式是:$ + 指定字段。请注意:不要漏写 $ 符号。 + +**示例** + +**统计基础类型** + +假设集合 passages 的记录如下: + +```js +{ "category": "Web" } +{ "category": "Web" } +{ "category": "Life" } +``` + +下面的代码就可以统计文章的分类信息,并且计算每个分类的数量。即对 category 字段执行 sortByCount 聚合操作。 + +```js +let res = await db.collection('passages') + .aggregate() + .sortByCount('$category') + .end() +``` + +返回的结果如下所示:Web 分类下有2篇文章,Life 分类下有1篇文章。 + +```js +{ "_id": "Web", "count": 2 } +{ "_id": "Life", "count": 1 } +``` + +**解构数组类型** + +假设集合 passages 的记录如下:tags 字段对应的值是数组类型。 + +```js +{ "tags": [ "JavaScript", "C#" ] } +{ "tags": [ "Go", "C#" ] } +{ "tags": [ "Go", "Python", "JavaScript" ] } +``` + +如何统计文章的标签信息,并且计算每个标签的数量?因为 tags 字段对应的数组,所以需要借助 unwind 操作解构 tags 字段,然后再调用 sortByCount。 + +下面的代码实现了这个功能: + +```js +let res = await db.collection('passages') + .aggregate() + .unwind(`$tags`) + .sortByCount(`$tags`) + .end() +``` + +返回的结果如下所示: + +```js +{ "_id": "Go", "count": 2 } +{ "_id": "C#", "count": 2 } +{ "_id": "JavaScript", "count": 2 } +{ "_id": "Python", "count": 1 } +``` + +## unwind + +聚合阶段。使用指定的数组字段中的每个元素,对文档进行拆分。拆分后,文档会从一个变为一个或多个,分别对应数组的每个元素。 + +**API 说明** + +使用指定的数组字段中的每个元素,对文档进行拆分。拆分后,文档会从一个变为一个或多个,分别对应数组的每个元素。 + +**unwind 有两种使用形式:** + +**参数是一个字段名** + +```js +unwind(<字段名>) +``` + +**参数是一个对象** + +```js +unwind({ + path: <字段名>, + includeArrayIndex: , + preserveNullAndEmptyArrays: +}) +``` + +|字段 |类型 |说明 | +|---- |---- |---- | +|path |string |想要拆分的数组的字段名,需要以 $ 开头。 | +|includeArrayIndex |string |可选项,传入一个新的字段名,数组索引会保存在这个新的字段上。新的字段名不能以 $ 开头。 | +|preserveNullAndEmptyArrays |boolean|如果为 true,那么在 path 对应的字段为 null、空数组或者这个字段不存在时,依然会输出这个文档;如果为 false,unwind 将不会输出这些文档。默认为 false。| + +**示例** + +**拆分数组** + +假设我们有一个 products 集合,包含数据如下: + +```js +{ "_id": "1", "product": "tshirt", "size": ["S", "M", "L"] } +{ "_id": "2", "product": "pants", "size": [] } +{ "_id": "3", "product": "socks", "size": null } +{ "_id": "4", "product": "trousers", "size": ["S"] } +{ "_id": "5", "product": "sweater", "size": ["M", "L"] } +``` + +我们根据 size 字段对这些文档进行拆分 + +```js +db.collection('products') + .aggregate() + .unwind('$size') + .end() +``` + +输出如下: + +```js +{ "_id": "1", "product": "tshirt", "size": "S" } +{ "_id": "1", "product": "tshirt", "size": "M" } +{ "_id": "1", "product": "tshirt", "size": "L" } +{ "_id": "4", "product": "trousers", "size": "S" } +{ "_id": "5", "product": "sweater", "size": "M" } +{ "_id": "5", "product": "sweater", "size": "L" } +``` + +**拆分后,保留原数组的索引** + +我们根据 size 字段对文档进行拆分后,想要保留原数组索引在新的 index 字段中。 + +```js +let res = await db.collection('products') + .aggregate() + .unwind({ + path: '$size', + includeArrayIndex: 'index' + }) + .end() +``` + +输出如下: + +```js +{ "_id": "1", "product": "tshirt", "size": "S", "index": 0 } +{ "_id": "1", "product": "tshirt", "size": "M", "index": 1 } +{ "_id": "1", "product": "tshirt", "size": "L", "index": 2 } +{ "_id": "4", "product": "trousers", "size": "S", "index": 0 } +{ "_id": "5", "product": "sweater", "size": "M", "index": 0 } +{ "_id": "5", "product": "sweater", "size": "L", "index": 1 } +``` + +**保留字段为空的文档** + +注意到我们的集合中有两行特殊的空值数据: + +```js +... +{ "_id": "2", "product": "pants", "size": [] } +{ "_id": "3", "product": "socks", "size": null } +... +``` + +如果想要在输出中保留 size 为空数组、null,或者 size 字段不存在的文档,可以使用 preserveNullAndEmptyArrays 参数 + +```js +let res = await db.collection('products') + .aggregate() + .unwind({ + path: '$size', + preserveNullAndEmptyArrays: true + }) + .end() +``` + +输出如下: + +```js +{ "_id": "1", "product": "tshirt", "size": "S" } +{ "_id": "1", "product": "tshirt", "size": "M" } +{ "_id": "1", "product": "tshirt", "size": "L" } +{ "_id": "2", "product": "pants", "size": null } +{ "_id": "3", "product": "socks", "size": null } +{ "_id": "4", "product": "trousers", "size": "S" } +{ "_id": "5", "product": "sweater", "size": "M" } +{ "_id": "5", "product": "sweater", "size": "L" } +``` + +## end + +标志聚合操作定义完成,发起实际聚合操作 + +**返回值** + +Promise.<Object> + +|属性 |类型 |说明 | +|--- |--- |--- | +|list |Array.<any>|聚合结果列表 | + +**示例代码** + +```js +const $ = db.command.aggregate +let res = await db.collection('books').aggregate() + .group({ + // 按 category 字段分组 + _id: '$category', + // 让输出的每组记录有一个 avgSales 字段,其值是组内所有记录的 sales 字段的平均值 + avgSales: $.avg('$sales') + }) + .end() +``` diff --git a/docs/guide/db/command.md b/docs/guide/db/command.md new file mode 100644 index 0000000000..389e3a3842 --- /dev/null +++ b/docs/guide/db/command.md @@ -0,0 +1,1132 @@ +--- +title: 数据库操作符 +--- + +# {{ $frontmatter.title }} + +Laf 云函数支持多种不同的数据库操作符,用于执行查询、更新、删除等操作。 + +## 初始化操作符 + +```typescript +const db = cloud.database() +const _ = db.command +// 后续操作 用 _ 即可 +``` + +## 查询·逻辑操作符 + +### and + +查询操作符,用于表示逻辑 "与" 的关系,表示需同时满足多个查询筛选条件 + +#### 使用说明 + + `and` 有两种使用情况: + +**1. 用在根查询条件** + + 此时需传入多个查询条件,表示需同时满足提供的多个完整查询条件 + +```js +const _ = db.command +let res = await db.collection('todo').where(_.and([ + { + progress: _.gt(50) + }, + { + tags: 'cloud' + } +])).get() +``` + +但以上用 `and` 组成的查询条件是不必要的,因为传入的对象的各字段隐式组成了 "与" 的关系,上述条件等价于下方更简洁的写法: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.gt(50), + tags: 'cloud' +}).get() +``` + +通常需要显示使用 `and` 是用在有跨字段或操作的时候 + +**2. 用在字段查询条件** + + 需传入多个查询操作符或常量,表示字段需满足或匹配给定的条件。 + + 如以下用前置写法的方式表示 "progress 字段值大于 50 且小于 100" + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.and(_.gt(50), _.lt(100)) +}).get() +``` + +还可以用后置写法的方式表示同样的条件: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.gt(50).and(_.lt(100)) +}).get() +``` + +注意 `Command` 默认也可以直接链式调用其他 `Command`,默认表示多个 `Command` 的与操作,因此上述代码还可以精简为: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.gt(50).lt(100) +}).get() +``` + +### or + +查询操作符,用于表示逻辑 "或" 的关系,表示需同时满足多个查询筛选条件。或指令有两种用法,一是可以进行字段值的 "或" 操作,二是也可以进行跨字段的“或”操作。 + +#### 字段值的或操作 + + 字段值的“或”操作指的是指定一个字段值为多个值之一即可。 + + 如筛选出进度大于 80 或小于 20 的 todo: + + 流式写法: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.gt(80).or(_.lt(20)) +}).get() +``` + +前置写法: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.or(_.gt(80), _.lt(20)) +}).get() +``` + +前置写法也可接收一个数组: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.or([_.gt(80), _.lt(20)]) +}).get() +``` + +#### 跨字段的或操作 + + 跨字段的“或”操作指条件“或”,相当于可以传入多个 where 语句,满足其中一个即可。 + + 如筛选出进度大于 80 或已标为已完成的 todo: + +```js +const _ = db.command +let res = await db.collection('todo').where(_.or([ + { + progress: _.gt(80) + }, + { + done: true + } +])).get() +``` + +### not + +查询操作符,用于表示逻辑 "非" 的关系,表示需不满足指定的条件。 + +#### 示例 + + 如筛选出进度不等于 100 的 todo: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.not(_.eq(100)) +}).get() +``` + +`not` 也可搭配其他逻辑指令使用,包括 `and`, `or`, `nor`, `not`,如 `or`: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.not(_.or([_.lt(50), _.eq(100)])) +}).get() +``` + +### nor + +查询操作符,用于表示逻辑 "都不" 的关系,表示需不满足指定的所有条件。如果记录中没有对应的字段,则默认满足条件。 + +#### 示例 1 + + 筛选出进度既不小于 20 又不大于 80 的 todo: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.nor([_.lt(20), _.gt(80)]) +}).get() +``` + +以上同时会筛选出不存在 `progress` 字段的记录,如果要要求 `progress` 字段存在,可以用 `exists` 指令: + +```js +const _ = db.command +let res = await db.collection('todo').where({ + progress: _.exists(true).nor([_.lt(20), _.gt(80)]) + // 等价于以下非链式调用的写法: + // progress: _.exists(true).and(_.nor([_.lt(20), _.gt(80)])) +}).get() +``` + +#### 示例 2 + + 筛选出 `progress` 不小于 20 且 `tags` 数组不包含 `miniprogram` 字符串的记录: + +```js +const _ = db.command +db.collection('todo').where(_.nor([{ + progress: _.lt(20), +}, { + tags: 'miniprogram', +}])).get() +``` + +以上会筛选出满足以下条件之一的记录: + +1. `progress` 不小于 20 且 `tags` 数组不包含 `miniprogram` 字符串 3. `progress` 不小于 20 且 `tags` 字段不存在 5. `progress` 字段不存在 且 `tags` 数组不包含 `miniprogram` 字符串 7. `progress` 不小于 20 且 `tags` 字段不存在 + 如果要求 `progress` 和 `tags` 字段存在,可以用 `exists` 指令: + +```js +const _ = db.command +let res = await db.collection('todo').where( + _.nor([{ + progress: _.lt(20), + }, { + tags: 'miniprogram', + }]) + .and({ + progress: _.exists(true), + tags: _.exists(true), + }) +).get() +``` + +## 查询·比较操作符 + +### eq + +查询筛选条件,表示字段等于某个值。`eq` 指令接受一个字面量 (literal),可以是 `number`, `boolean`, `string`, `object`, `array`, `Date`。 + +#### 使用说明 + + 比如筛选出所有自己发表的文章,除了用传对象的方式: + +```js +const openID = 'xxx' +let res = await db.collection('articles').where({ + _openid: openID +}).get() +``` + +还可以用指令: + +```js +const _ = db.command +const openID = 'xxx' +let res = await db.collection('articles').where({ + _openid: _.eq(openid) +}).get() +``` + +注意 `eq` 指令比对象的方式有更大的灵活性,可以用于表示字段等于某个对象的情况,比如: + +```js +// 这种写法表示匹配 stat.publishYear == 2018 且 stat.language == 'zh-CN' +let res = await db.collection('articles').where({ + stat: { + publishYear: 2018, + language: 'zh-CN' + } +}).get() +// 这种写法表示 stat 对象等于 { publishYear: 2018, language: 'zh-CN' } +const _ = db.command +let res = await db.collection('articles').where({ + stat: _.eq({ + publishYear: 2018, + language: 'zh-CN' + }) +}).get() +``` + +### neq + +查询筛选条件,表示字段不等于某个值。`eq` 指令接受一个字面量 (literal),可以是 `number`, `boolean`, `string`, `object`, `array`, `Date`。 + +#### 使用说明 + + 表示字段不等于某个值,和 [eq](#eq) 相反 + +### lt + +查询筛选操作符,表示需小于指定值。可以传入 `Date` 对象用于进行日期比较。 + +#### 示例代码 + + 找出进度小于 50 的 todo + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.lt(50) +}) +.get() +``` + +### lte + +查询筛选操作符,表示需小于或等于指定值。可以传入 `Date` 对象用于进行日期比较。 + +#### 示例代码 + + 找出进度小于或等于 50 的 todo + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.lte(50) +}) +.get() +``` + +### gt + +查询筛选操作符,表示需大于指定值。可以传入 `Date` 对象用于进行日期比较。 + +#### 示例代码 + + 找出进度大于 50 的 todo + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.gt(50) +}) +.get() +``` + +### gte + +查询筛选操作符,表示需大于或等于指定值。可以传入 `Date` 对象用于进行日期比较。 + +#### 示例代码 + + 找出进度大于或等于 50 的 todo + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.gte(50) +}) +.get() +``` + +### in + +查询筛选操作符,表示要求值在给定的数组内。 + +#### 示例代码 + + 找出进度为 0 或 100 的 todo + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.in([0, 100]) +}) +.get() +``` + +### nin + +查询筛选操作符,表示要求值不在给定的数组内。 + +#### 示例代码 + + 找出进度不是 0 或 100 的 todo + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.nin([0, 100]) +}) +.get() +``` + +## 查询·字段操作符 + +### exists + +判断字段是否存在,true 为存在,false 为不存在 + +#### 示例代码 + + 找出存在 tags 字段的记录 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + tags: _.exists(true) +}) +.get() +``` + +### mod + +查询筛选操作符,给定除数 divisor 和余数 remainder,要求字段作为被除数时 value % divisor = remainder。 + +#### 示例代码 + + 找出进度为 10 的倍数的字段的记录 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + progress: _.mod(10, 0) +}) +.get() +``` + +## 查询·数组操作符 + +### all + +数组查询操作符。用于数组字段的查询筛选条件,要求数组字段中包含给定数组的所有元素。 + +#### 示例代码 1:普通数组 + + 找出 tags 数组字段同时包含 cloud 和 database 的记录 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + tags: _.all(['cloud', 'database']) +}) +.get() +``` + +#### 示例代码 2:对象数组 + + 如果数组元素是对象,则可以用 `_.elemMatch` 匹配对象的部分字段 + + 假设有字段 `places` 定义如下: + +```js +{ + "type": string + "area": number + "age": number +} +``` + +找出数组字段中至少同时包含一个满足“area 大于 100 且 age 小于 2”的元素和一个满足“type 为 mall 且 age 大于 5”的元素 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + places: _.all([ + _.elemMatch({ + area: _.gt(100), + age: _.lt(2), + }), + _.elemMatch({ + type: 'mall', + age: _.gt(5), + }), + ]), +}) +.get() +``` + +### elemMatch + +用于数组字段的查询筛选条件,要求数组中包含至少一个满足 `elemMatch` 给定的所有条件的元素 + +#### 示例代码:数组是对象数组的情况 + + 假设集合示例数据如下: + +```js +{ + "_id": "a0", + "city": "x0", + "places": [{ + "type": "garden", + "area": 300, + "age": 1 + }, { + "type": "theatre", + "area": 50, + "age": 15 + }] +} +``` + +找出 `places` 数组字段中至少同时包含一个满足“area 大于 100 且 age 小于 2”的元素 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + places: _.elemMatch({ + area: _.gt(100), + age: _.lt(2), + }) +}) +.get() +``` + +*注意**:如果不使用 `elemMatch` 而直接如下指定条件,则表示的是 `places` 数组字段中至少有一个元素的 `area` 字段大于 100 且 `places` 数组字段中至少有一个元素的 `age` 字段小于 2: + +```js +const _ = db.command +let res = await db.collection('todos').where({ + places: { + area: _.gt(100), + age: _.lt(2), + } +}) +.get() +``` + +#### 示例代码:数组元素都是普通数据类型的情况 + + 假设集合示例数据如下: + +```js +{ + "_id": "a0", + "scores": [60, 80, 90] +} +``` + +找出 `scores` 数组字段中至少同时包含一个满足“大于 80 且小于 100”的元素 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + scores: _.elemMatch(_.gt(80).lt(100)) +}) +.get() +``` + +### size + +更新操作符,用于数组字段的查询筛选条件,要求数组长度为给定值 + +#### 示例 + + 找出 tags 数组字段长度为 2 的所有记录 + +```js +const _ = db.command +let res = await db.collection('todos').where({ + places: _.size(2) +}) +.get() +``` + +## 查询·地理位置操作符 + +### geoNear + +按从近到远的顺序,找出字段值在给定点的附近的记录。 + +#### 索引要求 + + 需对查询字段建立地理位置索引 + +#### 示例代码 + + 找出离给定位置 1 公里到 5 公里范围内的记录 + +```js +const _ = db.command +let res = await db.collection('restaurants').where({ + location: _.geoNear({ + geometry: new db.Geo.Point(113.323809, 23.097732), + minDistance: 1000, + maxDistance: 5000, + }) +}).get() +``` + +### geoWithin + +找出字段值在指定区域内的记录,无排序。指定的区域必须是多边形(Polygon)或多边形集合(MultiPolygon)。 + +#### 索引要求 + + 需对查询字段建立地理位置索引 + +#### 示例代码 1:给定多边形 + +```js +const _ = db.command +const { Point, LineString, Polygon } = db.Geo +let res = await .collection('restaurants').where({ + location: _.geoWithin({ + geometry: new Polygon([ + new LineString([ + new Point(0, 0), + new Point(3, 2), + new Point(2, 3), + new Point(0, 0) + ]) + ]), + }) +}).get() +``` + +#### 示例代码 2:给定圆形 + + 可以不用 `geometry` 而用 `centerSphere` 构建一个圆形。 + + `centerSphere` 对应的值的定义是:`[ [经度, 纬度], 半径 ]` + + 半径需以弧度计,比如需要 10km 的半径,则用距离除以地球半径 6378.1km 得出的数字。 + +```js +const _ = db.command +let res = await db.collection('restaurants').where({ + location: _.geoWithin({ + centerSphere: [ + [-88, 30], + 10 / 6378.1, + ] + }) +}).get() +``` + +### geoIntersects + +找出给定的地理位置图形相交的记录 + +#### 索引要求 + + 需对查询字段建立地理位置索引 + +#### 示例代码:找出和一个多边形相交的记录 + +```js +const _ = db.command +const { Point, LineString, Polygon } = db.Geo +let res = await db.collection('restaurants').where({ + location: _.geoIntersects({ + geometry: new Polygon([ + new LineString([ + new Point(0, 0), + new Point(3, 2), + new Point(2, 3), + new Point(0, 0) + ]) + ]), + }) +}).get() +``` + +## 查询·表达式操作符 + +### expr + +查询操作符,用于在查询语句中使用聚合表达式,方法接收一个参数,该参数必须为聚合表达式 + +#### 使用说明 + +1. `expr` 可用于在聚合 `match`流水线阶段中引入聚合表达式 3. 如果聚合 `match`阶段是在 `lookup`) 阶段内,此时的 `expr` 表达式内可使用 `lookup` 中使用 `let` 参数定义的变量,具体示例可见 `lookup` 的 `指定多个连接条件` 例子 5. `expr` 可用在普通查询语句(`where`)中引入聚合表达式 + +#### 示例代码 1:比较同一个记录中的两个字段 + + 假设 `items` 集合的数据结构如下: + +```js +{ + "_id": string, + "inStock": number, // 库存量 + "ordered": number // 被订量 +} +``` + +找出被订量大于库存量的记录: + +```js +const _ = db.command +const $ = _.aggregate +let res = await db.collection('items').where(_.expr($.gt(['$ordered', '$inStock']))).get() +``` + +#### 示例代码 2:与条件语句组合使用 + + 假设 `items` 集合的数据结构如下: + +```json +{ + "_id": string, + "price": number +} +``` + +假设价格小于等于 10 的打 8 折,大于 10 的打 5 折,让数据库查询返回打折后价格小于等于 8 的记录: + +```js +const _ = db.command +const $ = _.aggregate +let res = await db.collection('items').where( + _.expr( + $.lt([ + $.cond({ + if: $.gte(['$price', 10]), + then: $.multiply(['$price', '0.5']), + else: $.multiply(['$price', '0.8']), + }) + , + 8 + ]) +)).get() +``` + +## 更新·字段操作符 + +### set + +更新操作符,用于设定字段等于指定值。 + +#### 使用说明 + + 这种方法相比传入纯 JS 对象的好处是能够指定字段等于一个对象 + +#### 示例 + +```js +// 以下方法只会更新 style.color 为 red,而不是将 style 更新为 { color: 'red' },即不影响 style 中的其他字段 +let res = await db.collection('todos').doc('doc-id').update({ + style: { + color: 'red' + } +}) + +// 以下方法更新 style 为 { color: 'red', size: 'large' } +let res = await db.collection('todos').doc('doc-id').update({ + style: _.set({ + color: 'red', + size: 'large' + }) +}) +``` + +### remove + +更新操作符,用于表示删除某个字段。 + +#### 示例代码 + + 删除 style 字段: + +```js +const _ = db.command +let res = await db.collection('todos').doc('todo-id').update({ + style: _.remove() +}) +``` + +### inc + +更新操作符,原子操作,用于指示字段自增 + +#### 原子自增 + + 多个用户同时写,对数据库来说都是将字段自增,不会有后来者覆写前者的情况 + +#### 示例代码 + + 将一个 todo 的进度自增 10: + +```js +const _ = db.command +let res = await db.collection('todos').doc('todo-id').update({ + progress: _.inc(10) +}) +``` + +### mul + +更新操作符,原子操作,用于指示字段自乘某个值 + +#### 原子自乘 + + 多个用户同时写,对数据库来说都是将字段自乘,不会有后来者覆写前者的情况 + +#### 示例代码 + + 将一个 todo 的进度自乘 10: + +```js +const _ = db.command +let res = await db.collection('todos').doc('todo-id').update({ + progress: _.mul(10) +}) +``` + +### min + +更新操作符,给定一个值,只有该值小于字段当前值才进行更新。 + +#### 示例代码 + + 如果字段 progress > 50,则更新到 50 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + progress: _.min(50) +}) +``` + +### max + +更新操作符,给定一个值,只有该值大于字段当前值才进行更新。 + +#### 示例代码 + + 如果字段 progress < 50,则更新到 50 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + progress: _.max(50) +}) +``` + +### rename + +更新操作符,字段重命名。如果需要对嵌套深层的字段做重命名,需要用点路径表示法。不能对嵌套在数组里的对象的字段进行重命名。 + +#### 示例 1:重命名顶层字段 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + progress: _.rename('totalProgress') +}) +``` + +#### 示例 2:重命名嵌套字段 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + someObject: { + someField: _.rename('someObject.renamedField') + } +}) +``` + +或: + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + 'someObject.someField': _.rename('someObject.renamedField') +}) +``` + +## 更新·数组操作符 + +### push + +数组更新操作符。对一个值为数组的字段,往数组添加一个或多个值。或字段原为空,则创建该字段并设数组为传入值。 + +#### 参数说明 + +**position 说明** + + 要求必须同时有 `each` 参数存在。 + + 非负数代表从数组开始位置数的位置,从 0 开始计。如果数值大于等于数组长度,则视为在尾部添加。负数代表从数组尾部倒数的位置,比如 -1 就代表倒数第二个元素的位置。如果负数数值的绝对值大于等于数组长度,则视为从数组头部添加。 + +**sort 说明** + + 要求必须同时有 `each` 参数存在。给定 1 代表升序,-1 代表降序。 + + 如果数组元素是记录,则用 `{ <字段>: 1 | -1 }` 的格式表示根据记录中的什么字段做升降序排序。 + +**slice** 说明** + + 要求必须同时有 `each` 参数存在 + +|值 |说明 | +|:-: |:-: | +|0 |将字段更新为空数组 | +|正数 |数组只保留前 n 个元素| +|负数 |数组只保留后 n 个元素| + +#### 示例 1:尾部添加元素 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push(['mini-program', 'cloud']) +}) +``` + +#### 示例 2:从第二个位置开始插入 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push({ + each: ['mini-program', 'cloud'], + position: 1, + }) +}) +``` + +#### 示例 3:排序 + +插入后对整个数组做排序 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push({ + each: ['mini-program', 'cloud'], + sort: 1, + }) +}) +``` + +不插入,只对数组做排序 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push({ + each: [], + sort: 1, + }) +}) +``` + +如果字段是对象数组,可以如下根据元素对象里的字段进行排序: + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push({ + each: [ + { name: 'miniprogram', weight: 8 }, + { name: 'cloud', weight: 6 }, + ], + sort: { + weight: 1, + }, + }) +}) +``` + +#### 示例 4:截断保留 + + 插入后只保留后 2 个元素 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push({ + each: ['mini-program', 'cloud'], + slice: -2, + }) +}) +``` + +#### 示例 5:在指定位置插入、然后排序、最后只保留前 2 个元素 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.push({ + each: ['mini-program', 'cloud'], + position: 1, + slice: 2, + sort: 1, + }) +}) +``` + +### pop + +数组更新操作符,对一个值为数组的字段,将数组尾部元素删除,仅可以删除末尾一个 + +#### 示例代码 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.pop() +}) +``` + +### unshift + +数组更新操作符,对一个值为数组的字段,往数组头部添加一个或多个值。或字段原为空,则创建该字段并设数组为传入值。 + +#### 示例代码 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.unshift(['mini-program', 'cloud']) +}) +``` + +### shift + +数组更新操作符,对一个值为数组的字段,将数组头部元素删除。 + +#### 示例代码 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.shift() +}) +``` + +### pull + +数组更新操作符。给定一个值或一个查询条件,将数组中所有匹配给定值或查询条件的元素都移除掉。 + +#### 示例代码 1:根据常量匹配移除 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.pull('database') +}) +``` + +#### 示例代码 2:根据查询条件匹配移除 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.pull(_.in(['database', 'cloud'])) +}) +``` + +#### 示例代码 3:对象数组时,根据查询条件匹配移除 + + 假设有字段 `places` 数组中的元素结构如下 + +```json +{ + "type": string + "area": number + "age": number +} +``` + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + places: _.pull({ + area: _.gt(100), + age: _.lt(2), + }) +}) +``` + +#### 示例代码 4:有嵌套对象的对象数组时,根据查询条件匹配移除 + + 假设有字段 `cities` 数组中的元素结构如下 + +```js +{ + "name": string + "places": Place[] +} +``` + +`Place` 结构如下: + +```js +{ + "type": string + "area": number + "age": number +} +``` + +可用 `elemMatch` 匹配嵌套在对象数组里面的对象数组字段 places + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + cities: _.pull({ + places: _.elemMatch({ + area: _.gt(100), + age: _.lt(2), + }) + }) +}) +``` + +### pullAll + +数组更新操作符。给定一个值或一个查询条件,将数组中所有匹配给定值的元素都移除掉。跟 `pull` 的差别在于只能指定常量值、传入的是数组。 + +#### 示例代码:根据常量匹配移除 + + 从 tags 中移除所有 database 和 cloud 字符串 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.pullAll(['database', 'cloud']) +}) +``` + +### addToSet + +数组更新操作符。原子操作。给定一个或多个元素,除非数组中已存在该元素,否则添加进数组。 + +#### 示例代码 1:添加一个元素 + + 如果 tags 数组中不包含 database,添加进去 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.addToSet('database') +}) +``` + +#### 示例代码 2:添加多个元素 + +需传入一个对象,其中有一个字段 `each`,其值为数组,每个元素就是要添加的元素 + +```js +const _ = db.command +let res = await db.collection('todos').doc('doc-id').update({ + tags: _.addToSet({ + $each: ['database', 'cloud'] + }) +}) +``` diff --git a/docs/guide/db/del.md b/docs/guide/db/del.md new file mode 100644 index 0000000000..ce65d21a24 --- /dev/null +++ b/docs/guide/db/del.md @@ -0,0 +1,37 @@ +--- +title: 删除数据 +--- + +# {{ $frontmatter.title }} + +Laf 云数据库删除数据,包括删除文档和删除集合。同时支持单个删除和批量删除。 + +## 通过指定条件删除单个文档 + +我们可以配合 `where` 以及各种高级指令来使用 `remove`。 + +```js + // 删除 user 集合中,name 为 jack 的一条记录 + const res = await db.collection('user').where({ name: "jack" }).remove() + console.log(res) +``` + +## 通过指定条件批量删除文档 + +上面示例执行一次只能删除一条数据,如果想要批量删除要在 `remove()` 中添加 `{multi: true}` + +```js +// 删除 user 表中所有 name 为 jack 的记录 +await db.collection('user') +.where({ name: "jack" }) +.remove({ multi: true }) +``` + +## 清空集合(危险操作) + +如果我们想删除一个集合中的所有数据,可以这样操作。 + +```js +// 清空 user 集合 +await db.collection('user').remove({ multi: true }) +``` diff --git a/docs/guide/db/find.md b/docs/guide/db/find.md new file mode 100644 index 0000000000..e2a5b9a7e8 --- /dev/null +++ b/docs/guide/db/find.md @@ -0,0 +1,608 @@ +--- +title: 查询数据 +--- + +# {{ $frontmatter.title }} + +Laf 云数据库支持传入不同的条件来查询数据,并且对查询结果进行处理。本文档将通过示例说明如何通过 `cloud.database()` 在云函数中执行查询。 + +查询数据操作主要支持 `where()` `limit()` `skip()` `orderBy()` `field()` `get()` `getOne()` `count()` 等 + +包括: + +[[toc]] + +## 获取所有记录 + +::: tip +可通过 `where` 设置查询条件,以及通过 `limit` 设置显示数量等 +::: + +```typescript +import cloud from '@lafjs/cloud' +// 获取数据库引用 +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + // get 方法发起查询请求,不带 where 就是直接查询全部数据,默认最多查询 100 条数据 + const result1 = await db.collection('user').get() + console.log(result1) + + // get 方法发起查询请求,配置 where 条件 + const result2 = await db.collection('user').where({ + name: 'laf' + }).get() + console.log(result2) + + // get 方法发起查询请求,想一次获取更多数据,最多一次获取 1000 条数据 + const result3 = await db.collection('user').limit(1000).get() + console.log(result3) +} +``` + +`get()` 前面支持 `where()`、`limit()`、`skip()`、`orderBy()`、`field()` 等操作。下面会逐一讲解。 + +## 获取一条记录 + +如果我们查询的数据只有一条,我们也可以使用 getOne 方法,它和 get 方法不同的是它只能获取一条数据,并且 data 的格式为对象。 + +```typescript +import cloud from '@lafjs/cloud' +// 获取数据库引用 +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + const res = await db.collection('user').geOne() + console.log(res) +// getOne 获取的结果: +// { +// ok: true, +// data: { _id: '641d21992de2b789c963e5e0', name: 'jack' }, +// requestId: undefined +// } + + const res = await db.collection('user').get() + console.log(res) +// get 获取的结果: +// { +// data: [ { _id: '641d22292de2b789c963e5fd', name: 'jack' } ], +// requestId: undefined, +// ok: true +// } +} +``` + +`getOne()` 前面支持 `where()`、`limit()`、`skip()`、`orderBy()`、`field()` 等操作。下面会逐一讲解。 + +## 添加查询条件 + +`collection.where()` + +设置查询条件条件 +where 可接收对象作为参数,表示筛选出拥有和传入对象相同的 key-value 的文档。支持多个条件同时筛选。 + +比如筛选出所有名字叫 jack 的用户: + +```typescript +// 查询 user 集合中 name 字段等于 jack 的记录 +await db.collection("user").where({ + name:"jack" +}); +``` + +:::tip +这里注意,`where` 并不会去查询数据,需参考我们上面的栗子加上 `get()` 或者 `getOne()` +::: + +## 根据 ID 查询数据 + +`collection.doc()` + +跟 `where` 的区别是,`doc` 只根据_id 筛选 + +::: warning +如果是用 cloud.database() 新增的文档,_id 类型为字符串 +如果是用 cloud.mongo.db 新增的文档,_id 类型一般为 ObjectId +::: + +```typescript +// 查询 user 集合中 _id 为 '644148fd1eeb2b524dba499e' 的文档 +await db.collection("user").doc('644148fd1eeb2b524dba499e'); + +// 其实等同于 where 的筛选条件只有 _id +await db.collection("user").where({ + _id: '644148fd1eeb2b524dba499e' +}); +``` + +```typescript +// _id 的类型为 ObjectId 的情况 +import { ObjectId } from 'mongodb' // 需要在云函数顶部引入 ObjectId 类型 + +await db.collection("user").doc(ObjectId('644148fd1eeb2b524dba499e')); +``` + +## 高级查询指令 + +如果要表达更复杂的查询,可使用高级查询指令。这里需要用到数据库操作符。详细使用可看 [数据库操作符](/guide/db/command) + +::: tip +`where` 结尾不会直接查询,需要后面加 `get` 或 `getOne` +::: + +### gt 字段大于指定值 + +可用于查询数字、日期等类型的字段。如果是字符串对比,则会按照字典序进行比较。 + +此例子筛选出所有年龄大于 18 的用户: + +```typescript +const db = cloud.database() +const _ = db.command; // 这里拿到指令 +await db.collection("user").where({ + age: _.gt(18) // 表示大于 18 + }, +); +``` + +### gte 字段大于或等于指定值 + +可用于查询数字、日期等类型的字段。如果是字符串对比,则会按照字典序进行比较。 + +```typescript +const db = cloud.database() +const _ = db.command; // 这里拿到指令 +await db.collection("user").where({ + age: _.gte(18) // 表示大于或等于 18 + }, +); +``` + +### lt 字段小于指定值 + +可用于查询数字、日期等类型的字段。如果是字符串对比,则会按照字典序进行比较。 + +### lte 字段小于或等于指定值 + +可用于查询数字、日期等类型的字段。如果是字符串对比,则会按照字典序进行比较。 + +### eq 表示字段等于某个值 + +`eq` 指令接受一个字面量 (literal),可以是 `number`, `boolean`, `string`, `object`, `array`。 + +比如筛选出所有自己发表的文章,除了用传对象的方式: + +```typescript +const myOpenID = "xxx"; +await db.collection("articles").where({ + _openid: myOpenID, +}); +``` + +还可以用指令: + +```typescript +const db = cloud.database() +const _ = db.command; +const myOpenID = "xxx"; +await db.collection("articles").where({ + _openid: _.eq(myOpenID), +}); +``` + +注意 `eq` 指令比对象的方式有更大的灵活性,可以用于表示字段等于某个对象的情况,比如: + +```typescript +// 这种写法表示匹配 stat.publishYear == 2018 且 stat.language == 'zh-CN' +await db.collection("articles").where({ + stat: { + publishYear: 2018, + language: "zh-CN", + }, +}); + +// 这种写法表示 stat 对象等于 { publishYear: 2018, language: 'zh-CN' } +const _ = db.command; +await db.collection("articles").where({ + stat: _.eq({ + publishYear: 2018, + language: "zh-CN", + }), +}); +``` + +### neq 表示字段不等于某个值 + +字段不等于。`neq` 指令接受一个字面量 (literal),可以是 `number`, `boolean`, `string`, `object`, `array`。 + +如筛选出品牌不为 X 的计算机: + +```typescript +const _ = db.command; +await db.collection("goods").where({ + category: "computer", + type: { + brand: _.neq("X"), + }, +}); +``` + +### in 字段值在给定的数组中 + +如:筛选出年龄为 18 或 20 岁的用户: + +```typescript +const _ = db.command; +await db.collection("user").where({ + age: _.in([18, 20]), +}); +``` + +### nin 字段值不在给定的数组中 + +筛选出年龄不是 18 或 20 岁的用户: + +```typescript +const _ = db.command; +await db.collection("user").where({ + age: _.nin([8, 20]), +}); +``` + +### and 表示需同时满足指定的两个或以上的条件 + +如筛选出年龄大于 18 小于 60 的用户: + +流式写法: + +```typescript +const _ = db.command; +await db.collection("user").where({ + age: _.gt(18).and(_.lt(60)), +}); +``` + +前置写法: + +```typescript +const _ = db.command; +await db.collection("user").where({ + age: _.and(_.gt(18), _.lt(60)), +}); +``` + +### or 表示需满足所有指定条件中的至少一个 + +如筛选出用户年龄等于 18 或等于 60 的用户: + +流式写法: + +```typescript +const _ = db.command; +await db.collection("user").where({ + age: _.eq(18).or(_.eq(60)), +}); +``` + +前置写法: + +```typescript +const _ = db.command; +await db.collection("user").where({ + age: _.or(_.eq(18),_.eq(60)), +}); +``` + +如果要跨字段“或”操作:(如筛选出内存 8g 或 cpu 3.2 ghz 的计算机) + +```typescript +const _ = db.command; +await db.collection("goods").where( + _.or( + { + type: { + memory: _.gt(8), + }, + }, + { + type: { + cpu: 3.2, + }, + } + ) +); +``` + +### exists 判断字段是否存在 + +```typescript +const _ = db.command; +await db.collection("users").where( + name: _.exists(true), // name 字段存在 + age: _.exists(false), // age 字段不存在 +); +``` + +## 正则表达式查询 + +`db.RegExp` 根据正则表达式进行筛选 + +例如下面可以筛选出 `version` 字段开头是 "数字+s" 的记录,并且忽略大小写: + +```typescript +// 可以直接使用正则表达式 +await db.collection('articles').where({ + version: /^\ds/i +}) + +// 或者 +await db.collection('articles').where({ + version: new db.RegExp({ + regex: '^\\ds' // 正则表达式为 /^\ds/,转义后变成 '^\\ds' + options: 'i' // i 表示忽略大小写 + }) +}) +``` + +## 获取查询数量 + +collection.count() 查询符合条件的数量 + +参数 + +```typescript +await db.collection("goods").where({ + category: "computer", + type: { + memory: 8, + }, +}).count() +``` + +响应参数 + +| 字段 | 类型 | 必填 | 说明 | +| --------- | ------- | ---- | ------------------------ | +| code | string | 否 | 状态码,操作成功则不返回 | +| message | string | 否 | 错误描述 | +| total | Integer | 否 | 计数结果 | +| requestId | string | 否 | 请求序列号,用于错误排查 | + +## 设置记录数量 + +collection.limit() 限制展示数量,最大 1000 + +参数说明 + +| 参数 | 类型 | 必填 | 说明 | +| ----- | ------- | ---- | -------------- | +| value | Integer | 是 | 限制展示的数值 | + +使用示例 + +```typescript +await db.collection("user").limit(1).get() +``` + +## 设置起始位置 + +collection.skip() 跳过展示的数据 + +参数说明 + +| 参数 | 类型 | 必填 | 说明 | +| ----- | ------- | ---- | -------------- | +| value | Integer | 是 | 跳过展示的数据 | + +使用示例 + +```typescript +await db.collection("user").skip(4).get() +``` + +## 分页查询 + +`skip()` 和 `limit()` 组合可做分页查询,这里不能用 `getOne()` + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + // 每页显示数量 + const pageSize = 3; + // 第几页 + const page = 2; + const res = await db.collection('user') + .skip((page - 1) * pageSize) + .limit(pageSize) + .get() +} +``` + +## 嵌套查询 + +如果是对象或数组中的某个字段进行查询 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + // 查询 userInfo.name = 'Jack' 且 userInfo.age = 10 的数据 + // 写法 1 + const result1 = await db.collection('user') + .where({ + userInfo: { + name: "Jack", + age: 10 + } + }).get() + // 写法 2 + const result2 = await db.collection('user') + .where({ + 'userInfo.name': 'Jack', + 'userInfo.age': 10 + }).get() +} +``` + +如数据库中 `test` 集合中有如下数据 + +```json +[ + { + "arr":[{ + "name": "item-1" + },{ + "name": "item-2" + }] + }, + { + "arr":[{ + "name": "item-3" + },{ + "name": "item-4" + }] + } +] +``` + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + // 查询 arr[0].name = 'item-1' 的数据 + const result = await db.collection('test') + .where({ + 'arr.0.name': "item-1" + }).get() +} +``` + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + // 查询 arr 内某个元素的 name 为 'item-2' 的文档 + const result = await db.collection('test') + .where({ + 'arr.name': "item-2" + }).get() +} +``` + +## 对结果排序 + +collection.orderBy() 对数据排序后再展示 + +参数说明 + +| 参数 | 类型 | 必填 | 说明 | +| --------- | ------ | ---- | ----------------------------------- | +| field | string | 是 | 排序的字段 | +| orderType | string | 是 | 排序的顺序,升序 (asc) 或 降序 (desc) | + +使用示例 + +```typescript +// 按照创建时间 createAt 的升序排序 +await db.collection("user").orderBy("createAt", "asc").get() +``` + +## 指定返回字段 + +collection.field() 只返回指定字段 + +参数说明 + +| 参数 | 类型 | 必填 | 说明 | +| ---- | ------ | ---- | ----------------------------------------- | +| - | object | 是 | 要过滤的字段,不返回传 0,返回传 1 | + +::: tip +备注:只能指定要返回的字段或者不要返回的字段,即 `{'a': 1, 'b': 0}` 是一种错误的参数格式。默认会显示 id。 +::: + +使用示例 + +```typescript +await db.collection("user").field({ age: 1 }); +``` + +同样的后面也要加上 `get()` 或 `getOne()` ,才可以查询到结果 + +## with 关联查询 + +with / withOne 联表查询,可以实现查询一个集合时,连同某个字段的相关联记录一同查出(可跨表),比如查询“班级”时连同班级内的“学生”一起查询出来,又比如查询“文章”时连同它的“作者”一并查出等等。 + +:::info +with / withOne 联表查询在 sdk 内部是先查询了主表后,再查询子表,然后在本地(云函数或客户端)完成拼接后再传回业务开发者;如果你还没有使用 with 联表查询,推荐使用聚合操作的 [lookup 联表查询](#lookup-关联查询)。 +::: + +### 一对多关系查询 + +主要用于「一对多」关系的子查询,可跨表查询,要求用户拥有子表的查询权限 + +```typescript +await const { data } = await db + .collection("article") + .with({ + query: db.collection("tag"), + localField: "id", // 主表连接键,即 article.id + foreignField: "article_id", // 子表连接键,即 tag.article_id + as: "tags", // 查询结果中字段重命名,缺省为子表名 + }) + .get(); +console.log(data); +// [ { id: 1, name: xxx, tags: [...] } ] +``` + +### 一对一关系查询 + +> 类似 sql left join 查询 + +```typescript +const { data } = await db + .collection("article") + .withOne({ + query: db.collection("user"), + localField: "author_id", // 主表连接键,即 article.id + foreignField: "id", // 子表连接键,即 tag.article_id + as: "author", // 查询结果中字段重命名,缺省为子表名 + }) + .get(); + +console.log(data); +// [ { id: 1, name: xxx, author: {...} } ] +``` + +## lookup 关联查询 + +:::info +lookup 联表查询并非 `collection` 下的方法! + +事实上其为聚合 `aggregate` 下的方法,然而前文提到了 `with 联表查询` 用途与此一致,故在此先做说明,以避免开发者以为 lookup 不得使用,导致额外适配成 with 联表查询的成本。 +::: + +用途与 `with 联表查询` 基本一致,同 with 联表查询的示例:查询 article 集合时,把各记录的 tag 标签一同查出。 + +```typescript +const { data } = await db + .collection("article") + .aggregate() + .lookup({ + from: "tag", + localField: "id", // 主表连接键,即 article.id + foreignField: "article_id", // 子表连接键,即 tag.article_id + as: "tags", // 查询结果中字段重命名,缺省为子表名 + }) + .end(); +console.log(data); +``` + +## groupBy 分组查询 + +分组查询请看 [聚合操作](/guide/db/aggregate.html#bucket) 文档 diff --git a/docs/guide/db/geo.md b/docs/guide/db/geo.md index 99581fe812..a9dd4ee202 100644 --- a/docs/guide/db/geo.md +++ b/docs/guide/db/geo.md @@ -1,5 +1,5 @@ --- -title: 地理信息API +title: 地理信息 API --- # {{ $frontmatter.title }} diff --git a/docs/guide/db/index.md b/docs/guide/db/index.md index 2e5aaf0d21..1e5fde5bf4 100644 --- a/docs/guide/db/index.md +++ b/docs/guide/db/index.md @@ -4,15 +4,19 @@ title: 云数据库介绍 # {{ $frontmatter.title }} -云数据库是基于 MongoDB 实现的,其中的绝大多数概念、操作和 MongoDB 是一致的。 +Laf 云数据库提供了开箱即用的数据库,无需复杂配置和连接。在云函数中可通过 `cloud.database()` 新建 DB 实例去操作数据库。 + +Laf 云数据库是使用的 `MongoDB` ,既保留了 `MongoDB` 原生查询数据库操作方法,也封装了更方便的操作方法。 + +Laf 云数据库是一个 JSON 格式的文档型数据库,数据库中的每条记录都是一个 JSON 格式的文档。因此在 Laf 数据库中,集合对应 MySQL 的数据表,文档对应 MySQL 的行,字段对应 MySQL 的列。 ## 基本概念 ### 文档 -数据库的每一条记录都是类似于 JSON 的文档: +数据库的每条记录都是一个 JSON 格式的文档,如: -```js +```typescript { "username": "hello", "password": "123456", @@ -26,104 +30,117 @@ title: 云数据库介绍 集合是一组文档的集合,每个文档都在一个集合里面。如所有的用户放在 `users` 集合里。 +```typescript +[ + { + "username": "name1", + "password": "123456", + "extraInfo": { + "mobile": "15912345678" + } + }, + { + "username": "name2", + "password": "12345678", + "extraInfo": { + "mobile": "15912345679" + } + } + ... +] +``` + ### 数据库 每个 Laf 应用有且仅有一个数据库,但是一个数据库可以创建多个集合。 -## 访问数据库 +![dblist](/doc-images/dblist.jpg) -### 在云函数中访问数据库 +上图代表当前 Laf 应用下有 2 个集合,分别是 `test` 集合和 `messages` 集合 -云函数需要使用 `@lafjs/cloud` 来获取数据库访问器。 +同时在 Laf 的 `Web IDE` 中可以很方便的看到全部的集合列表,以及简单的管理。 -```js -import cloud from "@lafjs/cloud"; +## 数据类型 -// 数据库对象 -const db = cloud.database(); -``` +云数据库提供了以下类型: -### 在客户端中访问数据库 +__常用数据类型__ -前端可使用 [laf-client-sdk](https://github.com/labring/laf/tree/main/packages/client-sdk) “直连”数据库,无需与服务端对接口。 +- `String` 字符串类型,存储任意长度的 UTF-8 编码的字符串 +- `Number` 数字类型,包括整数和浮点数 +- `Boolean` 布尔类型,包括 true 和 false +- `Date` 日期类型,存储日期和时间 +- `ObjectId` 对象 ID 类型,用于存储文档的唯一标识符 +- `Array` 数组类型,可以包含任意数量的值,包括其他数据类型和嵌套数组 +- `Object` 对象类型,可以包含任意数量的键值对,其中值可以是任何数据类型,包括其他对象和嵌套数组 -在访问数据库之前,需要先设置一个访问策略。在 云数据库-访问策略 中创建一个新的策略,策略内容如下: +__其他数据类型__ -```js -{ - "read": true, - "count": true, - "update": false, - "remove": false, - "add": false -} -``` +- `Null` 相当于一个占位符,表示一个字段存在但是值为空 +- `GeoPoint` 地理位置点 +- `GeoLineStringLine` 地理路径 +- `GeoPolygon` 地理多边形 +- `GeoMultiPoint` 多个地理位置点 +- `GeoMultiLineString` 多个地理路径 +- `GeoMultiPolygon` 多个地理多边形 -创建好后可以在 访问策略列表中获得入口地址。 +### Date 类型 -在前端项目中安装 laf-client-sdk: +Date 类型用于表示时间,精确到毫秒,可以用 JavaScript 内置 Date 对象创建。 -```shell -npm install laf-client-sdk -``` +::: warning +注意:当前服务端时间可能会有时区问题,可能不是东八区时间,在存储数据库的时候,可以先把时区转换成东八区或者使用时间戳 +::: + +在云函数中,可以直接使用 `new Date()` 获取当前服务端时间 -在使用前,需要初始化 SDK: - -```js -const cloud = require("laf-client-sdk").init({ - // 应用的服务地址,在欢迎-服务地址 可找到 - baseUrl: "http://localhost:8000", - // 刚刚创建的访问策略的入口地址 - dbProxyUrl: "/proxy/app", - // provide your own token-get-function, a standard JWT token is expected - getAccessToken: () => localStorage.getItem("access_token"), - /** - * 客户端环境, 默认是 'h5': - * - `h5` for browsers - * - `wxmp` for WeChat MiniProgram - * - `uniapp` for uni-app - */ - environment: "h5", -}); - -// 获取数据库访问器 -const db = cloud.database(); +```typescript +//服务端当前时间 +console.log(new Date()) +// 输出结果:2023-04-21T14:47:32.697Z + +const date = new Date(); +const timestamp = date.getTime(); +console.log(timestamp); +// 输出一个以毫秒为单位的时间戳,例如:1650560477427 ``` -## 数据类型 +获取东八区时间 -云数据库提供了如下的类型: +```typescript +// 获取当前时间的东八区时间 +const date = new Date(); +const offset = 8; // 东八区偏移量为 +8 -- String:字符串 -- Number:数字 -- Object:对象 -- Array:数组 -- Bool:布尔值 -- GeoPoint:地理位置点 -- GeoLineStringL: 地理路径 -- GeoPolygon: 地理多边形 -- GeoMultiPoint: 多个地理位置点 -- GeoMultiLineString: 多个地理路径 -- GeoMultiPolygon: 多个地理多边形 -- Date:时间 -- Null +// 计算当前时间的 UTC 时间,再加上偏移量得到东八区时间 +const utcTime = date.getTime() + (date.getTimezoneOffset() * 60 * 1000); +const beijingTime = new Date(utcTime + (offset * 60 * 60 * 1000)); +console.log(beijingTime); // 输出东八区时间的 Date 对象 +``` -### 1. Date 类型 +下面演示云函数在 `test` 集合中添加一条记录,并添加创建时间 `createTime` 和创建时间戳 `createTimestamp` 2 个字段 -Date 类型用于表示时间,精确到毫秒,可以用 JavaScript 内置 Date 对象创建。需要特别注意的是,用此方法创建的时间是客户端时间,不是服务端时间。如果需要使用服务端时间,应该用 API 中提供的 serverDate 对象来创建一个服务端当前时间的标记,当使用了 serverDate 对象的请求抵达服务端处理时,该字段会被转换成服务端当前的时间,更棒的是,我们在构造 serverDate 对象时还可通过传入一个有 offset 字段的对象来标记一个与当前服务端时间偏移 offset 毫秒的时间,这样我们就可以达到比如如下效果:指定一个字段为服务端时间往后一个小时。 +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() -那么当我们需要使用客户端时间时,存放 Date 对象和存放毫秒数是否是一样的效果呢?不是的,我们的数据库有针对日期类型的优化,建议大家使用时都用 Date 或 serverDate 构造时间对象。 +export async function main(ctx: FunctionContext) { -```js -//服务端当前时间 -new db.serverDate(); -``` + // 获取当前时间的东八区时间 + const date = new Date(); + const offset = 8; // 东八区偏移量为 +8 -```js -//服务端当前时间加1S -new db.serverDate({ - offset: 1000, -}); + // 计算当前时间的 UTC 时间,再加上偏移量得到东八区时间 + const utcTime = date.getTime() + (date.getTimezoneOffset() * 60 * 1000); + const beijingTime = new Date(utcTime + (offset * 60 * 60 * 1000)); + console.log(beijingTime); // 输出东八区时间的 Date 对象 + + await db.collection('test').add({ + name: 'xiaoming', + createTime: beijingTime, + createTimestamp: date.getTime() + }) +} ``` ### Null 类型 diff --git a/docs/guide/db/operator.md b/docs/guide/db/operator.md new file mode 100644 index 0000000000..bf5eb14017 --- /dev/null +++ b/docs/guide/db/operator.md @@ -0,0 +1,4663 @@ +--- +title: 数据库运算 +--- + +# {{ $frontmatter.title }} + +**等同于 mongoDB 聚合操作符概念** + +## 算术操作符 + +### abs + + + +返回一个数字的绝对值。 + +#### API 说明 + +语法如下: + +```typescript +db.command.aggregate.abs() +``` + +`abs` 传入的值除了数字常量外,也可以是任何最终解析成一个数字的表达式。 + + 如果表达式解析为 `null` 或者指向一个不存在的字段,则 `abs` 的结果是 `null`。如果值解析为 `NaN`,则结果是 `NaN`。 + +#### 示例代码 + + 假设集合 `ratings` 有如下记录: + +```typescript +{ _id: 1, start: 5, end: 8 } +{ _id: 2, start: 4, end: 4 } +{ _id: 3, start: 9, end: 7 } +{ _id: 4, start: 6, end: 7 } +``` + +··· +可以用如下方式求得各个记录的 `start` 和 `end` 之间的绝对差异大小: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('ratings').aggregate() + .project({ + delta: $.abs($.subtract(['$start', '$end'])) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id" : 1, "delta" : 3 } +{ "_id" : 2, "delta" : 0 } +{ "_id" : 3, "delta" : 2 } +{ "_id" : 4, "delta" : 1 } +``` + +### add + + + +将数字相加或将数字加在日期上。如果数组中的其中一个值是日期,那么其他值将被视为毫秒数加在该日期上。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.add([<表达式1>, <表达式2>, ...]) +``` + +表达式可以是形如 `$ + 指定字段`,也可以是普通字符串。只要能够被解析成字符串即可。 + +#### 示例代码 + + 假设集合 `staff` 有如下记录: + +```typescript +{ _id: 1, department: "x", sales: 5, engineer: 10, lastUpdate: ISODate("2019-05-01T00:00:00Z") } +{ _id: 2, department: "y", sales: 10, engineer: 20, lastUpdate: ISODate("2019-05-01T02:00:00Z") } +{ _id: 3, department: "z", sales: 20, engineer: 5, lastUpdate: ISODate("2019-05-02T03:00:00Z") } +``` + +**数字求和** + + 可以用如下方式求得各个记录人数总数: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('staff').aggregate() + .project({ + department: 1, + total: $.add(['$sales', '$engineer']) + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, department: "x", total: 15 } +{ _id: 2, department: "y", total: 30 } +{ _id: 3, department: "z", total: 25 } +``` + +**增加日期值** + + 如下操作可以获取各个记录的 `lastUpdate` 加一个小时之后的值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('staff').aggregate() + .project({ + department: 1, + lastUpdate: $.add(['$lastUpdate', 60*60*1000]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, department: "x", lastUpdate: ISODate("2019-05-01T01:00:00Z") } +{ _id: 2, department: "y", lastUpdate: ISODate("2019-05-01T03:00:00Z") } +{ _id: 3, department: "z", lastUpdate: ISODate("2019-05-02T04:00:00Z") } +``` + +### ceil + +向上取整,返回大于或等于给定数字的最小整数。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.ceil() +``` + +`` 可以是任意解析为数字的表达式。如果表达式解析为 `null` 或指向一个不存在的字段,则返回 `null`,如果解析为 `NaN`,则返回 `NaN`。 + +#### 示例代码 + + 假设集合 `sales` 有如下记录: + +```typescript +{ _id: 1, sales: 5.2 } +{ _id: 2, sales: 1.32 } +{ _id: 3, sales: -3.2 } +``` + +可以用如下方式取各个数字的向上取整值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('sales').aggregate() + .project({ + sales: $.ceil('$sales') + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, sales: 6 } +{ _id: 2, sales: 2 } +{ _id: 3, sales: -3 } +``` + +### divide + +传入被除数和除数,求商。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.divide([<被除数表达式>, <除数表达式>]) +``` + +表达式可以是任意解析为数字的表达式。 + +#### 示例代码 + + 假设集合 `railroads` 有如下记录: + +```typescript +{ _id: 1, meters: 5300 } +{ _id: 2, meters: 64000 } +{ _id: 3, meters: 130 } +``` + +可以用如下方式取各个数字转换为千米之后的值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('railroads').aggregate() + .project({ + km: $.divide(['$meters', 1000]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, km: 5.3 } +{ _id: 2, km: 64 } +{ _id: 3, km: 0.13 } +``` + +### exp + +取 e(自然对数的底数,欧拉数)的 n 次方。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.exp() +``` + +`` 可以是任意解析为数字的表达式。如果表达式解析为 `null` 或指向一个不存在的字段,则返回 `null`,如果解析为 `NaN`,则返回 `NaN`。 + +#### 示例代码 + + 假设集合 `math` 有如下记录: + +```typescript +{ _id: 1, exp: 0 } +{ _id: 2, exp: 1 } +{ _id: 3, exp: 2 } +``` + +```typescript +const $ = db.command.aggregate +let res = await db.collection('math').aggregate() + .project({ + result: $.exp('$exp') + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, result: 1 } +{ _id: 2, result: 2.71828182845905 } +{ _id: 3, result: 7.38905609893065 } +``` + +### floor + +向下取整,返回大于或等于给定数字的最小整数。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.floor() +``` + +`` 可以是任意解析为数字的表达式。如果表达式解析为 `null` 或指向一个不存在的字段,则返回 `null`,如果解析为 `NaN`,则返回 `NaN`。 + +#### 示例代码 + + 假设集合 `sales` 有如下记录: + +```typescript +{ _id: 1, sales: 5.2 } +{ _id: 2, sales: 1.32 } +{ _id: 3, sales: -3.2 } +``` + +可以用如下方式取各个数字的向下取整值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('sales').aggregate() + .project({ + sales: $.floor('$sales') + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, sales: 5 } +{ _id: 2, sales: 1 } +{ _id: 3, sales: -4 } +``` + +### ln + +计算给定数字在自然对数值。 + +#### API 说明 + +语法如下: + +```typescript +db.command.aggregate.ln() +``` + +`` 可以是任意解析为非负数字的表达式。 + +`ln` 等价于 `log([, Math.E])`,其中 `Math.E` 是 `JavaScript` 获取 `e` 的值的方法。 + +#### 示例代码 + +假设集合 curve 有如下记录: + +```typescript +{ _id: 1, x: 1 } +{ _id: 2, x: 2 } +{ _id: 3, x: 3 } +``` + +计算 ln(x) 的值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('curve').aggregate() + .project({ + log: $.ln('$x') + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, ln: 0 } +{ _id: 2, ln: 0.6931471805599453 } +{ _id: 3, ln: 1.0986122886681098 } +``` + +### log + +计算给定数字在给定对数底下的 log 值。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.log([, ]) +``` + +`` 可以是任意解析为非负数字的表达式。`` 可以是任意解析为大于 1 的数字的表达式。 + + 如果任一参数解析为 `null` 或指向任意一个不存在的字段,`log` 返回 `null`。如果任一参数解析为 `NaN`,`log` 返回 `NaN`。 + +#### 示例代码 + + 假设集合 `curve` 有如下记录: + +```typescript +{ _id: 1, x: 1 } +{ _id: 2, x: 2 } +{ _id: 3, x: 3 } +``` + +计算 `log2(x)` 的值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('curve').aggregate() + .project({ + log: $.log(['$x', 2]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, log: 0 } +{ _id: 2, log: 1 } +{ _id: 3, log: 1.58496250072 } +``` + +### log10 + +计算给定数字在对数底为 10 下的 log 值。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.log() +``` + +`` 可以是任意解析为非负数字的表达式。 + + `log10` 等同于 `log` 方法的第二个参数固定为 10。 + +#### 示例代码 + +#### db.command.aggregate.log10 + +计算给定数字在对数底为 10 下的 log 值。 + +语法如下: + +```typescript +db.command.aggregate.log() +``` + +`` 可以是任意解析为非负数字的表达式。 + + `log10` 等同于 `log` 方法的第二个参数固定为 10。 + +### mod + +取模运算,取数字取模后的值。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.mod([, ]) +``` + +第一个数字是被除数,第二个数字是除数。参数可以是任意解析为数字的表达式。 + +#### 示例代码 + + 假设集合 `shopping` 有如下记录: + +```typescript +{ _id: 1, bags: 3, items: 5 } +{ _id: 2, bags: 2, items: 8 } +{ _id: 3, bags: 5, items: 16 } +``` + +各记录取 `items` 除以 `bags` 的余数(`items % bags`): + +```typescript +const $ = db.command.aggregate +let res = await db.collection('shopping').aggregate() + .project({ + overflow: $.mod(['$items', '$bags']) + }) + .end() +``` + +返回结果如下: + +```typescript +{ _id: 1, overflow: 2 } +{ _id: 2, overflow: 0 } +{ _id: 3, overflow: 1 } +``` + +### multiply + +取传入的数字参数相乘的结果。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.multiply([, , ...]) +``` + +参数可以是任意解析为数字的表达式。 + +#### 示例代码 + + 假设集合 `fruits` 有如下记录: + +```typescript +{ "_id": 1, "name": "apple", "price": 10, "quantity": 100 } +{ "_id": 2, "name": "orange", "price": 15, "quantity": 50 } +{ "_id": 3, "name": "lemon", "price": 5, "quantity": 20 } +``` + +求各个水果的的总价值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('fruits').aggregate() + .project({ + name: 1, + total: $.multiply(['$price', '$quantity']), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "name": "apple", "total": 1000 } +{ "_id": 2, "name": "orange", "total": 750 } +{ "_id": 3, "name": "lemo", "total": 100 } +``` + +### pow + +求给定基数的指数次幂。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.pow([, ]) +``` + +参数可以是任意解析为数字的表达式。 + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ "_id": 1, "x": 2, "y": 3 } +{ "_id": 2, "x": 5, "y": 7 } +{ "_id": 3, "x": 10, "y": 20 } +``` + +求 `x` 和 `y` 的平方和: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('stats').aggregate() + .project({ + sumOfSquares: $.add([$.pow(['$x', 2]), $.pow(['$y', 2])]), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "sumOfSquares": 13 } +{ "_id": 2, "sumOfSquares": 74 } +{ "_id": 3, "sumOfSquares": 500 } +``` + +### sqrt + +求平方根。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.sqrt([]) +``` + +参数可以是任意解析为非负数字的表达式。 + +#### 示例代码 + + 假设直角三角形集合 `triangle` 有如下记录: + +```typescript +{ "_id": 1, "x": 2, "y": 3 } +{ "_id": 2, "x": 5, "y": 7 } +{ "_id": 3, "x": 10, "y": 20 } +``` + +假设 `x` 和 `y` 分别为两直角边,则求斜边长: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('triangle').aggregate() + .project({ + len: $.sqrt([$.add([$.pow(['$x', 2]), $.pow(['$y', 2])])]), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "len": 3.605551275463989 } +{ "_id": 2, "len": 8.602325267042627 } +{ "_id": 3, "len": 22.360679774997898 } +``` + +### subtract + +将两个数字相减然后返回差值,或将两个日期相减然后返回相差的毫秒数,或将一个日期减去一个数字返回结果的日期。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.subtract([, ]) +``` + +参数可以是任意解析为数字或日期的表达式。 + +#### 示例代码 + + 假设集合 `scores` 有如下记录: + +```typescript +{ "_id": 1, "max": 10, "min": 1 } +{ "_id": 2, "max": 7, "min": 5 } +{ "_id": 3, "max": 6, "min": 6 } +``` + +求各个记录的 `max` 和 `min` 的差值。: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('scores').aggregate() + .project({ + diff: $.subtract(['$max', '$min']) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "diff": 9 } +{ "_id": 2, "diff": 2 } +{ "_id": 3, "diff": 0 } +``` + +### trunc + +将数字截断为整形。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.trunc() +``` + +参数可以是任意解析为数字的表达式。 + +#### 示例代码 + + 假设集合 `scores` 有如下记录: + +```typescript +{ "_id": 1, "value": 1.21 } +{ "_id": 2, "value": 3.83 } +{ "_id": 3, "value": -4.94 } +``` + +```typescript +const $ = db.command.aggregate +let res = await db.collection('scores').aggregate() + .project({ + int: $.trunc('$value') + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "value": 1 } +{ "_id": 2, "value": 3 } +{ "_id": 3, "value": -4 } +``` + +## 数组操作符 + +### arrayElemAt + +返回在指定数组下标的元素。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.arrayElemAt([, ]) +``` + +`` 可以是任意解析为数组的表达式。 + + `` 可以是任意解析为整形的表达式。如果是正数,`arrayElemAt` 返回在 `index` 位置的元素,如果是负数,`arrayElemAt` 返回从数组尾部算起的 `index` 位置的元素。 + +#### 示例代码 + + 假设集合 `exams` 有如下记录: + +```typescript +{ "_id": 1, "scores": [80, 60, 65, 90] } +{ "_id": 2, "scores": [78] } +{ "_id": 3, "scores": [95, 88, 92] } +``` + +求各个第一次考试的分数和和最后一次的分数: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('exams').aggregate() + .project({ + first: $.arrayElemAt(['$scores', 0]), + last: $.arrayElemAt(['$scores', -1]), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "first": 80, "last": 90 } +{ "_id": 2, "first": 78, "last": 78 } +{ "_id": 3, "first": 95, "last": 92 } +``` + +### arrayToObject + +将一个数组转换为对象。 + +#### API 说明 + + 语法可以取两种: + + 第一种:传入一个二维数组,第二维的数组长度必须为 2,其第一个值为字段名,第二个值为字段值 + +```typescript +db.command.aggregate.arrayToObject([ + [, ], + [, ], + ... +]) +``` + +第二种:传入一个对象数组,各个对象必须包含字段 `k` 和 `v`,分别指定字段名和字段值 + +```typescript +db.command.aggregate.arrayToObject([ + { "k": , "v": }, + { "k": , "v": }, + ... +]) +``` + +传入 `arrayToObject` 的参数只要可以解析为上述两种表示法之一即可。 + +#### 示例代码 + + 假设集合 `shops` 有如下记录: + +```typescript +{ "_id": 1, "sales": [ ["max", 100], ["min", 50] ] } +{ "_id": 2, "sales": [ ["max", 70], ["min", 60] ] } +{ "_id": 3, "sales": [ { "k": "max", "v": 50 }, { "k": "min", "v": 30 } ] } +``` + +将数组转换为对象: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('shops').aggregate() + .project({ + sales: $.arrayToObject('$sales'), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "sales": { "max": 100, "min": 50 } } +{ "_id": 2, "sales": { "max": 70, "min": 60 } } +{ "_id": 3, "sales": { "max": 50, "min": 30 } } +``` + +### concatArrays + +将多个数组拼接成一个数组。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.concatArrays([ , , ... ]) +``` + +参数可以是任意解析为数组的表达式。 + +#### 示例代码 + + 假设集合 `items` 有如下记录: + +```typescript +{ "_id": 1, "fruits": [ "apple" ], "vegetables": [ "carrot" ] } +{ "_id": 2, "fruits": [ "orange", "lemon" ], "vegetables": [ "cabbage" ] } +{ "_id": 3, "fruits": [ "strawberry" ], "vegetables": [ "spinach" ] } +``` + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + list: $.concatArrays(['$fruits', '$vegetables']), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "list": [ "apple", "carrot" ] } +{ "_id": 2, "list": [ "orange", "lemon", "cabbage" ] } +{ "_id": 3, "list": [ "strawberry", "spinach" ] } +``` + +### filter + +根据给定条件返回满足条件的数组的子集。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.filter({ + input: , + as: , + cond: +}) +``` + +|字段 |说明 | +|---- |---- | +|input|一个可以解析为数组的表达式 | +|as |可选,用于表示数组各个元素的变量,默认为 this | +|cond |一个可以解析为布尔值的表达式,用于判断各个元素是否满足条件,各个元素的名字由 as 参数决定(参数名需加 $$ 前缀,如 $$this)| + +参数可以是任意解析为数组的表达式。 + +#### 示例代码 + + 假设集合 `fruits` 有如下记录: + +```typescript +{ + "_id": 1, + "stock": [ + { "name": "apple", "price": 10 }, + { "name": "orange", "price": 20 } + ], +} +{ + "_id": 2, + "stock": [ + { "name": "lemon", "price": 15 }, + ], +} +``` + +```typescript +const _ = db.command +const $ = db.command.aggregate +let res = await db.collection('fruits').aggregate() + .project({ + stock: $.filter({ + input: '$stock', + as: 'item', + cond: $.gte(['$$item.price', 15]) + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "stock": [ { "name": "orange", "price": 20} ] } +{ "_id": 2, "stock": [ { "name": "lemon", "price": 15 } ] } +``` + +### in + +给定一个值和一个数组,如果值在数组中则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.in([, ]) +``` + +`` 可以是任意表达式。 + + `` 可以是任意解析为数组的表达式。 + +#### 示例代码 + + 假设集合 `shops` 有如下记录: + +```typescript +{ "_id": 1, "topsellers": ["bread", "ice cream", "butter"] } +{ "_id": 2, "topsellers": ["ice cream", "cheese", "yagurt"] } +{ "_id": 3, "topsellers": ["croissant", "cucumber", "coconut"] } +``` + +标记销量最高的商品包含 `ice cream` 的记录。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + included: $.in(['ice cream', '$topsellers']) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "included": true } +{ "_id": 2, "included": true } +{ "_id": 3, "included": false } +``` + +### indexOfArray + +在数组中找出等于给定值的第一个元素的下标,如果找不到则返回 -1。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.indexOfArray([ , , , ]) +``` + +|字段 |类型 |说明 | +|---- |---- |---- | +|- |string |一个可以解析为数组的表达式,如果解析为 null,则 indexOfArray 返回 null | +|- |string |对数据各个元素应用的条件匹配表达式 | +|- |integer|可选,用于指定搜索的开始下标,必须是非负整数 | +|- |integer|可选,用于指定搜索的结束下标,必须是非负整数,指定了 时也应指定,否则 默认当做| + +参数可以是任意解析为数组的表达式。 + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ + "_id": 1, + "sales": [ 1, 6, 2, 2, 5 ] +} +{ + "_id": 2, + "sales": [ 4, 2, 1, 5, 2 ] +} +{ + "_id": 3, + "sales": [ 2, 5, 3, 3, 1 ] +} +``` + +```typescript +const $ = db.command.aggregate +let res = await db.collection('stats').aggregate() + .project({ + index: $.indexOfArray(['$sales', 2, 2]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "index": 2 } +{ "_id": 2, "index": 4 } +{ "_id": 3, "index": -1 } +``` + +### isArray + +判断给定表达式是否是数组,返回布尔值。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.isArray() +``` + +参数可以是任意表达式。 + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ + "_id": 1, + "base": 10, + "sales": [ 1, 6, 2, 2, 5 ] +} +{ + "_id": 2, + "base": 1, + "sales": 100 +} +``` + +计算总销量,如果 `sales` 是数字,则求 `sales * base`,如果 `sales` 是数组,则求数组元素之和与 `base` 的乘积。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('stats').aggregate() + .project({ + sum: $.cond({ + if: $.isArray('$sales'), + then: $.multiply([$.sum(['$sales']), '$base']), + else: $.multiply(['$sales', '$base']), + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "sum": 160 } +{ "_id": 2, "sum": 100 } +``` + +### map + +类似 JavaScript Array 上的 `map` 方法,将给定数组的每个元素按给定转换方法转换后得出新的数组。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.map({ + input: , + as: , + in: +}) +``` + +|字段 |说明 | +|---- |---- | +|input|一个可以解析为数组的表达式 | +|as |可选,用于表示数组各个元素的变量,默认为 this | +|in |一个可以应用在给定数组的各个元素上的表达式,各个元素的名字由 as 参数决定(参数名需加 $$ 前缀,如 $$this)| + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ + "_id": 1, + "sales": [ 1.32, 6.93, 2.48, 2.82, 5.74 ] +} +{ + "_id": 2, + "sales": [ 2.97, 7.13, 1.58, 6.37, 3.69 ] +} +``` + +将各个数字截断为整形,然后求和 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('stats').aggregate() + .project({ + truncated: $.map({ + input: '$sales', + as: 'num', + in: $.trunc('$$num'), + }) + }) + .project({ + total: $.sum('$truncated') + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "total": 16 } +{ "_id": 2, "total": 19 } +``` + +### objectToArray + +将一个对象转换为数组。方法把对象的每个键值对都变成输出数组的一个元素,元素形如 `{ k: , v: }`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.objectToArray() +``` + +#### 示例代码 + + 假设集合 `items` 有如下记录: + +```typescript +{ "_id": 1, "attributes": { "color": "red", "price": 150 } } +{ "_id": 2, "attributes": { "color": "blue", "price": 50 } } +{ "_id": 3, "attributes": { "color": "yellow", "price": 10 } } +``` + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + array: $.objectToArray('$attributes') + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "array": [{ "k": "color", "v": "red" }, { "k": "price", "v": 150 }] } +{ "_id": 2, "array": [{ "k": "color", "v": "blue" }, { "k": "price", "v": 50 }] } +{ "_id": 3, "array": [{ "k": "color", "v": "yellow" }, { "k": "price", "v": 10 }] } +``` + +### range + +返回一组生成的序列数字。给定开始值、结束值、非零的步长,`range` 会返回从开始值开始逐步增长、步长为给定步长、但不包括结束值的序列。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.range([, , ]) +``` + +|字段 |说明 | +|---- |---- | +|start |开始值,一个可以解析为整形的表达式 | +|end |结束值,一个可以解析为整形的表达式 | +|non-zero step|可选,步长,一个可以解析为非零整形的表达式,默认为 1 | + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ "_id": 1, "max": 52 } +{ "_id": 2, "max": 38 } +``` + +```typescript +const $ = db.command.aggregate +db.collection('stats').aggregate() + .project({ + points: $.range([0, '$max', 10]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "points": [0, 10, 20, 30, 40, 50] } +{ "_id": 2, "points": [0, 10, 20, 30] } +``` + +### reduce + +类似 JavaScript 的 `reduce` 方法,应用一个表达式于数组各个元素然后归一成一个元素。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.reduce({ + input: + initialValue: , + in: +}) +``` + +|字段 |说明 | +|---- |---- | +|input |输入数组,可以是任意解析为数组的表达式 | +|initialValue |初始值 | +|in |用来作用于每个元素的表达式,在 in 中有两个可用变量,value 是表示累计值的变量,this 是表示当前数组元素的变量| + +#### 示例代码 + +**简易字符串拼接** + + 假设集合 `player` 有如下记录: + +```typescript +{ "_id": 1, "fullname": [ "Stephen", "Curry" ] } +{ "_id": 2, "fullname": [ "Klay", "Thompsom" ] } +``` + +获取各个球员的全名,并加 `Player:` 前缀: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('player').aggregate() + .project({ + info: $.reduce({ + input: '$fullname', + initialValue: 'Player:', + in: $.concat(['$$value', ' ', '$$this']), + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "info": "Player: Stephen Curry" } +{ "_id": 2, "info": "Player: Klay Thompson" } +``` + +获取各个球员的全名,不加前缀: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('player').aggregate() + .project({ + name: $.reduce({ + input: '$fullname', + initialValue: '', + in: $.concat([ + '$$value', + $.cond({ + if: $.eq(['$$value', '']), + then: '', + else: ' ', + }), + '$$this', + ]), + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "name": "Stephen Curry" } +{ "_id": 2, "name": "Klay Thompson" } +``` + +### reverseArray + +返回给定数组的倒序形式。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.reverseArray() +``` + +参数可以是任意解析为数组表达式。 + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ + "_id": 1, + "sales": [ 1, 2, 3, 4, 5 ] +} +``` + +取 `sales` 倒序: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('stats').aggregate() + .project({ + reversed: $.reverseArray('$sales'), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "reversed": [5, 4, 3, 2, 1] } +``` + +### size + +返回数组长度。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.size() +``` + +`` 可以是任意解析为数组的表达式。 + +#### 示例代码 + + 假设集合 `shops` 有如下记录: + +```typescript +{ "_id": 1, "staff": [ "John", "Middleton", "George" ] } +{ "_id": 2, "staff": [ "Steph", "Jack" ] } +``` + +计算各个商店的雇员数量: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('shops').aggregate() + .project({ + totalStaff: $.size('$staff') + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "totalStaff": 3 } +{ "_id": 2, "totalStaff": 2 } +``` + +### slice + +类似 JavaScritp 的 `slice` 方法。返回给定数组的指定子集。 + +#### API 说明 + + 语法有两种: + + 返回从开头或结尾开始的 `n` 个元素: + +```typescript +db.command.aggregate.slice([, ]) +``` + +返回从指定位置算作数组开头、再向后或向前的 `n` 个元素: + +```typescript +db.command.aggregate.slice([, , ]) +``` + +`` 可以是任意解析为数组的表达式。 + + `` 可以是任意解析为整形的表达式。如果是正数,则将数组的第 `` 个元素作为数组开始;如果 `` 比数组长度更长,`slice` 返回空数组。如果是负数,则将数组倒数第 `` 个元素作为数组开始;如果 `` 的绝对值大于数组长度,则开始位置即为数组开始位置。 + + `` 可以是任意解析为整形的表达式。如果 `` 有提供,则 `` 必须为正整数。如果是正数,`slice` 返回前 `n` 个元素。如果是负数,`slice` 返回后 `n` 个元素。 + +#### 示例代码 + + 假设集合 `people` 有如下记录: + +```typescript +{ "_id": 1, "hobbies": [ "basketball", "football", "tennis", "badminton" ] } +{ "_id": 2, "hobbies": [ "golf", "handball" ] } +{ "_id": 3, "hobbies": [ "table tennis", "swimming", "rowing" ] } +``` + +统一返回前两个爱好: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('fruits').aggregate() + .project({ + hobbies: $.slice(['$hobbies', 2]), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "hobbies": [ "basketball", "football" ] } +{ "_id": 2, "hobbies": [ "golf", "handball" ] } +{ "_id": 3, "hobbies": [ "table tennis", "swimming" ] } +``` + +### zip + +把二维数组的第二维数组中的相同序号的元素分别拼装成一个新的数组进而组装成一个新的二维数组。如可将 `[ [ 1, 2, 3 ], [ "a", "b", "c" ] ]` 转换成 `[ [ 1, "a" ], [ 2, "b" ], [ 3, "c" ] ]`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.zip({ + inputs: [, , ...], + useLongestLength: , + defaults: +}) +``` + +`inputs` 是一个二维数组(`inputs` 不可以是字段引用),其中每个元素的表达式(这个可以是字段引用)都可以解析为数组。如果其中任意一个表达式返回 `null`,`` 也返回 `null`。如果其中任意一个表达式不是指向一个合法的字段 / 解析为数组 / 解析为 `null`,则返回错误。 + + `useLongestLength` 决定输出数组的长度是否采用输入数组中的最长数组的长度。默认为 `false`,即输入数组中的最短的数组的长度即是输出数组的各个元素的长度。 + + `defaults` 是一个数组,用于指定在输入数组长度不一的情况下时采用的数组各元素默认值。指定这个字段则必须指定 `useLongestLength`,否则返回错误。如果 `useLongestLength` 是 `true` 但是 `defaults` 是空或没有指定,则 `zip` 用 `null` 做数组元素的缺省默认值。指定各元素默认值时 `defaults` 数组的长度必须是输入数组最大的长度。 + +#### 示例代码 + + 假设集合 `stats` 有如下记录: + +```typescript +{ "_id": 1, "zip1": [1, 2], "zip2": [3, 4], "zip3": [5, 6] ] } +{ "_id": 2, "zip1": [1, 2], "zip2": [3], "zip3": [4, 5, 6] ] } +{ "_id": 3, "zip1": [1, 2], "zip2": [3] ] } +``` + +**只传 inputs** + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + zip: $.zip({ + inputs: [ + '$zip1', // 字段引用 + '$zip2', + '$zip3', + ], + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] } +{ "_id": 2, "zip": [ [1, 3, 4] ] } +{ "_id": 3, "zip": null } +``` + +**设置 useLongestLength** + + 如果设 `useLongestLength` 为 `true`: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + zip: $.zip({ + inputs: [ + '$zip1', // 字段引用 + '$zip2', + '$zip3', + ], + useLongestLength: true, + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] } +{ "_id": 2, "zip": [ [1, 3, 4], [2, null, 5], [null, null, 6] ] } +{ "_id": 3, "zip": null } +``` + +**设置 defaults** + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + zip: $.zip({ + inputs: [ + '$zip1', // 字段引用 + '$zip2', + '$zip3', + ], + useLongestLength: true, + defaults: [-300, -200, -100], + }) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] } +{ "_id": 2, "zip": [ [1, 3, 4], [2, -200, 5], [-300, -200, 6] ] } +{ "_id": 3, "zip": null } +``` + +## 布尔操作符 + +### and + +给定多个表达式,`and` 仅在所有表达式都返回 `true` 时返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.and([, , ...]) +``` + +如果表达式返回 `false`、`null`、`0`、或 `undefined`,表达式会解析为 `false`,否则对其他返回值都认为是 `true`。 + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "min": 10, "max": 100 } +{ "_id": 2, "min": 60, "max": 80 } +{ "_id": 3, "min": 30, "max": 50 } +``` + +求 `min` 大于等于 30 且 `max` 小于等于 80 的记录。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + fullfilled: $.and([$.gte(['$min', 30]), $.lte(['$max', 80])]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "fullfilled": false } +{ "_id": 2, "fullfilled": true } +{ "_id": 3, "fullfilled": true } +``` + +### not + +给定一个表达式,如果表达式返回 `true`,则 `not` 返回 `false`,否则返回 `true`。注意表达式不能为逻辑表达式(`and`、`or`、`nor`、`not`)。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.not() +``` + +如果表达式返回 `false`、`null`、`0`、或 `undefined`,表达式会解析为 `false`,否则对其他返回值都认为是 `true`。 + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "min": 10, "max": 100 } +{ "_id": 2, "min": 60, "max": 80 } +{ "_id": 3, "min": 30, "max": 50 } +``` + +求 `min` 不大于 40 的记录。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + fullfilled: $.not($.gt(['$min', 40])) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "fullfilled": true } +{ "_id": 2, "fullfilled": false } +{ "_id": 3, "fullfilled": true } +``` + +### or + +给定多个表达式,如果任意一个表达式返回 `true`,则 `or` 返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.or([, , ...]) +``` + +如果表达式返回 `false`、`null`、`0`、或 `undefined`,表达式会解析为 `false`,否则对其他返回值都认为是 `true`。 + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "min": 10, "max": 100 } +{ "_id": 2, "min": 50, "max": 60 } +{ "_id": 3, "min": 30, "max": 50 } +``` + +求 `min` 小于 40 或 `max` 大于 60 的记录。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + fullfilled: $.or([$.lt(['$min', 40]), $.gt(['$max', 60])]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "fullfilled": true } +{ "_id": 2, "fullfilled": false } +{ "_id": 3, "fullfilled": true } +``` + +## 比较操作符 + +### cmp + +给定两个值,返回其比较值: + +#### API 说明 + + 如果第一个值小于第二个值,返回 -1 +如果第一个值大于第二个值,返回 1 +如果两个值相等,返回 0 + + 语法如下: + +```typescript +db.command.aggregate.cmp([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "shop1": 10, "shop2": 100 } +{ "_id": 2, "shop1": 80, "shop2": 20 } +{ "_id": 3, "shop1": 50, "shop2": 50 } +``` + +求 `shop1` 和 `shop2` 的各个物品的价格对比。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + compare: $.cmp(['$shop1', '$shop2'])) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "compare": -1 } +{ "_id": 2, "compare": 1 } +{ "_id": 3, "compare": 0 } +``` + +### eq + +匹配两个值,如果相等则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.eq([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "value": 10 } +{ "_id": 2, "value": 80 } +{ "_id": 3, "value": 50 } +``` + +求 `value` 等于 50 的记录。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + matched: $.eq(['$value', 50]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "matched": false } +{ "_id": 2, "matched": false } +{ "_id": 3, "matched": true } +``` + +### gt + +匹配两个值,如果前者大于后者则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.gt([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "value": 10 } +{ "_id": 2, "value": 80 } +{ "_id": 3, "value": 50 } +``` + +判断 `value` 是否大于 50。 + +```typescript +const $ = db.command.aggregate +db.collection('price').aggregate() + .project({ + matched: $.gt(['$value', 50]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "matched": false } +{ "_id": 2, "matched": true } +{ "_id": 3, "matched": false } +``` + +### gte + +匹配两个值,如果前者大于或等于后者则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.gte([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "value": 10 } +{ "_id": 2, "value": 80 } +{ "_id": 3, "value": 50 } +``` + +判断 `value` 是否大于或等于 50。 + +```typescript +const $ = db.command.aggregate +let res = await b.collection('price').aggregate() + .project({ + matched: $.gte(['$value', 50]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "matched": false } +{ "_id": 2, "matched": true } +{ "_id": 3, "matched": true } +``` + +### lt + +匹配两个值,如果前者小于后者则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.lt([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +``` +{ "_id": 1, "value": 10 } +{ "_id": 2, "value": 80 } +{ "_id": 3, "value": 50 } +``` + +判断 `value` 是否小于 50。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + matched: $.lt(['$value', 50]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "matched": true } +{ "_id": 2, "matched": false } +{ "_id": 3, "matched": false } +``` + +### lte + +匹配两个值,如果前者小于或等于后者则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.lte([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "value": 10 } +{ "_id": 2, "value": 80 } +{ "_id": 3, "value": 50 } +``` + +判断 `value` 是否小于 50。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + matched: $.lte(['$value', 50]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "matched": true } +{ "_id": 2, "matched": false } +{ "_id": 3, "matched": true } +``` + +### neq + +匹配两个值,如果不相等则返回 `true`,否则返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.neq([, ]) +``` + +#### 示例代码 + + 假设集合 `price` 有如下记录: + +```typescript +{ "_id": 1, "value": 10 } +{ "_id": 2, "value": 80 } +{ "_id": 3, "value": 50 } +``` + +求 `value` 不等于 50 的记录。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price').aggregate() + .project({ + matched: $.neq(['$value', 50]) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "matched": true } +{ "_id": 2, "matched": true } +{ "_id": 3, "matched": false } +``` + +## 条件操作符 + +### cond + +计算布尔表达式,返回指定的两个值其中之一。 + +#### API 说明 + + `cond` 的使用形式如下: + +```typescript +cond({ if: <布尔表达式>, then: <真值>, else: <假值> }) +``` + +或者: + +```typescript +cond([ <布尔表达式>, <真值>, <假值> ]) +``` + +两种形式中,三个参数(`if`、`then`、`else`)都是必须的。 + + 如果布尔表达式为真,那么 `$cond` 将会返回 `<真值>`,否则会返回 `<假值>` + +#### 示例代码 + + 假设集合 `items` 的记录如下: + +```typescript +{ "_id": "0", "name": "item-a", "amount": 100 } +{ "_id": "1", "name": "item-b", "amount": 200 } +{ "_id": "2", "name": "item-c", "amount": 300 } +``` + +我们可以使用 `cond`,根据 `amount` 字段,来生成新的字段 `discount`: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + name: 1, + discount: $.cond({ + if: $.gte(['$amount', 200]), + then: 0.7, + else: 0.9 + }) + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": "0", "name": "item-a", "discount": 0.9 } +{ "_id": "1", "name": "item-b", "discount": 0.7 } +{ "_id": "2", "name": "item-c", "discount": 0.7 } +``` + +### ifNull + +计算给定的表达式,如果表达式结果为 null、undefined 或者不存在,那么返回一个替代值;否则返回原值。 + +#### API 说明 + + `ifNull` 的使用形式如下: + +```typescript +ifNull([ <表达式>, <替代值> ]) +``` + +#### 示例代码 + + 假设集合 `items` 的记录如下: + +```typescript +{ "_id": "0", "name": "A", "description": "这是商品 A" } +{ "_id": "1", "name": "B", "description": null } +{ "_id": "2", "name": "C" } +``` + +我们可以使用 `ifNull`,对不存在 `desc` 字段的文档,或者 `desc` 字段为 `null` 的文档,补充一个替代值。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + _id: 0, + name: 1, + description: $.ifNull(['$description', '商品描述空缺']) + }) + .end() +``` + +输出如下: + +```typescript +{ "name": "A", "description": "这是商品 A" } +{ "name": "B", "description": "商品描述空缺" } +{ "name": "C", "description": "商品描述空缺" } +``` + +### switch + +根据给定的 `switch-case-default` 计算返回值、 + +#### API 说明 + + `switch` 的使用形式如下: + +```typescript +switch({ + branches: [ + case: <表达式>, then: <表达式>, + case: <表达式>, then: <表达式>, + ... + ], + default: <表达式> +}) +``` + +#### 示例代码 + + 假设集合 `items` 的记录如下: + +```typescript +{ "_id": "0", "name": "item-a", "amount": 100 } +{ "_id": "1", "name": "item-b", "amount": 200 } +{ "_id": "2", "name": "item-c", "amount": 300 } +``` + +我们可以使用 `switch`,根据 `amount` 字段,来生成新的字段 `discount`: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + name: 1, + discount: $.switch({ + branches: [ + { case: $.gt(['$amount', 250]), then: 0.8 }, + { case: $.gt(['$amount', 150]), then: 0.9 } + ], + default: 1 + }) + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": "0", "name": "item-a", "discount": 1 } +{ "_id": "1", "name": "item-b", "discount": 0.9 } +{ "_id": "2", "name": "item-c", "discount": 0.8 } +``` + +## 日期操作符 + +**注意** + +- 以下日期操作符中`timezone`均支持以下几种形式 + +```typescript +timezone: "Asia/Shanghai" // Asia/Shanghai时区 +timezone: "+08" // utc+8 时区 +timezone: "+08:30" // 时区偏移 8 小时 30 分 +timezone: "+0830" // 时区偏移 8 小时 30 分,同上 +``` + +### dateFromParts + +给定日期的相关信息,构建并返回一个日期对象。 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.dateFromParts({ + year: , + month: , + day: , + hour: , + minute: , + second: , + millisecond: , + timezone: +}) +``` + +你也可以使用 ISO 8601 的标准: + +```typescript +db.command.aggregate.dateFromParts({ + isoWeekYear: , + isoWeek: , + isoDayOfWeek: , + hour: , + minute: , + second: , + millisecond: , + timezone: +}) +``` + +#### 示例代码 + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + date: $.dateFromParts({ + year: 2017, + month: 2, + day: 8, + hour: 12, + timezone: 'America/New_York' + }), + }) + .end() +``` + +输出如下: + +```typescript +{ + "date": ISODate("2017-02-08T17:00:00.000Z") +} +``` + +### dateFromString + +将一个日期/时间字符串转换为日期对象 + +#### API 说明 + + 语法如下: + +```typescript +db.command.aggregate.dateFromString({ + dateString: , + timezone: +}) +``` + +#### 示例代码 + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + date: $.dateFromString({ + dateString: "2019-05-14T09:38:51.686Z" + }) + }) + .end() +``` + +输出如下: + +```typescript +{ + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +### dateToString + +根据指定的表达式将日期对象格式化为符合要求的字符串。 + +#### API 说明 + + `dateToString` 的调用形式如下: + +```typescript +db.command.aggregate.dateToString({ + date: <日期表达式>, + format: <格式化表达式>, + timezone: <时区表达式>, + onNull: <空值表达式> +}) +``` + +下面是四种表达式的详细说明: + +|名称 |描述 | +|---- |---- | +|日期表达式 |必选。指定字段值应该是能转化为字符串的日期。 | +|格式化表达式 |可选。它可以是任何包含“格式说明符”的有效字符串。 | +|时区表达式 |可选。指明运算结果的时区。它可以解析格式为 [UTC Offset](https://en.wikipedia.org/wiki/List_of_UTC_time_offsets) 或者 [Olson Timezone Identifier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) 的字符串。| +|空值表达式 |可选。当 <日期表达式> 返回空或者不存在的时候,会返回此表达式指明的值。 | + +下面是格式说明符的详细说明: + +|说明符 |描述 |合法值 | +|---- |---- |---- | +|%d |月份的日期(2 位数,0 填充) |01 - 31 | +|%G |ISO 8601 格式的年份 |0000 - 9999| +|%H |小时(2 位数,0 填充,24 小时制) |00 - 23 | +|%j |一年中的一天(3 位数,0 填充) |001 - 366 | +|%L |毫秒(3 位数,0 填充) |000 - 999 | +|%m |月份(2 位数,0 填充) |01 - 12 | +|%M |分钟(2 位数,0 填充) |00 - 59 | +|%S |秒(2 位数,0 填充) |00 - 60 | +|%w |星期几 |1 - 7 | +|%u |ISO 8601 格式的星期几 |1 - 7 | +|%U |一年中的一周(2 位数,0 填充) |00 - 53 | +|%V |ISO 8601 格式的一年中的一周 |1 - 53 | +|%Y |年份(4 位数,0 填充) |0000 - 9999| +|%z |与 UTC 的时区偏移量 |+/-[hh][mm]| +|%Z |以分钟为单位,与 UTC 的时区偏移量|+/-mmm | +|%% |百分号作为字符 |% | + +#### 示例代码 + + 假设集合 `students` 有如下记录: + +```typescript +{ "date": "1999-12-11T16:00:00.000Z", "firstName": "Yuanxin", "lastName": "Dong" } +{ "date": "1998-11-10T16:00:00.000Z", "firstName": "Weijia", "lastName": "Wang" } +{ "date": "1997-10-09T16:00:00.000Z", "firstName": "Chengxi", "lastName": "Li" } +``` + +**格式化日期** + + 下面是将 `date` 字段的值,格式化成形如 `年份-月份-日期` 的字符串: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + formatDate: $.dateToString({ + date: '$date', + format: '%Y-%m-%d' + }) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "formatDate": "1999-12-11" } +{ "formatDate": "1998-11-10" } +{ "formatDate": "1997-10-09" } +``` + +**时区时间** + + 下面是将 `date` 字段值格式化为上海时区时间的例子: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + formatDate: $.dateToString({ + date: '$date', + format: '%H:%M:%S', + timezone: 'Asia/Shanghai' + }) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "formatDate": "00:00:00" } +{ "formatDate": "00:00:00" } +{ "formatDate": "00:00:00" } +``` + +**缺失情况的默认值** + + 当指定的 `<日期表达式>` 返回空或者不存在的时候,可以设置缺失情况下的默认值: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + formatDate: $.dateToString({ + date: '$empty', + onNull: 'null' + }) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "formatDate": "null" } +{ "formatDate": "null" } +{ "formatDate": "null" } +``` + +### dayOfMonth + +返回日期字段对应的天数(一个月中的哪一天),是一个介于 1 至 31 之间的数字。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.dayOfMonth(<日期字段>) + +db.command.aggregate.dayOfMonth({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + + 假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `dayOfMonth()` 对 `date` 字段进行投影,获取对应的日期: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + dayOfMonth: $.dayOfMonth('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "dayOfMonth": 14 +} +``` + +### dayOfWeek + +返回日期字段对应的天数(一周中的第几天),是一个介于 1(周日)到 7(周六)之间的整数。 + +#### API 说明 + +**注意:周日是每周的第 1 天** + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.dayOfWeek(<日期字段>) + +db.command.aggregate.dayOfWeek({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + + 假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `dayOfWeek()` 对 `date` 字段进行投影,获取对应的天数(一周中的第几天): + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + dayOfWeek: $.dayOfWeek('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "dayOfWeek": 3 +} +``` + +### dayOfYear + +返回日期字段对应的天数(一年中的第几天),是一个介于 1 到 366 之间的整数。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.dayOfYear(<日期字段>) + +db.command.aggregate.dayOfYear({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + + 假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `dayOfYear()` 对 `date` 字段进行投影,获取对应的天数(一年中的第几天): + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + dayOfYear: $.dayOfYear('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "dayOfYear": 134 +} +``` + +### hour + +返回日期字段对应的小时数,是一个介于 0 到 23 之间的整数。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.hour(<日期字段>) + +db.command.aggregate.hour({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + + 假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `hour()` 对 `date` 字段进行投影,获取对应的小时数: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + hour: $.hour('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "hour": 9 +} +``` + +### isoDayOfWeek + +返回日期字段对应的 ISO 8601 标准的天数(一周中的第几天),是一个介于 1(周一)到 7(周日)之间的整数。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.isoDayOfWeek(<日期字段>) + +db.command.aggregate.isoDayOfWeek({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `isoDayOfWeek()` 对 `date` 字段进行投影,获取对应的 ISO 8601 标准的天数(一周中的第几天): + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + isoDayOfWeek: $.isoDayOfWeek('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "isoDayOfWeek": 2 +} +``` + +### isoWeek + +返回日期字段对应的 ISO 8601 标准的周数(一年中的第几周),是一个介于 1 到 53 之间的整数。 + +#### API 说明 + +根据 ISO 8601 标准,周一到周日视为一周,本年度第一个周四所在的那周,视为本年度的第 1 周。 + +例如:2016 年 1 月 7 日是那年的第一个周四,那么 2016.01.04(周一)到 2016.01.10(周日)即为第 1 周。同理,2016 年 1 月 1 日的周数为 53。 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.isoWeek(<日期字段>) + +db.command.aggregate.isoWeek({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `isoWeek()` 对 `date` 字段进行投影,获取对应的 ISO 8601 标准的周数(一年中的第几周): + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + isoWeek: $.isoWeek('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "isoWeek": 20 +} +``` + +### isoWeekYear + +返回日期字段对应的 ISO 8601 标准的天数(一年中的第几天)。 + +#### API 说明 + +此处的“年”以第一周的周一为开始,以最后一周的周日为结束。 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.isoWeekYear(<日期字段>) + +db.command.aggregate.isoWeekYear({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `isoWeekYear()` 对 `date` 字段进行投影,获取对应的 ISO 8601 标准的天数(一年中的第几天): + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + isoWeekYear: $.isoWeekYear('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "isoWeekYear": 2019 +} +``` + +### millisecond + +返回日期字段对应的毫秒数,是一个介于 0 到 999 之间的整数。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.millisecond(<日期字段>) + +db.command.aggregate.millisecond({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `millisecond()` 对 `date` 字段进行投影,获取对应的毫秒数: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + millisecond: $.millisecond('$date'), + }) + .end() +``` + +输出如下: + +```typescript +{ + "millisecond": 686 +} +``` + +### minute + +返回日期字段对应的分钟数,是一个介于 0 到 59 之间的整数。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.minute(<日期字段>) + +db.command.aggregate.minute({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `minute()` 对 `date` 字段进行投影,获取对应的分钟数: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + minute: $.minute('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "minute": 38 +} +``` + +### month + +返回日期字段对应的月份,是一个介于 1 到 12 之间的整数。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.month(<日期字段>) + +db.command.aggregate.month({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + + 假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `month()` 对 `date` 字段进行投影,获取对应的月份: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + month: $.month('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "month": 5 +} +``` + +### second + +返回日期字段对应的秒数,是一个介于 0 到 59 之间的整数,在特殊情况下(闰秒)可能等于 60。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.second(<日期字段>) + +db.command.aggregate.second({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `second()` 对 `date` 字段进行投影,获取对应的秒数: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + second: $.second('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "second": 51 +} +``` + +### week + +返回日期字段对应的周数(一年中的第几周),是一个介于 0 到 53 之间的整数。 + +#### API 说明 + +每周以周日为开头,**每年的第一个周日**即为 `week 1` 的开始,这天之前是 `week 0`。 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.week(<日期字段>) + +db.command.aggregate.week({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `week()` 对 `date` 字段进行投影,获取对应的周数(一年中的第几周): + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + week: $.week('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "week": 19 +} +``` + +### year + +返回日期字段对应的年份。 + +#### API 说明 + +该接口有以下两种用法,语法如下: + +```typescript +db.command.aggregate.year(<日期字段>) + +db.command.aggregate.year({date:<日期字段>,timezone:<时区>}) +``` + +#### 示例代码 + +假设集合 `dates` 有以下文档: + +```typescript +{ + "_id": 1, + "date": ISODate("2019-05-14T09:38:51.686Z") +} +``` + +我们使用 `year()` 对 `date` 字段进行投影,获取对应的年份: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('dates') + .aggregate() + .project({ + _id: 0, + year: $.year('$date') + }) + .end() +``` + +输出如下: + +```typescript +{ + "year": 2019 +} +``` + +## 常量操作符 + +### literal + +直接返回一个值的字面量,不经过任何解析和处理。 + +#### API 说明 + + `literal` 使用形式如下: + +```typescript +literal(<值>) +``` + +如果 `<值>` 是一个表达式,那么 `literal` **不会**解析或者计算这个表达式,而是直接返回这个表达式。 + +#### 示例代码 + + 比如我们有一个 `items` 集合,其中数据如下: + +```typescript +{ "_id": "0", "price": "$1" } +{ "_id": "1", "price": "$5.60" } +{ "_id": "2", "price": "$8.90" } +``` + +**以字面量的形式使用 $** + + 下面的代码使用 `literal`,生成了一个新的字段 `isOneDollar`,表示 `price` 字段是否严格等于 `"$1"`。 + + 注意:我们这里无法使用 `eq(['$price', '$1'])`,因为 `"$1"` 是一个表达式,代表 `"1"` 字段对应的值,而不是字符串字面量 `"$1"`。 + +```typescript +const $ = db.command.aggregate +let res = await db.collection('items').aggregate() + .project({ + isOneDollar: $.eq(['$price', $.literal('$1')]) + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": "0", "isOneDollar": true } +{ "_id": "1", "isOneDollar": false } +{ "_id": "2", "isOneDollar": false } +``` + +**投影一个字段,对应的值为 1** + + 下面的代码使用 `literal`,投影了一个新的字段 `amount`,其值为 `1`。 + +```typescript +const $ = db.command.aggregate +db.collection('items').aggregate() + .project({ + price: 1, + amount: $.literal(1) + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": "0", "price": "$1", "amount": 1 } +{ "_id": "1", "price": "$5.60", "amount": 1 } +{ "_id": "2", "price": "$8.90", "amount": 1 } +``` + +## 对象操作符 + +### mergeObjects + +将多个文档合并为单个文档。 + +#### API 说明 + + 使用形式如下: +在 `group()` 中使用时: + +```typescript +mergeObjects() +``` + +在其它表达式中使用时: + +```typescript +mergeObjects([, , ...]) +``` + +#### 示例代码 + +**搭配 `group()` 使用** + + 假设集合 `sales` 存在以下文档: + +```typescript +{ "_id": 1, "year": 2018, "name": "A", "volume": { "2018Q1": 500, "2018Q2": 500 } } +{ "_id": 2, "year": 2017, "name": "A", "volume": { "2017Q1": 400, "2017Q2": 300, "2017Q3": 0, "2017Q4": 0 } } +{ "_id": 3, "year": 2018, "name": "B", "volume": { "2018Q1": 100 } } +{ "_id": 4, "year": 2017, "name": "B", "volume": { "2017Q3": 100, "2017Q4": 250 } } +``` + +下面的代码使用 `mergeObjects()`,将用相同 `name` 的文档合并: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('sales').aggregate() + .group({ + _id: '$name', + mergedVolume: $.mergeObjects('$volume') + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": "A", "mergedVolume": { "2017Q1": 400, "2017Q2": 300, "2017Q3": 0, "2017Q4": 0, "2018Q1": 500, "2018Q2": 500 } } +{ "_id": "B", "mergedVolume": { "2017Q3": 100, "2017Q4": 250, "2018Q1": 100 } } +``` + +**一般用法** + +假设集合 `test` 存在以下文档: + +```typescript +{ "_id": 1, "foo": { "a": 1 }, "bar": { "b": 2 } } +{ "_id": 2, "foo": { "c": 1 }, "bar": { "d": 2 } } +{ "_id": 3, "foo": { "e": 1 }, "bar": { "f": 2 } } +``` + +下面的代码使用 `mergeObjects()`,将文档中的 `foo` 和 `bar` 字段合并为 `foobar`: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('sales').aggregate() + .project({ + foobar: $.mergeObjects(['$foo', '$bar']) + }) + .end() +``` + +输出结果如下: + +```typescript +{ "_id": 1, "foobar": { "a": 1, "b": 2 } } +{ "_id": 2, "foobar": { "c": 1, "d": 2 } } +{ "_id": 3, "foobar": { "e": 1, "f": 2 } } +``` + +## 集合操作符 + +### allElementsTrue + +输入一个数组,或者数组字段的表达式。如果数组中所有元素均为真值,那么返回 `true`,否则返回 `false`。空数组永远返回 `true`。 + +#### API 说明 + +语法如下: + +```typescript +allElementsTrue([]) +``` + +#### 示例代码 + +假设集合 `test` 有如下记录: + +```typescript +{ "_id": 1, "array": [ true ] } +{ "_id": 2, "array": [ ] } +{ "_id": 3, "array": [ false ] } +{ "_id": 4, "array": [ true, false ] } +{ "_id": 5, "array": [ 0 ] } +{ "_id": 6, "array": [ "stark" ] } +``` + +下面的代码使用 `allElementsTrue()`,判断 `array` 字段中是否均为真值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price') + .aggregate() + .project({ + isAllTrue: $.allElementsTrue(['$array']) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "isAllTrue": true } +{ "_id": 2, "isAllTrue": true } +{ "_id": 3, "isAllTrue": false } +{ "_id": 4, "isAllTrue": false } +{ "_id": 5, "isAllTrue": false } +{ "_id": 6, "isAllTrue": true } +``` + +### anyElementTrue + +输入一个数组,或者数组字段的表达式。如果数组中任意一个元素为真值,那么返回 `true`,否则返回 `false`。空数组永远返回 `false`。 + +#### API 说明 + + 语法如下: + +```typescript +anyElementTrue([]) +``` + +#### 示例代码 + + 假设集合 `test` 有如下记录: + +```typescript +{ "_id": 1, "array": [ true ] } +{ "_id": 2, "array": [ ] } +{ "_id": 3, "array": [ false ] } +{ "_id": 4, "array": [ true, false ] } +{ "_id": 5, "array": [ 0 ] } +{ "_id": 6, "array": [ "stark" ] } +``` + +下面的代码使用 `anyElementTrue()`,判断 `array` 字段中是否含有真值: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('price') + .aggregate() + .project({ + isAnyTrue: $.anyElementTrue(['$array']) + }) + .end() +``` + +返回结果如下: + +```typescript +{ "_id": 1, "isAnyTrue": true } +{ "_id": 2, "isAnyTrue": false } +{ "_id": 3, "isAnyTrue": false } +{ "_id": 4, "isAnyTrue": true } +{ "_id": 5, "isAnyTrue": false } +{ "_id": 6, "isAnyTrue": true } +``` + +### setDifference + +输入两个集合,输出只存在于第一个集合中的元素。 + +#### API 说明 + + 使用形式如下: + +```typescript +setDifference([, ]) +``` + +#### 示例代码 + + 假设集合 `test` 存在以下数据: + +```typescript +{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] } +{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] } +{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] } +{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] } +{ "_id": 5, "A": [ 1, 2 ], "B": [ ] } +{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] } +{ "_id": 7, "A": [ ], "B": [ ] } +{ "_id": 8, "A": [ ], "B": [ 1 ] } +``` + +下面的代码使用 `setDifference`,找到只存在于 `B` 中的数字: + +```typescript +let res = await db.collection('test') + .aggregate() + .project({ + isBOnly: $.setDifference(['$B', '$A']) + }) + .end() +``` + +```typescript +{ "_id": 1, "isBOnly": [] } +{ "_id": 2, "isBOnly": [] } +{ "_id": 3, "isBOnly": [3] } +{ "_id": 4, "isBOnly": [3] } +{ "_id": 5, "isBOnly": [] } +{ "_id": 6, "isBOnly": [{}, []] } +{ "_id": 7, "isBOnly": [] } +{ "_id": 8, "isBOnly": [1] } +``` + +### setEquals + +输入两个集合,判断两个集合中包含的元素是否相同(不考虑顺序、去重)。 + +#### API 说明 + + 使用形式如下: + +```typescript +setEquals([, ]) +``` + +#### 示例代码 + + 假设集合 `test` 存在以下数据: + +```typescript +{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] } +{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] } +{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] } +{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] } +{ "_id": 5, "A": [ 1, 2 ], "B": [ ] } +{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] } +{ "_id": 7, "A": [ ], "B": [ ] } +{ "_id": 8, "A": [ ], "B": [ 1 ] } +``` + +下面的代码使用 `setEquals`,判断两个集合中包含的元素是否相同: + +```typescript +let res = await db.collection('test') + .aggregate() + .project({ + sameElements: $.setEquals(['$A', '$B']) + }) + .end() +``` + +```typescript +{ "_id": 1, "sameElements": true } +{ "_id": 2, "sameElements": true } +{ "_id": 3, "sameElements": false } +{ "_id": 4, "sameElements": false } +{ "_id": 5, "sameElements": false } +{ "_id": 6, "sameElements": false } +{ "_id": 7, "sameElements": true } +{ "_id": 8, "sameElements": false } +``` + +### setIntersection + +输入两个集合,输出两个集合的交集。 + +#### API 说明 + + 使用形式如下: + +```typescript +setIntersection([, ]) +``` + +#### 示例代码 + + 假设集合 `test` 存在以下数据: + +```typescript +{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] } +{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] } +{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] } +{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] } +{ "_id": 5, "A": [ 1, 2 ], "B": [ ] } +{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] } +{ "_id": 7, "A": [ ], "B": [ ] } +{ "_id": 8, "A": [ ], "B": [ 1 ] } +``` + +下面的代码使用 `setIntersection`,输出两个集合的交集: + +```typescript +let res = await db.collection('test') + .aggregate() + .project({ + commonToBoth: $.setIntersection(['$A', '$B']) + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": 1, "commonToBoth": [ 1, 2 ] } +{ "_id": 2, "commonToBoth": [ 1, 2 ] } +{ "_id": 3, "commonToBoth": [ 1, 2 ] } +{ "_id": 4, "commonToBoth": [ 1 ] } +{ "_id": 5, "commonToBoth": [ ] } +{ "_id": 6, "commonToBoth": [ ] } +{ "_id": 7, "commonToBoth": [ ] } +{ "_id": 8, "commonToBoth": [ ] } +``` + +### setIsSubset + +输入两个集合,判断第一个集合是否是第二个集合的子集。 + +#### API 说明 + + 使用形式如下: + +```typescript +setIsSubset([, ]) +``` + +#### 示例代码 + + 假设集合 `test` 存在以下数据: + +```typescript +{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] } +{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] } +{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] } +{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] } +{ "_id": 5, "A": [ 1, 2 ], "B": [ ] } +{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] } +{ "_id": 7, "A": [ ], "B": [ ] } +{ "_id": 8, "A": [ ], "B": [ 1 ] } +``` + +下面的代码使用 `setIsSubset`,判断第一个集合是否是第二个集合的子集: + +```typescript +let res = await db.collection('test') + .aggregate() + .project({ + AisSubsetOfB: $.setIsSubset(['$A', '$B']) + }) + .end() +``` + +```typescript +{ "_id": 1, "AisSubsetOfB": true } +{ "_id": 2, "AisSubsetOfB": true } +{ "_id": 3, "AisSubsetOfB": true } +{ "_id": 4, "AisSubsetOfB": false } +{ "_id": 5, "AisSubsetOfB": false } +{ "_id": 6, "AisSubsetOfB": false } +{ "_id": 7, "AisSubsetOfB": true } +{ "_id": 8, "AisSubsetOfB": true } +``` + +### setUnion + +输入两个集合,输出两个集合的并集。 + +#### API 说明 + + 使用形式如下: + +```typescript +setUnion([, ]) +``` + +#### 示例代码 + + 假设集合 `test` 存在以下数据: + +```typescript +{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] } +{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] } +{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] } +{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] } +{ "_id": 5, "A": [ 1, 2 ], "B": [ ] } +{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] } +{ "_id": 7, "A": [ ], "B": [ ] } +{ "_id": 8, "A": [ ], "B": [ 1 ] } +``` + +下面的代码使用 `setUnion`,输出两个集合的并集: + +```typescript +let res = await db.collection('test') + .aggregate() + .project({ + AB: $.setUnion(['$A', '$B']) + }) + .end() +``` + +输出如下: + +```typescript +{ "_id": 1, "AB": [ 1, 2 ] } +{ "_id": 2, "AB": [ 1, 2 ] } +{ "_id": 3, "AB": [ 1, 2, 3 ] } +{ "_id": 4, "AB": [ 1, 2, 3 ] } +{ "_id": 5, "AB": [ 1, 2 ] } +{ "_id": 6, "AB": [ 1, 2, {}, [] ] } +{ "_id": 7, "AB": [ ] } +{ "_id": 8, "AB": [ 1 ] } +``` + +## 字符串操作符 + +### concat + +连接字符串,返回拼接后的字符串。 + +#### API 说明 + + `concat` 的语法如下: + +```typescript +db.command.aggregate.concat([<表达式1>, <表达式2>, ...]) +``` + +表达式可以是形如 `$ + 指定字段`,也可以是普通字符串。只要能够被解析成字符串即可。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `concat` 可以拼接 `lastName` 和 `firstName` 字段,得到每位学生的名字全称: + +```typescript +const $ = db.command.aggregate +db + .collection('students') + .aggregate() + .project({ + _id: 0, + fullName: $.concat(['$firstName', ' ', '$lastName']) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "fullName": "Yuanxin Dong" } +{ "fullName": "Weijia Wang" } +{ "fullName": "Chengxi Li" } +``` + +### indexOfBytes + +在目标字符串中查找子字符串,并返回第一次出现的 `UTF-8` 的字节索引(从 0 开始)。如果不存在子字符串,返回 -1。 + +#### API 说明 + + `indexOfBytes` 的语法如下: + +```typescript +db.command.aggregate.indexOfBytes([<目标字符串表达式>, <子字符串表达式>, <开始位置表达式>, <结束位置表达式>]) +``` + +下面是 4 种表达式的详细描述: + +|表达式 |描述 | +|---- |---- | +|目标字符串表达式 |任何可以被解析为字符串的表达式 | +|子字符串表达式 |任何可以被解析为字符串的表达式 | +|开始位置表达式 |任何可以被解析为非负整数的表达式 | +|结束位置表达式 |任何可以被解析为非负整数的表达式 | + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `indexOfBytes` 查找字符 `"a"` 在字段 `firstName` 中的位置: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + aStrIndex: $.indexOfBytes(['$firstName', 'a']) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "aStrIndex": 2 } +{ "aStrIndex": 5 } +{ "aStrIndex": -1 } +``` + +### indexOfCP + +在目标字符串中查找子字符串,并返回第一次出现的 `UTF-8` 的 `code point` 索引(从 0 开始)。如果不存在子字符串,返回 -1。 + +#### API 说明 + + `code point` 是“码位”,又名“编码位置”。这里特指 `Unicode` 包中的码位,范围是从 0(16 进制)到 10FFFF(16 进制)。 + + `indexOfCP` 的语法如下: + +```typescript +db.command.aggregate.indexOfCP([<目标字符串表达式>, <子字符串表达式>, <开始位置表达式>, <结束位置表达式>]) +``` + +下面是 4 种表达式的详细描述: + +|表达式 |描述 | +|---- |---- | +|目标字符串表达式 |任何可以被解析为字符串的表达式 | +|子字符串表达式 |任何可以被解析为字符串的表达式 | +|开始位置表达式 |任何可以被解析为非负整数的表达式 | +|结束位置表达式 |任何可以被解析为非负整数的表达式 | + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `indexOfCP` 查找字符 `"a"` 在字段 `firstName` 中的位置: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + aStrIndex: $.indexOfCP(['$firstName', 'a']) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "aStrIndex": 2 } +{ "aStrIndex": 5 } +{ "aStrIndex": -1 } +``` + +### split + +按照分隔符分隔数组,并且删除分隔符,返回子字符串组成的数组。如果字符串无法找到分隔符进行分隔,返回原字符串作为数组的唯一元素。 + +#### API 说明 + + `split` 的语法如下: + +```typescript +db.command.aggregate.split([<字符串表达式>, <分隔符表达式>]) +``` + +字符串表达式和分隔符表达式可以是任意形式的表达式,只要它可以被解析为字符串即可。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "birthday": "1999/12/12" } +{ "birthday": "1998/11/11" } +{ "birthday": "1997/10/10" } +``` + +通过 `split` 将每条记录中的 `birthday` 字段对应值分隔成数组,每个数组分别由代表年、月、日的 3 个元素组成: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + birthday: $.split(['$birthday', '/']) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "birthday": [ "1999", "12", "12" ] } +{ "birthday": [ "1998", "11", "11" ] } +{ "birthday": [ "1997", "10", "10" ] } +``` + +### strLenBytes + +计算并返回指定字符串中 `utf-8` 编码的字节数量。 + +#### API 说明 + + `strLenBytes` 的语法如下: + +```typescript +db.command.aggregate.strLenBytes(<表达式>) +``` + +只要表达式可以被解析成字符串,那么它就是有效表达式。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "name": "dongyuanxin", "nickname": "心谭" } +``` + +借助 `strLenBytes` 计算 `name` 字段和 `nickname` 字段对应值的字节长度: + +```typescript +const $ = db.command.aggregate +db + .collection('students') + .aggregate() + .project({ + _id: 0, + nameLength: $.strLenBytes('$name'), + nicknameLength: $.strLenBytes('$nickname') + }) + .end() +``` + +返回结果如下: + +```typescript +{ "nameLength": 11, "nicknameLength": 6 } +``` + +### strLenCP + +计算并返回指定字符串的 UTF-8 [code points](http://www.unicode.org/glossary/#code_point) 数量。 + +#### API 说明 + + `strLenCP` 的语法如下: + +```typescript +db.command.aggregate.strLenCP(<表达式>) +``` + +只要表达式可以被解析成字符串,那么它就是有效表达式。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "name": "dongyuanxin", "nickname": "心谭" } +``` + +借助 `strLenCP` 计算 `name` 字段和 `nickname` 字段对应值的 UTF-8 [code points](http://www.unicode.org/glossary/#code_point)的数量: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + nameLength: $.strLenCP('$name'), + nicknameLength: $.strLenCP('$nickname') + }) + .end() +``` + +返回结果如下: + +```typescript +{ "nameLength": 11, "nicknameLength": 2 } +``` + +### strcasecmp + +对两个字符串在不区分大小写的情况下进行大小比较,并返回比较的结果。 + +#### API 说明 + + `strcasecmp` 的语法如下: + +```typescript +db.command.aggregate.strcasecmp([<表达式1>, <表达式2>]) +``` + +只要 `表达式1`和 `表达式2` 可以被解析成字符串,那么它们就是有效的。 + + 返回的比较结果有 1,0 和 -1 三种: + +- 1:`表达式1` 解析的字符串 > `表达式2` 解析的字符串 - 0:`表达式1` 解析的字符串 = `表达式2` 解析的字符串 - -1:`表达式1` 解析的字符串 < `表达式2` 解析的字符串 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `strcasecmp` 比较 `firstName` 字段值和 `lastName` 字段值的大小: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + result: $.strcasecmp(['$firstName', '$lastName']), + }) + .end() +``` + +返回结果如下: + +```typescript +{ "result": 1 } +{ "result": 1 } +{ "result": -1 } +``` + +### substr + +返回字符串从指定位置开始的指定长度的子字符串。它是 `db.command.aggregate.substrBytes` 的别名,更推荐使用后者。 + +#### API 说明 + + `substr` 的语法如下: + +```typescript +db.command.aggregate.substr([<表达式1>, <表达式2>, <表达式3>]) +``` + +`表达式1` 是任何可以解析为字符串的有效表达式,`表达式2` 和 `表达式3` 是任何可以解析为数字的有效表达式。 + + 如果 `表达式2` 是负数,返回的结果为 `""`。 + + 如果 `表达式3` 是负数,返回的结果为从 `表达式2` 指定的开始位置以及之后其余部分的子字符串。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "birthday": "1999/12/12", "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "birthday": "1998/11/11", "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "birthday": "1997/10/10", "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `substr` 可以提取 `birthday` 中的年、月、日信息,代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + year: $.substr(['$birthday', 0, 4]), + month: $.substr(['$birthday', 5, 2]), + day: $.substr(['$birthday', 8, -1]) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "day": "12", "month": "12", "year": "1999" } +{ "day": "11", "month": "11", "year": "1998" } +{ "day": "10", "month": "10", "year": "1997" } +``` + +### substrBytes + +返回字符串从指定位置开始的指定长度的子字符串。子字符串是由字符串中指定的 `UTF-8` 字节索引的字符开始,长度为指定的字节数。 + +#### API 说明 + + `substrBytes` 的语法如下: + +```typescript +db.command.aggregate.substrBytes([<表达式1>, <表达式2>, <表达式3>]) +``` + +`表达式1` 是任何可以解析为字符串的有效表达式,`表达式2` 和 `表达式3` 是任何可以解析为数字的有效表达式。 + + 如果 `表达式2` 是负数,返回的结果为 `""`。 + + 如果 `表达式3` 是负数,返回的结果为从 `表达式2` 指定的开始位置以及之后其余部分的子字符串。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "birthday": "1999/12/12", "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "birthday": "1998/11/11", "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "birthday": "1997/10/10", "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `substrBytes` 可以提取 `birthday` 中的年、月、日信息,代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + year: $.substrBytes(['$birthday', 0, 4]), + month: $.substrBytes(['$birthday', 5, 2]), + day: $.substrBytes(['$birthday', 8, -1]) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "day": "12", "month": "12", "year": "1999" } +{ "day": "11", "month": "11", "year": "1998" } +{ "day": "10", "month": "10", "year": "1997" } +``` + +### substrCP + +返回字符串从指定位置开始的指定长度的子字符串。子字符串是由字符串中指定的 `UTF-8` 字节索引的字符开始,长度为指定的字节数。 + +#### API 说明 + + `substrCP` 的语法如下: + +```typescript +db.command.aggregate.substrCP([<表达式1>, <表达式2>, <表达式3>]) +``` + +`表达式1` 是任何可以解析为字符串的有效表达式,`表达式2` 和 `表达式3` 是任何可以解析为数字的有效表达式。 + + 如果 `表达式2` 是负数,返回的结果为 `""`。 + + 如果 `表达式3` 是负数,返回的结果为从 `表达式2` 指定的开始位置以及之后其余部分的子字符串。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "name": "dongyuanxin", "nickname": "心谭" } +``` + +借助 `substrCP` 可以提取 `nickname` 字段值的第一个汉字: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + firstCh: $.substrCP(['$nickname', 0, 1]) + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "firstCh": "心" } +``` + +### toLower + +将字符串转化为小写并返回。 + +#### API 说明 + + `toLower` 的语法如下: + +```typescript +db.command.aggregate.toLower(表达式) +``` + +只要表达式可以被解析成字符串,那么它就是有效表达式。例如:`$ + 指定字段`。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `toLower` 将 `firstName` 的字段值转化为小写: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + result: $.toLower('$firstName'), + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "result": "yuanxin" } +{ "result": "weijia" } +{ "result": "chengxi" } +``` + +### toUpper + +将字符串转化为大写并返回。 + +#### API 说明 + + `toUpper` 的语法如下: + +```typescript +db.command.aggregate.toUpper(表达式) +``` + +只要表达式可以被解析成字符串,那么它就是有效表达式。例如:`$ + 指定字段`。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 } +{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 } +{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 } +``` + +借助 `toUpper` 将 `lastName` 的字段值转化为大写: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .project({ + _id: 0, + result: $.toUpper('$lastName'), + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "result": "DONG" } +{ "result": "WANG" } +{ "result": "LI" } +``` + +## 分组运算方法 + +### addToSet + +聚合运算符。向数组中添加值,如果数组中已存在该值,不执行任何操作。它只能在 `group stage` 中使用。 + +#### API 说明 + +`addToSet` 语法如下: + +```typescript +db.command.aggregate.addToSet(<表达式>) +``` + +表达式是形如 `$ + 指定字段` 的字符串。如果指定字段的值是数组,那么整个数组会被当作一个元素。 + +#### 示例代码 + +假设集合 `passages` 的记录如下: + +```typescript +{ "category": "web", "tags": [ "JavaScript", "CSS" ], "title": "title1" } +{ "category": "System", "tags": [ "C++", "C" ], "title": "title2" } +``` + +**非数组字段** + + 每条记录的 `category` 对应值的类型是非数组,利用 `addToSet` 统计所有分类: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('passages') + .aggregate() + .group({ + _id: null, + categories: $.addToSet('$category') + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "_id": null, "categories": [ "System", "web" ] } +``` + +**数组字段** + + 每条记录的 `tags` 对应值的类型是数组,数组不会被自动展开: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('passages') + .aggregate() + .group({ + _id: null, + tagsList: $.addToSet('$tags') + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "_id": null, "tagsList": [ [ "C++", "C" ], [ "JavaScript", "CSS" ] ] } +``` + +### avg + + + +返回一组集合中,指定字段对应数据的平均值。 + +#### API 说明 + + `avg` 的语法如下: + +```typescript +db.command.aggregate.avg() +``` + +`avg` 传入的值除了数字常量外,也可以是任何最终解析成一个数字的表达式。它会忽略非数字值。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "group": "a", "name": "stu1", "score": 84 } +{ "group": "a", "name": "stu2", "score": 96 } +{ "group": "b", "name": "stu3", "score": 80 } +{ "group": "b", "name": "stu4", "score": 100 } +``` + +借助 `avg` 可以计算所有记录的 `score` 的平均值: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .group({ + _id: null, + average: $.avg('$score') + }) + .end() +``` + +返回的结果如下: + +```typescript +{ "_id": null, "average": 90 } +``` + +### first + +返回指定字段在一组集合的第一条记录对应的值。仅当这组集合是按照某种定义排序( `sort` )后,此操作才有意义。 + +#### API 说明 + + `first` 的语法如下: + +```typescript +db.command.aggregate.first(<表达式>) +``` + +表达式是形如 `$ + 指定字段` 的字符串。 + + `first` 只能在 `group` 阶段被使用,并且需要配合 `sort` 才有意义。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "group": "a", "name": "stu1", "score": 84 } +{ "group": "a", "name": "stu2", "score": 96 } +{ "group": "b", "name": "stu3", "score": 80 } +{ "group": "b", "name": "stu4", "score": 100 } +``` + +如果需要得到所有记录中 `score` 的最小值,可以先将所有记录按照 `score` 排序,然后取出第一条记录的 `first`。 + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .sort({ + score: 1 + }) + .group({ + _id: null, + min: $.first('$score') + }) + .end() +``` + +返回的数据结果如下: + +```typescript +{ "_id": null, "min": 80 } +``` + +### last + +返回指定字段在一组集合的最后一条记录对应的值。仅当这组集合是按照某种定义排序( `sort` )后,此操作才有意义。 + +#### API 说明 + + `last` 的语法如下: + +```typescript +db.command.aggregate.last(<表达式>) +``` + +表达式是形如 `$ + 指定字段` 的字符串。 + + `last` 只能在 `group` 阶段被使用,并且需要配合 `sort` 才有意义。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "group": "a", "name": "stu1", "score": 84 } +{ "group": "a", "name": "stu2", "score": 96 } +{ "group": "b", "name": "stu3", "score": 80 } +{ "group": "b", "name": "stu4", "score": 100 } +``` + +如果需要得到所有记录中 `score` 的最大值,可以先将所有记录按照 `score` 排序,然后取出最后一条记录的 `last`。 + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .sort({ + score: 1 + }) + .group({ + _id: null, + max: $.last('$score') + }) + .end() +``` + +返回的数据结果如下: + +```typescript +{ "_id": null, "max": 100 } +``` + +### max + +返回一组数值的最大值。 + +#### API 说明 + + `max` 的语法如下: + +```typescript +db.command.aggregate.max(<表达式>) +``` + +表达式是形如 `$ + 指定字段` 的字符串。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "group": "a", "name": "stu1", "score": 84 } +{ "group": "a", "name": "stu2", "score": 96 } +{ "group": "b", "name": "stu3", "score": 80 } +{ "group": "b", "name": "stu4", "score": 100 } +``` + +借助 `max` 可以统计不同组( `group` )中成绩的最高值,代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .group({ + _id: '$group', + maxScore: $.max('$score') + }) + .end() +``` + +返回的数据结果如下: + +```typescript +{ "_id": "b", "maxScore": 100 } +{ "_id": "a", "maxScore": 96 } +... +``` + +### min + +返回一组数值的最小值。 + +#### API 说明 + + `min` 的语法如下: + +```typescript +db.command.aggregate.min(<表达式>) +``` + +表达式是形如 `$ + 指定字段` 的字符串。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "group": "a", "name": "stu1", "score": 84 } +{ "group": "a", "name": "stu2", "score": 96 } +{ "group": "b", "name": "stu3", "score": 80 } +{ "group": "b", "name": "stu4", "score": 100 } +``` + +借助 `min` 可以统计不同组( `group` )中成绩的最低值,代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .group({ + _id: '$group', + minScore: $.min('$score') + }) + .end() +``` + +返回的数据结果如下: + +```typescript +{ "_id": "b", "minScore": 80 } +{ "_id": "a", "minScore": 84 } +``` + +### push + +在 `group` 阶段,返回一组中表达式指定列与对应的值,一起组成的数组。 + +#### API 说明 + + `push` 语法如下: + +```typescript +db.command.aggregate.push({ + <字段名1>: <指定字段1>, + <字段名2>: <指定字段2>, + ... +}) +``` + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "group": "a", "name": "stu1", "score": 84 } +{ "group": "a", "name": "stu2", "score": 96 } +{ "group": "b", "name": "stu3", "score": 80 } +{ "group": "b", "name": "stu4", "score": 100 } +``` + +借助 `push` 操作,对不同分组 ( `group` ) 的所有记录,聚合所有数据并且将其放入一个新的字段中,进一步结构化和语义化数据。 + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('students') + .aggregate() + .group({ + _id: '$group', + students: $.push({ + name: '$name', + score: '$score' + }) + }) + .end() +``` + +输出结果如下: + +```typescript +{ "_id": "b", "students": [{ "name": "stu3", "score": 80 }, { "name": "stu4", "score": 100 }] } +{ "_id": "a", "students": [{ "name": "stu1", "score": 84 }, { "name": "stu2", "score": 96 }] } +``` + +### stdDevPop + +返回一组字段对应值的标准差。 + +#### API 说明 + + `stdDevPop` 的使用形式如下: + +```typescript +db.command.aggregate.stdDevPop(<表达式>) +``` + +表达式传入的是指定字段,指定字段对应的值的数据类型必须是 `number` ,否则结果会返回 `null`。 + +#### 示例代码 + + 假设集合 `students` 的记录如下:`a` 组同学的成绩分别是 84 和 96,`b`组同学的成绩分别是 80 和 100。 + +```typescript +{ "group":"a", "score":84 } +{ "group":"a", "score":96 } +{ "group":"b", "score":80 } +{ "group":"b", "score":100 } +``` + +可以用 `stdDevPop` 来分别计算 `a` 和 `b` 两组同学成绩的标准差,以此来比较哪一组同学的成绩更稳定。代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('students').aggregate() + .group({ + _id: '$group', + stdDev: $.stdDevPop('$score') + }) + .end() +``` + +返回的数据结果如下: + +```typescript +{ "_id": "b", "stdDev": 10 } +{ "_id": "a", "stdDev": 6 } +``` + +### stdDevSamp + +计算输入值的样本标准偏差。如果输入值代表数据总体,或者不概括更多的数据,请改用 `db.command.aggregate.stdDevPop`。 + +#### API 说明 + + `stdDevSamp` 的使用形式如下: + +```typescript +db.command.aggregate.stdDevSamp(<表达式>) +``` + +表达式传入的是指定字段,`stdDevSamp` 会自动忽略非数字值。如果指定字段所有的值均是非数字,那么结果返回 `null`。 + +#### 示例代码 + + 假设集合 `students` 的记录如下: + +```typescript +{ "score": 80 } +{ "score": 100 } +``` + +可以用 `stdDevSamp` 来计算成绩的标准样本偏差。代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db.collection('students').aggregate() + .group({ + _id: null, + ageStdDev: $.stdDevSamp('$score') + }) + .end() +``` + +返回的数据结果如下: + +```typescript +{ "_id": null, "ageStdDev": 14.142135623730951 } +``` + +如果向集合 `students` 添加一条新记录,它的 `score` 字段类型是 `string`: + +```typescript +{ "score": "aa" } +``` + +用上面代码计算标准样本偏差时,`stdDevSamp` 会自动忽略类型不为 `number` 的记录,返回结果保持不变。 + +### sum + + + +计算并且返回一组字段所有数值的总和。 + +#### API 说明 + + `sum` 的使用形式如下: + +```typescript +db.command.aggregate.sum(<表达式>) +``` + +表达式可以传入指定字段,也可以传入指定字段组成的列表。`sum` 会自动忽略非数字值。如果字段下的所有值均是非数字,那么结果返回 0。若传入数字常量,则当做所有记录该字段的值都给给定常量,在聚合时相加,最终值为输入记录数乘以常量。 + +#### 示例代码 + + 假设代表商品的集合 `goods` 的记录如下:`price` 代表商品销售额,`cost` 代表商品成本 + +```typescript +{ "cost": -10, "price": 100 } +{ "cost": -15, "price": 1 } +{ "cost": -10, "price": 10 } +``` + +**单独字段** + + 借助 `sum` 可以计算所有商品的销售总和,代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('goods') + .aggregate() + .group({ + _id: null, + totalPrice: $.sum('$price') + }) + .end() +``` + +返回的数据结果如下:销售额是 111 + +```typescript +{ "_id": null, "totalPrice": 111 } +``` + +**字段列表** + + 如果需要计算所有商品的利润总额,那么需要将每条记录的 `cost` 和 `price` 相加得到此记录对应商品的利润。最后再计算所有商品的利润总额。 + + 借助 `sum`,代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('goods') + .aggregate() + .group({ + _id: null, + totalProfit: $.sum( + $.sum(['$price', '$cost']) + ) + }) + .end() +``` + +返回的数据结果如下:利润总额为 76 + +```typescript +{ "_id": null, "totalProfit": 76 } +``` + +## 变量操作符 + +### let + +自定义变量,并且在指定表达式中使用,返回的结果是表达式的结果。 + +#### API 说明 + + `let` 的语法如下: + +```typescript +db.command.aggregate.let({ + vars: { + <变量1>: <变量表达式>, + <变量2>: <变量表达式>, + ... + }, + in: <结果表达式> +}) +``` + +`vars` 中可以定义多个变量,变量的值由 `变量表达式` 计算而来,并且被定义的变量只有在 `in` 中的 `结果表达式` 才可以访问。 + + 在 `in` 的结果表达式中访问自定义变量时候,请在变量名前加上双美元符号 ( `$$` ) 并用引号括起来。 + +#### 示例代码 + + 假设代表商品的集合 `goods` 的记录如下:`price` 代表商品价格,`discount` 代表商品折扣率,`cost` 代表商品成本 + +```typescript +{ "cost": -10, "discount": 0.95, "price": 100 } +{ "cost": -15, "discount": 0.98, "price": 1 } +{ "cost": -10, "discount": 1, "price": 10 } +``` + +借助 `let` 可以定义并计算每件商品实际的销售价格,并将其赋值给自定义变量 `priceTotal`。最后再将 `priceTotal` 与 `cost` 进行取和 ( `sum` ) 运算,得到每件商品的利润。 + + 代码如下: + +```typescript +const $ = db.command.aggregate +let res = await db + .collection('goods') + .aggregate() + .project({ + profit: $.let({ + vars: { + priceTotal: $.multiply(['$price', '$discount']) + }, + in: $.sum(['$$priceTotal', '$cost']) + }) + }) + .end() +``` + +返回的数据结果如下: + +``` +{ "profit": 85 } +{ "profit": -14.02 } +{ "profit": 0 } +``` diff --git a/docs/guide/db/policy.md b/docs/guide/db/policy.md index cf4ab5bb27..86a1a48f59 100644 --- a/docs/guide/db/policy.md +++ b/docs/guide/db/policy.md @@ -4,8 +4,6 @@ title: 访问策略 # {{ $frontmatter.title }} -## 数据访问策略 - 前端可使用 [laf-client-sdk](https://github.com/labring/laf/tree/main/packages/client-sdk) “直连”数据库,无需与服务端对接口。 访问策略用来对客户端对数据库的操作进行安全控制,一个访问策略由多个集合的访问规则组成,每个集合可配置读写操作权限的访问规则。 @@ -17,34 +15,105 @@ title: 访问策略 - `app` 用于用户端客户端的访问策略,一般可以是 App、小程序、H5 等 - `admin` 用于应用的后台管理的访问策略 -## 操作权限 +## 创建策略 -当前支持以下五种数据库操作: +首先我们切换到集合页面,按照下面步骤为 user 集合添加一个访问策略。 -- `read` 读操作 -- `update` 更新操作 -- `add` 新增操作 -- `remove` 删除操作 -- `count` 统计集合总数量操作 -- `aggregate` 聚合操作 +:::tip +如果你还没有 user 集合就先创建一个。 +::: -以下为 `products` (商品集合)的访问策略示例,开放客户端读的权限,在客户端可以直接查询该集合的数据: +![creat-polocy](../../doc-images/creat-polocy.png) -`read: true` 代表所有基于此策略对 `products` 表的读操作都将放行,该集合未配置 `update` `add` `remove` 操作权限,代表该策略不允许对 `products` 的更新、添加和删除操作。 +![add-polocy](../../doc-images/add-polocy.png) -```json +做完这两步之后,我们就成功的创建了一个访问策略,并且把策略放在了 user 集合上。 +这里我们解释一下规则内容: + +```js { - "products": { - "read": true - } + "read": true, // 查询权限 + "count": true, // 计数权限 + "update": false, // 修改权限 + "remove": false, // 删除权限 + "add": false // 新增权限 +} +``` + +我们把值设为 true 则代表允许,false 则为不允许,按照我们刚刚默认的规则,前端可以直接对我们的集合进行`查询`和`计数`操作,而增 删 改,是不允许的。 +这里还有另外一个值得留意的地方,就是"入口地址" 刚刚我们设置的策略名称为 app,那么入口地址就是 /proxy/app,接下来演示一下如何使用。 + +## 前端“直连” + +在演示之前我们先往 user 集合中加一点数据。 + +![polocy-db-data](../../doc-images/polocy-db-data.png) + +我们来到前端项目,这里使用 Vue 项目来演示,其他项目同理。 + +### 首先安装 SDK + +```bash +npm i laf-client-sdk +``` + +### 然后创建 cloud 对像 + +这里注意了,我们多填写一个参数 dbProxyUrl,那么它的值就是我们刚刚强调的入口地址 `/proxy/app` + +```js +import { Cloud } from "laf-client-sdk"; + +const cloud = new Cloud({ + baseUrl: "https:/.laf.run", // 在首页应用列表获取 + getAccessToken: () => "", // 这里不需要授权,先填空 + dbProxyUrl: "/proxy/app", // 这里就填写我们刚刚强调的“入口地址” +}) +``` + +创建完 cloud 对像之后我们尝试一下在前端直接发起查询。 + +```js +async function get() { + const res = await cloud.database().collection("user").get(); + console.log(res); +// { +// "data": [ +// { +// "_id": "641d22292de2b789c963e5fd", +// "name": "jack" +// }, +// { +// "_id": "641e87d52c9ce609db4d6047", +// "name": "rose" +// } +// ], +// "ok": true +// } } ``` -以下为 `users` (用户集合)的访问策略示例: +现在我们来试试 count。 + +```js +async function get() { + const res = await cloud.database().collection("user").count(); + console.log(res); + // { + // "total": 2, + // "ok": true + // } +} +``` + +可以看到,简单的查询计数我们已经不需要写云函数,直接在前端即可实现,如果你想体验 `增删改` 可以修改对应策略的权限为 true,但这是一个很危险的行为。 + +访问策略也可以是表达式,以下为 `users` (用户集合)的访问策略示例: 其中`query` 是数据查询的条件对象,`uid === query._id` 表示该策略只允许当前用户读取自己的用户数据。 ```json - "users": { + "users" + { "read": "uid === query._id" } ``` @@ -58,10 +127,8 @@ title: 访问策略 ```json { - "products": { - "read": { - "condition": true - } + "read": { + "condition": true } } ``` @@ -74,7 +141,7 @@ title: 访问策略 - `data` 更新或新增数据操作时的数据对象 - `data` 数据验证器,接受一个对象,对「更新或新增数据操作时的数据对象」中的各字段进行验证,具体参考以下示例 - `query` 查询条件对象验证器,接受一个对象,对「查询条件对象」中的各字段进行验证,具体参考以下示例 -- `multi` 是否允许批量操作,接受一个表达式做为配置。 默认只有 `read` 操作允许批量操作,如需开启其它批量操作需要显式指定此验证器 +- `multi` 是否允许批量操作,接受一个表达式做为配置。默认只有 `read` 操作允许批量操作,如需开启其它批量操作需要显式指定此验证器 ## 实践建议 @@ -83,7 +150,7 @@ title: 访问策略 - 最小权限原则,即只给客户端必要的访问权限,只开放给客户端必要的集合; - 即便只开放 `read` 权限,也可能节省 30%~ 50% 的后端接口; - - 再配合一些基本的 `condition` 判断,可有效减少 70%~ 90% 的后接接口; + - 再配合一些基本的 `condition` 判断,可有效减少 70%~ 90% 的后端接口; - 事务性的数据操作、复杂的表单提交,建议使用云函数实现: @@ -99,104 +166,99 @@ title: 访问策略 ### 简单示例 1:简单个人博客 ```json +"categories" { - "categories": { - "read": true, - "update": "uid", - "add": "uid", - "remove": "uid" - }, - "articles": { - "read": true, - "update": "uid", - "add": "uid", - "remove": "uid" - } + "read": true, + "update": "uid", + "add": "uid", + "remove": "uid" +}, +"articles" +{ + "read": true, + "update": "uid", + "add": "uid", + "remove": "uid" } ``` -> 提示:其中类似 `"update": "uid"` 的规则,是 `uid` 不为假值的意思(undefined | null | false 等) +> 提示:其中类似 `"update": "uid"` 的规则,是 `uid` 不为假值的意思 (undefined | null | false 等) ### 简单示例 2:多用户博客 ```json + { - "articles": { - "read": true, - "update": "uid === query.author_id", - "add": "uid === query.author_id", - "remove": "uid === query.author_id" - } + "read": true, + "update": "uid === query.author_id", + "add": "uid === query.author_id", + "remove": "uid === query.author_id" } + ``` -### 复杂示例 1: 数据验证 +### 复杂示例 1:数据验证 ```json { - "articles": { - "read": true, - "add": { - "condition": "uid === query.author_id", - "data": { - "title": { "length": [1, 64], "required": true }, - "content": { "length": [1, 4096] }, - "status": { "boolean": [true, false] }, - "likes": { "number": [0], "default": 0 }, - "author_id": "$value == uid" - } - }, - "remove": "uid === query.author_id", - "count": true - } + "read": true, + "add": { + "condition": "uid === query.author_id", + "data": { + "title": { "length": [1, 64], "required": true }, + "content": { "length": [1, 4096] }, + "status": { "boolean": [true, false] }, + "likes": { "number": [0], "default": 0 }, + "author_id": "$value == uid" + } + }, + "remove": "uid === query.author_id", + "count": true } ``` ### 复杂示例 2:更高级的数据验证 -> 场景介绍: 用户之间站内消息表访问规则 +> 场景介绍:用户之间站内消息表访问规则 ```json { - "messages": { - "read": "uid === query.receiver || uid === query.sender", - "update": { - "condition": "$uid === query.receiver", - "data": { - "read": { "in": [true] } - } - }, - "add": { - "condition": "uid === data.sender", - "data": { - "read": { "in": [false] }, - "content": { "length": [1, 20480], "required": true }, - "receiver": { "exists": "/users/id" }, - "read": { "in": [true, false], "default": false } - } - }, - "remove": false - } + "read": "uid === query.receiver || uid === query.sender", + "update": { + "condition": "$uid === query.receiver", + "data": { + "read": { "in": [true] } + } + }, + "add": { + "condition": "uid === data.sender", + "data": { + "read": { "in": [false] }, + "content": { "length": [1, 20480], "required": true }, + "receiver": { "exists": "/users/id" }, + "read": { "in": [true, false], "default": false } + } + }, + "remove": false } ``` ### data 验证器示例 ```json + "categories" { - "categories": { - "read": true, - "update": "role === 'admin'", - "add": { - "condition": "role === 'admin'", - "data": { - "password": { "match": "^\\d{6,10}$" }, - "author_id": "$value == uid", - "type": { "required": true, "in": ["choice", "fill"] }, - "title": { "length": [4, 64], "required": true, "unique": true }, - "content": { "length": [4, 20480] }, - "total": { "number": [0, 100], "default": 0, "required": true } - } + "read": true, + "update": "role === 'admin'", + "add": { + "condition": "role === 'admin'", + "data": { + "password": { "match": "^\\d{6,10}$" }, + "author_id": "$value == uid", + "type": { "required": true, "in": ["choice", "fill"] }, + "title": { "length": [4, 64], "required": true, "unique": true }, + "content": { "length": [4, 20480] }, + "total": { "number": [0, 100], "default": 0, "required": true } } } } diff --git a/docs/guide/db/query.md b/docs/guide/db/query.md deleted file mode 100644 index e37394e77b..0000000000 --- a/docs/guide/db/query.md +++ /dev/null @@ -1,444 +0,0 @@ ---- -title: 云数据库查询 ---- - -# {{ $frontmatter.title }} - -## 获取集合的引用 - -```js -// 获取 `user` 集合的引用 -const collection = db.collection("user"); -``` - -支持 `where()`、`limit()`、`skip()`、`orderBy()`、`get()`、`update()`、`field()`、`count()` 等操作。 - -只有当调用`get()` `update()`时才会真正发送请求。 -注:默认取前 100 条数据,最大取前 100 条数据。 - -## 添加查询条件 - -collection.where() -参数 - -设置过滤条件 -where 可接收对象作为参数,表示筛选出拥有和传入对象相同的 key-value 的文档。比如筛选出所有类型为计算机的、内存为 8g 的商品: - -```js -db.collection("goods").where({ - category: "computer", - type: { - memory: 8, - }, -}); -``` - -如果要表达更复杂的查询,可使用高级查询指令,比如筛选出所有内存大于 8g 的计算机商品: - -```js -const _ = db.command; // 取指令 -db.collection("goods").where({ - category: "computer", - type: { - memory: _.gt(8), // 表示大于 8 - }, -}); -``` - -## 获取查询数量 - -collection.count() - -参数 - -```js -//promise -db.collection("goods") - .where({ - category: "computer", - type: { - memory: 8, - }, - }) - .count() - .then(function (res) {}); -``` - -响应参数 - -| 字段 | 类型 | 必填 | 说明 | -| --------- | ------- | ---- | ------------------------ | -| code | string | 否 | 状态码,操作成功则不返回 | -| message | string | 否 | 错误描述 | -| total | Integer | 否 | 计数结果 | -| requestId | string | 否 | 请求序列号,用于错误排查 | - -## 设置记录数量 - -collection.limit() - -参数说明 - -| 参数 | 类型 | 必填 | 说明 | -| ----- | ------- | ---- | -------------- | -| value | Integer | 是 | 限制展示的数值 | - -使用示例 - -```js -//promise -collection - .limit(1) - .get() - .then(function (res) {}); -``` - -## 设置起始位置 - -collection.skip() - -参数说明 - -| 参数 | 类型 | 必填 | 说明 | -| ----- | ------- | ---- | -------------- | -| value | Integer | 是 | 跳过展示的数据 | - -使用示例 - -```js -//promise -collection - .skip(4) - .get() - .then(function (res) {}); -``` - -## 对结果排序 - -collection.orderBy() - -参数说明 - -| 参数 | 类型 | 必填 | 说明 | -| --------- | ------ | ---- | ----------------------------------- | -| field | string | 是 | 排序的字段 | -| orderType | string | 是 | 排序的顺序,升序(asc) 或 降序(desc) | - -使用示例 - -```js -//promise -collection - .orderBy("name", "asc") - .get() - .then(function (res) {}); -``` - -## 指定返回字段 - -collection.field() - -参数说明 - -| 参数 | 类型 | 必填 | 说明 | -| ---- | ------ | ---- | ----------------------------------------- | -| - | object | 是 | 要过滤的字段,不返回传 0,返回传 1 | - -使用示例 - -```js -collection.field({ age: 1 }); -``` - -备注:只能指定要返回的字段或者不要返回的字段。即{'a': 1, 'b': 0}是一种错误的参数格式 - -## 查询指令 - -### eq - -表示字段等于某个值。`eq` 指令接受一个字面量 (literal),可以是 `number`, `boolean`, `string`, `object`, `array`。 - -比如筛选出所有自己发表的文章,除了用传对象的方式: - -```js -const myOpenID = "xxx"; -db.collection("articles").where({ - _openid: myOpenID, -}); -``` - -还可以用指令: - -```js -const _ = db.command; -const myOpenID = "xxx"; -db.collection("articles").where({ - _openid: _.eq(openid), -}); -``` - -注意 `eq` 指令比对象的方式有更大的灵活性,可以用于表示字段等于某个对象的情况,比如: - -```js -// 这种写法表示匹配 stat.publishYear == 2018 且 stat.language == 'zh-CN' -db.collection("articles").where({ - stat: { - publishYear: 2018, - language: "zh-CN", - }, -}); -// 这种写法表示 stat 对象等于 { publishYear: 2018, language: 'zh-CN' } -const _ = db.command; -db.collection("articles").where({ - stat: _.eq({ - publishYear: 2018, - language: "zh-CN", - }), -}); -``` - -### neq - -字段不等于。`neq` 指令接受一个字面量 (literal),可以是 `number`, `boolean`, `string`, `object`, `array`。 - -如筛选出品牌不为 X 的计算机: - -```js -const _ = db.command; -db.collection("goods").where({ - category: "computer", - type: { - brand: _.neq("X"), - }, -}); -``` - -### gt - -字段大于指定值。 - -如筛选出价格大于 2000 的计算机: - -```js -const _ = db.command; -db.collection("goods").where({ - category: "computer", - price: _.gt(2000), -}); -``` - -### gte - -字段大于或等于指定值。 - -### lt - -字段小于指定值。 - -### lte - -字段小于或等于指定值。 - -### in - -字段值在给定的数组中。 - -筛选出内存为 8g 或 16g 的计算机商品: - -```js -const _ = db.command; -db.collection("goods").where({ - category: "computer", - type: { - memory: _.in([8, 16]), - }, -}); -``` - -### nin - -字段值不在给定的数组中。 - -筛选出内存不是 8g 或 16g 的计算机商品: - -```js -const _ = db.command; -db.collection("goods").where({ - category: "computer", - type: { - memory: _.nin([8, 16]), - }, -}); -``` - -### and - -表示需同时满足指定的两个或以上的条件。 - -如筛选出内存大于 4g 小于 32g 的计算机商品: - -流式写法: - -```js -const _ = db.command; -db.collection("goods").where({ - category: "computer", - type: { - memory: _.gt(4).and(_.lt(32)), - }, -}); -``` - -前置写法: - -```js -const _ = db.command; -db.collection("goods").where({ - category: "computer", - type: { - memory: _.and(_.gt(4), _.lt(32)), - }, -}); -``` - -### or - -表示需满足所有指定条件中的至少一个。如筛选出价格小于 4000 或在 6000-8000 之间的计算机: - -流式写法: - -```js -const _ = db.command; -db.collection("goods").where({ - category: "computer", - type: { - price: _.lt(4000).or(_.gt(6000).and(_.lt(8000))), - }, -}); -``` - -前置写法: - -```js -const _ = db.command; -db.collection("goods").where({ - category: "computer", - type: { - price: _.or(_.lt(4000), _.and(_.gt(6000), _.lt(8000))), - }, -}); -``` - -如果要跨字段 “或” 操作:(如筛选出内存 8g 或 cpu 3.2 ghz 的计算机) - -```js -const _ = db.command; -db.collection("goods").where( - _.or( - { - type: { - memory: _.gt(8), - }, - }, - { - type: { - cpu: 3.2, - }, - } - ) -); -``` - -## 正则表达式查询 - -### db.RegExp - -根据正则表达式进行筛选 - -例如下面可以筛选出 `version` 字段开头是 "数字+s" 的记录,并且忽略大小写: - -```js -// 可以直接使用正则表达式 -db.collection('articles').where({ - version: /^\ds/i -}) - -// 或者 -db.collection('articles').where({ - version: new db.RegExp({ - regex: '^\\ds' // 正则表达式为 /^\ds/,转义后变成 '^\\ds' - options: 'i' // i表示忽略大小写 - }) -}) -``` - -## with 关联查询 - -with / withOne 联表查询,可以实现查询一个集合时,连同某个字段的相关联记录一同查出(可跨表),比如查询“班级”时连同班级内的“学生”一起查询出来,又比如查询“文章”时连同它的“作者”一并查出等等。 - -:::info -with / withOne 联表查询在 sdk 内部是先查询了主表后,再查询子表,然后在本地(云函数或客户端)完成拼接后再传回业务开发者;如果你还没有使用 with 联表查询,推荐使用聚合操作的 [lookup 联表查询](#lookup-联表查询)。 -::: - -### 一对多关系查询 - -主要用于「一对多」关系的子查询,可跨表查询,要求用户拥有子表的查询权限 - -```js -const { data } = await db - .collection("article") - .with({ - query: db.collection("tag"), - localField: "id", // 主表连接键,即 article.id - foreignField: "article_id", // 子表连接键,即 tag.article_id - as: "tags", // 查询结果中字段重命名,缺省为子表名 - }) - .get(); - -console.log(data); -// [ { id: 1, name: xxx, tags: [...] } ] -``` - -### 一对一关系查询 - -> 类似 sql left join 查询 - -```js -const { data } = await db - .collection("article") - .withOne({ - query: db.collection("user"), - localField: "author_id", // 主表连接键,即 article.id - foreignField: "id", // 子表连接键,即 tag.article_id - as: "author", // 查询结果中字段重命名,缺省为子表名 - }) - .get(); - -console.log(data); -// [ { id: 1, name: xxx, author: {...} } ] -``` - -## lookup 关联查询 - -:::info -lookup 联表查询并非 `collection` 下的方法! - -事实上其为聚合 `aggregate` 下的方法,然而前文提到了 `with 联表查询` 用途与此一致,故在此先做说明,以避免开发者以为 lookup 不得使用,导致额外适配成 with 联表查询的成本。 -::: - -用途与 `with 联表查询` 基本一致,同 with 联表查询的示例: 查询 article 集合时,把各记录的 tag 标签一同查出。 - -```js -const { data } = await db - .collection("article") - .aggregate() - .lookup({ - from: "tag", - localField: "id", // 主表连接键,即 article.id - foreignField: "article_id", // 子表连接键,即 tag.article_id - as: "tags", // 查询结果中字段重命名,缺省为子表名 - }) - .end(); - -console.log(data); -``` diff --git a/docs/guide/db/quickstart.md b/docs/guide/db/quickstart.md new file mode 100644 index 0000000000..b2bd2278db --- /dev/null +++ b/docs/guide/db/quickstart.md @@ -0,0 +1,146 @@ +--- +title: 数据库入门 +--- + +# {{ $frontmatter.title }} + +Laf 为每个应用提供了一个开箱即用的数据库,并且非常易用。下面是一个简单的数据库的增删改查的例子,来快速的了解 Laf 的数据库操作。 + +## 新建数据库实例 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() +// db 为新建的数据库实例 +``` + +## 云函数插入文档 + +使用 `add` 方法可以往集合插入数据 + +如下例子:往 `user` 集合中添加一个文档,`name` 为 `Jack` 的数据 + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + const res = await db.collection('user').add({ + name: 'Jack' + }) + console.log(res) +} +``` + +```json +// 集合 test 中会新增数据,_id 为自动生成 +{ + "_id": "6442b2cac4f3afd9a186ecd9", + "name": "Jack" +} +``` + +## 云函数查询文档 + +使用 `get` 方法可以查询集合中的文档 + +::: tip +`get` 方法一次最多能获取 100 条记录,如需一次查询更多请看数据查询文档 +::: + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + const res = await db.collection('user').get() + console.log(res) + // 查询结果 + // { + // data: [ { _id: '6442b2cac4f3afd9a186ecd9', name: 'Jack' } ], + // requestId: undefined, + // ok: true + // } +} +``` + +使用 `getOne` 方法查询集合中的文档 + +::: tip +`getOne` 方法一次获取一条最新数据 +::: + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + const res = await db.collection('user').getOne() + console.log(res) + // 查询结果 + // { + // ok: true, + // data: { _id: '6442b2cac4f3afd9a186ecd9', name: 'Jack' }, + // requestId: undefined + // } +} +``` + +## 云函数修改文档 + +查出 `name` 为 `Jack` 的文档的_id,然后根据_id 修改文档 + +使用 `update` 方法修改文档 + +::: tip +`where` 可设置查询条件,`doc` 根据 id 查询 +::: + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + const res = await db.collection('test').where({ + name:'Jack' + }).get() + // console.log(res) + const id = res.data[0]._id + const updateRes = await db.collection('test').doc(id).update({ + name:'Tom' + }) + console.log(updateRes) + // 修改结果:updated:1 代表已成功修改 1 个文档 + // { + // requestId: undefined, + // updated: 1, + // matched: 1, + // upsertId: null, + // ok: true + // } +} +``` + +## 云函数删除文档 + +先查出 `name` 为 `Tom` 的文档并删除 + +::: tip +`remove` 默认只能删除单条数据,如需批量删除,请查看数据删除文档 +::: + +```typescript +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export async function main(ctx: FunctionContext) { + const res = await db.collection('test').where({ name: "Tom" }).remove() + console.log(res) + // 删除结果:deleted:1 代表已成功删除 1 个文档 + // { requestId: undefined, deleted: 1, ok: true } +} +``` + +-------- + +相信一步一步跟着文档操作,已经初步的了解数据库的增删改查,但是如果需要深入使用数据库操作,还需要仔细查看后续的文档 diff --git a/docs/guide/db/update.md b/docs/guide/db/update.md new file mode 100644 index 0000000000..810d94a472 --- /dev/null +++ b/docs/guide/db/update.md @@ -0,0 +1,129 @@ +--- +title: 更新数据 +--- + +# {{ $frontmatter.title }} + +Laf 云数据库更新数据,实际上就是针对集合中的文档进行修改,通过 `where` 等操作符设置查询条件,然后通过 `update` 或 `set` 等更新操作符进行修改。 + +## 更新文档 + +### 更新指定文档 + +我们这里把 jack 的名字改为 Tom。 + +```typescript +await db.collection('user') +.where({ name: 'jack' }) +.update({ name: "Tom" }) +``` + +同样我们也可以一次更新同一个文档的多个属性,比如:更改名字的同时也更改年龄。 + +```typescript +await db.collection('user') +.where({ name: 'jack' }) +.update({ name: "Tom", age: "18" }) +``` + +### 批量更新文档 + +这里我们没有加条件限制,直接把 `user` 表中的所有 `name` 都改成了 `Tom` ,操作和之前一样只需要多传入一个对像 `{multi:true}` 即可。 + +```typescript +await db.collection('user') +.update({ name: "Tom" },{ multi:true }) +``` + +## 更新指令 + +### set + +更新指令。如果数据不存在,则会新增一个文档。 + +::: warning +注意:使用 `set` 需要使用 `doc` 去根据 ID 查询文档,然后进行更新,如果查询不到文档,则会新增一个文档, +`doc` [使用文档](/guide/db/find.html#根据id查询数据) +::: + +```typescript +await collection.doc('644148fd1eeb2b524dba499e').set({ + name: "Hey" +}) +``` + +### inc + +更新指令。用于指示字段自增某个值,需要是正整数或者负整数。这是个原子操作,使用这个操作指令而不是先读数据、再加、再写回的好处是: + +1. 原子性:多个用户同时写,对数据库来说都是将字段加一,不会有后来者覆写前者的情况 +2. 减少一次网络请求:不需先读再写 + +之后的 mul 指令同理。 + +如给收藏的商品数量加一: + +```typescript +const _ = db.command; +await db.collection("user") + .where({ + _openid: "my-open-id", + }) + .update({ + count: { + favorites: _.inc(1), + }, + }) +``` + +### mul + +更新指令。用于指示字段自乘某个值。需要是正整数或者负整数或者 0。 + +### remove + +更新指令。用于表示删除某个字段。如某人删除了自己一条商品评价中的评分: + +```typescript +const _ = db.command; +await db.collection("comments") + .doc("comment-id") + .update({ + rating: _.remove(), + }) +``` + +### push + +向数组尾部追加元素,支持传入单个元素或数组 + +```typescript +const _ = db.command; +await db.collection("comments") + .doc("comment-id") + .update({ + // users: _.push('aaa') + users: _.push(["aaa", "bbb"]), + }) +``` + +### pop + +删除数组尾部元素 + +```typescript +const _ = db.command; +await db.collection("comments") + .doc("comment-id") + .update({ + users: _.pop(), + }) +``` + +### unshift + +向数组头部添加元素,支持传入单个元素或数组。使用同 push + +### shift + +删除数组头部元素。使用同 pop diff --git a/docs/guide/faq/index.md b/docs/guide/faq/index.md deleted file mode 100644 index 60e02e6e64..0000000000 --- a/docs/guide/faq/index.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: 问答 ---- - -# {{ $frontmatter.title }} - -## 1.小程序-微信云迁移laf云 - -[微信云迁移laf云](https://docs.qq.com/doc/DSEV1SHZ5c0ZCRnJa) - -## 2.私有化部署如何关闭注册? - -`ACCOUNT_SIGNUP_MODE` 设置为 `1` 即可。[参考](https://github.com/labring/laf/pull/181/files#diff-e45e45baeda1c1e73482975a664062aa56f20c03dd9d64a827aba57775bed0d3R51) \ No newline at end of file diff --git a/docs/guide/function/call-function-in-client.md b/docs/guide/function/call-function-in-client.md index cc0ab0cdae..b4641cf96b 100644 --- a/docs/guide/function/call-function-in-client.md +++ b/docs/guide/function/call-function-in-client.md @@ -4,24 +4,25 @@ title: 在客户端中调用 # {{ $frontmatter.title }} -云函数编写完成并发布后,客户端可通过 `sdk` 的方式进行调用。 +云函数编写完成并发布后,客户端可通过 `laf-client-sdk` 进行调用。 ::: info 目前 SDK 暂时只支持发送 POST 请求 ::: -## 安装sdk +## 前端项目中安装 sdk ```shell npm i laf-client-sdk ``` -## 初始化 `cloud` 对象: +## 初始化 `cloud` 对象 + ```typescript import { Cloud } from "laf-client-sdk"; const cloud = new Cloud({ - baseUrl: "APP_ID.laf.run", // App id 可在首页应用列表中获取 + baseUrl: "https://APPID.laf.run", // APPID 在首页应用列表获取 getAccessToken: () => "", // 这里不需要授权,先填空 }) ``` @@ -29,11 +30,14 @@ const cloud = new Cloud({ ## 调用云函数 ```typescript +// 这里的第一个参数就是云函数的名字,第二个参数是传入的数据,对应云函数中的 ctx.body const res = await cloud.invoke('get-user-info', { userid }) -console.log(res) // user data find by id +console.log(res) // 这里的 res 是云函数中 return 的内容 ``` -怎么样,是不是很方便, 只需简单的配置和一行代码即可实现对云函数的调用。 +怎么样,是不是很方便,只需简单的配置和一行代码即可实现对云函数的调用。 +## laf-client-sdk 详细文档 +查看详细文档:[client-sdk](/guide/client-sdk/) diff --git a/docs/guide/function/call-function-in-http.md b/docs/guide/function/call-function-in-http.md new file mode 100644 index 0000000000..23a2d81191 --- /dev/null +++ b/docs/guide/function/call-function-in-http.md @@ -0,0 +1,56 @@ +# HTTP 调用 + +云函数每个云函数都提供了 API 地址,理论上我们可以在任何能发起 http 请求的地方调用云函数。 + +![function-url](../../doc-images/function-url.png) + +## `axios` 调用 + +下面是用前端使用 `axios` 请求云函数的简单示例。 + +```typescript +// get 请求 +import axios from 'axios'; + +const { data } = await axios({ + url: "", + method: "get", +}); + +console.log(data); +``` + +```typescript +// post 请求 +import axios from 'axios'; + +const { data } = await axios({ + url: "", + method: "post", + data: { + name: 'Jack' + } +}); + +console.log(data); +``` + +## `curl` 调用 + +当然也可以使用 `curl` 去调用云函数 + +GET 请求 + +```shell +curl ?query=hello&limit=10 \ + -H "Authorization: Bearer abc123" \ + -H "Content-Type: application/json" +``` + +POST 请求 + +```shell +curl -X POST \ + -H "Content-Type: application/json" \ + -d '{"name": "John", "age": 30}' +``` diff --git a/docs/guide/function/call-function.md b/docs/guide/function/call-function.md index 55d285452d..ba004619cd 100644 --- a/docs/guide/function/call-function.md +++ b/docs/guide/function/call-function.md @@ -6,10 +6,13 @@ title: 在云函数中调用 云函数在开发完毕并发布后,可以在其他云函数中进行调用。 +::: info +`cloud.invoke`方法已不推荐使用,可使用[引入云函数](/guide/function/use-function.html#云函数引入) +::: ## 编写并发布待调用云函数 -比如,我们创建一个名为 `get-user-info` 的云函数,并编写如下代码: +比如,我们创建一个名为 `get-user-info` 的云函数,并编写如下代码: ```typescript import cloud from '@lafjs/cloud' @@ -22,32 +25,25 @@ export async function main(ctx: FunctionContext) { if (!userid) return { err: 1, errmsg: 'userid not exists' } const userCollection = db.collection('user') - const { data: user } = await userCollection.where({ id: userid }).get() if (!user) return { err: 2, errmsg: 'user not found' } - return { err: 0, data: user } } ``` -该函数接收一个名为 userid 的参数, 并通过id在数据库中查找相应用户,并将 查找到的数据返回。 - +该函数接收一个名为 userid 的参数,并通过 id 在数据库中查找相应用户,并将 查找到的数据返回。 ## 调用已发布云函数 -`get-user-info` 云函数发布后, 我们可以在其他云函数调用该函数。 +`get-user-info` 云函数发布后,我们可以在其他云函数调用该函数。 ```typescript import cloud from '@lafjs/cloud' export async function main(ctx: FunctionContext) { - - const res = await cloud.invoke('get-user-info', { ...ctx, body: { userid: 'user id' }}) - console.log(res) - } ``` @@ -55,4 +51,4 @@ export async function main(ctx: FunctionContext) { 该方法接收两个参数:第一个参数为 待调用的函数名,第二个参数为传递的数据 -可以看到,`body` 传入了我们请求参数,如果函数内部需要使用ctx中的某些属性,还可用 `...ctx` 的方式传入ctx以便被调用函数使用。 \ No newline at end of file +可以看到,`body` 传入了我们请求参数,如果函数内部需要使用 ctx 中的某些属性,还可用 `...ctx` 的方式传入 ctx 以便被调用函数使用。 diff --git a/docs/guide/function/depend.md b/docs/guide/function/depend.md index 8004aca130..6a305f7e71 100644 --- a/docs/guide/function/depend.md +++ b/docs/guide/function/depend.md @@ -4,33 +4,35 @@ title: 依赖管理 # {{ $frontmatter.title }} -应用开发过程中,通常有添加 `npm` 依赖的需求,`laf` 提供了在线可视化管理这些第三方包模块的方法, 用户可非常方便的进行搜索、安装、升级和卸载。 +应用开发过程中,通常有添加 `npm` 依赖的需求,`laf` 提供了在线可视化管理这些第三方包模块的方法,用户可非常方便的进行搜索、安装、升级和卸载。 + +::: warning +Laf 云开发可安装来自 的依赖,如果所需依赖无法在该网站中找到,是无法安装的 +::: ## 添加依赖 -![](/doc-images/add-packages.png) +![add-packages](/doc-images/add-packages.png) -如上图所示,我们依次点击屏幕左下方的 `NPM 依赖`、 添加按钮, 搜索想要安装的包名(此处以 [moment](https://www.npmjs.com/package/moment) 为例),勾选后点击 `保存并重启` 按钮即可。 +如上图所示,我们依次点击屏幕左下方的 `NPM 依赖`、添加按钮,搜索想要安装的包名(此处以 [moment](https://www.npmjs.com/package/moment) 为例),勾选后点击 `保存并重启` 按钮即可。 > 安装的持续时间会根据包的大小和网络情况而不同,请耐心等待完成。 -![](/doc-images/package-list.png) - +![package-list](/doc-images/package-list.png) 安装完成后用户可在界面左下方 `依赖管理` 中查看已安装的依赖和版本。 -## 版本 +## 依赖版本选择 -![](/doc-images/select-package-version.png) +![select-package-version](/doc-images/select-package-version.png) 为保证用户应用稳定性,`Laf` 不会自动更新应用的 `Npm package` 版本。 添加依赖时,默认勾选为最新版`latest`,用户如需指定版本,可在安装时在版本下拉框中选择对应版本。 - ## 云函数使用 -安装完成后,即可在云函数中引入并使用。例如,创建一个云函数 `hello-moment`,并修改代码如下: +安装完成后,即可在云函数中引入并使用。例如,创建一个云函数 `hello-moment`,并修改代码如下: ```typescript import cloud from '@lafjs/cloud' @@ -45,7 +47,7 @@ export async function main(ctx: FunctionContext) { } ``` -点击界面右方运行按钮或按下 `Ctrl + S` 保存,可看到运行结果: +点击界面右方运行按钮或按下 `Ctrl + S` 保存,可看到运行结果: ```json { @@ -53,4 +55,12 @@ export async function main(ctx: FunctionContext) { "now": "2023-02-08 02:14:05", "twoHoursLater": "2023-02-08 04:14:05" } -``` \ No newline at end of file +``` + +## 切换已安装依赖版本 + +![change-package-version](/doc-images/change-package-version.png) + +## 卸载已安装依赖版本 + +![delete-package](/doc-images/delete-package.png) diff --git a/docs/guide/function/env.md b/docs/guide/function/env.md index c1007bc08d..ccbeef92ec 100644 --- a/docs/guide/function/env.md +++ b/docs/guide/function/env.md @@ -4,43 +4,27 @@ title: 在云函数中使用环境变量 # {{ $frontmatter.title }} - ## 添加环境变量 -1. 首先点击页面左下角的小齿轮按钮,打开应用设置页面 - -![](/doc-images/add-env-step1.png) - - -2. 其次在弹出的应用设置界面,点击 新增环境变量按钮,输入环境变量的 `key` 和 `value`, 并点击确定 +1. 首先点击页面左下角的小齿轮按钮,打开应用设置页面。 +2. 其次在弹出的应用设置界面,点击环境变量,在下方新起一行输入你的环境变量。格式为:`NAME='value'` +3. 点击更新生效。 -![](/doc-images/add-env-step2.png) +## 使用环境变量 -3. 确认更新环境变量 +环境变量添加完成后,即可在任意云函数中通过访问 `process.env` 来使用。 -::: warning -请注意,更新环境变量需要重启当前应用以生效。 -重启期间应用将无法正常提供服务,因此在重启之前,请确保应用已暂停业务请求。 +:::tip + `cloud.env` 已废弃 ::: -这里我们添加一个 `name` 为 `MY_ENV_KEY`, `value` 为 `MY_ENV_VALUE` 的环境变量,并等待应用重启完成。 - -![](/doc-images/add-env-step3.png) - - -## 使用环境变量 - -环境变量添加完成后,即可在任意云函数中通过访问 `cloud.env` 来使用。 - ```typescript import cloud from '@lafjs/cloud' export async function main(ctx: FunctionContext) { - const env = cloud.env + const env = process.env console.log(env) - // 可以看到,我们刚才添加的 MY_ENV_NAME: MY_ENV_VALUE 已经生效了 + // 所有的环境变量都在 process.env 里面 } - ``` - diff --git a/docs/guide/function/faq.md b/docs/guide/function/faq.md new file mode 100644 index 0000000000..f50568eb93 --- /dev/null +++ b/docs/guide/function/faq.md @@ -0,0 +1,392 @@ +--- +title: 云函数常见问题 +--- + +# {{ $frontmatter.title }} + +这里是云函数开发过程中可能会遇到的一些问题。欢迎 Pr~ + +[[toc]] + +## 云函数延迟执行 + +```typescript +import cloud from '@lafjs/cloud' + +export async function main(ctx: FunctionContext) { + const startTime = Date.now() + console.log(startTime) + await sleep(5000) // 延迟 5 秒 + console.log(Date.now() - startTime) +} + +async function sleep(ms) { + return new Promise(resolve => + setTimeout(resolve, ms) + ); +} +``` + +## 云函数设置某请求超时时间 + +```typescript +import cloud from '@lafjs/cloud' + +export async function main(ctx: FunctionContext) { + // 如果 getData 的异步操作在 4 秒内完成并返回,则 responseText 为 getDat 的返回值 + // 如果 4 秒内未完成,则 responseText 为'',不影响 getData 的实际运行 + const responseText = await Promise.race([ + getData(), + sleep(4000).then(() => ''), + ]); + console.log(responseText, Date.now()) +} + +async function sleep(ms) { + return new Promise(resolve => + setTimeout(resolve, ms) + ); +} + +async function getData(){ + // 某个异步操作,以下通过 sleep 模拟超过 4 秒的情况 + await sleep(5000) + const text = "getData 的返回值" + console.log(text, Date.now()) + return text +} +``` + +## 云函数对接公众号简单示例 + +以下代码只兼容明文模式 + +```typescript +import * as crypto from 'crypto' +import cloud from '@lafjs/cloud' + +export async function main(ctx: FunctionContext) { + const { signature, timestamp, nonce, echostr } = ctx.query; + const token = '123456'; // 这里的 token 自定义,需要对应微信后台的配置的 token + + // 验证消息是否合法,若不合法则返回错误信息 + if (!verifySignature(signature, timestamp, nonce, token)) { + return 'Invalid signature'; + } + + // 如果是首次验证,则返回 echostr 给微信服务器 + if (echostr) { + return echostr; + } + + // 处理接收到的消息 + const payload = ctx.body.xml; + // 如果接收的是文本 + if (payload.msgtype[0] === 'text') { + // 公众号发什么回复什么 + return toXML(payload, payload.content[0]); + } +} + +// 校验微信服务器发送的消息是否合法 +function verifySignature(signature, timestamp, nonce, token) { + const arr = [token, timestamp, nonce].sort(); + const str = arr.join(''); + const sha1 = crypto.createHash('sha1'); + sha1.update(str); + return sha1.digest('hex') === signature; +} + +// 返回组装 xml +function toXML(payload, content) { + const timestamp = Date.now(); + const { tousername: fromUserName, fromusername: toUserName } = payload; + return ` + + + + ${timestamp} + + + + ` +} +``` + +## 云函数合成图片 + +需要先安装依赖 `canvas` + +```typescript +import { createCanvas } from 'canvas' + +export async function main(ctx: FunctionContext) { + const canvas = createCanvas(200, 200) + const context = canvas.getContext('2d') + + // Write "hello!" + context.font = '30px Impact' + context.rotate(0.1) + context.fillText('hello!', 50, 100) + + // Draw line under text + var text = context.measureText('hello!') + context.strokeStyle = 'rgba(0,0,0,0.5)' + context.beginPath() + context.lineTo(50, 102) + context.lineTo(30 + text.width, 102) + context.stroke() + + // Write "Laf!" + context.font = '30px Impact' + context.rotate(0.1) + context.fillText('Laf!', 50, 150) + console.log(canvas.toDataURL()) + return `` +} +``` + +## 云函数防抖 + +通过 Laf 云函数的全局缓存可以很方便的设置防抖 + +以下是一个简单的防抖例子,前端请求时,需要在 header 中带上用户 token。 + +```typescript +// 云函数生成 Token +const accessToken_payload = { + // 除了示例的,还可以加别的参数 + uid: login_user[0]._id, //一般是 user 表的_id + role: login_user[0].role, //如果没有 role,可以不要 + exp: (Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7) * 1000, //7天过期 +} +const token = cloud.getToken(accessToken_payload) +console.log(token) +``` + +```typescript +import cloud from '@lafjs/cloud' + +export async function main(ctx: FunctionContext) { + const FunctionName = ctx.request.params.name + const sharedName = FunctionName + ctx.user.uid + let lastCallTime = cloud.shared.get(sharedName) + console.log(lastCallTime) + if (lastCallTime > Date.now()) { + console.log("请求太快了") + return '请求太快了' + } + cloud.shared.set(sharedName, Date.now() + 1000) + // 原有逻辑 + + // 逻辑完毕后删除全局缓存 + cloud.shared.delete(sharedName) +} +``` + +## 云函数域名验证 + +部分微信服务需要验证 MP 开头的 txt 文件的值,以判断域名是否有权限 + +可以新建一个该文件名的云函数,如:`MP_123456789.txt` + +直接返回该文本的内容 + +```typescript +import cloud from '@lafjs/cloud' + +export async function main(ctx: FunctionContext) { + // 这里直接返回文本内容 + return 'abcd...' +} +``` + +## Laf 应用 IP 池(IP 白名单) + +下满例子为使用的是 laf.run 的情况。使用 laf.dev 或其他,下面命令需要更换域名。 + +- Windows 可在 CMD 中执行 `nslookup laf.run` + +- Mac 可在终端中执行 `nslookup laf.run` + +可看到全部 IP 池 + +## 云函数发送阿里云短信验证码 + +使用阿里云短信接口,编写发送短信验证码的云函数。 +需要你提供阿里云短信服务的 `AccessKey` 和 `SecretKey`,以及短信模板 ID。 + +创建 `sendsms` 云函数,添加依赖 @alicloud/dysmsapi20170525,编写以下代码: + +```typescript +import Dysmsapi, * as dysmsapi from "@alicloud/dysmsapi20170525"; +import * as OpenApi from "@alicloud/openapi-client"; +import * as Util from "@alicloud/tea-util"; + +const accessKeyId = "xxxxxxxxxxxxxx"; +const accessKeySecret = "xxxxxxxxxxxxxx"; +const signName = "XXXX"; +const templateCode = "SMS_xxxxx"; +const endpoint = "dysmsapi.aliyuncs.com"; + + +export default async function (ctx: FunctionContext) { + const { phone, code } = ctx.body; + + const sendSmsRequest = new dysmsapi.SendSmsRequest({ + phoneNumbers: phone, + signName, + templateCode, + templateParam: `{"code":${code}}`, + }); + + const config = new OpenApi.Config({ accessKeyId, accessKeySecret, endpoint }); + const client = new Dysmsapi(config); + const runtime = new Util.RuntimeOptions({}); + const res = await client.sendSmsWithOptions(sendSmsRequest, runtime); + return res.body; +}; +``` + +## 云函数微信 native 支付 + +Native 支付适用于 PC 网站、实体店单品或订单、媒体广告支付等场景。[微信官方介绍](https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter2_7_0.shtml) + +Native 支付服务端下单之后微信支付会返回一个 code-url, 然后前端接收这个返回值,直接把这个 code-url 在前端 +生成一个二维码即可用微信扫描支付。 + +- `code-url` 结构类似:`weixin://wxpay/bizpayurl?pr=aIQrOYOzz` + +- `notify_url` 也可以写一个 laf 云函数来接受支付结果的通知。此处不包含 `notify_url` 代码。 + +创建 `wx-pay` 云函数,安装依赖 [wxpay-v3](https://github.com/yangfuhe/node-wxpay),代码如下: + +```typescript +import cloud from "@lafjs/cloud"; +const Payment = require("wxpay-v3"); + +export default async function (ctx: FunctionContext) { + const { goodsName, totalFee, payOrderId } = ctx.body; + + // create payment instance + const payment = new Payment({ + appid: "应用 ID", + mchid: "商户 id", + private_key: getPrivateKey(), + serial_no: "序列号", + apiv3_private_key: "api v3 密钥", + notify_url: "付退款结果通知的回调地址", + }); + + // 下单 + const result = await payment.native({ + description: goodsName, + out_trade_no: payOrderId, + amount: { + total: totalFee, + }, + }); + return result; +}; + +function getPrivateKey() { + const key = `-----BEGIN PRIVATE KEY----- +HOBHEk+4cdiPcvhowhC8ii7838DP4qC+18ibL/KAySWyZjUC/keOr4MxhxQ1T+OV +... +... +475J8ALCRltkgTSxicoXS7SpjLqvIH2FPpv2BI+qQ3nOmAugsRkeH9lZdC/nSC0m +uI205SwTsTaT70/vF90AwQ== +-----END PRIVATE KEY----- +`; + return key; +} +``` + +## 云函数支付宝支付 + +创建 `aliPay` 云函数,安装依赖 `alipay-sdk`,编写以下代码: + +```typescript +import cloud from "@lafjs/cloud"; +import alipay from "alipay-sdk"; +const AlipayFormData = require("alipay-sdk/lib/form").default; + + +export default async function (ctx: FunctionContext) { + const { totalFee, goodsName, goodsDetail, payOrderId } = ctx.body; + + const ali = new alipay({ + appId: "2016091800536572", + signType: "RSA2", + privateKey: "MIIEow......Yf2Mlz6xqG/Aq", + alipayPublicKey: "MIIBI......IDAQAB", + gateway: "https://openapi.alipaydev.com/gateway.do", //沙箱测试网关 + }); + + const formData = new AlipayFormData(); + formData.setMethod("get"); + formData.addField( + "notifyUrl", + "https://APPID.lafyun.com/alipay_notify_callback" + ); + formData.addField("bizContent", { + subject: goodsName, + body: goodsDetail, + outTradeNo: payOrderId, + totalAmount: totalFee, + }); + + const result = await ali.exec( + "alipay.trade.app.pay", + {}, + { formData: formData } + ); + + return { + code: 0, + data: result, + }; +}; +``` + +## 云函数发送邮件 + +使用 SMTP 服务发送邮件 + +创建 `sendmail` 云函数,安装依赖 `nodemailer`,代码如下: + +```typescript +import from 'nodemailer' + +// 邮件服务器配置 +const transportConfig = { + host: 'smtp.exmail.qq.com', // smtp 服务地址,示例腾讯企业邮箱地址 + port: 465, // smtp 服务端口,一般服务器未开此端口,需要手动开启 + secureConnection: true, // 使用了 SSL + auth: { + user: 'sender@xx.com', // 发件人邮箱,写你的邮箱地址即可 + pass: 'your password', // 你设置的 smtp 专用密码或登录密码,每家服务不相同,QQ 邮箱需要开启并配置授权码,即这里的 pass + } +} + +// 邮件配置 +const mailOptions = { + from: '"SenderName" ', // 发件人 + to: 'hi@xx.com', // 收件人 + subject: 'Hello', // 邮件主题 + html: 'Hello world?' // html 格式邮件正文 + // text: 'hello' // 文本格式有限正文 +} + +export default async function (ctx: FunctionContext) { + const transporter = nodemailer.createTransport(transportConfig) + + transporter.sendMail(mailOptions, (error, info) => { + if (error) { + return console.log(error); + } + console.log('Message sent: %s', info.messageId); + return info.messageId + }) +}; +``` diff --git a/docs/guide/function/function-param.md b/docs/guide/function/function-param.md new file mode 100644 index 0000000000..2fd7b5c71f --- /dev/null +++ b/docs/guide/function/function-param.md @@ -0,0 +1,49 @@ +--- +title: 云函数参数 返回值 +--- + +# {{ $frontmatter.title }} + +## 参数 + +在 `main` 函数中,可以通过第一个参数 `ctx` 来获取用户传递的请求信息。 +下面的例子可以读取前端传递的 Query 参数`username`: + +```js +export default async function (ctx: FunctionContext) { + return `hello, ${ctx.query.username}`; +}; +``` + +这样可以读取前端传递的 body 参数 + +```js +export default async function (ctx: FunctionContext) { + return `hello, ${ctx.body}`; +}; +``` + +`ctx` 具有下面的一些内容: + +| 属性 | 介绍 | +| --------------- | ----------------------------------------------------------------------------------- | +| `ctx.requestId` | 当前请求的唯一 ID | +| `ctx.method` | 当前请求的方法,如`GET`、`POST` | +| `ctx.headers` | 所有请求的 headers | +| `ctx.auth` | 使用 Http Bearer Token 认证时,解析出的 token 值 | +| `ctx.query` | 当前请求的 query 参数 | +| `ctx.body` | 当前请求的 body 参数 | +| `ctx.response` | HTTP 响应,和`express`的`Response`实例保持一致 | +| `ctx.socket` | [WebSocket](https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket) 实例 | +| `ctx.files` | 上传的文件 ([File](https://developer.mozilla.org/zh-CN/docs/Web/API/File) 对象数组) | + +## 返回值 + +那我们如何把数据传给前端呢?很简单,只需要在云函数中 return 出去就可以了。 + +```js +export default async function (ctx: FunctionContext) { + // 这里用字符串示例,你可以返回任何数据类型。 + return "这里是返回给前端的数据" +}; +``` diff --git a/docs/guide/function/function-sdk.md b/docs/guide/function/function-sdk.md new file mode 100644 index 0000000000..fbc8b58f5f --- /dev/null +++ b/docs/guide/function/function-sdk.md @@ -0,0 +1,223 @@ +--- +title: 云函数 SDK +--- + +# {{ $frontmatter.title }} + +引入 Laf 的 Cloud SDK + +在云函数上,Laf 提供了专门的 SDK `@lafjs/cloud` 让云函数支持访问网络、数据库、对象存储等。 + +::: danger +`@lafjs/cloud` 是一个专有的模块,只能在云函数上使用,不支持通过 npm 安装到其他位置。 +::: + +## 导入 SDK + +每个 Laf 应用默认已经安装了 SDK 依赖,不需要额外安装了。直接在云函数顶部 import 即可。 + +```js +import cloud from "@lafjs/cloud"; +``` + +## 发送网络请求 + +使用 `cloud.fetch()` 可发起 HTTP 请求,调用三方接口,可完成如支付接口、短信验证码等等三方接口操作。 + +该接口是对 `axios` 请求库的封装,其调用方法与 `axios` 完全一致。调用方法可参考:[axios 文档](https://www.axios-http.cn/docs/api_intro) + +可以理解为 `cloud.fetch === axios`,可以做到互相替换。 + +```typescript +import cloud from "@lafjs/cloud"; + +export async function main(ctx: FunctionContext) { + const ret = await cloud.fetch({ + url: "http://api.github.com/", + method: "post", + }); + console.log(ret.data); + return ret.data; +}; +``` + +还可以这么写 + +```typescript +// get 请求 +const getRes = await cloud.fetch.get("http://api.github.com/"); +// post 请求 +const postRes = await cloud.fetch.post("http://api.github.com/",{ + name: 'laf' +}); +``` + +## 操作数据库 + +通过`cloud.database()` 可以获取数据库对象,进而对数据库进行操作。 + +::: info +数据库 API 的详细操作方法可以参考 _[云数据库](/guide/db/)_ 章节 +::: + +下面的例子可以获取数据库中的用户信息: + +```typescript +import cloud from "@lafjs/cloud"; + +export async function main(ctx: FunctionContext) { + const { username } = ctx.body; + // 数据库操作 + const db = cloud.database(); + const ret = await db.collection("users").where({ username }).get(); + console.log(ret); +}; +``` + +## 调用其他云函数 + +通过`cloud.invoke()` 调用本应用内的其他云函数。 + +::: info +该方法已不推荐使用,现可直接[引入云函数](#云函数引入) +::: + +```typescript +import cloud from '@lafjs/cloud' + +export async function main(ctx: FunctionContext) { + // 调用 hello 云函数 + await cloud.invoke('hello') +} +``` + +如果调用的云函数需要用到 ctx 里面的东西,我们可以通过这样的方式传入。 + +```typescript +import cloud from '@lafjs/cloud' + +export async function main(ctx: FunctionContext) { + // 调用云函数 hello 并传入 ctx + await cloud.invoke('hello',ctx) +} +``` + +## 生成和解密 JWT token + +```typescript +cloud.getToken(payload); // payload 可参考下方的示例代码 +cloud.parseToken(token); // token 为前端请求时 header 里的 authorization 中的 token +``` + +以下实现简单的生成和解密 JWT token + +```js +import cloud from "@lafjs/cloud"; + +export async function main(ctx: FunctionContext) { + const payload = { + uid: 1, + // 默认 token 有效期为 7 天,请务必提供此 `exp` 字段,详见 JWT 文档。 + exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7, + }; + // 生成 access_token + const access_token = cloud.getToken(payload); + console.log("云函数生成的 token:", access_token) + // ctx.user 会自动解密 + console.log(ctx.user) + const authHeader = ctx.headers.authorization; + const token = authHeader.split(' ')[1]; // 提取 JWT + console.log("前端请求带的 token:", token) + const parseToken = cloud.parseToken(token); + console.log("解密 token 后的数据:", parseToken) +}; +``` + +![getToken-parseToken](/doc-images/getToken-parseToken.png) + +以下实现简单登录函数,并生成 JWT token + +> 注意:出于演示目的,对 password 以明文方式查询,并未做 hash 处理考虑,不建议实际开发过程中如此使用。 + +```typescript +import cloud from "@lafjs/cloud"; + +export async function main(ctx: FunctionContext) { + const { username, password } = ctx.body; + + const db = cloud.database(); + const { data: user } = await db + .collection("users") + .where({ username, password }) + .getOne(); + + if (!user) { + return "invalid username or password"; + } + + // payload of token + const payload = { + uid: user._id, + // 默认 token 有效期为 7 天,请务必提供此 `exp` 字段,详见 JWT 文档。 + exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7, + }; + const access_token = cloud.getToken(payload); + + return { + access_token, + uid: user._id, + username: user.username, + expired_at: payload.exp, + }; +}; +``` + +## 云函数全局缓存 + +云函数全局内存单例对象,可跨多次调用、不同云函数之间共享数据 + +`cloud.shared`是 JS 中标准的 Map 对象,可参照 MDN 文档学习使用:[Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) + +使用场景: + +1. 可将一些全局配置初始化到 shared 中,如微信开发信息、短信发送配置 +2. 可共享一些常用方法,如 checkPermission 等,以提升云函数性能 +3. 可做热数据的缓存。如:缓存微信 access_token。(建议少量使用,此对象是在 node vm 堆中分配,因为 node vm 堆内存限制) + +::: info +应用重启后缓存会全部清空,不重启会一直保留 +::: + +```typescript +import cloud from "@lafjs/cloud"; + +export async function main(ctx: FunctionContext) { + cloud.shared.set(key, val); // 设置一个缓存 + cloud.shared.get(key); // 获取缓存的值 + cloud.shared.has(key); // 判断缓存是否存在 + cloud.shared.delete(key); // 删除缓存 + cloud.shared.clear(); // 清空所有缓存 + // ... 其他方法可访问上方 MDN 的 Map 文档查看 +}; +``` + +## 云函数原生 MongoDriverObject 实例 + +熟悉 MongoDB 的同学建议优先使用原生 MongoDriverObject 实例去操作数据库。 + +可参照 mongodb 官方 crud 文档学习使用:[mongodb](https://www.mongodb.com/docs/mongodb-shell/crud/) + +下面是一个简单的使用实例: + +```typescript +import cloud from "@lafjs/cloud"; + +export async function main(ctx: FunctionContext) { + const db = cloud.mongo.db + const data = { + name : "张三" + } + const res = await db.collection('test').insertOne(data) + console.log(res) +}; +``` diff --git a/docs/guide/function/index.md b/docs/guide/function/index.md index a5664f10c1..cb69cecb3f 100644 --- a/docs/guide/function/index.md +++ b/docs/guide/function/index.md @@ -4,436 +4,56 @@ title: 云函数入门 # {{ $frontmatter.title }} -云函数是运行在云端的 JavaScript 代码。 +## 云函数简介 -云函数可使用 Typescript 编写,无需管理服务器,在开发控制台在线编写、在线调试、一键保存即可运行后端代码。 +`Laf云函数`是运行在云端的 `JavaScript` 代码。 -在你的应用中,大多数数据的获取都可在客户端直接操作数据库,但是通常业务中会使用到「非数据库操作」,如注册、登录、文件操作、事务、第三方接口等,可直接使用云函数实现。 +云函数可使用 `Typescript/JavaScript` 编写,无需管理服务器,在 Web 开发控制台在线编写、在线调试、一键保存即可运行后端代码。 -## 创建云函数 - -点击页面左上角「函数」按钮,点击加号,添加云函数 - -![](/doc-images/create-function.jpg) - -## 编辑云函数 - -可直接在线编辑代码 - -![](/doc-images/edit-cloudfunction.png) - -## 运行云函数 - -云函数可直接运行调试,未发布的云函数也可以在此进行运行调试 - -![](/doc-images/run-cloudfunction.png) - -## 发布云函数 - -云函数发布后,才可正式使用 - -::: warning -云函数不会自动保存,发布后才会保存并生效 -::: - -![](/doc-images/publish-cloudfunction.png) - -## 访问云函数 - -### 通过 URL 访问云函数 - -发布云函数后,可以在发布按钮右边找到该云函数的访问地址。 - -使用浏览器或者 PostMan 等工具访问该地址,即可得到 `hello laf`字符串。 -::: warning -暂不能设置云函数 url 化的 path -::: - -### 通过 SDK 访问云函数 - -除了通过 HTTP 请求来访问,还可以使用 [laf-client-sdk](https://www.npmjs.com/package/laf-client-sdk) 来访问云函数。 - -::: info -目前 SDK 暂时只支持发送 POST 请求 -::: - -首先,安装 SDK: - -```shell -npm i laf-client-sdk -``` - -接下来,需要创建一个`cloud` 对象: - -```js -import { Cloud } from "laf-client-sdk"; - -const cloud = new Cloud({ - baseUrl: "xxx", // 这个地址可以在欢迎页面中的“服务地址”中找到 - getAccessToken: () => "", // 这里不需要授权,先填空 - //environment: "wxmp", // 微信小程序中使用 - //environment: "uniapp", // UNI-APP中使用 -}); -``` - -然后,就可以调用云函数了: - -```js -const ret = await cloud.invokeFunction("hello-laf"); - -console.log(ret); // hello laf -``` - -## 获取用户传递的参数 - -刚刚介绍的云函数只能静态地返回一些内容,但在实际场景下,我们需要让云函数能够和用户交互。 - -在 `main` 函数中,可以通过第一个参数 `ctx` 来获取用户传递的请求信息。 - -`ctx` 具有下面的一些内容: - -| 属性 | 介绍 | -| --------------- | ----------------------------------------------------------------------------------- | -| `ctx.requestId` | 当前请求的唯一 ID | -| `ctx.method` | 当前请求的方法,如`GET`、`POST` | -| `ctx.headers` | 所有请求的 headers | -| `ctx.auth` | 使用 Http Bearer Token 认证时,解析出的 token 值 | -| `ctx.query` | 当前请求的 query 参数 | -| `ctx.body` | 当前请求的 body 参数 | -| `ctx.response` | HTTP 响应,和`express`的`Response`实例保持一致 | -| `ctx.socket` | [WebSocket](https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket) 实例 | -| `ctx.files` | 上传的文件 ([File](https://developer.mozilla.org/zh-CN/docs/Web/API/File) 对象数组) | -| `ctx.env` | 自定义的环境变量 ([env](env.md)) | - -下面的例子可以读取用户传递的 Query 参数`username`: - -```js -exports.main = function (ctx) { - return `hello, ${ctx.query.username}`; -}; -``` - -访问 `调用地址?username=test`,你将得到: - -```js -hello, test; -``` - -::: warning -laf 现有对 `request` 请求体和请求流的大小限制是 10M(后期会做考虑做 laf 应用环境变量的管理) -::: - -### 在客户端 SDK 调用带参数的云函数 - -`invokeFunction` 函数的第二个参数指明了用于发送的数据,这个数据会以 Body 的形式发送: - -```js -const ret = await cloud.invokeFunction("函数名", { name: "test" }); -``` - -## 同步云函数 - -如下面代码所示: - -```js -exports.main = function () { - return "hello world!"; -}; -``` - -当然,使用 ESModule 的语法也是可以的: - -```js -export function main() { - return "hello world!"; -} -``` - -## 异步的云函数 - -在实际应用中,云函数需要执行的异步操作(如网络请求)。 - -幸运的是,云函数本身是支持异步调用的,你只需要在函数的前面加上 `async` ,就能轻松的让函数支持异步操作: - -```js -exports.main = async function (ctx) { - await someAsyncAction; - return `hello, ${ctx.query.username}`; -}; -``` - -## 云函数的返回值 - -云函数的返回值支持多种类型: +可在无需购买和管理服务器的情况下,快速开发后端代码。并且自带数据库和对象存储,极大降低后端开发难度。 -```js -Buffer.from("whoop"); // Buffer -{ - some: "json"; -} // 对象,会被处理成JSON -("

some html

"); // HTML -("Sorry, we cannot find that!"); // 字符串 -``` +每个云函数都是一个单独的 `Typescript` 文件,Laf 为云函数单独封装了 `@lafjs/cloud` 模块,以便于更加方便的编写云函数。 -如果需要发送状态码,则需要使用 `ctx` 对象上的 `response` 属性: - -```js -ctx.response.status(403); // 发送403状态码 -``` - -## 导入模块 - -我们可以很轻松地借助 ESModule 的 `import` 语法或 CommonJS 的 `require` 语法来导入模块。 - -::: warning -不建议使用 `require` 引入包,虽然也能运行,但在线 IDE 无法给出智能提示 -::: - -### 导入 Node.js 内置包 - -下面的例子使用了 Node.js 内置的包 `crypto`,来对密码进行哈希: - -```ts -import cloud from "@lafjs/cloud"; -import crypto from "crypto"; - -exports.main = async function (ctx) { - const { password } = await ctx.body; - - const password_hash = crypto - .createHash("sha256") - .update(content) - .digest("hex"); - - return password_hash; -}; -``` - -### 导入 NPM 包 - -在使用 npm 包之前,需要在 _依赖管理_ 处安装对应的包。 - -```ts -import cloud from "@lafjs/cloud"; -import dayjs from "dayjs"; - -exports.main = function () { - return dayjs().format(); -}; -``` - -### 导入云函数 +## 创建云函数 -目前 Laf 暂不支持导入其他的云函数,敬请期待。 +创建并进入 Laf 应用后,点击页面左上角「函数」按钮,点击加号,添加云函数 -::: info -虽然不支持导入,但支持执行其他的云函数。 -::: +![create-function](/doc-images/create-function.png) -## Cloud SDK +**函数名** : 可使用 `字母` `数字` `-` `_` `.` 五种,函数名不可重复 -刚刚编写的一些云函数都是比较基础的一些功能,但并没有和 Laf 的其他功能连接起来。 +**标签** : 用来分类管理的,可通过标签名筛选云函数,可为每个云函数设置多个标签 -在云函数上,Laf 提供了云 SDK `@lafjs/cloud` 让云函数支持访问网络、数据库、对象存储等。 +**请求方式** : 只有被勾选的请求方式才允许请求 -::: warning -`@lafjs/cloud` 是一个专有的模块,只能在云函数上使用,不支持通过 npm 安装到其他位置。 -::: +**函数描述** : 方便后续查看云函数的功能,相当于备注 -### 导入 SDK +**函数模板** : 选择不同的函数模板可初始化不同的代码 -SDK 的所有内容通过它的默认导出来访问。 +## 编辑云函数 -```js -import cloud from "@lafjs/cloud"; -``` +Laf 自带 `Web IDE`,可直接在浏览器在线编辑、运行(调试)、发布云函数。 -### 发送网络请求 +![edit-cloudfunction](/doc-images/edit-cloudfunction.png) -使用 `cloud.fetch()` 可发起 HTTP 请求,调用三方接口,可完成如支付接口、短信验证码等等三方接口操作。 +## 运行云函数 -该接口是对 `axios` 请求库的封装,其调用方法与 `axios` 完全一致。 +云函数编写后可直接运行调试,未发布的云函数也可以在此进行运行调试。 -```ts -import cloud from "@lafjs/cloud"; +![run-cloudfunction](/doc-images/run-cloudfunction.png) -exports.main = async function (ctx) { - const ret = await cloud.fetch({ - url: "http://api.github.com/", - method: "post", - }); +如在云函数中添加 `console.log` 打印日志的代码,运行后也会直接显示在 Console 控制台,同时也会将云函数的返回值打印在运行结果中。 - console.log(ret.data); - return ret.data; -}; -``` +可切换请求方式以及配置请求参数,默认是 `GET` 请求,此处显示的请求方式与勾选的请求方式有关。 -### 操作数据库 +## 发布云函数 -通过`cloud.database()` 可以获取数据库对象,进而对数据库进行操作。 +云函数 **发布后** ,才是正式生效。前端才可以进行请求。 -::: info -数据库 API 的详细操作方法可以参考 _云数据库_ 章节 +::: danger +**云函数修改的代码,会自动在当前浏览器中缓存,只有在发布后才是真正的保存以及生效!** ::: -下面的例子可以获取数据库中的用户信息: - -```ts -import cloud from "@lafjs/cloud"; - -exports.main = async function (ctx) { - const { username } = ctx.body; - // 数据库操作 - const db = cloud.database(); - const ret = await db.collection("users").where({ username }).get(); - - console.log(ret); - return ret.data; -}; -``` - -### 调用其他云函数 - -通过`cloud.invoke()` 调用本应用内的其他云函数。 - -下方例子演示了创建用户成功后为用户发送邀请邮件(`send_mail`函数需自行实现): - -```ts -import cloud from "@lafjs/cloud"; - -// invoke方法模型 - -exports.main = async function (ctx) { - const { username } = ctx.body; - // 数据库操作 - const db = cloud.database(); - const ret = await db.collection("users").add({ - name: "jack", - password: "*******", - }); - if (ret?.ok) { - await cloud.invoke("send_mail", { - ...ctx, // 如果函数内部需要使用ctx中的某些属性,可按此方法传入 - body: { - title: "xxx", - content: "xxx", - date: "xxx", - }, - }); - } - - console.log(ret); - return ret.ok; -}; -``` - -### 发送云函数事件 - -通过`cloud.emit()` 调用本应用内的其他云函数。 - -上面的例子演示了创建用户成功后为用户发送邀请邮件,但如果在用户创建成功后有许多操作要做(如同时发送欢迎邮件、欢迎短信、为邀请人分配奖励等),这样的操作显然不是很合适。使用`cloud.emit`可简化相关操作。 - -> 本例仅做`emit`示例使用,业务开发中可直接使用触发器监听`DatabaseChange:users#add`事件实现此功能。[查看详情](trigger.md) - -```ts -import cloud from "@lafjs/cloud"; - -// invoke方法模型 -// invoke(name: string, ctx: FunctionContext): Promise - -exports.main = async function (ctx) { - const { username } = ctx.body; - // 数据库操作 - const db = cloud.database(); - const ret = await db.collection("users").add({ - name: "jack", - password: "*******", - }); - if (ret?.ok) { - await cloud.emit("user_created", { - ...ctx, // 如果函数内部需要使用ctx中的某些属性,可按此方法传入 - body: { - id: ret?.insertId, - }, - }); - } - - console.log(ret); - return ret.ok; -}; -``` - -之后可在[触发器](trigger.md)处使用 -![image](https://user-images.githubusercontent.com/27558572/191404414-7d69811e-b192-4d55-9a26-59829d9932aa.png) - -在事件处填入你要监听的事件名称,当有云函数`emit`这个事件时,会自动执行这个云函数 -![image](https://user-images.githubusercontent.com/27558572/191404535-700c43b4-3e1c-427a-a36d-4198e10dcc7d.png) - -> 新建触发器后需要点击`新建函数`旁的`发布函数`发布后才会应用触发器。 - -### 生成 JWT token - -以下实现简单登录函数,以演示 标准 JWT token 的生成,预期开发者已熟悉 JWT 相关知识。 - -可查看[JSON Web Token 入门教程](https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html) - -> 注意:出于演示目的,对 password 以明文方式查询,并未做 hash 处理考虑,不建议实际开发过程中如此使用。 - -```ts -import cloud from "@lafjs/cloud"; - -exports.main = async function (ctx) { - const { username, password } = ctx.body; - - const db = cloud.database(); - const { data: user } = await db - .collection("users") - .where({ username, password }) - .getOne(); - - if (!user) { - return "invalid username or password"; - } - - // payload of token - const payload = { - uid: user._id, - // 默认 token 有效期为 7 天,请务必提供此 `exp` 字段,详见 JWT 文档。 - exp: Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7, - }; - const access_token = cloud.getToken(payload); - - return { - access_token, - uid: user._id, - username: user.username, - expired_at: payload.exp, - }; -}; -``` - -### 操作缓存数据 - -::: info -云函数全局内存单例对象,可跨多次调用、不同云函数之间共享数据 -`cloud.shared`是 JS 中标准的 Map 对象,可参照 MDN 文档学习使用:[Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) - -使用场景: - -1. 可将一些全局配置初始化到 shared 中,如微信开发信息、短信发送配置 -2. 可共享一些常用方法,如 checkPermission 等,以提升云函数性能 -3. 可做热数据的缓存。如:缓存微信 access_token。(建议少量使用,此对象是在 node vm 堆中分配,因为 node vm 堆内存限制) - ::: - -```ts -import cloud from "@lafjs/cloud"; +![publish-cloudfunction](/doc-images/publish-cloudfunction.png) -exports.main = async function (ctx) { - await cloud.shared.set(key, val); // 设置一个缓存 - await cloud.shared.get(key); // 获取缓存的值 - await cloud.shared.has(key); // 判断缓存是否存在 - await cloud.shared.delete(key); // 删除缓存 - await cloud.shared.clear(); // 清空所有缓存 - // ... 其他方法可访问上方MDN的Map文档查看 -}; -``` +发布页面,左边是之前发布的代码,右边是即将发布的代码。可以方便的查看代码的差异,从而检查是否需要发布。 diff --git a/docs/guide/function/init.md b/docs/guide/function/init.md new file mode 100644 index 0000000000..ba5b38cfc2 --- /dev/null +++ b/docs/guide/function/init.md @@ -0,0 +1,25 @@ +--- +title: 应用初始化 +--- + +# {{ $frontmatter.title }} + +Laf 应用在重新启动后,可以在一个云函数中执行初始化操作,如数据库的初始化,全局缓存的初始化等。 + +:::tip +应用初始化云函数名为固定云函数名:`__init__`,其他名称均不会生效 +::: + +下面是一个简单的应用初始化云函数例子,在 Laf 应用启动时记录启动时间 + +```typescript +import cloud from '@lafjs/cloud' + +export async function main(ctx: FunctionContext) { + // 记录 Laf 应用启动时间 + const db = cloud.database() + await db.collection('init').add({ + time: Date.now() + }) +} +``` diff --git a/docs/guide/function/interceptor.md b/docs/guide/function/interceptor.md new file mode 100644 index 0000000000..25891dbc1a --- /dev/null +++ b/docs/guide/function/interceptor.md @@ -0,0 +1,31 @@ +--- +title: 云函数拦截器 +--- + +# {{ $frontmatter.title }} + +如果需要使用拦截器,需要创建一个云函数并且命名为 `__interceptor__`的云函数。 + +::: info +`__interceptor__` 为固定命名 +::: + +Laf 云函数拦截器,是在所有的云函数请求之前被请求,故而也可以叫做前置拦截器。 + +只有拦截器的返回值为 `true` ,才会去请求的原本的云函数 + +下面是一个简单的拦截器示例,如果 IP 是`111.111.111.111`,则可以继续访问原本的云函数 + +```typescript +export async function main(ctx: FunctionContext) { + // 获取请求的实际 IP + const ip = ctx.headers['x-real-ip'] + if(ip == '111.111.111.111'){ + return true + }else{ + return false + } +} +``` + +更多用途可自由发挥! diff --git a/docs/guide/function/logs.md b/docs/guide/function/logs.md new file mode 100644 index 0000000000..4e9676f0cf --- /dev/null +++ b/docs/guide/function/logs.md @@ -0,0 +1,45 @@ +--- +title: 云函数历史日志 +--- + +# {{ $frontmatter.title }} + +:::warning +只有在云函数中加 `console` 打印才会保存日志! +::: + +云函数的全部历史日志,全部都自动保存到了日志板块中,日志会保留 3 天 + +可根据请求 ID `requestId` 和云函数名筛选 + +![function-log](/doc-images/function-log.png) + +1、点击日志,切换到日志板块 + +2、可根据 `requestId` 和云函数名搜索指定日志 + +3、点击单个日志,可查看详细内容 + +## 手动清理日志 + +Laf 云函数的运行日志都在一个隐藏的集合中:`__function_logs__` + +所以我们可以通过云函数操作数据库的方法,清理日志 + +以下是清理全部日志的云函数写法: + +::: danger +以下操作会删除全部历史日志,请谨慎操作 +::: + +```typescript +import cloud from '@lafjs/cloud' + +export async function main(ctx: FunctionContext) { + console.log('Hello World') + // 数据库,删除全部日志 + const db = cloud.database(); + const res = await db.collection('__function_logs__').remove({multi:true}) + console.log(res) +} +``` diff --git a/docs/guide/function/trigger.md b/docs/guide/function/trigger.md index 091ebc98aa..bbeb1ebca1 100644 --- a/docs/guide/function/trigger.md +++ b/docs/guide/function/trigger.md @@ -4,7 +4,7 @@ title: 云函数触发器 # {{ $frontmatter.title }} -触发器(`Trigger`)是触发函数执行的方式。我们可以给云函数绑定触发器来控制函数的调用。 +触发器 (`Trigger`) 是触发函数执行的方式。我们可以给云函数绑定触发器来控制函数的调用。 ::: info 当前 触发器 仅支持 定时触发器 类型。 @@ -14,24 +14,24 @@ title: 云函数触发器 ![](/doc-images/create-injector.png) -第一步: 点击函数列表右侧的触发器按钮 +第一步:点击函数列表右侧的触发器按钮 -第二步: 新建触发器 +第二步:新建触发器 -第三步: 输入触发器的名称,后期方便搜索和管理 +第三步:输入触发器的名称,后期方便搜索和管理 -第四步: 选择触发器的类型,当前仅支持定时触发器 +第四步:选择触发器的类型,当前仅支持定时触发器 -第五步: 选择定时任务的执行策略,这里是支持 cron原生表达式的。 +第五步:选择定时任务的执行策略,这里是支持 cron 原生表达式的。 如您对 `cron` 表达式不熟悉,可点击下方链接选择预置的三种方案。 -或者也可以点击 [更多示例](https://crontab.guru/examples.html) 按钮找到您需要的定时策略,也可以在 [在线Cron表达式](http://cron.ciding.cc/) 网站上生成您需要的表达式。 +或者也可以点击 [更多示例](https://crontab.guru/examples.html) 按钮找到您需要的定时策略,也可以在 [在线 Cron 表达式](http://cron.ciding.cc/) 网站上生成您需要的表达式。 ## 一个具体的例子 -在微信公众号开发过程中,通常需要我们使用中控服务器统一获取和刷新 `access_token` ,其他业务逻辑服务器所使用的 `access_token` 均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致access_token覆盖而影响业务。 -一般来说, access_token的有效期是 `2小时`, 利用定时触发器可以很好的解决这个问题。 +在微信公众号开发过程中,通常需要我们使用中控服务器统一获取和刷新 `access_token` ,其他业务逻辑服务器所使用的 `access_token` 均来自于该中控服务器,不应该各自去刷新,否则容易造成冲突,导致 access_token 覆盖而影响业务。 +一般来说,access_token 的有效期是 `2小时`, 利用定时触发器可以很好的解决这个问题。 1. 首先我们创建一个名为 `get-access-token` 的云函数 @@ -64,11 +64,10 @@ export async function main(ctx: FunctionContext) { } ``` -上述代码中,我们遵循微信开放文档中的 [接口调用请求说明](https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html) 来请求 `access_token`, 并将其存入 `cloud.shared` 中, 其他业务函数可以随时进行读取。 +上述代码中,我们遵循微信开放文档中的 [接口调用请求说明](https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html) 来请求 `access_token`, 并将其存入 `cloud.shared` 中,其他业务函数可以随时进行读取。 2. 使用触发器 ![](/doc-images/use-injector.png) -还记得刚才创建触发器的过程吗,我们只需选择关联的函数为 `get-access-token`, 并将 Cron 表达式设为 2小时,即可实现每两小时去请求微信的接口,来刷新 access_token 以保证有效。 - +还记得刚才创建触发器的过程吗,我们只需选择关联的函数为 `get-access-token`, 并将 Cron 表达式设为 2 小时,即可实现每两小时去请求微信的接口,来刷新 access_token 以保证有效。 diff --git a/docs/guide/function/use-function.md b/docs/guide/function/use-function.md new file mode 100644 index 0000000000..94eb60fb0a --- /dev/null +++ b/docs/guide/function/use-function.md @@ -0,0 +1,181 @@ +--- +title: 云函数用法 +--- + +# {{ $frontmatter.title }} + +## 云函数参数 + +在 `main` 函数中,可以通过参数 `ctx` 来获取用户传递的请求信息。 +下面的例子可以读取前端传递的 `Query` 参数`username`: + +![function-query](/doc-images/function-query.png) + +云函数代码如下: + +```js +export function main(ctx: FunctionContext) { + console.log(ctx.query.username) +}; +``` + +还可以读取前端 HTTP 请求传递的 `body` 参数`username`: + +![function-query](/doc-images/function-body.png) + +云函数代码如下: + +```js +export function main(ctx: FunctionContext) { + console.log(ctx.body.username) +}; +``` + +`ctx` 具有下面的一些参数: + +| 属性 | 介绍 | +| --------------- | ----------------------------------------------------------------------------------- | +| `ctx.requestId` | 当前请求的唯一 ID | +| `ctx.method` | 当前请求的方法,如`GET`、`POST` | +| `ctx.headers` | 所有请求的 headers | +| `ctx.user` | 使用 Http Bearer Token 认证时,解析出的 token 值 | +| `ctx.query` | 当前请求的 query 参数 | +| `ctx.body` | 当前请求的 body 参数 | +| `ctx.request` | HTTP 响应,和`express`的`Request`实例保持一致 | +| `ctx.response` | HTTP 响应,和`express`的`Response`实例保持一致 | +| `ctx.socket` | [WebSocket](https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket) 实例,[Laf WebSocket 使用文档](/guide/function/websocket.html) | +| `ctx.files` | 上传的文件 ([File](https://developer.mozilla.org/zh-CN/docs/Web/API/File) 对象数组) | +| `ctx.env` | 本应用自定义的环境变量 ([env](env.md)) | + +## 云函数返回值 + +那我们如何把数据返回出去呢? + +### 方法 1:return + +很简单,只需要在云函数中 return 出去就可以了 + +```js +export function main (ctx: FunctionContext) { + // 这里用字符串示例,你可以返回任何数据类型。 + return "这里是返回给前端的数据" +}; +``` + +云函数的返回值支持多种类型: + +```js +return Buffer.from("whoop"); // Buffer +return { + some: "json"; +} // 对象,会被处理成 JSON +return ("

some html

"); // HTML +return ("Sorry, we cannot find that!"); // 字符串 +``` + +### 方法 2: ctx.response 设置响应头、状态码和响应体等信息 + +这里`ctx.response`对齐`express`框架的`Response`实例 + +以下是一些常见的 res 对象方法: + +```js +ctx.response.send(body) // 发送响应体,可以是一个字符串、一个 Buffer 对象、一个 JSON 对象、一个数组等 +ctx.response.json(body) // 发送一个 JSON 响应 +ctx.response.status(statusCode) // 设置 HTTP 响应的状态码 +ctx.response.setHeader(name, value) // 设置一个响应头 +... +``` + +如果需要发送状态码,则需要使用 `ctx.response.status` : + +```js +ctx.response.status(403); // 发送 403 状态码 +``` + +如果需要分段发送数据,则需要使用 `ctx.response.write` 和 `ctx.response.end` : + +例如: + +```js +export function main (ctx: FunctionContext) { + // 设置响应头 + ctx.response.type = 'text/html'; + ctx.response.status = 200; + // 写入数据块 + ctx.response.write(''); + ctx.response.write('

Hello, world!

'); + ctx.response.write(''); + // 结束响应 + ctx.response.end(); +}; +``` + +## 支持异步操作 + +在实际应用中,云函数需要执行的异步操作(如网络请求,数据库操作等)。 + +幸运的是,云函数本身是支持异步调用的,你只需要在函数的前面加上 `async` ,就能轻松的让函数支持异步操作 + +新建云函数时默认已经在 main 函数的前面加上 `async` + +:::tip +在云函数中执行异步操作,尽可能的使用 `await` 去等待执行完成 +::: + +如下面的例子,去查询数据库中的 user 集合 + +```js +import cloud from '@lafjs/cloud' +const db = cloud.database() + +export default async function (ctx: FunctionContext) { + // 在数据库等异步操作前面添加 await + const res = await db.collection('user').get() + // 同步操作无需添加 await + console.log(res.data) +}; +``` + +## 云函数引入 + +现可直接在云函数中引入另外一个云函数 + +::: tip +被引入的云函数需要发布后,才可以被引入 +::: + +引入写法: + +```js +// funcName 为 default 函数 +import funcName from '@/funcName' +// 引入名为 func 的函数 +import { func } from '@/funcName' +``` + +如:在`test`云函数中引入`util`云函数 + +```js +// util 云函数 +export default async function main () { + return "util 已引入" +}; + +export function add(a: number, b: number) { + return a + b +}; +``` + +```js +// test 云函数 +import util, { add } from '@/util' + +export async function main(ctx: FunctionContext) { + // 由于 util 的 default 方法是 async 的,所以需要加 await + console.log(await util()) + // 打印结果:"util 已引入" + console.log(add(1, 2)) + // 打印结果:3 +} +``` diff --git a/docs/guide/function/websocket.md b/docs/guide/function/websocket.md index b43695978c..c9059b14c3 100644 --- a/docs/guide/function/websocket.md +++ b/docs/guide/function/websocket.md @@ -4,53 +4,40 @@ title: 云函数处理 WebSocket 长连接 # {{ $frontmatter.title }} -## WebSocket 触发器 +WebSocket 是一个长连接,可以主动给客户端推送消息,但是很可惜很多 Severless 架构不支持 WebSocket 的功能。值得开心的是,Laf 可以很轻松的使用 WebSocket,这给了我们更多的应用场景。 -提示:在使用 WebSocket 之前一定要建立触发器,详见触发器章节 +## WebSocket 云函数 -当应用收到 WebSocket 消息时,会触发以下云函数事件,开发者为任一云函数配置以下触发器,即可处理 WebSocket 消息 +在 Laf 使用 WebSocket 需要创建一个云函数并且命名为 `__websocket__` -- `WebSocket:connection` 有新 WebSocket 连接建立时触发,通过 `ctx.socket` 获取连接 -- `WebSocket:message` 接收 WebSocket 消息时触发,通过 `ctx.params` 获取消息数据 -- `WebSocket:close` 有 WebSocket 连接关闭时触发 -- `WebSocket:error` 有 WebSocket 连接出错时触发 +:::tip +WebSocket 云函数名为固定云函数名:`__websocket__`,其他名称均不会生效 +::: 以下是云函数中处理 WebSocket 示例: -```ts -exports.main = async function (ctx) { +```typescript +export async function main(ctx: FunctionContext) { + if (ctx.method === "WebSocket:connection") { - ctx.socket.send("hi connection succeed"); + ctx.socket.send('hi connection succeed') } - if (ctx.method === "WebSocket:message") { + if (ctx.method === 'WebSocket:message') { const { data } = ctx.params; console.log(data.toString()); ctx.socket.send("I have received your message"); } -}; +} ``` -以下是通过云函数向所有 WebSocket 连接发送消息示例: - -```ts -import cloud from "@lafjs/cloud"; - -exports.main = async function (ctx) { - const sockets: Set = cloud.sockets; - sockets.forEach((socket) => { - socket.send("Everyone will receive this message"); - }); - return "ok"; -}; -``` - -更多用法请参考: https://github.com/websockets/ws +更多用法请参考: ## 客户端 WebSocket 连接 -```js -const wss = new WebSocket("wss://your-own-appid.lafyun.com"); +```typescript +const wss = new WebSocket("wss://your-own-appid.laf.run/__websocket__"); + wss.onopen = (socket) => { console.log("connected"); wss.send("hi"); @@ -65,3 +52,82 @@ wss.onclose = () => { console.log("closed"); }; ``` + +## 连接演示 + +1、替换 `__websocket__` 代码并发布 + +```js +import cloud from '@lafjs/cloud' + +export async function main(ctx: FunctionContext) { + // 初始化 websocket user Map 列表 + // 也可用数据库保存,本示例代码用的 Laf 云函数的全局缓存 + let wsMap = cloud.shared.get("wsMap") // 获取 wsMap + if(!wsMap){ + wsMap = new Map() + cloud.shared.set("wsMap", wsMap) // 设置 wsMap + } + // websocket 连接成功 + if (ctx.method === "WebSocket:connection") { + const userId = generateUserId() + wsMap = cloud.shared.get("wsMap") // 获取 wsMap + wsMap.set(userId, ctx.socket); + cloud.shared.set("wsMap", wsMap) // 设置 wsMap + ctx.socket.send("连接成功,你的 userID 是:"+userId); + } + + // websocket 消息事件 + if (ctx.method === "WebSocket:message") { + const { data } = ctx.params; + console.log("接收到的信息:",data.toString()); + const userId = getKeyByValue(wsMap, ctx.socket); + ctx.socket.send("服务端已接收到消息事件,你的 userID 是:"+userId); + } + + // websocket 关闭消息 + if (ctx.method === "WebSocket:close") { + wsMap = cloud.shared.get("wsMap") // 获取 wsMap + const userId = getKeyByValue(wsMap, ctx.socket); + wsMap.delete(userId); + cloud.shared.set("wsMap", wsMap) // 设置 wsMap + ctx.socket.send("服务端已接收到关闭事件消息,你的 userID 是:"+userId); + } +} +// 生成随机用户 ID +function generateUserId() { + return Math.random().toString(36).substring(2, 15); +} + +// 遍历 userID +function getKeyByValue(map, value) { + for (const [key, val] of map.entries()) { + if (val === value) { + return key; + } + } +} +``` + +2、获得你的 WebSocket 链接 + +一般格式为: + +your-own-appid 换成你的 Laf 应用 appid + +`wss://your-own-appid.laf.run/__websocket__` + +3、客户端链接 WebSocket 链接,并获得 userID + +4、新建云函数通过 userID 去推送消息 + +```js +import cloud from '@lafjs/cloud' + +export async function main(ctx: FunctionContext) { + const userID = '' + let wsMap = cloud.shared.get("wsMap") + ctx.socket = wsMap.get(userID) + ctx.socket.send("消息测试"); +} +``` diff --git a/docs/guide/index.md b/docs/guide/index.md index 814fc50037..a90a8f8374 100644 --- a/docs/guide/index.md +++ b/docs/guide/index.md @@ -33,16 +33,16 @@ title: 介绍 云存储 - - + + 云数据库:数据管理 应用列表 - - + + @@ -77,10 +77,10 @@ title: 介绍 - 你可以不必折腾数据库、对象存储、nginx,随时随地让你的应用上线 - 你可以随手将一段 Node.js 代码上云,比如一段爬虫,一段监控代码,像写博客一样写 Node! -5. 独立开发者、初创创业团队, 节约成本,快速开始,专注业务 +5. 独立开发者、初创创业团队,节约成本,快速开始,专注业务 - 减少启动项目开发的流程,快速启动,缩短产品验证周期 - 极大程度提高迭代速度,随时应对变化,随时发布 - - 专注于产品业务本身,快速推出最小可用产品(MVP),快速进行产品、市场验证 + - 专注于产品业务本身,快速推出最小可用产品 (MVP),快速进行产品、市场验证 - 一个人 + `laf` = 团队 > life is short, you need laf:) @@ -89,10 +89,10 @@ title: 介绍 > `laf` 是应用的后端开发平台,理论上可以做任何应用! -1. 使用 laf 快速开发微信小程序/公众号: 电商、社交、工具、教育、金融、游戏、短视频、社区、企业等应用! +1. 使用 laf 快速开发微信小程序/公众号:电商、社交、工具、教育、金融、游戏、短视频、社区、企业等应用! - - 微信小程序强要求 https 访问,可直接使用 [lafyun.com](http://www.lafyun.com) 创建应用,为小程序提供 https 的接口服务 - - 可将应用的 h5 页面和管理端(admin) 直接部署到可由 `laf` 静态托管 + - 微信小程序强要求 https 访问,可直接使用 [laf.run](https://laf.run) 创建应用,为小程序提供 https 的接口服务 + - 可将应用的 h5 页面和管理端 (admin) 直接部署到可由 `laf` 静态托管 - 将 h5 直接托管到 `laf` 上,将分配的专用域名配置到公众号即可在线访问 - 使用云函数实现微信授权、支付等业务 - 使用云存储存储视频、头像等用户数据 @@ -100,12 +100,12 @@ title: 介绍 2. 开发 Android or iOS 应用 - 使用云函数、云数据库、云存储进行业务处理 - - 应用的后端管理(admin) 直接部署到可由 `laf` 静态托管 + - 应用的后端管理 (admin) 直接部署到可由 `laf` 静态托管 - 可使用云函数实现微信授权、支付、热更新等业务 3. 部署个人博客、企业官网 - - 将 vuepress / hexo / hugo 等静态生成的博客,一键部署到 `laf` 静态托管上, 见 [laf-cli](https://github.com/labring/laf/tree/main/packages/cli) + - 将 vuepress / hexo / hugo 等静态生成的博客,一键部署到 `laf` 静态托管上,见 [laf-cli](https://github.com/labring/laf/tree/main/cli) - 可使用云函数来处理用户留言、评论、访问统计等业务 - 可使用云函数扩展博客的其它能力,如课程、投票、提问等 - 可使用云存储存储视频、图片 @@ -135,5 +135,7 @@ title: 介绍 ## 🏘️ 社群 +- [论坛](https://forum.laf.run/) - [微信群](https://cdn.jsdelivr.net/gh/yangchuansheng/imghosting3@main/uPic/2022-04-22-14-21-MRJH9o.png) - QQ 群:`603059673` +- 官方公众号:`laf-dev` diff --git a/docs/guide/laf-assistant/index.md b/docs/guide/laf-assistant/index.md new file mode 100644 index 0000000000..c8a8c9bd45 --- /dev/null +++ b/docs/guide/laf-assistant/index.md @@ -0,0 +1,65 @@ +--- +title: laf assistant +--- + +# {{ $frontmatter.title }} + +`laf assistant` 为前社区用户 `白夜` 由于兴趣开发。基于 `laf-cli` 封装开发而成。 + +详细介绍可看:[Laf Assistant:云开发从未如此爽快!](https://mp.weixin.qq.com/s/SueTSmWFXDySaRSx3uAPIg) + +## 应用安装 + +`vs Code` 应用中直接搜索 `laf assistant` 或点击链接[在线安装](https://marketplace.visualstudio.com/items?itemName=NightWhite.laf-assistant) + +:::tip +使用`laf assistant`需 node 版本大于等于 16 + +node version >= 16 +::: + +## 初始化 + +在对接到 Laf 云开发的前端项目中新建目录 `laf-cloud` + +在`laf-cloud`上右键点击登录。 + +需要配置 Laf 应用的相关信息,包括 `apiurl`、`pat` 和 `appid` + +- `apiurl` 当前登录的 Laf 网址前面添加 `api`。如:`https://api.laf.dev` + +- `pat` pat 获取方式可查看 [laf-cli 文档](/guide/cli/#登录) + +- `appid` Laf 应用 appid 可查看[Web IDE 介绍](/guide/web-ide/#应用管理) + +:::warning +`laf assistant`默认会自动安装`laf-cli`,如果出现自动安装失败的情况,可以[手动安装 laf-cli](/guide/cli/#安装) +::: + +都填完后,重新在`laf-cloud`上右键点击登录。右下角会提示登录成功。 + +登录成功后,继续在`laf-cloud`上右键点击初始化。即完成初始化工作。 + +:::warning +初始化成功后,会在`laf-cloud`目录中初始化很多文件,请不要随意删除 +::: + +## 同步线上依赖 + +在 Laf 应用安装的依赖,可通过同步线上依赖的方式下载到本地,仅为方便开发时查看代码提示,可不同步,不参与编译或代码运行。如果线上增加了新的依赖,可再执行一次。 + +## 发布/下载全部云函数 + +登录并初始化后,在`laf-cloud`文件夹上右键,发布/下载全部云函数。 + +## 新增云函数 + +在`laf-cloud`文件夹上右键,新增云函数。 + +## 操作单个云函数 + +打开`laf-cloud/functions`,任意打开一个云函数,在编辑框右键即可 `发布/下载/运行` 当前云函数。可在 `vs Code` 设置里自定义快捷键,操作更加方便。 + +## 其他功能 + +其他 `laf-cli` 功能暂未添加,可在终端输入 `laf -h` 查看,也可直接查看 [laf-cli 文档](/guide/cli/) diff --git a/docs/guide/oss/get-sts.md b/docs/guide/oss/get-sts.md index 4861a0fa5b..952f22b7b5 100644 --- a/docs/guide/oss/get-sts.md +++ b/docs/guide/oss/get-sts.md @@ -1,24 +1,30 @@ --- -title: 生成云存储临时令牌(STS) +title: 生成云存储临时令牌 (STS) --- # {{ $frontmatter.title }} -在「开发控制台」-> 「云函数」 -> 「依赖管理」,添加 `@aws-sdk/client-sts` 依赖(需重启应用生效)。 +前端或云函数环境以外的地方需要请求云存储,是需要一个 STS 临时令牌的,下面云函数可以直接请求并获取一个 STS 临时令牌。 + +## 安装依赖 + +安装 `@aws-sdk/client-sts` 依赖(需重启应用生效)。 + +## 创建`get-oss-sts`云函数 创建云函数 `get-oss-sts`,添加如下代码: -```ts +```typescript import cloud from "@lafjs/cloud"; import { STSClient, AssumeRoleCommand } from "@aws-sdk/client-sts"; -exports.main = async function (ctx: FunctionContext) { +export default async function (ctx: FunctionContext) { const sts: any = new STSClient({ - region: cloud.env.OSS_REGION, - endpoint: cloud.env.OSS_INTERNAL_ENDPOINT, + region: process.env.OSS_REGION, + endpoint: process.env.OSS_INTERNAL_ENDPOINT, credentials: { - accessKeyId: cloud.env.OSS_ACCESS_KEY, - secretAccessKey: cloud.env.OSS_ACCESS_SECRET, + accessKeyId: process.env.OSS_ACCESS_KEY, + secretAccessKey: process.env.OSS_ACCESS_SECRET, }, }); @@ -34,14 +40,14 @@ exports.main = async function (ctx: FunctionContext) { return { credentials: res.Credentials, - endpoint: cloud.env.OSS_EXTERNAL_ENDPOINT, - region: cloud.env.OSS_REGION, + endpoint: process.env.OSS_EXTERNAL_ENDPOINT, + region: process.env.OSS_REGION, }; }; ``` > 保存 & 发布云函数,即可访问。 -### 前端使用 STS 令牌访问云存储 +## 前端使用 STS 令牌访问云存储 @see [前端使用 STS 令牌访问云存储](use-sts-in-client.md) diff --git a/docs/guide/oss/index.md b/docs/guide/oss/index.md index f4aa55b4de..5806db2a35 100644 --- a/docs/guide/oss/index.md +++ b/docs/guide/oss/index.md @@ -1,227 +1,40 @@ --- -title: 云存储(OSS)使用介绍 +title: 云存储简介 --- # {{ $frontmatter.title }} -`laf` 云存储是基于 [MinIO](https://min.io/) 提供的对象存储服务,laf 提供了具完全 MinIO 的对象存储服务,开发者也可参考 [MinIO](https://min.io/) 的文档来使用 laf 云存储。 +`laf` 云存储是基于 [MinIO](https://min.io/) 提供的对象存储服务,提供了完全的 MinIO 的对象存储服务,同时也是标准的 s3 接口,我们可以通过 s3 api 来控制云存储中文件的增删改查。 -开发者可自由选择以下 SDK 来操作 laf oss: +## 创建 bucket -- 使用 aws-sdk for javascript 操作云存储示例: https://docs.min.io/docs/how-to-use-aws-sdk-for-javascript-with-minio-server.html -- 使用 minio sdk for javascript 操作云存储示例: https://docs.min.io/docs/javascript-client-quickstart-guide.html +![create-bucket-1](../../doc-images/create-bucket-1.png) -同时, [MinIO 文档](https://docs.min.io/docs/javascript-client-quickstart-guide.html) 还提供了 `Java` `Python` `Golang` 等多种语言的 SDK 。 +step 1.切换到存储页 -在云函数里访问 Laf 云存储 +step 2.点击加号 -Laf 的云存储是标准的 s3 接口,同时 阿里云 腾讯云等的对象存储 都是 s3 api 兼容的,我们可以通过 s3 api 来控制文件的增删改查 +step 3.设置 bucket 名称,名称由`小写字母` `数字` `-` 组成 -我们可以使用 `aws-sdk` 库,实现文件实现增删改查,当然你也可以所以其他库 +step 4.设置读写权限 -操作之前需要在 依赖管理 里添加 `aws-sdk` 库 +step 5.点击确定创建成功 -1. 获取 s3 客户端 +## Web 控制台上传文件 -我们可以通过如下代码来导入 aws-sdk 库 +![upload](../../doc-images/upload.png) -```javascript -const AWS = require("aws-sdk"); -``` +step 1.点击上传按钮 -你可以通过 `AWS.S3` 来创建一个 s3 客户端 +step 2.选择上传文件或者文件夹,文件和文件夹需分别上传 -```javascript -new AWS.S3({ - accessKeyId: cloud.env.OSS_ACCESS_KEY, - secretAccessKey: cloud.env.OSS_ACCESS_SECRET, - endpoint: "https://oss.lafyun.com", - s3ForcePathStyle: true, - signatureVersion: "v4", - region: cloud.env.OSS_REGION, -}); -``` +## Web 控制台获取文件访问地址 -注意: endpoint 是云存储的地址,一定要和 云存储页面里的文件管理页面 上方 `OSS EndPoint` 里的值一样 +点击文件后面的眼睛按钮,如果是开启了可读属性,即已经获取到文件的访问/下载地址。 -2. 上传文件 +如果是开启了不可读属性,点击眼睛按钮会获得临时访问链接。 -```javascript -const s3 = getS3Client(); // 获取s3客户端 可参考上面的 +## Web 控制台删除文件 -const res = s3 - .putObject({ - Bucket: bucket, - Key: key, - ContentType: contentType, - Body: body, - }) - .promise(); -``` +点击文件垃圾桶符号,即可删除文件,但是目前在 Web 控制台无法批量删除文件。 -- Bucket 文件桶的名字 格式是:`${appid}-${bucketName}` -- Key 文件存储路径 - - 如果传入的路径不存在,会自动创建 - - 如果传入的文件存在,会自动覆盖源文件 -- ContentType 上传文件的 `mimetype` -- Body 文件对象 - -3. 获取上传文件访问 Url - -```javascript -const s3 = getS3Client(); // 获取s3客户端 可参考上面的 - -const res = s3.getSignedUrl("getObject", { - Bucket: bucket, - Key: key, -}); -``` - -- Bucket 文件桶的名字 格式是:`${appid}-${bucketName}` -- Key 要获取 url 的文件的路径 - -会直接返回要获取路径的文件的 url - -4. 删除文件 - -```javascript -const s3 = getS3Client(); // 获取s3客户端 可参考上面的 - -const res = await s3 - .deleteObject({ - Bucket: bucket, - Key: key, - }) - .promise(); -``` - -- Bucket 文件桶的名字 格式是:`${appid}-${bucketName}` -- Key 要删除的文件的路径 - -一些小小的案例 - -1. 把上传的文件存到云存储里 - -在 Laf 中 上传的文件可以在 `ctx.files` 里找到 - -我们可以通过 `ctx.files[0].path` 来获取上传的第一个文件的 临时路径 - -我们可以使用 nodejs 自带的 `fs`库 来获取文件对象 - -```javascript -var fs = require("fs"); -var data = await fs.readFileSync(ctx.files[0].path); -``` - -- data 里面就是文件对象 - -通过 `ctx.files[0].mimetype` 可以获取上传文件的 mimetype - -组合一下: - -```javascript -import cloud from "@lafjs/cloud"; -const AWS = require("aws-sdk"); -var fs = require("fs"); - -//获取s3客户端 -function getS3Client() { - return new AWS.S3({ - accessKeyId: cloud.env.OSS_ACCESS_KEY, - secretAccessKey: cloud.env.OSS_ACCESS_SECRET, - endpoint: "https://oss.lafyun.com", - s3ForcePathStyle: true, - signatureVersion: "v4", - region: cloud.env.OSS_REGION, - }); -} - -//拼接文件桶名字 -function getInternalBucketName(bucketName) { - const appid = cloud.env.APP_ID; - return `${appid}-${bucketName}`; -} - -//上传文件 -function uploadAppFile(bucketName, key, body, contentType) { - const s3 = getS3Client(); - const bucket = getInternalBucketName(bucketName); - - const res = s3 - .putObject({ - Bucket: bucket, - Key: key, - ContentType: contentType, - Body: body, - }) - .promise(); - return res; -} - -//获取文件url -export function getAppFileUrl(bucketName, key) { - const s3 = getS3Client(); - const bucket = getInternalBucketName(bucketName); - - const res = s3.getSignedUrl("getObject", { Bucket: bucket, Key: key }); - return res; -} - -exports.main = async function (ctx: FunctionContext) { - //获取上传文件的对象 - var data = await fs.readFileSync(ctx.files[0].path); - - const res = await uploadAppFile( - "test", - "image/test.jpg", - data, - ctx.files[0].mimetype - ); - const fileUrl = await getAppFileUrl("test", "image/test.jpg"); - - return fileUrl; -}; -``` - -2. 删除刚才上传的文件 - -```javascript -import cloud from "@lafjs/cloud"; -const AWS = require("aws-sdk"); - -//获取s3客户端 -function getS3Client() { - return new AWS.S3({ - accessKeyId: cloud.env.OSS_ACCESS_KEY, - secretAccessKey: cloud.env.OSS_ACCESS_SECRET, - // sessionToken: credentials.sessionToken, - endpoint: "https://oss.lafyun.com", - s3ForcePathStyle: true, - signatureVersion: "v4", - region: cloud.env.OSS_REGION, - }); -} - -//拼接文件桶名字 -function getInternalBucketName(bucketName) { - const appid = cloud.env.APP_ID; - return `${appid}-${bucketName}`; -} - -//删除文件 -export async function deleteAppFile(bucketName, key) { - const s3 = getS3Client(); - const bucket = getInternalBucketName(bucketName); - - const res = await s3.deleteObject({ Bucket: bucket, Key: key }).promise(); - return res; -} - -exports.main = async function (ctx: FunctionContext) { - const res = await deleteAppFile("test", "image/test.jpg"); - - return {}; -}; -``` - -参考资料 https://github.com/labring/laf/blob/v0.8/packages/app-console/src/api/oss.js diff --git a/docs/guide/oss/oss-by-function.md b/docs/guide/oss/oss-by-function.md new file mode 100644 index 0000000000..599fcba28a --- /dev/null +++ b/docs/guide/oss/oss-by-function.md @@ -0,0 +1,352 @@ +--- +title: 云存储操作云存储 +--- + +# {{ $frontmatter.title }} + +以下是用 S3 客户端来操作数据库,也有其他的操作方式,这里主要写 S3 客户端的常见的几个操作命令。更多命令可以参考:[`@aws-sdk/client-s3`官方文档](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/index.html) + +:::tip +S3 客户端依赖 `@aws-sdk/client-s3` 已默认安装,无需重新安装 +::: + +## 初始化 S3 客户端 + +```typescript +import { S3 } from "@aws-sdk/client-s3"; +const s3Client = new S3({ + endpoint: process.env.OSS_EXTERNAL_ENDPOINT, + region: process.env.OSS_REGION, + credentials: { + accessKeyId: process.env.OSS_ACCESS_KEY, + secretAccessKey: process.env.OSS_ACCESS_SECRET + }, + forcePathStyle: true, +}) +``` + +## 上传文件 + +:::tip +如果上传文件已存在会自动覆盖之前的文件 +::: + +```typescript +await s3Client.putObject({ + Bucket: bucket, + Key: path, + Body: content, + ContentType: contentType +}); +``` + +- Bucket 文件桶的名字 格式是:`${appid}-${bucketName}` +- Key 上传文件在 S3 存储桶中的唯一标识符 + - 文件路径和名称:比如 `avatars/user1.png` + - 文件夹名称 (以 / 结尾):比如 `avatars/` 用于创建文件夹 + - 相对路径:比如 `avatars/2021/01/` + - 绝对路径:比如 `/avatars/2021/01/user1.png` +- Body 文件对象 + - Blob:原生文件对象,比如从 input 文件选择控件选择的文件 + - Buffer:Node.js 的二进制数据对象 + - String:文本文件内容 + - ReadableStream:文件流,用于上传大文件 +- ContentType(MIME 类型) + - image/png:PNG 图片 + - image/jpeg:JPEG 图片 + - application/json:JSON 文件 + - text/plain:TXT 文本文件 + - application/octet-stream:二进制流文件 + - 等等 + +## 删除云存储对象 + +可删除云存储文件或者文件夹 + +```typescript +await s3Client.deleteObject({ + Bucket: bucket, + Key: path +}) +``` + +- Bucket 文件桶的名字 格式是:`${appid}-${bucketName}` +- Key 删除文件在 S3 存储桶中的唯一标识符 + - 文件路径和名称:比如 `avatars/user1.png` + - 文件夹名称 (以 / 结尾):比如 `avatars/` 用于删除文件夹 + - 相对路径:比如 `avatars/2021/01/` + - 绝对路径:比如 `/avatars/2021/01/user1.png` + +## 生成文件预签名链接 + +用来生成没有读权限的文件的临时访问链接 + +```typescript +import { S3 , GetObjectCommand } from "@aws-sdk/client-s3"; // 加入 GetObjectCommand 的引入 +import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; // 云函数顶部引入 + +const url = await getSignedUrl(s3Client, new GetObjectCommand({ + Bucket: bucket, + Key: path, +}), +{ + expiresIn: expiresSeconds +}); +``` + +- Bucket 文件桶的名字 格式是:`${appid}-${bucketName}` +- Key 分享文件在 S3 存储桶中的唯一标识符 + - 文件路径和名称:比如 `avatars/user1.png` + - 绝对路径:比如 `/avatars/2021/01/user1.png` +- expiresIn 访问过期时间,超过时间将无法访问 + +## 列出云存储 bucket 中的文件对象 + +```typescript +await s3Client.listObjectsV2({ + Bucket: bucket, + MaxKeys: size, + Prefix: prefix, + StartAfter: startAfter +}) +``` + +- Bucket 文件桶的名字 格式是:`${appid}-${bucketName}` +- Delimiter: 可选。一个分隔符,listObjectsV2 将不会返回 Delimiter 之后的对象键。用于跳过文件夹中的对象。 +- EncodingType: 可选。指定响应应返回的对象键的编码方法。可以是 url。 +- FetchOwner: 可选。如果为 true,响应将包含 Owner 信息。默认 false。 +- MaxKeys: 可选。要返回的最大对象数量。默认为 1000。如果有更多结果,响应将被截断。 +- NextContinuationToken: 可选。用于获取列表操作结果的下一页。从前一个 listObjectsV2 调用中获取。 +- Prefix: 可选。用于过滤对象键的前缀。只返回与此前缀匹配的键。一般用来获取文件夹中的文件列表。 +- StartAfter: 可选。列出的对象键应开始于的起点。用于实现更高效的分页。 + +例如,要列出 bucket 中前缀为 "photos/" 的所有对象,每页 100 个: + +```typescript +let response = await s3Client.listObjectsV2({ + Bucket: 'bucket-name', + Prefix: 'photos/', + MaxKeys: 100 +}); +``` + +例如,要实现存储桶文件对象的分页查询 + +假设您的存储桶有 100,000 个对象,MaxKeys 为 1000 + +分页方法 1: + +```typescript +const pageSize = 2 +let response = await s3Client.listObjectsV2({ + Bucket: 'bucket-name', + MaxKeys: pageSize, + Delimiter: '/' // 只显示根级别对象并跳过所有子文件夹,您可以将 Delimiter 设置为 / +}); +console.log(response) +// IsTruncated 为 true 则代表还有下一页 +if (response.IsTruncated) { + // 获取下一页需要使用最后一个对象的 Key 作为 StartAfter: + const array = response.Contents + const lastObject = array[array.length - 1] + const lastKey = lastObject.Key + let response2 = await s3Client.listObjectsV2({ + Bucket: 'bucket-name', + MaxKeys: pageSize, + StartAfter: lastKey + }); + console.log(response2) +} +``` + +分页方法 2: + +```typescript +const pageSize = 2 +let response = await s3Client.listObjectsV2({ + Bucket: 'bucket-name', + MaxKeys: pageSize +}); +console.log(response) +// IsTruncated 为 true 则代表还有下一页 +if (response.IsTruncated) { + // 获取下一页将当前的 NextContinuationToken 传给下一次查询的 ContinuationToken: + const nextToken = response.NextContinuationToken; + let response2 = await s3Client.listObjectsV2({ + Bucket: 'bucket-name', + MaxKeys: pageSize, + ContinuationToken: nextToken, + }); + console.log(response2) +} +``` + +## 前端通过云函数上传文件存云存储 + +### 前端上传文件到云函数 + +以微信小程序为例 + +```js +// 微信聊天回话选择文件 +wx.chooseMessageFile({ + count: 1, + type: 'all', + success(res) { + // 选择的文件临时路径 + const tempFilePaths = res.tempFiles[0].path + wx.uploadFile({ + url: '云函数地址', + filePath: tempFilePaths, + name: 'file', + success(res) { + console.log(res.data) + } + }) + } +}) +``` + +### 云函数接收文件的参数 + +前端上传的文件在云函数的`ctx.files` 里可以找到 + +在 Laf 中 上传的文件可以在 `ctx.files` 里找到,以下是云函数接收到文件后`ctx.files`的打印结果范例。 + +```javascript +console.log(ctx.files) +// 输出结果 +// [ +// { +// fieldname: 'file', +// originalname: 'WWcBsfDKw45X965dd934f04a7b0a405467b91800d7ce.jpg', +// encoding: '7bit', +// mimetype: 'image/jpeg', +// destination: '/tmp', +// filename: 'e6feb0a3-85d7-4fe3-b9ae-78701146acd8.jpg', +// path: '/tmp/e6feb0a3-85d7-4fe3-b9ae-78701146acd8.jpg', +// size: 219043 +// } +// ] +``` + +可以通过 `ctx.files[0].path` 来获取上传文件的临时路径 + +还可以使用 nodejs 自带的 `fs`库 来获取文件对象 + +```javascript +var fs = require("fs"); +var data = await fs.readFileSync(ctx.files[0].path); +``` + +- data 里面就是文件对象 + +通过 `ctx.files[0].mimetype` 可以获取上传文件的 mimetype + +### 新建云函数上传文件云函数 + +如:`uploadFile`,代码如下: + +```typescript +import cloud from "@lafjs/cloud"; +import { GetObjectCommand, S3 } from "@aws-sdk/client-s3"; +import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; +const s3Client = new S3({ + endpoint: process.env.OSS_EXTERNAL_ENDPOINT, + region: process.env.OSS_REGION, + credentials: { + accessKeyId: process.env.OSS_ACCESS_KEY, + secretAccessKey: process.env.OSS_ACCESS_SECRET + }, + forcePathStyle: true, +}) +var fs = require("fs"); +const bucketName = 'bucketName' // 不带 Laf 应用 appid + +//拼接文件桶名字 +function getInternalBucketName() { + const appid = process.env.APP_ID; + return `${appid}-${bucketName}`; +} + +//上传文件 +async function uploadAppFile(key, body, contentType) { + const bucket = getInternalBucketName(); + const res = await s3Client + .putObject({ + Bucket: bucket, + Key: key, + ContentType: contentType, + Body: body, + }) + return res; +} + +//获取文件 url +async function getAppFileUrl(key) { + const bucket = getInternalBucketName(); + const res = await getSignedUrl(s3Client, new GetObjectCommand({ + Bucket: bucket, + Key: key, + })); + return res; +} + +export default async function (ctx: FunctionContext) { + //获取上传文件的对象 + var data = await fs.readFileSync(ctx.files[0].path); + const res = await uploadAppFile( + ctx.files[0].filename, + data, + ctx.files[0].mimetype + ); + const fileUrl = await getAppFileUrl(ctx.files[0].filename); + return fileUrl; +}; +``` + +### 测试上传 + +1.发布云函数,并将该云函数的 URL 修改至前端云函数请求地址 + +2.前端选择文件并上传,控制台打印云存储返回的 Url,即成功 + +### 删除刚刚上传的文件 + +重新新建一个云函数,如命名为 `deleteFile` + +```typescript +import cloud from "@lafjs/cloud"; +import { S3 } from "@aws-sdk/client-s3"; +const s3Client = new S3({ + endpoint: process.env.OSS_EXTERNAL_ENDPOINT, + region: process.env.OSS_REGION, + credentials: { + accessKeyId: process.env.OSS_ACCESS_KEY, + secretAccessKey: process.env.OSS_ACCESS_SECRET + }, + forcePathStyle: true, +}) +const bucketName = 'bucketName' // 不带 Laf 应用 appid + +//拼接文件桶名字 +function getInternalBucketName() { + const appid = process.env.APP_ID; + return `${appid}-${bucketName}`; +} + +export default async function (ctx: FunctionContext) { + const key = "" // 这里填刚刚上传的文件名,可在云存储 Web 标签页中查看 + const bucket = getInternalBucketName() + await s3Client.deleteObject({ + Bucket: bucket, + Key: key + }) +} +``` + +- Key 文件存储路径 + - 如果传入的路径不存在,会自动创建 + - 如果传入的文件存在,会自动覆盖源文件 +- ContentType 上传文件的 `mimetype` 类型 +- Body 文件对象 diff --git a/docs/guide/oss/upload-by-function.md b/docs/guide/oss/upload-by-function.md new file mode 100644 index 0000000000..87f3de720a --- /dev/null +++ b/docs/guide/oss/upload-by-function.md @@ -0,0 +1,167 @@ +--- +title: 前端通过云函数上传文件 +--- + +# {{ $frontmatter.title }} + +## 前端上传文件到云函数 + +以微信小程序为例 + +```js +// 微信聊天回话选择文件 +wx.chooseMessageFile({ + count: 1, + type: 'all', + success(res) { + // 选择的文件临时路径 + const tempFilePaths = res.tempFiles[0].path + wx.uploadFile({ + url: '云函数地址', + filePath: tempFilePaths, + name: 'file', + success(res) { + console.log(res.data) + } + }) + } +}) +``` + +## 云函数接收文件的参数 + +前端上传的文件在云函数的`ctx.files` 里可以找到 + +在 Laf 中 上传的文件可以在 `ctx.files` 里找到,以下是云函数接收到文件后`ctx.files`的打印结果范例。 + +```javascript +console.log(ctx.files) +// 输出结果 +// [ +// { +// fieldname: 'file', +// originalname: 'WWcBsfDKw45X965dd934f04a7b0a405467b91800d7ce.jpg', +// encoding: '7bit', +// mimetype: 'image/jpeg', +// destination: '/tmp', +// filename: 'e6feb0a3-85d7-4fe3-b9ae-78701146acd8.jpg', +// path: '/tmp/e6feb0a3-85d7-4fe3-b9ae-78701146acd8.jpg', +// size: 219043 +// } +// ] +``` + +可以通过 `ctx.files[0].path` 来获取上传文件的临时路径 + +还可以使用 nodejs 自带的 `fs`库 来获取文件对象 + +```javascript +var fs = require("fs"); +var data = await fs.readFileSync(ctx.files[0].path); +``` + +- data 里面就是文件对象 + +通过 `ctx.files[0].mimetype` 可以获取上传文件的 mimetype + +## 新建云函数上传文件云函数 + +如:`uploadFile`,代码如下: + +```typescript +import cloud from "@lafjs/cloud"; +import { GetObjectCommand, S3 } from "@aws-sdk/client-s3"; +import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; +const s3Client = new S3({ + endpoint: process.env.OSS_EXTERNAL_ENDPOINT, + region: process.env.OSS_REGION, + credentials: { + accessKeyId: process.env.OSS_ACCESS_KEY, + secretAccessKey: process.env.OSS_ACCESS_SECRET + }, + forcePathStyle: true, +}) +var fs = require("fs"); +const bucketName = 'bucketName' // 不带 Laf 应用 appid + +//拼接文件桶名字 +function getInternalBucketName() { + const appid = process.env.APP_ID; + return `${appid}-${bucketName}`; +} + +//上传文件 +async function uploadAppFile(key, body, contentType) { + const bucket = getInternalBucketName(); + const res = await s3Client + .putObject({ + Bucket: bucket, + Key: key, + ContentType: contentType, + Body: body, + }) + return res; +} + +//获取文件 url +async function getAppFileUrl(key) { + const bucket = getInternalBucketName(); + const res = await getSignedUrl(s3Client, new GetObjectCommand({ + Bucket: bucket, + Key: key, + })); + return res; +} + +export default async function (ctx: FunctionContext) { + //获取上传文件的对象 + var data = await fs.readFileSync(ctx.files[0].path); + const res = await uploadAppFile( + ctx.files[0].filename, + data, + ctx.files[0].mimetype + ); + const fileUrl = await getAppFileUrl(ctx.files[0].filename); + return fileUrl; +}; +``` + +## 测试上传 + +1.发布云函数,并将该云函数的 URL 修改至前端云函数请求地址 + +2.前端选择文件并上传,控制台打印云存储返回的 Url,即成功 + +## 删除刚刚上传的文件 + +重新新建一个云函数,如命名为 `deleteFile` + +```typescript +import cloud from "@lafjs/cloud"; +import { S3 } from "@aws-sdk/client-s3"; +const s3Client = new S3({ + endpoint: process.env.OSS_EXTERNAL_ENDPOINT, + region: process.env.OSS_REGION, + credentials: { + accessKeyId: process.env.OSS_ACCESS_KEY, + secretAccessKey: process.env.OSS_ACCESS_SECRET + }, + forcePathStyle: true, +}) +const bucketName = 'bucketName' // 不带 Laf 应用 appid + +//拼接文件桶名字 +function getInternalBucketName() { + const appid = process.env.APP_ID; + return `${appid}-${bucketName}`; +} + +export default async function (ctx: FunctionContext) { + const key = "" // 这里填刚刚上传的文件名,可在云存储 Web 标签页中查看 + const bucket = getInternalBucketName() + await s3Client.deleteObject({ + Bucket: bucket, + Key: key + }) +} +``` diff --git a/docs/guide/oss/use-sts-in-client.md b/docs/guide/oss/use-sts-in-client.md index fd4ca89f54..b3143931f7 100644 --- a/docs/guide/oss/use-sts-in-client.md +++ b/docs/guide/oss/use-sts-in-client.md @@ -4,34 +4,31 @@ title: 前端使用 STS 令牌访问云存储 # {{ $frontmatter.title }} -在前端使用 [使用云函数生成云存储临时令牌(STS)](get-sts.md) 生成的 STS 令牌信息,访问云存储。 +在前端使用 [使用云函数生成云存储临时令牌 (STS)](get-sts.md) 生成的 STS 令牌信息,访问云存储。本方法需要先把文件上传至云函数,再由云函数上传到云存储,而是直接上传文件到云存储。 -1. 安装前端依赖 +1.安装前端依赖 ```bash npm i @aws-sdk/client-s3 laf-client-sdk ``` -2. 编写前端代码实现文件上传: +2.编写前端代码实现文件上传: -```ts +```typescript import { S3, PutObjectCommand } from "@aws-sdk/client-s3"; import { Cloud } from "laf-client-sdk"; -const APPID = "YOUR_APPID"; +const APPID = "YOUR_APPID"; // Laf 应用 appid const cloud = new Cloud({ - baseUrl: `https://${appid}.lafyun.com`, + baseUrl: `https://${appid}.laf.run`, getAccessToken: () => localStorage.getItem("access_token"), }); // 获取云存储临时令牌 -const { credentials, endpoint, region } = await cloud.invokeFunction( - "get-sts", - {} -); +const { credentials, endpoint, region } = await cloud.invoke("get-sts"); -const s3 = new S3({ +const s3Client = new S3({ endpoint: endpoint, region: region, credentials: { @@ -48,14 +45,16 @@ const bucket = `${APPID}-public`; const cmd = new PutObjectCommand({ Bucket: bucket, Key: "index.html", - Body: "Hello from laf oss!", // 文件内容可以是二进制数据,也可以是文本数据, 或者是 File 对象 + Body: "Hello from laf oss!", // 文件内容可以是二进制数据,也可以是文本数据,或者是 File 对象 ContentType: "text/html", }); -const res = await s3.send(cmd); +const res = await s3Client.send(cmd); console.log(res); ``` -::: info -这里我们使用 `@aws-sdk/client-s3` 库,实现文件上传,你可以使用任何兼容 aws s3 接口的 SDK 来替代,如 [minio js sdk](https://docs.min.io/docs/javascript-client-quickstart-guide.html) +::: tip +这里我们使用 `@aws-sdk/client-s3` 库,实现文件上传,其他命令使用方法同[云函数调用云存储](/guide/oss/oss-by-function) + +你可以使用任何兼容 aws s3 接口的 SDK 来替代,如 [minio js sdk](https://docs.min.io/docs/javascript-client-quickstart-guide.html) ::: diff --git a/docs/guide/quick-start/Todo.md b/docs/guide/quick-start/Todo.md new file mode 100644 index 0000000000..5584e99f7e --- /dev/null +++ b/docs/guide/quick-start/Todo.md @@ -0,0 +1,171 @@ +--- +title: 快速开始 +--- + +# {{ $frontmatter.title }} + +我们将在 [laf.run](https://laf.run) 上,通过开发一个简单的「Todo」的功能,快速体验 `laf` 云开发。 + +![todo-demo](../../doc-images/todo-demo.png) + +## 准备工作 + +1. 你需要在 [laf.run](https://laf.run) 上注册一个账户。 +2. 登录到 [laf.run](https://laf.run),点击 `新建` 按钮,创建一个空应用。 +3. 待应用成功启动后,点击右侧「开发」按钮,进入应用的「开发控制台」,接下来,我们将在「开发控制台」进行第一个 `laf` 应用的功能开发。 + +## 编写云函数 + +首先需要创建一个云函数。 + +![create-function](../../doc-images/create-function.png) + +然后在`get-list`云函数中写上以下代码,写完以后记得在右上角找到`发布`两个字,点一下发布。 + +```typescript +import cloud from '@lafjs/cloud' + +const db = cloud.database() +export async function main(ctx: FunctionContext) { + // 从 list 集合中查询数据 + const res = await db.collection('list').get() + // 返回给前端 + return res +} +``` + +按照刚刚的方式我们再创建 `add-todo` `del-todo` `update-todo`,三个云函数,并分别写入代码。 + +`add-todo` + +```typescript +import cloud from '@lafjs/cloud' + +const db = cloud.database() +export async function main(ctx: FunctionContext) { + // ctx.body 是前端传入的参数 + const data = ctx.body + const res = await db.collection('list').add(data) + + return res +} +``` + +`del-todo` + +```typescript +import cloud from '@lafjs/cloud' + +const db = cloud.database() +export async function main(ctx: FunctionContext) { + + const { id } = ctx.body + // 根据 id 删除数据 + const res = db.collection("list").where({ _id: id }).remove() + + return res +} +``` + +`update-todo` + +```typescript +import cloud from '@lafjs/cloud' + +const db = cloud.database() +export async function main(ctx: FunctionContext) { + + const { id, data } = ctx.body + // _id 是唯一主键,不能修改,所以我们这里删掉 + delete data._id + // 根据 id 来修改数据 + const res = await db.collection('list').where({ _id: id }).update(data) + + return res +} + +``` + +:::tip +再次提醒,更改过的每一个云函数都需要`发布`才能生效哦! +::: + +## 创建集合 + +这里的集合,对应着传统数据库的表,用来存储数据。 + +![create-gather](../../doc-images/create-gather.png) + +## 前端 + +前端这里我们用的是 Vue 项目来演示,React/Angular/小程序,操作都是相同的。 +首先需要在前端项目中安装 `laf-client-sdk`。 + +```shell +npm install laf-client-sdk +``` + +还记得刚创建完项目的页面吗,我们需要回到那里找到我们需要用到的``。 + +![AppID](../../doc-images/AppID.png) + +引入并创建 cloud 对象,这里需要注意的是``需要换成自己的。 + +```js +import { Cloud } from "laf-client-sdk"; // 引入 + +// 创建 cloud 对象 +const cloud = new Cloud({ + baseUrl: "https://.laf.run", // 这里的 需要换成自己的 AppID + getAccessToken: () => '', // 这里先为空 +}); +``` + +然后我们在前端需要的地方调用我们的云函数。 + +```js +async function getList() { + // 调用 get-list 云函数不传参 + const res = await cloud.invoke("get-list"); + list.value = res.data; +} + +async function submit() { + if (!newTodo.value) return; + + const obj = { + name: newTodo.value, + complete: false, + }; + // 调用 add-todo 传入参数 obj + await cloud.invoke("add-todo", obj); + newTodo.value = ""; + + getList(); +} + + +async function complete(index, id) { + list.value[index].complete = !list.value[index].complete; + // 调用 update-todo 传入参数 + await cloud.invoke("update-todo", { + id, + data: list.value[index], + }); +} + + +async function del(id) { + // 调用 del-todo 传入参数 + await cloud.invoke("del-todo", { id }); + getList(); +} +``` + +到这里我们已经完成了项目的核心功能,你也可以下载代码模板来体验。 + +:::tip +需要在 src/App.vue 中修改 `` +::: + +模板地址: diff --git a/docs/guide/quick-start/index.md b/docs/guide/quick-start/login.md similarity index 62% rename from docs/guide/quick-start/index.md rename to docs/guide/quick-start/login.md index d297c729dc..0f363d2ff9 100644 --- a/docs/guide/quick-start/index.md +++ b/docs/guide/quick-start/login.md @@ -4,34 +4,34 @@ title: 快速开始 # {{ $frontmatter.title }} -我们将在 [lafyun.com](https://www.lafyun.com) 上,通过开发一个简单的「用户登录/注册」的功能,快速体验 `laf` 云开发。 +我们将在 [laf.run](https://laf.run) 上,通过开发一个简单的「用户登录/注册」的功能,快速体验 `laf` 云开发。 下面代码对于初学者来说可能难以理解,不过可以先体验一下云函数,后面再详细了解云函数的具体内容。 ## 准备工作 -1. 你需要在 [lafyun.com](https://console.lafyun.com) 上注册一个账户 -2. 登录到 [lafyun.com 控制台](https://console.lafyun.com),点击左上角的 `新建` 按钮,创建一个空应用 -3. 待应用成功启动后,点击右侧 「开发」 按钮,进入应用的「开发控制台」,接下来,我们将在「开发控制台」 进行第一个 `laf` 应用的功能开发 +1. 你需要在 [laf.run](https://laf.run) 上注册一个账户 +2. 登录到 [laf.run 控制台](https://laf.run),点击左上角的 `新建` 按钮,创建一个空应用 +3. 待应用成功启动后,点击右侧「开发」按钮,进入应用的「开发控制台」,接下来,我们将在「开发控制台」进行第一个 `laf` 应用的功能开发 ## 编写云函数 -本教程会编写两个云函数: +本教程会编写两个云函数: - `register` 处理注册请求 -- `login` 处理登录请求. +- `login` 处理登录请求。 ### 用户注册云函数 -在「云函数」管理页面,点击 「新建函数」,创建注册云函数 `register`, +在「云函数」管理页面,点击「新建函数」,创建注册云函数 `register`, -点击 `register` 函数右侧的 「开发」按钮,进入 WebIDE,编写以下代码: +点击 `register` 函数,进入 WebIDE,编写以下代码: -```ts +```typescript import cloud from "@lafjs/cloud"; import { createHash } from "crypto"; -exports.main = async function (ctx: FunctionContext) { +export default async function (ctx: FunctionContext) { const username = ctx.body?.username || ""; const password = ctx.body?.password || ""; @@ -60,17 +60,17 @@ exports.main = async function (ctx: FunctionContext) { }; ``` -点击右上角的 「显示调试面板」(Ctrl/Cmd + B) 即可调试运行,点击 「保存」 & 「发布」 函数即发布上线! +点击右上角的「发布」函数即发布上线! ### 用户登录云函数 同上,创建 `login` 云函数,编写以下代码: -```ts +```typescript import cloud from "@lafjs/cloud"; import { createHash } from "crypto"; -exports.main = async function (ctx: FunctionContext) { +export default async function (ctx: FunctionContext) { const username = ctx.body?.username || ""; const password = ctx.body?.password || ""; @@ -102,24 +102,24 @@ exports.main = async function (ctx: FunctionContext) { }; ``` -点击右上角的 「显示调试面板」(Ctrl/Cmd + B) 即可调试运行,点击 「保存」 & 「发布」 函数即发布上线! +点击右上角的「发布」函数即发布上线! ## 使用 curl 调用云函数 -你可以通过云函数列表页面,查看 & 复制云函数的调用地址, +你可以在右上方复制云函数的调用地址, 或将以下 curl 命令中的 `APPID` 替换成你的 APPID 后执行: ```bash # 注册用户 -curl -X POST -H "Content-Type: application/json" -d '{"username": "admin", "password": "admin"}' https://APPID.lafyun.com/register +curl -X POST -H "Content-Type: application/json" -d '{"username": "admin", "password": "admin"}' https://APPID.laf.run/register # 用户登录 -curl -X POST -H "Content-Type: application/json" -d '{"username": "admin", "password": "admin"}' https://APPID.lafyun.com/login +curl -X POST -H "Content-Type: application/json" -d '{"username": "admin", "password": "admin"}' https://APPID.laf.run/login ``` -## 在前端项目中使用云函数 +## 在前端项目中用 SDK 调用云函数 在你的前端项目中安装 laf client sdk: @@ -129,17 +129,17 @@ npm install laf-client-sdk 然后填写下面的代码: -```ts +```typescript // user.ts import { Cloud } from "laf-client-sdk"; const cloud = new Cloud({ - baseUrl: "https://APPID.lafyun.com", + baseUrl: "https://APPID.laf.run", getAccessToken: () => localStorage.getItem("access_token"), }); -// regiser function +// register function export async function register(username: string, password: string) { const res = await cloud.invoke("register", { username: username, @@ -165,4 +165,38 @@ export async function login(username: string, password: string) { } ``` +## 在前端项目中用 HTTP 请求调用云函数 + +```js +import axios from 'axios' + +const url = 'https://APPID.laf.run' + +// register +async function register(username, password) { + try { + const response = await axios.post(url + "register", { + username: username, + password: password + }); + console.log(response); + } catch (error) { + console.error(error); + } +} + +// login +async function register(username, password) { + try { + const response = await axios.post(url + "login", { + username: username, + password: password + }); + console.log(response); + } catch (error) { + console.error(error); + } +} +``` + 最后,可以在你的 Vue/React/Angular/小程序 页面中调用这两个云函数完成具体的登录注册功能! diff --git a/docs/guide/web-ide/index.md b/docs/guide/web-ide/index.md new file mode 100644 index 0000000000..7a09f43814 --- /dev/null +++ b/docs/guide/web-ide/index.md @@ -0,0 +1,77 @@ +--- +title: Web IDE +--- + +# {{ $frontmatter.title }} + +Laf 为开发者提供了非常好用的 Web IDE,在线写代码,完善的类型提示、代码自动完成,像写博客一样写函数,随手发布上线! + +## 账号注册 + +服务器可用区 + +- 国内服务器: [laf.run](https://laf.run) + +- 新加坡服务器:[laf.dev](https://laf.dev) + +::: tip +laf.run 为备案域名,laf.dev 为未备案域名。 + +laf.dev 可直连 OpenAI API,请按照实际业务需求选择服务器 + +国内服务器和新加坡服务器数据互相独立哦~ +::: + +![index](../../doc-images/index.png) + +点击首页「立即体验」按钮 + +![register](../../doc-images/register.png) + +输入手机号即可注册和登录 + +::: tip +如果想使用密码登录,可在注册成功后,找回密码来设置新的密码哦~ +::: + +## 新建应用 + +![create-laf-app](../../doc-images/create-laf-app.jpg) + +登录账号后,会进入 Laf Web IDE 控制台 + +在这里可以新建应用,以及管理应用 + +![specification](../../doc-images/specification.jpg) + +选择不同的应用规格,然后创建 Laf 应用 + +::: tip +每个账号只能新建一个免费应用,请注意,免费应用会不定期停止实例,需要手动重启。 + +免费应用需每个月续费才可以继续使用! + +免费应用性能较低,如需正式商用请开通付费规格。 +::: + +## 应用管理 + +Laf 应用列表会显示应用名称、应用 App ID、应用运行状态、应用所在服务器、到期时间、以及开发代码和应用操作等 + +![app-list](../../doc-images/app-list.png) + +## 应用开发 + +在应用列表点击「开发」按钮即可进入 Laf 应用开发 IDE + +![web-ide-index](../../doc-images/web-ide-index.png) + +Web IDE 分为 3 个部分 + + ① 侧边栏:分别是云函数、集合(数据库管理)、存储、日志、用户设置、应用设置 + + ② 中间区:在切换不同的功能后,显示的内容不同。如图为云函数的函数列表、代码编辑器、调试和文档、NPM 依赖管理、Console(调试日志)、运行结果(调试结果) + + ③ 状态栏:应用状态栏,显示当前应用的名称、运行状态、到期时间 + +Laf 的 Web IDE 相当简洁,可以在线编辑云函数,操作数据库,以及管理云存储。随时随地可用浏览器去编辑和发布代码。 diff --git a/docs/guide/website-hosting/index.md b/docs/guide/website-hosting/index.md index 59889c6f8a..46bd3336d3 100644 --- a/docs/guide/website-hosting/index.md +++ b/docs/guide/website-hosting/index.md @@ -12,7 +12,124 @@ title: 静态网站托管介绍 静态托管会为你的网站自动提一个独立的域名,也可以绑定自定义域名。 -## 场景 +## 如何使用? -- 将基于 vuepress/hexo 等工具生成的静态博客一键上传上线 -- 将 Vue.js / React.js 等前端项目一键托管上传上线 +- 将开发好的项目打包。 +- 创建一个 bucket,将打包后的项目丢进去。 +- 点击开托管,上线成功! + +## 绑定自有域名 + +Laf 静态网站托管支持绑定自己的域名,并自动生成 `SSL` 证书,兼容 `https` 和 `http` 访问 + +@see [绑定自有域名步骤](#上线成功) + +## 演示 + +### 创建 bucket + +![create-bucket](../../doc-images/create-bucket.png) + +### 上传文件,开启网站托管 + +上传前端项目编译后的文件到刚刚新建的云存储中。 + +::: tip +大部分前端项目编译完的代码都在 `dist` 文件夹中,直接上传 `dist` 文件夹,即可将文件夹中全部文件上传到云存储中 +::: + +![open-website](../../doc-images/open-website.png) + +### 上线成功 + +这样我们就上线成功了,点击链接即可访问,当然我们也可以点击自定义域名来绑定自己的域名。 + +::: tip +绑定自己的域名后,Laf 将会自动为您的域名配置 `SSL` 证书,这个过程会有 30 秒 -2 分钟,之后即可通过 `https` 进行访问 +::: + +![website-hosting](../../doc-images/website-hosting.png) + +## 自动编译前端并发布 + +利用 `Github Actions` 即可实现自动编译前端并推送到 Laf 云存储中 + + + +1、在自己的前端项目的主分支中,新建 Actions,下面是一个基础模板 + +本模板效果是,如果有新代码推送到主分支,会自动触发 Actions + +- `API_URL` 为你当前的 Laf 应用的 API 地址,如:`laf.dev` 对应 `https://api.laf.dev`,`laf.run` 对应 `https://api.laf.run` + +- `WEB_PATH` 为你前端在当前项目的哪个路径,如果前端项目在根目录,则无需修改。如果在 web 目录下,则改成 `'web'` 即可。 + +- `DIST_PATH` 为编译后的目录名称,绝大部分项目编译后的目录名均为 dist + +```yaml +name: Build +on: + push: + branches: + - "*" + +env: + BUCKET_NAME: ${{ secrets.DOC_BUCKET_NAME }} + LAF_APPID: ${{ secrets.LAF_APPID }} + LAF_PAT: ${{ secrets.LAF_PAT }} + API_URL: "https://api.laf.dev" + WEB_PATH: . + DIST_PATH: "dist" +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: "16.x" + # 安装项目依赖 + - name: Install Dependencies + working-directory: ${{ env.WEB_PATH }} + run: npm install + # 编译项目 + - name: Build + working-directory: ${{ env.WEB_PATH }} + run: npm run build + # 安装 laf-cli + - name: Install Laf-CLI + run: npm i laf-cli -g + # 登录 laf api + - name: Login laf-cli + working-directory: ${{ env.WEB_PATH }} + run: laf login -r ${{ env.API_URL }} $LAF_PAT + # 初始化 Laf 应用然后将编译好的代码推送到云存储 + - name: Init appid and push + working-directory: ${{ env.WEB_PATH }} + env: + LAF_APPID: ${{ env.LAF_APPID }} + run: | + laf app init ${{ env.LAF_APPID }} + laf storage push -f ${{ env.BUCKET_NAME }} ${{ env.DIST_PATH }}/ +``` + +2、配置一些环境变量 + +- `DOC_BUCKET_NAME` 为你的前端托管的 bucket 名称 + +- `LAF_APPID` 为你的 Laf 应用 appid + +- `LAF_PAT` 为你的 Laf 应用的 PAT,获取方法可看:[获取 PAT](/guide/cli/#登录) + +将上面 3 个参数配置到项目的密钥中 + +![auto-build1](/doc-images/auto-build1.png) + +第一步:点击 `settings` + +![auto-build2](/doc-images/auto-build2.png) + +第二步:点击 `Secrets and variables` 下的 `Actions` + +第三步:依次添加 `DOC_BUCKET_NAME` `LAF_APPID` `LAF_PAT` diff --git a/docs/guide/website-hosting/quick-start.md b/docs/guide/website-hosting/quick-start.md deleted file mode 100644 index c49a0f9f7c..0000000000 --- a/docs/guide/website-hosting/quick-start.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: 托管静态网站 ---- - -# {{ $frontmatter.title }} - -## 托管静态网站 - -1. 创建一个 bucket 用于存储静态网站文件 -2. 上传静态网站文件到 bucket -3. 创建一个网站托管配置 - -## 创建一个存储 bucket - -1. 在「开发控制台」选择「文件管理」 -2. 点击「新建文件桶」按钮,创建一个 bucket, 并且设置 bucket 的权限必须为「公共读」,确认即可 -3. 点击「获取服务账号」按钮,先将 `AccessKey` 和 `SecretKey` 保存下来,下一步上传文件时使用 - - - -## 上传网页静态文件 - -1. 使用 laf-cli 上传静态文件 - -> [参考 laf-cli 使用说明](../cli/index.md) - -## 创建网站托管 - -1. 在「开发控制台」选择「网站托管」 -2. 点击「创建网站托管」按钮,选择你的 bucket,确认即可 - - - -3. 列表显示默认访问域名,也可以绑定自定义域名 - - - -## 注意事项 - -- 域名根路径对应 bucket 的根路径 diff --git a/docs/index.md b/docs/index.md index dd1e0d7c71..22e5f9657f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,17 +4,17 @@ layout: home hero: name: laf - text: 像写博客一样写函数 随时随地上线 + text: 像写博客一样写代码 随时随地上线 tagline: life is short, you need laf :) actions: - theme: brand text: 快速开始 link: /guide/ - theme: alt - text: 在线体验 - link: http://console.lafyun.com/ + text: 立即使用 + link: https://laf.run/ - theme: alt - text: GitHub仓库 + text: GitHub 仓库 link: https://github.com/labring/laf heroImage: https://socialify.git.ci/labring/laf/image?description=1& @@ -23,15 +23,15 @@ actionText: Get Started actionLink: /guide/ features: - title: 云函数 - details: 在云端运行的代码,使用 Typescript 编写云函数,支持 WebSocket,前端直接调用。云函数为 Node.js 运行环境。 + details: 在云端运行的代码,使用 Typescript 编写云函数,支持 WebSocket,前端直接调用。云函数为 Node.js 运行环境,无需冷启动。 - title: 云数据库 - details: 客户端“直接”通过访问策略操作数据库,无需后端提供接口,可节约90%+的后端接口,前端开发者可独立完成应用开发。 + details: 开箱即用,无需创建。还可客户端“直接”通过访问策略操作数据库,可节约 90%+ 的后端接口,前端开发者可独立完成应用开发。 - title: 在线编程 IDE - details: 使用 Typescript 在线编写云函数,支持全类型智能提示,在线编写、调试、日志,代码即内容,保存即发布。 + details: 支持 AI 生成云函数,码中生花。支持全类型智能提示,在线编写、调试、日志,代码即内容。随时随地,发布上线。 - title: 触发器 - details: 云函数可配置定时器和事件触发器,其中可监听数据库变更事件,数据变更可触发云函数的执行。 + details: 云函数可配置定时器和事件触发器,其中可监听数据库变更事件,数据变更可触发云函数的执行(事件触发器稍晚更新)。 - title: 云存储 - details: 提供专业兼容S3标准的对象存储服务(MinIO),支持 Service Account 开放能力。 + details: 提供专业兼容 S3 标准的对象存储服务(MinIO),支持 Service Account 开放能力。 - title: 静态网站托管 - details: 将前端静态网站一键部署到云存储,通过自动分配的二级域名直接访问,支持绑定自定义域名。 + details: 前端静态网站一键部署托管,自动分配的二级域名可直接访问,支持绑定自定义域名及自动生成 SSL 证书。 --- diff --git a/docs/package-lock.json b/docs/package-lock.json index f1e970279a..7723015df6 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -1,15 +1,20 @@ { "name": "laf-docs", - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "laf-docs", - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.7", + "hasInstallScript": true, "dependencies": { "markdown-it-custom-attrs": "^1.0.2", "vitepress": "^1.0.0-alpha.29" + }, + "devDependencies": { + "flexsearch": "^0.7.31", + "vitepress-plugin-search": "^1.0.4-alpha.20" } }, "node_modules/@algolia/autocomplete-core": { @@ -38,118 +43,118 @@ "integrity": "sha512-2VGCk7I9tA9Ge73Km99+Qg87w0wzW4tgUruvWAn/gfey1ZXgmxZtyIRBebk35R1O8TbK77wujVtCnpsGpRy1kg==" }, "node_modules/@algolia/cache-browser-local-storage": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.14.3.tgz", - "integrity": "sha512-hWH1yCxgG3+R/xZIscmUrWAIBnmBFHH5j30fY/+aPkEZWt90wYILfAHIOZ1/Wxhho5SkPfwFmT7ooX2d9JeQBw==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.17.0.tgz", + "integrity": "sha512-myRSRZDIMYB8uCkO+lb40YKiYHi0fjpWRtJpR/dgkaiBlSD0plRyB6lLOh1XIfmMcSeBOqDE7y9m8xZMrXYfyQ==", "dependencies": { - "@algolia/cache-common": "4.14.3" + "@algolia/cache-common": "4.17.0" } }, "node_modules/@algolia/cache-common": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.14.3.tgz", - "integrity": "sha512-oZJofOoD9FQOwiGTzyRnmzvh3ZP8WVTNPBLH5xU5JNF7drDbRT0ocVT0h/xB2rPHYzOeXRrLaQQBwRT/CKom0Q==" + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.17.0.tgz", + "integrity": "sha512-g8mXzkrcUBIPZaulAuqE7xyHhLAYAcF2xSch7d9dABheybaU3U91LjBX6eJTEB7XVhEsgK4Smi27vWtAJRhIKQ==" }, "node_modules/@algolia/cache-in-memory": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.14.3.tgz", - "integrity": "sha512-ES0hHQnzWjeioLQf5Nq+x1AWdZJ50znNPSH3puB/Y4Xsg4Av1bvLmTJe7SY2uqONaeMTvL0OaVcoVtQgJVw0vg==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.17.0.tgz", + "integrity": "sha512-PT32ciC/xI8z919d0oknWVu3kMfTlhQn3MKxDln3pkn+yA7F7xrxSALysxquv+MhFfNAcrtQ/oVvQVBAQSHtdw==", "dependencies": { - "@algolia/cache-common": "4.14.3" + "@algolia/cache-common": "4.17.0" } }, "node_modules/@algolia/client-account": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.14.3.tgz", - "integrity": "sha512-PBcPb0+f5Xbh5UfLZNx2Ow589OdP8WYjB4CnvupfYBrl9JyC1sdH4jcq/ri8osO/mCZYjZrQsKAPIqW/gQmizQ==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.17.0.tgz", + "integrity": "sha512-sSEHx9GA6m7wrlsSMNBGfyzlIfDT2fkz2u7jqfCCd6JEEwmxt8emGmxAU/0qBfbhRSuGvzojoLJlr83BSZAKjA==", "dependencies": { - "@algolia/client-common": "4.14.3", - "@algolia/client-search": "4.14.3", - "@algolia/transporter": "4.14.3" + "@algolia/client-common": "4.17.0", + "@algolia/client-search": "4.17.0", + "@algolia/transporter": "4.17.0" } }, "node_modules/@algolia/client-analytics": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.14.3.tgz", - "integrity": "sha512-eAwQq0Hb/aauv9NhCH5Dp3Nm29oFx28sayFN2fdOWemwSeJHIl7TmcsxVlRsO50fsD8CtPcDhtGeD3AIFLNvqw==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.17.0.tgz", + "integrity": "sha512-84ooP8QA3mQ958hQ9wozk7hFUbAO+81CX1CjAuerxBqjKIInh1fOhXKTaku05O/GHBvcfExpPLIQuSuLYziBXQ==", "dependencies": { - "@algolia/client-common": "4.14.3", - "@algolia/client-search": "4.14.3", - "@algolia/requester-common": "4.14.3", - "@algolia/transporter": "4.14.3" + "@algolia/client-common": "4.17.0", + "@algolia/client-search": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" } }, "node_modules/@algolia/client-common": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.14.3.tgz", - "integrity": "sha512-jkPPDZdi63IK64Yg4WccdCsAP4pHxSkr4usplkUZM5C1l1oEpZXsy2c579LQ0rvwCs5JFmwfNG4ahOszidfWPw==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.17.0.tgz", + "integrity": "sha512-jHMks0ZFicf8nRDn6ma8DNNsdwGgP/NKiAAL9z6rS7CymJ7L0+QqTJl3rYxRW7TmBhsUH40wqzmrG6aMIN/DrQ==", "dependencies": { - "@algolia/requester-common": "4.14.3", - "@algolia/transporter": "4.14.3" + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" } }, "node_modules/@algolia/client-personalization": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.14.3.tgz", - "integrity": "sha512-UCX1MtkVNgaOL9f0e22x6tC9e2H3unZQlSUdnVaSKpZ+hdSChXGaRjp2UIT7pxmPqNCyv51F597KEX5WT60jNg==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.17.0.tgz", + "integrity": "sha512-RMzN4dZLIta1YuwT7QC9o+OeGz2cU6eTOlGNE/6RcUBLOU3l9tkCOdln5dPE2jp8GZXPl2yk54b2nSs1+pAjqw==", "dependencies": { - "@algolia/client-common": "4.14.3", - "@algolia/requester-common": "4.14.3", - "@algolia/transporter": "4.14.3" + "@algolia/client-common": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" } }, "node_modules/@algolia/client-search": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.14.3.tgz", - "integrity": "sha512-I2U7xBx5OPFdPLA8AXKUPPxGY3HDxZ4r7+mlZ8ZpLbI8/ri6fnu6B4z3wcL7sgHhDYMwnAE8Xr0AB0h3Hnkp4A==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.17.0.tgz", + "integrity": "sha512-x4P2wKrrRIXszT8gb7eWsMHNNHAJs0wE7/uqbufm4tZenAp+hwU/hq5KVsY50v+PfwM0LcDwwn/1DroujsTFoA==", "dependencies": { - "@algolia/client-common": "4.14.3", - "@algolia/requester-common": "4.14.3", - "@algolia/transporter": "4.14.3" + "@algolia/client-common": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" } }, "node_modules/@algolia/logger-common": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.14.3.tgz", - "integrity": "sha512-kUEAZaBt/J3RjYi8MEBT2QEexJR2kAE2mtLmezsmqMQZTV502TkHCxYzTwY2dE7OKcUTxi4OFlMuS4GId9CWPw==" + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.17.0.tgz", + "integrity": "sha512-DGuoZqpTmIKJFDeyAJ7M8E/LOenIjWiOsg1XJ1OqAU/eofp49JfqXxbfgctlVZVmDABIyOz8LqEoJ6ZP4DTyvw==" }, "node_modules/@algolia/logger-console": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.14.3.tgz", - "integrity": "sha512-ZWqAlUITktiMN2EiFpQIFCJS10N96A++yrexqC2Z+3hgF/JcKrOxOdT4nSCQoEPvU4Ki9QKbpzbebRDemZt/hw==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.17.0.tgz", + "integrity": "sha512-zMPvugQV/gbXUvWBCzihw6m7oxIKp48w37QBIUu/XqQQfxhjoOE9xyfJr1KldUt5FrYOKZJVsJaEjTsu+bIgQg==", "dependencies": { - "@algolia/logger-common": "4.14.3" + "@algolia/logger-common": "4.17.0" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.14.3.tgz", - "integrity": "sha512-AZeg2T08WLUPvDncl2XLX2O67W5wIO8MNaT7z5ii5LgBTuk/rU4CikTjCe2xsUleIZeFl++QrPAi4Bdxws6r/Q==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.17.0.tgz", + "integrity": "sha512-aSOX/smauyTkP21Pf52pJ1O2LmNFJ5iHRIzEeTh0mwBeADO4GdG94cAWDILFA9rNblq/nK3EDh3+UyHHjplZ1A==", "dependencies": { - "@algolia/requester-common": "4.14.3" + "@algolia/requester-common": "4.17.0" } }, "node_modules/@algolia/requester-common": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.14.3.tgz", - "integrity": "sha512-RrRzqNyKFDP7IkTuV3XvYGF9cDPn9h6qEDl595lXva3YUk9YSS8+MGZnnkOMHvjkrSCKfoLeLbm/T4tmoIeclw==" + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.17.0.tgz", + "integrity": "sha512-XJjmWFEUlHu0ijvcHBoixuXfEoiRUdyzQM6YwTuB8usJNIgShua8ouFlRWF8iCeag0vZZiUm4S2WCVBPkdxFgg==" }, "node_modules/@algolia/requester-node-http": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.14.3.tgz", - "integrity": "sha512-O5wnPxtDRPuW2U0EaOz9rMMWdlhwP0J0eSL1Z7TtXF8xnUeeUyNJrdhV5uy2CAp6RbhM1VuC3sOJcIR6Av+vbA==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.17.0.tgz", + "integrity": "sha512-bpb/wDA1aC6WxxM8v7TsFspB7yBN3nqCGs2H1OADolQR/hiAIjAxusbuMxVbRFOdaUvAIqioIIkWvZdpYNIn8w==", "dependencies": { - "@algolia/requester-common": "4.14.3" + "@algolia/requester-common": "4.17.0" } }, "node_modules/@algolia/transporter": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.14.3.tgz", - "integrity": "sha512-2qlKlKsnGJ008exFRb5RTeTOqhLZj0bkMCMVskxoqWejs2Q2QtWmsiH98hDfpw0fmnyhzHEt0Z7lqxBYp8bW2w==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.17.0.tgz", + "integrity": "sha512-6xL6H6fe+Fi0AEP3ziSgC+G04RK37iRb4uUUqVAH9WPYFI8g+LYFq6iv5HS8Cbuc5TTut+Bwj6G+dh/asdb9uA==", "dependencies": { - "@algolia/cache-common": "4.14.3", - "@algolia/logger-common": "4.14.3", - "@algolia/requester-common": "4.14.3" + "@algolia/cache-common": "4.17.0", + "@algolia/logger-common": "4.17.0", + "@algolia/requester-common": "4.17.0" } }, "node_modules/@babel/parser": { @@ -164,27 +169,27 @@ } }, "node_modules/@docsearch/css": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.3.2.tgz", - "integrity": "sha512-dctFYiwbvDZkksMlsmc7pj6W6By/EjnVXJq5TEPd05MwQe+dcdHJgaIn1c8wfsucxHpIsdrUcgSkACHCq6aIhw==" + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.3.3.tgz", + "integrity": "sha512-6SCwI7P8ao+se1TUsdZ7B4XzL+gqeQZnBc+2EONZlcVa0dVrk0NjETxozFKgMv0eEGH8QzP1fkN+A1rH61l4eg==" }, "node_modules/@docsearch/js": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.3.2.tgz", - "integrity": "sha512-k2yiB9attFvKoiYswrRtKhIO+qHuzAj1FHYfFWrKz3wSzB2G6s/7EZL9Rf6iytUo1Ok00LUj2C6mWoOnsUTkxg==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.3.3.tgz", + "integrity": "sha512-2xAv2GFuHzzmG0SSZgf8wHX0qZX8n9Y1ZirKUk5Wrdc+vH9CL837x2hZIUdwcPZI9caBA+/CzxsS68O4waYjUQ==", "dependencies": { - "@docsearch/react": "3.3.2", + "@docsearch/react": "3.3.3", "preact": "^10.0.0" } }, "node_modules/@docsearch/react": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.3.2.tgz", - "integrity": "sha512-ugILab2TYKSh6IEHf6Z9xZbOovsYbsdfo60PBj+Bw+oMJ1MHJ7pBt1TTcmPki1hSgg8mysgKy2hDiVdPm7XWSQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.3.3.tgz", + "integrity": "sha512-pLa0cxnl+G0FuIDuYlW+EBK6Rw2jwLw9B1RHIeS4N4s2VhsfJ/wzeCi3CWcs5yVfxLd5ZK50t//TMA5e79YT7Q==", "dependencies": { "@algolia/autocomplete-core": "1.7.4", "@algolia/autocomplete-preset-algolia": "1.7.4", - "@docsearch/css": "3.3.2", + "@docsearch/css": "3.3.3", "algoliasearch": "^4.0.0" }, "peerDependencies": { @@ -205,9 +210,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.17.tgz", - "integrity": "sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.17.tgz", + "integrity": "sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg==", "cpu": [ "arm" ], @@ -220,9 +225,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz", - "integrity": "sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.17.tgz", + "integrity": "sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==", "cpu": [ "arm64" ], @@ -235,9 +240,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.17.tgz", - "integrity": "sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.17.tgz", + "integrity": "sha512-446zpfJ3nioMC7ASvJB1pszHVskkw4u/9Eu8s5yvvsSDTzYh4p4ZIRj0DznSl3FBF0Z/mZfrKXTtt0QCoFmoHA==", "cpu": [ "x64" ], @@ -250,9 +255,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz", - "integrity": "sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.17.tgz", + "integrity": "sha512-m/gwyiBwH3jqfUabtq3GH31otL/0sE0l34XKpSIqR7NjQ/XHQ3lpmQHLHbG8AHTGCw8Ao059GvV08MS0bhFIJQ==", "cpu": [ "arm64" ], @@ -265,9 +270,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz", - "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.17.tgz", + "integrity": "sha512-4utIrsX9IykrqYaXR8ob9Ha2hAY2qLc6ohJ8c0CN1DR8yWeMrTgYFjgdeQ9LIoTOfLetXjuCu5TRPHT9yKYJVg==", "cpu": [ "x64" ], @@ -280,9 +285,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz", - "integrity": "sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.17.tgz", + "integrity": "sha512-4PxjQII/9ppOrpEwzQ1b0pXCsFLqy77i0GaHodrmzH9zq2/NEhHMAMJkJ635Ns4fyJPFOlHMz4AsklIyRqFZWA==", "cpu": [ "arm64" ], @@ -295,9 +300,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz", - "integrity": "sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.17.tgz", + "integrity": "sha512-lQRS+4sW5S3P1sv0z2Ym807qMDfkmdhUYX30GRBURtLTrJOPDpoU0kI6pVz1hz3U0+YQ0tXGS9YWveQjUewAJw==", "cpu": [ "x64" ], @@ -310,9 +315,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz", - "integrity": "sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.17.tgz", + "integrity": "sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg==", "cpu": [ "arm" ], @@ -325,9 +330,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz", - "integrity": "sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.17.tgz", + "integrity": "sha512-2+pwLx0whKY1/Vqt8lyzStyda1v0qjJ5INWIe+d8+1onqQxHLLi3yr5bAa4gvbzhZqBztifYEu8hh1La5+7sUw==", "cpu": [ "arm64" ], @@ -340,9 +345,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz", - "integrity": "sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.17.tgz", + "integrity": "sha512-IBTTv8X60dYo6P2t23sSUYym8fGfMAiuv7PzJ+0LcdAndZRzvke+wTVxJeCq4WgjppkOpndL04gMZIFvwoU34Q==", "cpu": [ "ia32" ], @@ -355,9 +360,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz", - "integrity": "sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.17.tgz", + "integrity": "sha512-WVMBtcDpATjaGfWfp6u9dANIqmU9r37SY8wgAivuKmgKHE+bWSuv0qXEFt/p3qXQYxJIGXQQv6hHcm7iWhWjiw==", "cpu": [ "loong64" ], @@ -370,9 +375,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz", - "integrity": "sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.17.tgz", + "integrity": "sha512-2kYCGh8589ZYnY031FgMLy0kmE4VoGdvfJkxLdxP4HJvWNXpyLhjOvxVsYjYZ6awqY4bgLR9tpdYyStgZZhi2A==", "cpu": [ "mips64el" ], @@ -385,9 +390,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz", - "integrity": "sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.17.tgz", + "integrity": "sha512-KIdG5jdAEeAKogfyMTcszRxy3OPbZhq0PPsW4iKKcdlbk3YE4miKznxV2YOSmiK/hfOZ+lqHri3v8eecT2ATwQ==", "cpu": [ "ppc64" ], @@ -400,9 +405,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz", - "integrity": "sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.17.tgz", + "integrity": "sha512-Cj6uWLBR5LWhcD/2Lkfg2NrkVsNb2sFM5aVEfumKB2vYetkA/9Uyc1jVoxLZ0a38sUhFk4JOVKH0aVdPbjZQeA==", "cpu": [ "riscv64" ], @@ -415,9 +420,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz", - "integrity": "sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.17.tgz", + "integrity": "sha512-lK+SffWIr0XsFf7E0srBjhpkdFVJf3HEgXCwzkm69kNbRar8MhezFpkIwpk0qo2IOQL4JE4mJPJI8AbRPLbuOQ==", "cpu": [ "s390x" ], @@ -430,9 +435,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz", - "integrity": "sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.17.tgz", + "integrity": "sha512-XcSGTQcWFQS2jx3lZtQi7cQmDYLrpLRyz1Ns1DzZCtn898cWfm5Icx/DEWNcTU+T+tyPV89RQtDnI7qL2PObPg==", "cpu": [ "x64" ], @@ -445,9 +450,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz", - "integrity": "sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.17.tgz", + "integrity": "sha512-RNLCDmLP5kCWAJR+ItLM3cHxzXRTe4N00TQyQiimq+lyqVqZWGPAvcyfUBM0isE79eEZhIuGN09rAz8EL5KdLA==", "cpu": [ "x64" ], @@ -460,9 +465,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz", - "integrity": "sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.17.tgz", + "integrity": "sha512-PAXswI5+cQq3Pann7FNdcpSUrhrql3wKjj3gVkmuz6OHhqqYxKvi6GgRBoaHjaG22HV/ZZEgF9TlS+9ftHVigA==", "cpu": [ "x64" ], @@ -475,9 +480,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz", - "integrity": "sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.17.tgz", + "integrity": "sha512-V63egsWKnx/4V0FMYkr9NXWrKTB5qFftKGKuZKFIrAkO/7EWLFnbBZNM1CvJ6Sis+XBdPws2YQSHF1Gqf1oj/Q==", "cpu": [ "x64" ], @@ -490,9 +495,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz", - "integrity": "sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.17.tgz", + "integrity": "sha512-YtUXLdVnd6YBSYlZODjWzH+KzbaubV0YVd6UxSfoFfa5PtNJNaW+1i+Hcmjpg2nEe0YXUCNF5bkKy1NnBv1y7Q==", "cpu": [ "arm64" ], @@ -505,9 +510,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz", - "integrity": "sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.17.tgz", + "integrity": "sha512-yczSLRbDdReCO74Yfc5tKG0izzm+lPMYyO1fFTcn0QNwnKmc3K+HdxZWLGKg4pZVte7XVgcFku7TIZNbWEJdeQ==", "cpu": [ "ia32" ], @@ -520,9 +525,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz", - "integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.17.tgz", + "integrity": "sha512-FNZw7H3aqhF9OyRQbDDnzUApDXfC1N6fgBhkqEO2jvYCJ+DxMTfZVqg3AX0R1khg1wHTBRD5SdcibSJ+XF6bFg==", "cpu": [ "x64" ], @@ -534,15 +539,43 @@ "node": ">=12" } }, + "node_modules/@types/flexsearch": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@types/flexsearch/-/flexsearch-0.7.3.tgz", + "integrity": "sha512-HXwADeHEP4exXkCIwy2n1+i0f1ilP1ETQOH5KDOugjkTFZPntWo0Gr8stZOaebkxsdx+k0X/K6obU/+it07ocg==", + "dev": true + }, + "node_modules/@types/linkify-it": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", + "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "dev": true + }, + "node_modules/@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "dependencies": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", + "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", + "dev": true + }, "node_modules/@types/web-bluetooth": { "version": "0.0.16", "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==" }, "node_modules/@vitejs/plugin-vue": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.0.0.tgz", - "integrity": "sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.1.0.tgz", + "integrity": "sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==", "engines": { "node": "^14.18.0 || >=16.0.0" }, @@ -659,23 +692,23 @@ "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==" }, "node_modules/@vueuse/core": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.12.0.tgz", - "integrity": "sha512-h/Di8Bvf6xRcvS/PvUVheiMYYz3U0tH3X25YxONSaAUBa841ayMwxkuzx/DGUMCW/wHWzD8tRy2zYmOC36r4sg==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.0.2.tgz", + "integrity": "sha512-/UGc2cXbxbeIFLDSJyHUjI9QZ4CJJkhiJe9TbKNPSofcWmYhhUgJ+7iw9njXTKu/Xc3Z6UeXVR9fosW1+cyrnQ==", "dependencies": { "@types/web-bluetooth": "^0.0.16", - "@vueuse/metadata": "9.12.0", - "@vueuse/shared": "9.12.0", - "vue-demi": "*" + "@vueuse/metadata": "10.0.2", + "@vueuse/shared": "10.0.2", + "vue-demi": ">=0.14.0" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/core/node_modules/vue-demi": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", - "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz", + "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==", "hasInstallScript": true, "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", @@ -698,28 +731,28 @@ } }, "node_modules/@vueuse/metadata": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.12.0.tgz", - "integrity": "sha512-9oJ9MM9lFLlmvxXUqsR1wLt1uF7EVbP5iYaHJYqk+G2PbMjY6EXvZeTjbdO89HgoF5cI6z49o2zT/jD9SVoNpQ==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.0.2.tgz", + "integrity": "sha512-APSjlABrV+Q74c+FR0kFETvcN9W2pAaT3XF3WwqWUuk4srmVxv7DY4WshZxK2KYk1+MVY0Fus6J1Hk/JXVm6Aw==", "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.12.0.tgz", - "integrity": "sha512-TWuJLACQ0BVithVTRbex4Wf1a1VaRuSpVeyEd4vMUWl54PzlE0ciFUshKCXnlLuD0lxIaLK4Ypj3NXYzZh4+SQ==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.0.2.tgz", + "integrity": "sha512-7W2l6qZaFvla3zAeEVo8hNHkNRKCezJa3JjZAKv3K4KsevXobHhVNr+RHaOVNK/6ETpFmtqiK+0pMIADbHjjag==", "dependencies": { - "vue-demi": "*" + "vue-demi": ">=0.14.0" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/@vueuse/shared/node_modules/vue-demi": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", - "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz", + "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==", "hasInstallScript": true, "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", @@ -747,24 +780,24 @@ "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" }, "node_modules/algoliasearch": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.14.3.tgz", - "integrity": "sha512-GZTEuxzfWbP/vr7ZJfGzIl8fOsoxN916Z6FY2Egc9q2TmZ6hvq5KfAxY89pPW01oW/2HDEKA8d30f9iAH9eXYg==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.17.0.tgz", + "integrity": "sha512-JMRh2Mw6sEnVMiz6+APsi7lx9a2jiDFF+WUtANaUVCv6uSU9UOLdo5h9K3pdP6frRRybaM2fX8b1u0nqICS9aA==", "dependencies": { - "@algolia/cache-browser-local-storage": "4.14.3", - "@algolia/cache-common": "4.14.3", - "@algolia/cache-in-memory": "4.14.3", - "@algolia/client-account": "4.14.3", - "@algolia/client-analytics": "4.14.3", - "@algolia/client-common": "4.14.3", - "@algolia/client-personalization": "4.14.3", - "@algolia/client-search": "4.14.3", - "@algolia/logger-common": "4.14.3", - "@algolia/logger-console": "4.14.3", - "@algolia/requester-browser-xhr": "4.14.3", - "@algolia/requester-common": "4.14.3", - "@algolia/requester-node-http": "4.14.3", - "@algolia/transporter": "4.14.3" + "@algolia/cache-browser-local-storage": "4.17.0", + "@algolia/cache-common": "4.17.0", + "@algolia/cache-in-memory": "4.17.0", + "@algolia/client-account": "4.17.0", + "@algolia/client-analytics": "4.17.0", + "@algolia/client-common": "4.17.0", + "@algolia/client-personalization": "4.17.0", + "@algolia/client-search": "4.17.0", + "@algolia/logger-common": "4.17.0", + "@algolia/logger-console": "4.17.0", + "@algolia/requester-browser-xhr": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/requester-node-http": "4.17.0", + "@algolia/transporter": "4.17.0" } }, "node_modules/ansi-sequence-parser": { @@ -772,6 +805,12 @@ "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==" }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -795,10 +834,22 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/esbuild": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", - "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.17.tgz", + "integrity": "sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==", "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -807,28 +858,28 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.16.17", - "@esbuild/android-arm64": "0.16.17", - "@esbuild/android-x64": "0.16.17", - "@esbuild/darwin-arm64": "0.16.17", - "@esbuild/darwin-x64": "0.16.17", - "@esbuild/freebsd-arm64": "0.16.17", - "@esbuild/freebsd-x64": "0.16.17", - "@esbuild/linux-arm": "0.16.17", - "@esbuild/linux-arm64": "0.16.17", - "@esbuild/linux-ia32": "0.16.17", - "@esbuild/linux-loong64": "0.16.17", - "@esbuild/linux-mips64el": "0.16.17", - "@esbuild/linux-ppc64": "0.16.17", - "@esbuild/linux-riscv64": "0.16.17", - "@esbuild/linux-s390x": "0.16.17", - "@esbuild/linux-x64": "0.16.17", - "@esbuild/netbsd-x64": "0.16.17", - "@esbuild/openbsd-x64": "0.16.17", - "@esbuild/sunos-x64": "0.16.17", - "@esbuild/win32-arm64": "0.16.17", - "@esbuild/win32-ia32": "0.16.17", - "@esbuild/win32-x64": "0.16.17" + "@esbuild/android-arm": "0.17.17", + "@esbuild/android-arm64": "0.17.17", + "@esbuild/android-x64": "0.17.17", + "@esbuild/darwin-arm64": "0.17.17", + "@esbuild/darwin-x64": "0.17.17", + "@esbuild/freebsd-arm64": "0.17.17", + "@esbuild/freebsd-x64": "0.17.17", + "@esbuild/linux-arm": "0.17.17", + "@esbuild/linux-arm64": "0.17.17", + "@esbuild/linux-ia32": "0.17.17", + "@esbuild/linux-loong64": "0.17.17", + "@esbuild/linux-mips64el": "0.17.17", + "@esbuild/linux-ppc64": "0.17.17", + "@esbuild/linux-riscv64": "0.17.17", + "@esbuild/linux-s390x": "0.17.17", + "@esbuild/linux-x64": "0.17.17", + "@esbuild/netbsd-x64": "0.17.17", + "@esbuild/openbsd-x64": "0.17.17", + "@esbuild/sunos-x64": "0.17.17", + "@esbuild/win32-arm64": "0.17.17", + "@esbuild/win32-ia32": "0.17.17", + "@esbuild/win32-x64": "0.17.17" } }, "node_modules/estree-walker": { @@ -836,6 +887,12 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" }, + "node_modules/flexsearch": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/flexsearch/-/flexsearch-0.7.31.tgz", + "integrity": "sha512-XGozTsMPYkm+6b5QL3Z9wQcJjNYxp0CYn3U1gO7dwD6PAqU1SVWZxI9CCg3z+ml3YfqdPnrBehaBrnH2AGKbNA==", + "dev": true + }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -849,21 +906,11 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true }, "node_modules/hexo-pagination": { "version": "0.1.0", @@ -873,22 +920,20 @@ "object-assign": "^4.1.0" } }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/jsonc-parser": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" }, + "node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, "node_modules/lodash.pick": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", @@ -902,6 +947,27 @@ "sourcemap-codec": "^1.4.8" } }, + "node_modules/mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==" + }, + "node_modules/markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, "node_modules/markdown-it-custom-attrs": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/markdown-it-custom-attrs/-/markdown-it-custom-attrs-1.0.2.tgz", @@ -912,6 +978,17 @@ "nunjucks": "^3.0.1" } }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, + "node_modules/minisearch": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-6.0.1.tgz", + "integrity": "sha512-Ly1w0nHKnlhAAh6/BF/+9NgzXfoJxaJ8nhopFhQ3NcvFJrFIL+iCg9gw9e9UMBD+XIsp/RyznJ/o5UIe5Kw+kg==" + }, "node_modules/nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -955,11 +1032,6 @@ "node": ">=0.10.0" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -989,34 +1061,18 @@ } }, "node_modules/preact": { - "version": "10.11.3", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz", - "integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==", + "version": "10.13.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.2.tgz", + "integrity": "sha512-q44QFLhOhty2Bd0Y46fnYW0gD/cbVM9dUVtNTDKPcdXSMA7jfY+Jpd6rk3GB0lcQss0z5s/6CmVP0Z/hV+g6pw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" } }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/rollup": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.14.0.tgz", - "integrity": "sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q==", + "version": "3.20.6", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.6.tgz", + "integrity": "sha512-2yEB3nQXp/tBQDN0hJScJQheXdvU2wFhh6ld7K/aiZ1vYcak6N/BKjY1QrU6BvO2JWYS8bEs14FRaxXosxy2zw==", "bin": { "rollup": "dist/bin/rollup" }, @@ -1029,9 +1085,9 @@ } }, "node_modules/shiki": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.0.tgz", - "integrity": "sha512-fb9Fg1Yx/ElVJcTqPQIEOSfn7mSZlrT1W3CkymY08lL2Jsi+t7jPcZzKO1lCsQwlSDuyNhHvolnyA2OI4EgJNg==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.1.tgz", + "integrity": "sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw==", "dependencies": { "ansi-sequence-parser": "^1.1.0", "jsonc-parser": "^3.2.0", @@ -1061,26 +1117,20 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "deprecated": "Please use @jridgewell/sourcemap-codec instead" }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true }, "node_modules/vite": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.1.tgz", - "integrity": "sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.0.tgz", + "integrity": "sha512-JTGFgDh3dVxeGBpuQX04Up+JZmuG6wu9414Ei36vQzaEruY/M4K0AgwtuB2b4HaBgB7R8l+LHxjB0jcgz4d2qQ==", "dependencies": { - "esbuild": "^0.16.14", + "esbuild": "^0.17.5", "postcss": "^8.4.21", - "resolve": "^1.22.1", - "rollup": "^3.10.0" + "rollup": "^3.20.2" }, "bin": { "vite": "bin/vite.js" @@ -1121,24 +1171,46 @@ } }, "node_modules/vitepress": { - "version": "1.0.0-alpha.45", - "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.0.0-alpha.45.tgz", - "integrity": "sha512-8AVWdymQqBUPmXmAbpapDDg18iDmkNJ47l5eOklBlAjj3n8P3zDAsBhOWSQ6+Nvm6+/GaZATyAvsrg47JD5Idw==", + "version": "1.0.0-alpha.72", + "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.0.0-alpha.72.tgz", + "integrity": "sha512-Ou7fNE/OVYLrKGQMHSTVG6AcNsdv7tm4ACrdhx93SPMzEDj8UgIb4RFa5CTTowaYf3jeDGi2EAJlzXVC+IE3dg==", "dependencies": { - "@docsearch/css": "^3.3.2", - "@docsearch/js": "^3.3.2", - "@vitejs/plugin-vue": "^4.0.0", + "@docsearch/css": "^3.3.3", + "@docsearch/js": "^3.3.3", + "@vitejs/plugin-vue": "^4.1.0", "@vue/devtools-api": "^6.5.0", - "@vueuse/core": "^9.12.0", + "@vueuse/core": "^10.0.2", "body-scroll-lock": "4.0.0-beta.0", - "shiki": "^0.14.0", - "vite": "^4.0.4", - "vue": "^3.2.45" + "mark.js": "^8.11.1", + "minisearch": "^6.0.1", + "shiki": "^0.14.1", + "vite": "^4.2.1", + "vue": "^3.2.47" }, "bin": { "vitepress": "bin/vitepress.js" } }, + "node_modules/vitepress-plugin-search": { + "version": "1.0.4-alpha.20", + "resolved": "https://registry.npmjs.org/vitepress-plugin-search/-/vitepress-plugin-search-1.0.4-alpha.20.tgz", + "integrity": "sha512-zG+ev9pw1Mg7htABlFCNXb8XwnKN+qfTKw+vU0Ers6RIrABx+45EAAFBoaL1mEpl1FRFn1o/dQ7F4b8GP6HdGQ==", + "dev": true, + "dependencies": { + "@types/flexsearch": "^0.7.3", + "@types/markdown-it": "^12.2.3", + "glob-to-regexp": "^0.4.1", + "markdown-it": "^13.0.1" + }, + "engines": { + "node": "^14.13.1 || ^16.7.0 || >=18" + }, + "peerDependencies": { + "flexsearch": "^0.7.31", + "vitepress": "^1.0.0-alpha.65", + "vue": "3" + } + }, "node_modules/vscode-oniguruma": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", @@ -1185,118 +1257,118 @@ "integrity": "sha512-2VGCk7I9tA9Ge73Km99+Qg87w0wzW4tgUruvWAn/gfey1ZXgmxZtyIRBebk35R1O8TbK77wujVtCnpsGpRy1kg==" }, "@algolia/cache-browser-local-storage": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.14.3.tgz", - "integrity": "sha512-hWH1yCxgG3+R/xZIscmUrWAIBnmBFHH5j30fY/+aPkEZWt90wYILfAHIOZ1/Wxhho5SkPfwFmT7ooX2d9JeQBw==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.17.0.tgz", + "integrity": "sha512-myRSRZDIMYB8uCkO+lb40YKiYHi0fjpWRtJpR/dgkaiBlSD0plRyB6lLOh1XIfmMcSeBOqDE7y9m8xZMrXYfyQ==", "requires": { - "@algolia/cache-common": "4.14.3" + "@algolia/cache-common": "4.17.0" } }, "@algolia/cache-common": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.14.3.tgz", - "integrity": "sha512-oZJofOoD9FQOwiGTzyRnmzvh3ZP8WVTNPBLH5xU5JNF7drDbRT0ocVT0h/xB2rPHYzOeXRrLaQQBwRT/CKom0Q==" + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.17.0.tgz", + "integrity": "sha512-g8mXzkrcUBIPZaulAuqE7xyHhLAYAcF2xSch7d9dABheybaU3U91LjBX6eJTEB7XVhEsgK4Smi27vWtAJRhIKQ==" }, "@algolia/cache-in-memory": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.14.3.tgz", - "integrity": "sha512-ES0hHQnzWjeioLQf5Nq+x1AWdZJ50znNPSH3puB/Y4Xsg4Av1bvLmTJe7SY2uqONaeMTvL0OaVcoVtQgJVw0vg==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.17.0.tgz", + "integrity": "sha512-PT32ciC/xI8z919d0oknWVu3kMfTlhQn3MKxDln3pkn+yA7F7xrxSALysxquv+MhFfNAcrtQ/oVvQVBAQSHtdw==", "requires": { - "@algolia/cache-common": "4.14.3" + "@algolia/cache-common": "4.17.0" } }, "@algolia/client-account": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.14.3.tgz", - "integrity": "sha512-PBcPb0+f5Xbh5UfLZNx2Ow589OdP8WYjB4CnvupfYBrl9JyC1sdH4jcq/ri8osO/mCZYjZrQsKAPIqW/gQmizQ==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.17.0.tgz", + "integrity": "sha512-sSEHx9GA6m7wrlsSMNBGfyzlIfDT2fkz2u7jqfCCd6JEEwmxt8emGmxAU/0qBfbhRSuGvzojoLJlr83BSZAKjA==", "requires": { - "@algolia/client-common": "4.14.3", - "@algolia/client-search": "4.14.3", - "@algolia/transporter": "4.14.3" + "@algolia/client-common": "4.17.0", + "@algolia/client-search": "4.17.0", + "@algolia/transporter": "4.17.0" } }, "@algolia/client-analytics": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.14.3.tgz", - "integrity": "sha512-eAwQq0Hb/aauv9NhCH5Dp3Nm29oFx28sayFN2fdOWemwSeJHIl7TmcsxVlRsO50fsD8CtPcDhtGeD3AIFLNvqw==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.17.0.tgz", + "integrity": "sha512-84ooP8QA3mQ958hQ9wozk7hFUbAO+81CX1CjAuerxBqjKIInh1fOhXKTaku05O/GHBvcfExpPLIQuSuLYziBXQ==", "requires": { - "@algolia/client-common": "4.14.3", - "@algolia/client-search": "4.14.3", - "@algolia/requester-common": "4.14.3", - "@algolia/transporter": "4.14.3" + "@algolia/client-common": "4.17.0", + "@algolia/client-search": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" } }, "@algolia/client-common": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.14.3.tgz", - "integrity": "sha512-jkPPDZdi63IK64Yg4WccdCsAP4pHxSkr4usplkUZM5C1l1oEpZXsy2c579LQ0rvwCs5JFmwfNG4ahOszidfWPw==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.17.0.tgz", + "integrity": "sha512-jHMks0ZFicf8nRDn6ma8DNNsdwGgP/NKiAAL9z6rS7CymJ7L0+QqTJl3rYxRW7TmBhsUH40wqzmrG6aMIN/DrQ==", "requires": { - "@algolia/requester-common": "4.14.3", - "@algolia/transporter": "4.14.3" + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" } }, "@algolia/client-personalization": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.14.3.tgz", - "integrity": "sha512-UCX1MtkVNgaOL9f0e22x6tC9e2H3unZQlSUdnVaSKpZ+hdSChXGaRjp2UIT7pxmPqNCyv51F597KEX5WT60jNg==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.17.0.tgz", + "integrity": "sha512-RMzN4dZLIta1YuwT7QC9o+OeGz2cU6eTOlGNE/6RcUBLOU3l9tkCOdln5dPE2jp8GZXPl2yk54b2nSs1+pAjqw==", "requires": { - "@algolia/client-common": "4.14.3", - "@algolia/requester-common": "4.14.3", - "@algolia/transporter": "4.14.3" + "@algolia/client-common": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" } }, "@algolia/client-search": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.14.3.tgz", - "integrity": "sha512-I2U7xBx5OPFdPLA8AXKUPPxGY3HDxZ4r7+mlZ8ZpLbI8/ri6fnu6B4z3wcL7sgHhDYMwnAE8Xr0AB0h3Hnkp4A==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.17.0.tgz", + "integrity": "sha512-x4P2wKrrRIXszT8gb7eWsMHNNHAJs0wE7/uqbufm4tZenAp+hwU/hq5KVsY50v+PfwM0LcDwwn/1DroujsTFoA==", "requires": { - "@algolia/client-common": "4.14.3", - "@algolia/requester-common": "4.14.3", - "@algolia/transporter": "4.14.3" + "@algolia/client-common": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/transporter": "4.17.0" } }, "@algolia/logger-common": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.14.3.tgz", - "integrity": "sha512-kUEAZaBt/J3RjYi8MEBT2QEexJR2kAE2mtLmezsmqMQZTV502TkHCxYzTwY2dE7OKcUTxi4OFlMuS4GId9CWPw==" + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.17.0.tgz", + "integrity": "sha512-DGuoZqpTmIKJFDeyAJ7M8E/LOenIjWiOsg1XJ1OqAU/eofp49JfqXxbfgctlVZVmDABIyOz8LqEoJ6ZP4DTyvw==" }, "@algolia/logger-console": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.14.3.tgz", - "integrity": "sha512-ZWqAlUITktiMN2EiFpQIFCJS10N96A++yrexqC2Z+3hgF/JcKrOxOdT4nSCQoEPvU4Ki9QKbpzbebRDemZt/hw==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.17.0.tgz", + "integrity": "sha512-zMPvugQV/gbXUvWBCzihw6m7oxIKp48w37QBIUu/XqQQfxhjoOE9xyfJr1KldUt5FrYOKZJVsJaEjTsu+bIgQg==", "requires": { - "@algolia/logger-common": "4.14.3" + "@algolia/logger-common": "4.17.0" } }, "@algolia/requester-browser-xhr": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.14.3.tgz", - "integrity": "sha512-AZeg2T08WLUPvDncl2XLX2O67W5wIO8MNaT7z5ii5LgBTuk/rU4CikTjCe2xsUleIZeFl++QrPAi4Bdxws6r/Q==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.17.0.tgz", + "integrity": "sha512-aSOX/smauyTkP21Pf52pJ1O2LmNFJ5iHRIzEeTh0mwBeADO4GdG94cAWDILFA9rNblq/nK3EDh3+UyHHjplZ1A==", "requires": { - "@algolia/requester-common": "4.14.3" + "@algolia/requester-common": "4.17.0" } }, "@algolia/requester-common": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.14.3.tgz", - "integrity": "sha512-RrRzqNyKFDP7IkTuV3XvYGF9cDPn9h6qEDl595lXva3YUk9YSS8+MGZnnkOMHvjkrSCKfoLeLbm/T4tmoIeclw==" + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.17.0.tgz", + "integrity": "sha512-XJjmWFEUlHu0ijvcHBoixuXfEoiRUdyzQM6YwTuB8usJNIgShua8ouFlRWF8iCeag0vZZiUm4S2WCVBPkdxFgg==" }, "@algolia/requester-node-http": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.14.3.tgz", - "integrity": "sha512-O5wnPxtDRPuW2U0EaOz9rMMWdlhwP0J0eSL1Z7TtXF8xnUeeUyNJrdhV5uy2CAp6RbhM1VuC3sOJcIR6Av+vbA==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.17.0.tgz", + "integrity": "sha512-bpb/wDA1aC6WxxM8v7TsFspB7yBN3nqCGs2H1OADolQR/hiAIjAxusbuMxVbRFOdaUvAIqioIIkWvZdpYNIn8w==", "requires": { - "@algolia/requester-common": "4.14.3" + "@algolia/requester-common": "4.17.0" } }, "@algolia/transporter": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.14.3.tgz", - "integrity": "sha512-2qlKlKsnGJ008exFRb5RTeTOqhLZj0bkMCMVskxoqWejs2Q2QtWmsiH98hDfpw0fmnyhzHEt0Z7lqxBYp8bW2w==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.17.0.tgz", + "integrity": "sha512-6xL6H6fe+Fi0AEP3ziSgC+G04RK37iRb4uUUqVAH9WPYFI8g+LYFq6iv5HS8Cbuc5TTut+Bwj6G+dh/asdb9uA==", "requires": { - "@algolia/cache-common": "4.14.3", - "@algolia/logger-common": "4.14.3", - "@algolia/requester-common": "4.14.3" + "@algolia/cache-common": "4.17.0", + "@algolia/logger-common": "4.17.0", + "@algolia/requester-common": "4.17.0" } }, "@babel/parser": { @@ -1305,171 +1377,199 @@ "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==" }, "@docsearch/css": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.3.2.tgz", - "integrity": "sha512-dctFYiwbvDZkksMlsmc7pj6W6By/EjnVXJq5TEPd05MwQe+dcdHJgaIn1c8wfsucxHpIsdrUcgSkACHCq6aIhw==" + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.3.3.tgz", + "integrity": "sha512-6SCwI7P8ao+se1TUsdZ7B4XzL+gqeQZnBc+2EONZlcVa0dVrk0NjETxozFKgMv0eEGH8QzP1fkN+A1rH61l4eg==" }, "@docsearch/js": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.3.2.tgz", - "integrity": "sha512-k2yiB9attFvKoiYswrRtKhIO+qHuzAj1FHYfFWrKz3wSzB2G6s/7EZL9Rf6iytUo1Ok00LUj2C6mWoOnsUTkxg==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.3.3.tgz", + "integrity": "sha512-2xAv2GFuHzzmG0SSZgf8wHX0qZX8n9Y1ZirKUk5Wrdc+vH9CL837x2hZIUdwcPZI9caBA+/CzxsS68O4waYjUQ==", "requires": { - "@docsearch/react": "3.3.2", + "@docsearch/react": "3.3.3", "preact": "^10.0.0" } }, "@docsearch/react": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.3.2.tgz", - "integrity": "sha512-ugILab2TYKSh6IEHf6Z9xZbOovsYbsdfo60PBj+Bw+oMJ1MHJ7pBt1TTcmPki1hSgg8mysgKy2hDiVdPm7XWSQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.3.3.tgz", + "integrity": "sha512-pLa0cxnl+G0FuIDuYlW+EBK6Rw2jwLw9B1RHIeS4N4s2VhsfJ/wzeCi3CWcs5yVfxLd5ZK50t//TMA5e79YT7Q==", "requires": { "@algolia/autocomplete-core": "1.7.4", "@algolia/autocomplete-preset-algolia": "1.7.4", - "@docsearch/css": "3.3.2", + "@docsearch/css": "3.3.3", "algoliasearch": "^4.0.0" } }, "@esbuild/android-arm": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.17.tgz", - "integrity": "sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.17.tgz", + "integrity": "sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg==", "optional": true }, "@esbuild/android-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz", - "integrity": "sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.17.tgz", + "integrity": "sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==", "optional": true }, "@esbuild/android-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.17.tgz", - "integrity": "sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.17.tgz", + "integrity": "sha512-446zpfJ3nioMC7ASvJB1pszHVskkw4u/9Eu8s5yvvsSDTzYh4p4ZIRj0DznSl3FBF0Z/mZfrKXTtt0QCoFmoHA==", "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz", - "integrity": "sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.17.tgz", + "integrity": "sha512-m/gwyiBwH3jqfUabtq3GH31otL/0sE0l34XKpSIqR7NjQ/XHQ3lpmQHLHbG8AHTGCw8Ao059GvV08MS0bhFIJQ==", "optional": true }, "@esbuild/darwin-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz", - "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.17.tgz", + "integrity": "sha512-4utIrsX9IykrqYaXR8ob9Ha2hAY2qLc6ohJ8c0CN1DR8yWeMrTgYFjgdeQ9LIoTOfLetXjuCu5TRPHT9yKYJVg==", "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz", - "integrity": "sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.17.tgz", + "integrity": "sha512-4PxjQII/9ppOrpEwzQ1b0pXCsFLqy77i0GaHodrmzH9zq2/NEhHMAMJkJ635Ns4fyJPFOlHMz4AsklIyRqFZWA==", "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz", - "integrity": "sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.17.tgz", + "integrity": "sha512-lQRS+4sW5S3P1sv0z2Ym807qMDfkmdhUYX30GRBURtLTrJOPDpoU0kI6pVz1hz3U0+YQ0tXGS9YWveQjUewAJw==", "optional": true }, "@esbuild/linux-arm": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz", - "integrity": "sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.17.tgz", + "integrity": "sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg==", "optional": true }, "@esbuild/linux-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz", - "integrity": "sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.17.tgz", + "integrity": "sha512-2+pwLx0whKY1/Vqt8lyzStyda1v0qjJ5INWIe+d8+1onqQxHLLi3yr5bAa4gvbzhZqBztifYEu8hh1La5+7sUw==", "optional": true }, "@esbuild/linux-ia32": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz", - "integrity": "sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.17.tgz", + "integrity": "sha512-IBTTv8X60dYo6P2t23sSUYym8fGfMAiuv7PzJ+0LcdAndZRzvke+wTVxJeCq4WgjppkOpndL04gMZIFvwoU34Q==", "optional": true }, "@esbuild/linux-loong64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz", - "integrity": "sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.17.tgz", + "integrity": "sha512-WVMBtcDpATjaGfWfp6u9dANIqmU9r37SY8wgAivuKmgKHE+bWSuv0qXEFt/p3qXQYxJIGXQQv6hHcm7iWhWjiw==", "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz", - "integrity": "sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.17.tgz", + "integrity": "sha512-2kYCGh8589ZYnY031FgMLy0kmE4VoGdvfJkxLdxP4HJvWNXpyLhjOvxVsYjYZ6awqY4bgLR9tpdYyStgZZhi2A==", "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz", - "integrity": "sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.17.tgz", + "integrity": "sha512-KIdG5jdAEeAKogfyMTcszRxy3OPbZhq0PPsW4iKKcdlbk3YE4miKznxV2YOSmiK/hfOZ+lqHri3v8eecT2ATwQ==", "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz", - "integrity": "sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.17.tgz", + "integrity": "sha512-Cj6uWLBR5LWhcD/2Lkfg2NrkVsNb2sFM5aVEfumKB2vYetkA/9Uyc1jVoxLZ0a38sUhFk4JOVKH0aVdPbjZQeA==", "optional": true }, "@esbuild/linux-s390x": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz", - "integrity": "sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.17.tgz", + "integrity": "sha512-lK+SffWIr0XsFf7E0srBjhpkdFVJf3HEgXCwzkm69kNbRar8MhezFpkIwpk0qo2IOQL4JE4mJPJI8AbRPLbuOQ==", "optional": true }, "@esbuild/linux-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz", - "integrity": "sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.17.tgz", + "integrity": "sha512-XcSGTQcWFQS2jx3lZtQi7cQmDYLrpLRyz1Ns1DzZCtn898cWfm5Icx/DEWNcTU+T+tyPV89RQtDnI7qL2PObPg==", "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz", - "integrity": "sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.17.tgz", + "integrity": "sha512-RNLCDmLP5kCWAJR+ItLM3cHxzXRTe4N00TQyQiimq+lyqVqZWGPAvcyfUBM0isE79eEZhIuGN09rAz8EL5KdLA==", "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz", - "integrity": "sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.17.tgz", + "integrity": "sha512-PAXswI5+cQq3Pann7FNdcpSUrhrql3wKjj3gVkmuz6OHhqqYxKvi6GgRBoaHjaG22HV/ZZEgF9TlS+9ftHVigA==", "optional": true }, "@esbuild/sunos-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz", - "integrity": "sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.17.tgz", + "integrity": "sha512-V63egsWKnx/4V0FMYkr9NXWrKTB5qFftKGKuZKFIrAkO/7EWLFnbBZNM1CvJ6Sis+XBdPws2YQSHF1Gqf1oj/Q==", "optional": true }, "@esbuild/win32-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz", - "integrity": "sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.17.tgz", + "integrity": "sha512-YtUXLdVnd6YBSYlZODjWzH+KzbaubV0YVd6UxSfoFfa5PtNJNaW+1i+Hcmjpg2nEe0YXUCNF5bkKy1NnBv1y7Q==", "optional": true }, "@esbuild/win32-ia32": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz", - "integrity": "sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.17.tgz", + "integrity": "sha512-yczSLRbDdReCO74Yfc5tKG0izzm+lPMYyO1fFTcn0QNwnKmc3K+HdxZWLGKg4pZVte7XVgcFku7TIZNbWEJdeQ==", "optional": true }, "@esbuild/win32-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz", - "integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.17.tgz", + "integrity": "sha512-FNZw7H3aqhF9OyRQbDDnzUApDXfC1N6fgBhkqEO2jvYCJ+DxMTfZVqg3AX0R1khg1wHTBRD5SdcibSJ+XF6bFg==", "optional": true }, + "@types/flexsearch": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@types/flexsearch/-/flexsearch-0.7.3.tgz", + "integrity": "sha512-HXwADeHEP4exXkCIwy2n1+i0f1ilP1ETQOH5KDOugjkTFZPntWo0Gr8stZOaebkxsdx+k0X/K6obU/+it07ocg==", + "dev": true + }, + "@types/linkify-it": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", + "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "dev": true + }, + "@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "requires": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "@types/mdurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", + "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", + "dev": true + }, "@types/web-bluetooth": { "version": "0.0.16", "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==" }, "@vitejs/plugin-vue": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.0.0.tgz", - "integrity": "sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.1.0.tgz", + "integrity": "sha512-++9JOAFdcXI3lyer9UKUV4rfoQ3T1RN8yDqoCLar86s0xQct5yblxAE+yWgRnU5/0FOlVCpTZpYSBV/bGWrSrQ==", "requires": {} }, "@vue/compiler-core": { @@ -1577,41 +1677,41 @@ "integrity": "sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==" }, "@vueuse/core": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.12.0.tgz", - "integrity": "sha512-h/Di8Bvf6xRcvS/PvUVheiMYYz3U0tH3X25YxONSaAUBa841ayMwxkuzx/DGUMCW/wHWzD8tRy2zYmOC36r4sg==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.0.2.tgz", + "integrity": "sha512-/UGc2cXbxbeIFLDSJyHUjI9QZ4CJJkhiJe9TbKNPSofcWmYhhUgJ+7iw9njXTKu/Xc3Z6UeXVR9fosW1+cyrnQ==", "requires": { "@types/web-bluetooth": "^0.0.16", - "@vueuse/metadata": "9.12.0", - "@vueuse/shared": "9.12.0", - "vue-demi": "*" + "@vueuse/metadata": "10.0.2", + "@vueuse/shared": "10.0.2", + "vue-demi": ">=0.14.0" }, "dependencies": { "vue-demi": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", - "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz", + "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==", "requires": {} } } }, "@vueuse/metadata": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.12.0.tgz", - "integrity": "sha512-9oJ9MM9lFLlmvxXUqsR1wLt1uF7EVbP5iYaHJYqk+G2PbMjY6EXvZeTjbdO89HgoF5cI6z49o2zT/jD9SVoNpQ==" + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.0.2.tgz", + "integrity": "sha512-APSjlABrV+Q74c+FR0kFETvcN9W2pAaT3XF3WwqWUuk4srmVxv7DY4WshZxK2KYk1+MVY0Fus6J1Hk/JXVm6Aw==" }, "@vueuse/shared": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.12.0.tgz", - "integrity": "sha512-TWuJLACQ0BVithVTRbex4Wf1a1VaRuSpVeyEd4vMUWl54PzlE0ciFUshKCXnlLuD0lxIaLK4Ypj3NXYzZh4+SQ==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.0.2.tgz", + "integrity": "sha512-7W2l6qZaFvla3zAeEVo8hNHkNRKCezJa3JjZAKv3K4KsevXobHhVNr+RHaOVNK/6ETpFmtqiK+0pMIADbHjjag==", "requires": { - "vue-demi": "*" + "vue-demi": ">=0.14.0" }, "dependencies": { "vue-demi": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz", - "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz", + "integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==", "requires": {} } } @@ -1622,24 +1722,24 @@ "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" }, "algoliasearch": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.14.3.tgz", - "integrity": "sha512-GZTEuxzfWbP/vr7ZJfGzIl8fOsoxN916Z6FY2Egc9q2TmZ6hvq5KfAxY89pPW01oW/2HDEKA8d30f9iAH9eXYg==", + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.17.0.tgz", + "integrity": "sha512-JMRh2Mw6sEnVMiz6+APsi7lx9a2jiDFF+WUtANaUVCv6uSU9UOLdo5h9K3pdP6frRRybaM2fX8b1u0nqICS9aA==", "requires": { - "@algolia/cache-browser-local-storage": "4.14.3", - "@algolia/cache-common": "4.14.3", - "@algolia/cache-in-memory": "4.14.3", - "@algolia/client-account": "4.14.3", - "@algolia/client-analytics": "4.14.3", - "@algolia/client-common": "4.14.3", - "@algolia/client-personalization": "4.14.3", - "@algolia/client-search": "4.14.3", - "@algolia/logger-common": "4.14.3", - "@algolia/logger-console": "4.14.3", - "@algolia/requester-browser-xhr": "4.14.3", - "@algolia/requester-common": "4.14.3", - "@algolia/requester-node-http": "4.14.3", - "@algolia/transporter": "4.14.3" + "@algolia/cache-browser-local-storage": "4.17.0", + "@algolia/cache-common": "4.17.0", + "@algolia/cache-in-memory": "4.17.0", + "@algolia/client-account": "4.17.0", + "@algolia/client-analytics": "4.17.0", + "@algolia/client-common": "4.17.0", + "@algolia/client-personalization": "4.17.0", + "@algolia/client-search": "4.17.0", + "@algolia/logger-common": "4.17.0", + "@algolia/logger-console": "4.17.0", + "@algolia/requester-browser-xhr": "4.17.0", + "@algolia/requester-common": "4.17.0", + "@algolia/requester-node-http": "4.17.0", + "@algolia/transporter": "4.17.0" } }, "ansi-sequence-parser": { @@ -1647,6 +1747,12 @@ "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==" }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -1667,33 +1773,39 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" }, + "entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true + }, "esbuild": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", - "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==", + "version": "0.17.17", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.17.tgz", + "integrity": "sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==", "requires": { - "@esbuild/android-arm": "0.16.17", - "@esbuild/android-arm64": "0.16.17", - "@esbuild/android-x64": "0.16.17", - "@esbuild/darwin-arm64": "0.16.17", - "@esbuild/darwin-x64": "0.16.17", - "@esbuild/freebsd-arm64": "0.16.17", - "@esbuild/freebsd-x64": "0.16.17", - "@esbuild/linux-arm": "0.16.17", - "@esbuild/linux-arm64": "0.16.17", - "@esbuild/linux-ia32": "0.16.17", - "@esbuild/linux-loong64": "0.16.17", - "@esbuild/linux-mips64el": "0.16.17", - "@esbuild/linux-ppc64": "0.16.17", - "@esbuild/linux-riscv64": "0.16.17", - "@esbuild/linux-s390x": "0.16.17", - "@esbuild/linux-x64": "0.16.17", - "@esbuild/netbsd-x64": "0.16.17", - "@esbuild/openbsd-x64": "0.16.17", - "@esbuild/sunos-x64": "0.16.17", - "@esbuild/win32-arm64": "0.16.17", - "@esbuild/win32-ia32": "0.16.17", - "@esbuild/win32-x64": "0.16.17" + "@esbuild/android-arm": "0.17.17", + "@esbuild/android-arm64": "0.17.17", + "@esbuild/android-x64": "0.17.17", + "@esbuild/darwin-arm64": "0.17.17", + "@esbuild/darwin-x64": "0.17.17", + "@esbuild/freebsd-arm64": "0.17.17", + "@esbuild/freebsd-x64": "0.17.17", + "@esbuild/linux-arm": "0.17.17", + "@esbuild/linux-arm64": "0.17.17", + "@esbuild/linux-ia32": "0.17.17", + "@esbuild/linux-loong64": "0.17.17", + "@esbuild/linux-mips64el": "0.17.17", + "@esbuild/linux-ppc64": "0.17.17", + "@esbuild/linux-riscv64": "0.17.17", + "@esbuild/linux-s390x": "0.17.17", + "@esbuild/linux-x64": "0.17.17", + "@esbuild/netbsd-x64": "0.17.17", + "@esbuild/openbsd-x64": "0.17.17", + "@esbuild/sunos-x64": "0.17.17", + "@esbuild/win32-arm64": "0.17.17", + "@esbuild/win32-ia32": "0.17.17", + "@esbuild/win32-x64": "0.17.17" } }, "estree-walker": { @@ -1701,24 +1813,23 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" }, + "flexsearch": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/flexsearch/-/flexsearch-0.7.31.tgz", + "integrity": "sha512-XGozTsMPYkm+6b5QL3Z9wQcJjNYxp0CYn3U1gO7dwD6PAqU1SVWZxI9CCg3z+ml3YfqdPnrBehaBrnH2AGKbNA==", + "dev": true + }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "optional": true }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true }, "hexo-pagination": { "version": "0.1.0", @@ -1728,19 +1839,20 @@ "object-assign": "^4.1.0" } }, - "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "requires": { - "has": "^1.0.3" - } - }, "jsonc-parser": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" }, + "linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, "lodash.pick": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", @@ -1754,6 +1866,24 @@ "sourcemap-codec": "^1.4.8" } }, + "mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==" + }, + "markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, "markdown-it-custom-attrs": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/markdown-it-custom-attrs/-/markdown-it-custom-attrs-1.0.2.tgz", @@ -1764,6 +1894,17 @@ "nunjucks": "^3.0.1" } }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, + "minisearch": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-6.0.1.tgz", + "integrity": "sha512-Ly1w0nHKnlhAAh6/BF/+9NgzXfoJxaJ8nhopFhQ3NcvFJrFIL+iCg9gw9e9UMBD+XIsp/RyznJ/o5UIe5Kw+kg==" + }, "nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -1784,11 +1925,6 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -1805,32 +1941,22 @@ } }, "preact": { - "version": "10.11.3", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz", - "integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==" - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } + "version": "10.13.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.13.2.tgz", + "integrity": "sha512-q44QFLhOhty2Bd0Y46fnYW0gD/cbVM9dUVtNTDKPcdXSMA7jfY+Jpd6rk3GB0lcQss0z5s/6CmVP0Z/hV+g6pw==" }, "rollup": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.14.0.tgz", - "integrity": "sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q==", + "version": "3.20.6", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.6.tgz", + "integrity": "sha512-2yEB3nQXp/tBQDN0hJScJQheXdvU2wFhh6ld7K/aiZ1vYcak6N/BKjY1QrU6BvO2JWYS8bEs14FRaxXosxy2zw==", "requires": { "fsevents": "~2.3.2" } }, "shiki": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.0.tgz", - "integrity": "sha512-fb9Fg1Yx/ElVJcTqPQIEOSfn7mSZlrT1W3CkymY08lL2Jsi+t7jPcZzKO1lCsQwlSDuyNhHvolnyA2OI4EgJNg==", + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.1.tgz", + "integrity": "sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw==", "requires": { "ansi-sequence-parser": "^1.1.0", "jsonc-parser": "^3.2.0", @@ -1853,37 +1979,51 @@ "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true }, "vite": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.1.tgz", - "integrity": "sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.0.tgz", + "integrity": "sha512-JTGFgDh3dVxeGBpuQX04Up+JZmuG6wu9414Ei36vQzaEruY/M4K0AgwtuB2b4HaBgB7R8l+LHxjB0jcgz4d2qQ==", "requires": { - "esbuild": "^0.16.14", + "esbuild": "^0.17.5", "fsevents": "~2.3.2", "postcss": "^8.4.21", - "resolve": "^1.22.1", - "rollup": "^3.10.0" + "rollup": "^3.20.2" } }, "vitepress": { - "version": "1.0.0-alpha.45", - "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.0.0-alpha.45.tgz", - "integrity": "sha512-8AVWdymQqBUPmXmAbpapDDg18iDmkNJ47l5eOklBlAjj3n8P3zDAsBhOWSQ6+Nvm6+/GaZATyAvsrg47JD5Idw==", + "version": "1.0.0-alpha.72", + "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.0.0-alpha.72.tgz", + "integrity": "sha512-Ou7fNE/OVYLrKGQMHSTVG6AcNsdv7tm4ACrdhx93SPMzEDj8UgIb4RFa5CTTowaYf3jeDGi2EAJlzXVC+IE3dg==", "requires": { - "@docsearch/css": "^3.3.2", - "@docsearch/js": "^3.3.2", - "@vitejs/plugin-vue": "^4.0.0", + "@docsearch/css": "^3.3.3", + "@docsearch/js": "^3.3.3", + "@vitejs/plugin-vue": "^4.1.0", "@vue/devtools-api": "^6.5.0", - "@vueuse/core": "^9.12.0", + "@vueuse/core": "^10.0.2", "body-scroll-lock": "4.0.0-beta.0", - "shiki": "^0.14.0", - "vite": "^4.0.4", - "vue": "^3.2.45" + "mark.js": "^8.11.1", + "minisearch": "^6.0.1", + "shiki": "^0.14.1", + "vite": "^4.2.1", + "vue": "^3.2.47" + } + }, + "vitepress-plugin-search": { + "version": "1.0.4-alpha.20", + "resolved": "https://registry.npmjs.org/vitepress-plugin-search/-/vitepress-plugin-search-1.0.4-alpha.20.tgz", + "integrity": "sha512-zG+ev9pw1Mg7htABlFCNXb8XwnKN+qfTKw+vU0Ers6RIrABx+45EAAFBoaL1mEpl1FRFn1o/dQ7F4b8GP6HdGQ==", + "dev": true, + "requires": { + "@types/flexsearch": "^0.7.3", + "@types/markdown-it": "^12.2.3", + "glob-to-regexp": "^0.4.1", + "markdown-it": "^13.0.1" } }, "vscode-oniguruma": { diff --git a/docs/package.json b/docs/package.json index 320ab4b8d1..4b483a6073 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,10 +1,11 @@ { - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.7", "name": "laf-docs", "private": true, "scripts": { "start": "npm run dev", "dev": "vitepress dev", + "preinstall": "node ./scripts/check-version.js", "build": "vitepress build && npm run after-build", "serve": "vitepress serve", "after-build": "sed -i -e \"s@@@g\" ./.vitepress/dist/index.html", @@ -14,5 +15,9 @@ "dependencies": { "markdown-it-custom-attrs": "^1.0.2", "vitepress": "^1.0.0-alpha.29" + }, + "devDependencies": { + "flexsearch": "^0.7.31", + "vitepress-plugin-search": "^1.0.4-alpha.20" } -} +} \ No newline at end of file diff --git a/docs/public/logo.png b/docs/public/logo.png index 523a73cfaa..f3fa36060c 100644 Binary files a/docs/public/logo.png and b/docs/public/logo.png differ diff --git a/docs/public/zhuo.png b/docs/public/zhuo.png deleted file mode 100644 index 6624703a9d..0000000000 Binary files a/docs/public/zhuo.png and /dev/null differ diff --git a/docs/screenshots.md b/docs/screenshots.md deleted file mode 100644 index 7807b20d67..0000000000 --- a/docs/screenshots.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: laf.js 云开发预览图 -sidebar: false ---- - -# {{ $frontmatter.title }} - -## 应用列表 - -![](https://9b069020-06e3-4949-83d9-992a52ca99fe.lafyun.com/file/laf_preview_screens/apps.png) - -## 云函数列表 - -![](https://9b069020-06e3-4949-83d9-992a52ca99fe.lafyun.com/file/laf_preview_screens/functions.png) - -## 在线开发云函数 - -![](https://9b069020-06e3-4949-83d9-992a52ca99fe.lafyun.com/file/laf_preview_screens/ide.png) - -## 云存储:文件管理 - -![](https://9b069020-06e3-4949-83d9-992a52ca99fe.lafyun.com/file/laf_preview_screens/files.png) - -## 云数据库:数据管理 - -![](https://9b069020-06e3-4949-83d9-992a52ca99fe.lafyun.com/file/laf_preview_screens/collection.png) - -## 云数据库:访问策略 - -![](https://9b069020-06e3-4949-83d9-992a52ca99fe.lafyun.com/file/laf_preview_screens/policy.png) - -## 远程部署 - -![](https://9b069020-06e3-4949-83d9-992a52ca99fe.lafyun.com/file/laf_preview_screens/deploy.png) - -## 协作成员 - -![](https://9b069020-06e3-4949-83d9-992a52ca99fe.lafyun.com/file/laf_preview_screens/member.png) diff --git a/docs/scripts/check-version.js b/docs/scripts/check-version.js new file mode 100644 index 0000000000..4029ff68cd --- /dev/null +++ b/docs/scripts/check-version.js @@ -0,0 +1,7 @@ +// Lock lockFileVersion to version 2 And resolve import error when import xxx from 'node:xxx' +if (process.version && +process.version.slice(1).split(".")[0] < 16) { + console.log( + `Required node version >= 16 not satisfied with current version ${process.version}.` + ); + process.exit(1); +} diff --git a/docs/vite.config.js b/docs/vite.config.js index b926c8611b..8f9948b91a 100644 --- a/docs/vite.config.js +++ b/docs/vite.config.js @@ -1,11 +1,23 @@ -// vite.config.js -export default { - // config options +//vite.config.js +import { SearchPlugin } from "vitepress-plugin-search"; +import { defineConfig } from "vite"; + +export default defineConfig({ + base: "./", server: { - fs: { - // Allow serving files from one level up to the project root - allow: ["."], - strict: false, - }, + port: 5173, + hmr: false, + disableHostCheck: true, }, -}; + plugins: [ + SearchPlugin({ + encode: false, + tokenize: "full", + previewLength: 62, + buttonLabel: "Search", + placeholder: "Search docs", + cache: true, + context: false, + }), + ], +}); diff --git a/e2e/e2e.sh b/e2e/e2e.sh new file mode 100644 index 0000000000..3eb856baad --- /dev/null +++ b/e2e/e2e.sh @@ -0,0 +1,366 @@ +#!/bin/bash + +# This script is used to run e2e test, +# You can also run it locally to test laf installation and deployment. + +# cd to this dir and run `sh e2e.sh` to test + +############# setup env vars ############# + +echo "================= setup env vars =================" + +if [ -z "$DOMAIN" ]; then + DOMAIN="127.0.0.1.nip.io" +fi + +API_ENDPOINT="http://api.${DOMAIN}" + +if [ -z "$GET_LAF_API_ROUTE_MAX_RETRY_COUNT" ]; then + GET_LAF_API_ROUTE_MAX_RETRY_COUNT=60 +fi + +if [ -z "${LAF_DEPLOYMENT_TIMEOUT}" ]; then + LAF_DEPLOYMENT_TIMEOUT=180 +fi + +if [ -z "${LAF_SERVER_RESTART_TIMEOUT}" ]; then + LAF_SERVER_RESTART_TIMEOUT=120 +fi + +if [ -z "${LAF_CREATE_APP_NS_AND_POD_TIMEOUT}" ]; then + LAF_CREATE_APP_NS_AND_POD_TIMEOUT=180 +fi + +# We comment the following line to use this script both in github action and local +# GitHub Action: depoly laf in github action +# Local: deploy laf in advance and use telepresence to forward network requests from laf-server and runtime to local +# Local(on a clean Linux machine): (TODO: uncomment the following line and run) + +############# install sealos ############# + +# echo "================= install sealos =================" + +# echo "deb [trusted=yes] https://apt.fury.io/labring/ /" | sudo tee /etc/apt/sources.list.d/labring.list +# sudo apt update +# sudo apt install sealos=4.1.4 +# sudo sealos version + +############ Dockerize laf in local ############ + +# TODO: install buildx, build, tag to docker.io/lafyun/laf-xxx:latest (laf-server, laf-web, runtime-node-init) + +# ############# Build sealos cluster image ############# + +# TODO: install buildah and build sealos cluster image + +# echo "================= Deploy laf =================" + +# sudo sh ../deploy/scripts/install-on-linux.sh $DOMAIN + +############## Check Laf Deployment ############## + +echo "================= Check Laf Deployment =================" + +set +e +kubectl wait --for=condition=Ready pod --all -n laf-system --timeout=${LAF_DEPLOYMENT_TIMEOUT}s +if [ $? -ne 0 ]; then + echo "some pods in laf-system namespace are not running\n" + echo "try to describe pods in laf-system namespace whose status is not Running\n" + kubectl get pods -n laf-system --field-selector=status.phase!=Running -o=name | xargs kubectl describe -n laf-system + echo "try to log pods in laf-system namespace whose status is not Running\n" + kubectl get pods -n laf-system --field-selector=status.phase!=Running -o=name | xargs kubectl logs -n laf-system + exit 1 +fi + +############## Get Laf config and secrets ############## + +MONGODB_USER=$(kubectl get secret --namespace laf-system mongodb-mongodb-init -o jsonpath="{.data.username}" | base64 --decode) +MONGODB_PASSWORD=$(kubectl get secret --namespace laf-system mongodb-mongodb-init -o jsonpath="{.data.password}" | base64 --decode) + +echo "mongodb user is ${MONGODB_USER}" +echo "mongodb passwd is ${MONGODB_PASSWORD}" + +APISIX_ADMIN_KEY=$(kubectl get configmap apisix-configmap -n laf-system -o jsonpath='{.data.config\.yaml}' | grep "default_cluster_admin_key" | awk -F': ' '{print $2}' | tr -d '"') +echo "APISIX_ADMIN_KEY is ${APISIX_ADMIN_KEY}" + +############## Wait for Apisix api route ready ############## + +echo "================= Wait for Apisix api route ready =================" + +LAF_API_DOMAIN=api.$DOMAIN +APISIX_ADMIN_URL=http://$DOMAIN:9180/apisix/admin + +get_api_roytes_retry_count=0 + +while [ $get_api_roytes_retry_count -lt $GET_LAF_API_ROUTE_MAX_RETRY_COUNT ] +do + response=$(curl -s $APISIX_ADMIN_URL/routes -H "X-API-KEY: $APISIX_ADMIN_KEY") + laf_api_route_exists=$(echo $response | jq '.node.nodes[].value.host' | grep -c $LAF_API_DOMAIN) + if [ $laf_api_route_exists -gt 0 ] + then + echo "Find route for $LAF_API_DOMAIN" + break + fi + echo "Can not Find route for $LAF_API_DOMAIN. Retrying in 1 second..." + sleep 1 + get_api_roytes_retry_count=$((get_api_roytes_retry_count+1)) +done +if [ $laf_api_route_exists -eq 0 ] +then + echo "Can not Find route for $LAF_API_DOMAIN. Exit" + exit 1 +fi + +############## Get Laf token ############## + +echo "================= Get Laf token =================" + +# set -e +echo "Create a Laf user and get Laf token" + +get_laf_token_response=$(curl -X 'POST' -sS -o - \ + "${API_ENDPOINT}/v1/auth/passwd/signup" \ + -H 'accept: application/json' \ + -H 'Content-Type: application/json' \ + --data-raw '{"username":"laf-user","password":"laf-user-password","type":"Signup"}') + +echo "${get_laf_token_response}" + +LAF_TOKEN=$(echo "${get_laf_token_response}" | jq -r '.data.token') + +echo "LAF_TOKEN is ${LAF_TOKEN}" + +if [ -z "${LAF_TOKEN}" ] || [ "${LAF_TOKEN}" = "null" ]; then + echo "Error: LAF_TOKEN is empty or null." + exit 1 +fi +# echo "LAF_TOKEN=${LAF_TOKEN}" >> $GITHUB_ENV + +############### Get Laf region, bundle and runtime id ############### + + +echo "================= Get Laf region, bundle and runtime id =================" + +response=$(curl -X 'GET' -sS "${API_ENDPOINT}/v1/regions" -H 'accept: */*') +REGION_ID=$(echo $response | jq -r '.data[0].id') +BUNDLE_ID=$(echo $response | jq -r '.data[0].bundles[0].id') + +echo "REGION_ID is ${REGION_ID}" +echo "BUNDLE_ID is ${BUNDLE_ID}" + +# echo "REGION_ID=${REGION_ID}" >> $GITHUB_ENV +# echo "BUNDLE_ID=${BUNDLE_ID}" >> $GITHUB_ENV + +response=$(curl -X 'GET' -sS "${API_ENDPOINT}/v1/runtimes" -H 'accept: */*') +RUNTIME_ID=$(echo $response | jq -r '.data[0].id') +echo "RUNTIME_ID is ${RUNTIME_ID}" +# echo "RUNTIME_ID=${RUNTIME_ID}" >> $GITHUB_ENV + +############### Create a Laf application ############### + +echo "================= Create a Laf application =================" + +# set -e + +echo "Start to create Laf application" + +curl -sS "${API_ENDPOINT}/v1/subscriptions" \ + -H "Accept: application/json, text/plain, */*" \ + -H "Authorization: Bearer ${LAF_TOKEN}" \ + -H "Content-Type: application/json" \ + -H "DNT: 1" \ + -H "Connection: keep-alive" \ + --data-raw "{ + \"name\":\"laf-e2e-test\", + \"state\":\"Running\", + \"regionId\":\"${REGION_ID}\", + \"bundleId\":\"${BUNDLE_ID}\", + \"subscriptionOption\":{ + \"name\":\"monthly\", + \"displayName\":\"1 Month\", + \"duration\":2678400, + \"price\":0, + \"specialPrice\":0 + }, + \"runtimeId\":\"${RUNTIME_ID}\", + \"duration\":2678400 + }" --compressed --insecure + +echo "" + +echo "Start to get Laf APP_ID" + +MAX_RETRIES=30 +RETRY_INTERVAL=1 + +for i in $(seq 1 $MAX_RETRIES); do + echo "Trying request #$i ... to get APP_ID" + response=$(curl -s -X 'GET' "${API_ENDPOINT}/v1/applications" \ + -H 'accept: */*' \ + -H "Authorization: Bearer ${LAF_TOKEN}") + + count=$(echo $response | jq '.data | length') + + if [ $count -gt 0 ] + then + appid=$(echo $response | jq -r '.data[0].appid') + export APP_ID=$appid + echo "APP_ID is ${APP_ID}" + # echo "APP_ID=${APP_ID}" >> $GITHUB_ENV + break + else + retries=$((retries+1)) + sleep $RETRY_INTERVAL + fi +done + +if [ $count -eq 0 ] +then + echo "Failed to get APP_ID" + exit 1 +fi + +echo "Wait for Laf application to be ready" + +# wait for laf-server to create ns +i=0; while [ $i -lt ${LAF_CREATE_APP_NS_AND_POD_TIMEOUT} ]; do if kubectl get namespace ${APP_ID} > /dev/null 2>&1; then break; fi; i=$((i+1)); sleep 1; done + +# node: we can not use "kubectl wait --for=condition=Ready pod" straightly because it will cause "no matching resources found" error when pod is not created + +pod_count=0; +i=0; +while [ $pod_count -eq 0 ] && [ $i -lt ${LAF_CREATE_APP_NS_AND_POD_TIMEOUT} ]; do + pod_count=$(kubectl get pods -n ${APP_ID} --no-headers=true | wc -l); + if [ $pod_count -eq 0 ]; then + sleep 1; + i=$((i+1)); + fi; +done; + +if [ $pod_count -eq 0 ]; then + echo "timeout to create app pod in ${APP_ID} namespace" + exit 1 +fi + +# set +e +kubectl wait --for=condition=Ready pod --all -n ${APP_ID} --timeout=${LAF_CREATE_APP_NS_AND_POD_TIMEOUT}s +if [ $? -ne 0 ]; then + echo "app pod in ${APP_ID} namespace are not running\n" + echo "try to describe app pod in ${APP_ID} namespace whose status is not Running\n" + kubectl get pods -n ${APP_ID} --field-selector=status.phase!=Running -o=name | xargs kubectl describe -n ${APP_ID} + echo "try to log app pod in ${APP_ID} namespace whose status is not Running\n" + kubectl get pods -n ${APP_ID} --field-selector=status.phase!=Running -o=name | xargs kubectl logs -n ${APP_ID} + exit 1 +fi + + +################### Note ################### + +echo "================= This Code below should be rewritten with js/ts code with e2e test framework =================" + +################### Create a function(Hello Laf) ################### + +echo "================= Create a function =================" + +APP_BASE_URL=http://${APP_ID}.${DOMAIN} + +# or may occur "503 Service Temporarily Unavailable" +sleep 5 + +echo "Create a Hello Laf function" + +curl -sS "${API_ENDPOINT}/v1/apps/${APP_ID}/functions" \ + -H 'Accept: application/json, text/plain, */*' \ + -H 'Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7' \ + -H "Authorization: Bearer ${LAF_TOKEN}" \ + -H 'Connection: keep-alive' \ + -H 'Content-Type: application/json' \ + -H 'DNT: 1' \ + --data @f1-payload.json \ + --compressed \ + --insecure + +echo "" + +sleep 5 + +echo "Test Hello Laf function" + +curl "${APP_BASE_URL}/f1" -sS -o - \ + -H 'Accept: application/json, text/plain, */*' \ + -H 'Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7' \ + -H 'Cache-Control: no-cache' \ + -H 'Connection: keep-alive' \ + -H 'DNT: 1' \ + --compressed \ + --insecure | grep -q '{"data":"hi, laf"}' \ + || (echo "Error: response data during create hello laf function is not expected" && exit 1) + +echo "" + +echo "Succeed to create Hello Laf function and the response data is expected" + +echo "Create a function with db operation and test function PATCH" + +################### Create a function(db example) and PATCH ################### + +# first create a simple function +curl -sS "${API_ENDPOINT}/v1/apps/${APP_ID}/functions" \ + -H 'Accept: application/json, text/plain, */*' \ + -H 'Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7' \ + -H "Authorization: Bearer ${LAF_TOKEN}" \ + -H 'Connection: keep-alive' \ + -H 'Content-Type: application/json' \ + -H 'DNT: 1' \ + --data @f2-origin-payload.json \ + --compressed \ + --insecure + +echo "" + +sleep 1 + +# then patch it to a db function +curl -X 'PATCH' -sS "${API_ENDPOINT}/v1/apps/${APP_ID}/functions/f2" \ + -H 'Accept: application/json, text/plain, */*' \ + -H 'Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7' \ + -H "Authorization: Bearer ${LAF_TOKEN}" \ + -H 'Connection: keep-alive' \ + -H 'Content-Type: application/json' \ + -H 'DNT: 1' \ + --data @f2-update-payload.json \ + --compressed \ + --insecure + +echo "" + +sleep 1 + +# test POST in the meantime +response=$(curl -X POST -sS ${APP_BASE_URL}/f2 -d '') + +ok=$(echo $response | jq -r '.ok') +name=$(echo $response | jq -r '.data.name') + +if [ "$ok" != "true" ] || [ "$name" != "hello laf" ]; then + echo "Error: response data during create db example function is not expected" + exit 1 +fi + +echo "Succeed to create db example function and the response data is expected" + +# install mongodb +# if [ -x "$(command -v mongo)" ]; then +# echo "MongoDB client is already installed." +# else +# # Install MongoDB client using apt +# echo "MongoDB client is not installed. Installing..." +# sudo apt update +# sudo apt install -y mongodb-clients +# fi + +# echo "Read databse by API to check if the data is inserted" + +####################### execute js/ts test code ####################### + +echo "================= Test End =================" diff --git a/e2e/f1-payload.json b/e2e/f1-payload.json new file mode 100644 index 0000000000..c4fccea0b5 --- /dev/null +++ b/e2e/f1-payload.json @@ -0,0 +1,12 @@ +{ + "name": "f1", + "description": "laf e2e function(hello-laf)", + "methods": [ + "GET", + "POST" + ], + "code": "import cloud from '@lafjs/cloud'\n\nexport async function main(ctx: FunctionContext) {\n console.log('Hello World')\n return { data: 'hi, laf' }\n}", + "tags": [ + "e2e" + ] +} diff --git a/e2e/f2-origin-payload.json b/e2e/f2-origin-payload.json new file mode 100644 index 0000000000..c3d8d7b915 --- /dev/null +++ b/e2e/f2-origin-payload.json @@ -0,0 +1,12 @@ +{ + "name": "f2", + "description": "laf e2e function(db example)", + "methods": [ + "GET", + "POST" + ], + "code": "import cloud from '@lafjs/cloud'\n\nexport async function main(ctx: FunctionContext) {\n console.log('Hello World')\n return { data: 'hi, laf' }\n}", + "tags": [ + "e2e" + ] +} diff --git a/e2e/f2-update-payload.json b/e2e/f2-update-payload.json new file mode 100644 index 0000000000..043a63b072 --- /dev/null +++ b/e2e/f2-update-payload.json @@ -0,0 +1,12 @@ +{ + "name": "f2", + "description": "laf e2e function(db example)", + "methods": [ + "GET", + "POST" + ], + "code": "import cloud from '@lafjs/cloud'\n\nconst db = cloud.database()\n\nexport async function main(ctx: FunctionContext) {\n // insert data\n const insertRes = await db.collection('test').add({ name: \"hello laf\" })\n console.log(insertRes)\n if (insertRes.ok) {\n // get data\n const res = await db.collection('test').getOne()\n console.log(res)\n return res\n } else {\n return { data: insertRes.error }\n }\n}", + "tags": [ + "e2e" + ] +} diff --git a/lerna.json b/lerna.json index acf5c90a51..ab29816794 100644 --- a/lerna.json +++ b/lerna.json @@ -7,7 +7,7 @@ "./runtimes/nodejs", "./cli" ], - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "command": { "publish": { "ignoreChanges": [ diff --git a/packages/client-sdk/README.md b/packages/client-sdk/README.md index 07869fa84b..5223a16341 100644 --- a/packages/client-sdk/README.md +++ b/packages/client-sdk/README.md @@ -68,7 +68,7 @@ const cloud = new Cloud({ baseUrl: "https://APPID.lafyun.com", // the database proxy entry, `app` is the policy name which response for the security of database access dbProxyUrl: "/proxy/app", - getAccessToken: () => localStorage.getItem("access_token"), + getAccessToken: () => wx.getStorageSync('access_token'), environment: "wxmp", }); ``` diff --git a/packages/client-sdk/package-lock.json b/packages/client-sdk/package-lock.json index 89cccc5493..a52b90fd41 100644 --- a/packages/client-sdk/package-lock.json +++ b/packages/client-sdk/package-lock.json @@ -1,12 +1,12 @@ { "name": "laf-client-sdk", - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "laf-client-sdk", - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.7", "license": "ISC", "dependencies": { "axios": "^0.21.1", diff --git a/packages/client-sdk/package.json b/packages/client-sdk/package.json index d8bc85d636..7663702a5c 100644 --- a/packages/client-sdk/package.json +++ b/packages/client-sdk/package.json @@ -1,6 +1,6 @@ { "name": "laf-client-sdk", - "version": "1.0.0-beta.2", + "version": "1.0.0-beta.7", "description": "", "main": "dist/commonjs/index.js", "module": "dist/esm/index.js", diff --git a/packages/client-sdk/src/cloud.ts b/packages/client-sdk/src/cloud.ts index 556d42ee0a..a5abdb12dd 100644 --- a/packages/client-sdk/src/cloud.ts +++ b/packages/client-sdk/src/cloud.ts @@ -1,50 +1,53 @@ - -import { Db } from 'database-ql' -import { Request } from './request/request' -import { UniRequest } from './request/request-uni' -import { WxmpRequest } from './request/request-wxmp' -import { CloudOptions, EnvironmentType, RequestInterface } from './types' - +import { Db } from "database-ql"; +import { Request } from "./request/request"; +import { UniRequest } from "./request/request-uni"; +import { WxmpRequest } from "./request/request-wxmp"; +import { CloudOptions, EnvironmentType, RequestInterface } from "./types"; /** * class Cloud provide the interface to request cloud function and cloud database. */ class Cloud { - private config: CloudOptions + private config: CloudOptions; /** * request class by environment */ private get requestClass() { - const env = this.config?.environment - let ret = Request + const env = this.config?.environment; + let ret = Request; if (this.config?.requestClass) { - ret = this.config?.requestClass + ret = this.config?.requestClass; } else if (env === EnvironmentType.UNI_APP) { - ret = UniRequest + const { uniPlatform } = uni.getSystemInfoSync(); + if (uniPlatform == 'mp-weixin') { + ret = WxmpRequest; + } else { + ret = UniRequest; + } } else if (env === EnvironmentType.WX_MP) { - ret = WxmpRequest + ret = WxmpRequest; } else { - ret = Request + ret = Request; } - return ret + return ret; } /** * internal request class */ - protected _request: RequestInterface + protected _request: RequestInterface; /** * Create a cloud instance - * @param config + * @param config */ constructor(config: CloudOptions) { const warningFunc = () => { - console.warn('WARNING: no getAccessToken set for db proxy request') - return "" - } + console.warn("WARNING: no getAccessToken set for db proxy request"); + return ""; + }; this.config = { baseUrl: config.baseUrl, @@ -54,53 +57,47 @@ class Cloud { primaryKey: config?.primaryKey, timeout: config?.timeout, headers: config?.headers, - requestClass: config?.requestClass - } + requestClass: config?.requestClass, + }; - const reqClass = this.requestClass - this._request = new reqClass(this.config) + const reqClass = this.requestClass; + this._request = new reqClass(this.config); } /** * Get a cloud database instance - * @returns + * @returns */ database() { return new Db({ request: this._request, - primaryKey: this.config?.primaryKey - }) + primaryKey: this.config?.primaryKey, + }); } /** * Invoke cloud function by name use POST http method * @alias alias of `invoke()` for history reason - * @param functionName - * @param data - * @returns + * @param functionName + * @param data + * @returns */ - async invokeFunction(functionName: string, data: any): Promise { - const url = this.config.baseUrl + `/${functionName}` - const res = await this - ._request - .request(url, data) + async invokeFunction(functionName: string, data?: any): Promise { + const url = this.config.baseUrl + `/${functionName}`; + const res = await this._request.request(url, data); - return res.data + return res.data; } /** * Invoke cloud function by name use POST http method - * @param functionName - * @param data - * @returns + * @param functionName + * @param data + * @returns */ - async invoke(functionName: string, data: any): Promise { - return await this.invokeFunction(functionName, data) + async invoke(functionName: string, data?: any): Promise { + return await this.invokeFunction(functionName, data); } } -export { - Cloud, - Db, - Request -} +export { Cloud, Db, Request }; diff --git a/packages/cloud-sdk/package-lock.json b/packages/cloud-sdk/package-lock.json index 593be7348c..2b607abd82 100644 --- a/packages/cloud-sdk/package-lock.json +++ b/packages/cloud-sdk/package-lock.json @@ -1,12 +1,12 @@ { "name": "@lafjs/cloud", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@lafjs/cloud", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "license": "ISC", "dependencies": { "@types/express": "^4.17.15", diff --git a/packages/cloud-sdk/package.json b/packages/cloud-sdk/package.json index 7274e630dc..114aabe944 100644 --- a/packages/cloud-sdk/package.json +++ b/packages/cloud-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@lafjs/cloud", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "description": "The cloud sdk for laf cloud function", "main": "dist/index.js", "scripts": { diff --git a/packages/cloud-sdk/src/cloud.interface.ts b/packages/cloud-sdk/src/cloud.interface.ts index 407c52148c..e2f1de34c2 100644 --- a/packages/cloud-sdk/src/cloud.interface.ts +++ b/packages/cloud-sdk/src/cloud.interface.ts @@ -33,6 +33,7 @@ export interface CloudSdkInterface { /** * Invoke cloud function + * @deprecated Just import the cloud function directly, and then call it */ invoke: InvokeFunctionType diff --git a/runtimes/nodejs/Dockerfile b/runtimes/nodejs/Dockerfile index 3dd1bc5826..d376610085 100644 --- a/runtimes/nodejs/Dockerfile +++ b/runtimes/nodejs/Dockerfile @@ -1,5 +1,6 @@ -FROM node:18-alpine -RUN apk add --no-cache openssl +FROM node:18 + +RUN apt update && apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev git -y # RUN npm install npm -g diff --git a/runtimes/nodejs/Dockerfile.init b/runtimes/nodejs/Dockerfile.init index 86d5045a10..aaa1003b71 100644 --- a/runtimes/nodejs/Dockerfile.init +++ b/runtimes/nodejs/Dockerfile.init @@ -1,20 +1,3 @@ -FROM node:18-alpine -RUN apk add --no-cache openssl +FROM lafyun/runtime-node:latest -# RUN npm install npm -g - -EXPOSE 8000 -WORKDIR /app -ENV LOG_LEVEL=debug -COPY . /app -# COPY --chown=node:node . /app -RUN mkdir /app/data || true -RUN chown node:node /app/data -# RUN npm install -# RUN npm run build -RUN chown -R node:node /app/node_modules -RUN chown node:node /app/package.json -RUN chown node:node /app/package-lock.json - -USER node CMD [ "sh", "/app/init.sh" ] \ No newline at end of file diff --git a/runtimes/nodejs/README.md b/runtimes/nodejs/README.md index 48974e89c6..05715f5a76 100644 --- a/runtimes/nodejs/README.md +++ b/runtimes/nodejs/README.md @@ -52,7 +52,3 @@ npm start ```bash telepresence leave $APPID-$APPID ``` - -## Troubleshooting - -- `telepresence helm install` failed for `arm64 / Apple Chip` cluster, please upgrade your telepresence to `v2.11.1` or later. diff --git a/runtimes/nodejs/package-lock.json b/runtimes/nodejs/package-lock.json index 3261cf01f1..5219395c92 100644 --- a/runtimes/nodejs/package-lock.json +++ b/runtimes/nodejs/package-lock.json @@ -1,19 +1,19 @@ { "name": "runtime-nodejs", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "runtime-nodejs", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "dependencies": { "@aws-sdk/client-s3": "^3.231.0", "@aws-sdk/client-sts": "^3.231.0", "@aws-sdk/s3-request-presigner": "^3.231.0", "@kubernetes/client-node": "^0.18.0", - "@lafjs/cloud": "^1.0.0-beta.4", - "alipay-sdk": "^3.2.0", + "@lafjs/cloud": "^1.0.0-beta.7", + "alipay-sdk": "^2.0.2", "axios": "^1.2.1", "cors": "^2.8.5", "database-proxy": "^1.0.0-beta.2", @@ -49,7 +49,7 @@ "@types/nodemailer": "^6.4.4", "@types/validator": "^13.1.3", "@types/ws": "^8.5.3", - "typescript": "^4.9.5" + "typescript": "^5.0.2" } }, "node_modules/@aws-crypto/crc32": { @@ -1526,91 +1526,36 @@ "node": ">=14.0.0" } }, - "node_modules/@fidm/asn1": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@fidm/asn1/-/asn1-1.0.4.tgz", - "integrity": "sha512-esd1jyNvRb2HVaQGq2Gg8Z0kbQPXzV9Tq5Z14KNIov6KfFD6PTaRIO8UpcsYiTNzOqJpmyzWgVTrUwFV3UF4TQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@fidm/x509": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@fidm/x509/-/x509-1.2.1.tgz", - "integrity": "sha512-nwc2iesjyc9hkuzcrMCBXQRn653XuAUKorfWM8PZyJawiy1QzLj4vahwzaI25+pfpwOLvMzbJ0uKpWLDNmo16w==", - "dependencies": { - "@fidm/asn1": "^1.0.4", - "tweetnacl": "^1.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/@kubernetes/client-node": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.18.0.tgz", - "integrity": "sha512-Mp6q0OkZQBp+HslIgvHYpsPJk8z6mch231QWtIZQHvs+PaTE6mkUfusYE8fNw3jMjru5mVO/JDz6PTjB9YT2rQ==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.18.1.tgz", + "integrity": "sha512-F3JiK9iZnbh81O/da1tD0h8fQMi/MDttWc/JydyUVnjPEom55wVfnpl4zQ/sWD4uKB8FlxYRPiLwV2ZXB+xPKw==", "dependencies": { "@types/js-yaml": "^4.0.1", - "@types/node": "^10.12.0", + "@types/node": "^18.11.17", "@types/request": "^2.47.1", - "@types/ws": "^6.0.1", + "@types/ws": "^8.5.3", "byline": "^5.0.0", - "execa": "5.0.0", - "isomorphic-ws": "^4.0.1", + "isomorphic-ws": "^5.0.0", "js-yaml": "^4.1.0", - "jsonpath-plus": "^0.19.0", + "jsonpath-plus": "^7.2.0", "request": "^2.88.0", "rfc4648": "^1.3.0", - "shelljs": "^0.8.5", "stream-buffers": "^3.0.2", "tar": "^6.1.11", "tmp-promise": "^3.0.2", "tslib": "^2.4.1", "underscore": "^1.13.6", - "ws": "^7.3.1" + "ws": "^8.11.0" }, "optionalDependencies": { "openid-client": "^5.3.0" } }, - "node_modules/@kubernetes/client-node/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" - }, - "node_modules/@kubernetes/client-node/node_modules/@types/ws": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz", - "integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@kubernetes/client-node/node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/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/@lafjs/cloud": { - "version": "1.0.0-beta.4", - "resolved": "https://registry.npmjs.org/@lafjs/cloud/-/cloud-1.0.0-beta.4.tgz", - "integrity": "sha512-NRFLRL0ZkvPLl/0qUZS7kEt+ZoK7NOVkM/zFfKbxsBMjSOAjzlofDNSR3xulQl3AV+/SEiRENnlBxH/L08XD1Q==", + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@lafjs/cloud/-/cloud-1.0.0-beta.7.tgz", + "integrity": "sha512-JyVIon9sxq7fqROCU/4pn/2xcORKEZfZ65MwpUSf7yvXYv/BvhRMHFj98N9r6mGFLyfwJXfzGDNdjqMlGUKGPg==", "dependencies": { "@types/express": "^4.17.15", "@types/ws": "^8.5.3", @@ -1755,9 +1700,9 @@ } }, "node_modules/@types/node": { - "version": "18.11.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.15.tgz", - "integrity": "sha512-VkhBbVo2+2oozlkdHXLrb3zjsRkpdnaU2bXmX8Wgle3PUi569eLRaHGlgETQHR7lLL1w7GiG3h9SnePhxNDecw==" + "version": "18.15.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.5.tgz", + "integrity": "sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==" }, "node_modules/@types/nodemailer": { "version": "6.4.4", @@ -1946,31 +1891,18 @@ } }, "node_modules/alipay-sdk": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/alipay-sdk/-/alipay-sdk-3.2.0.tgz", - "integrity": "sha512-JnTXyn+t+3mkQReWvw6n56e1QlxXlJ/jg1G2Q6/Rbf6aBABaC7VlMhIPs9OTBLFnVbIADM95goTigtoGQYVjyA==", - "dependencies": { - "@fidm/x509": "^1.2.1", - "@types/node": "^9.6.0", - "bignumber.js": "^9.0.0", - "camelcase-keys": "^4.2.0", - "crypto-js": "^4.0.0", - "decamelize": "^2.0.0", - "is": "^3.2.1", - "is-json": "^2.0.1", - "isuri": "^2.0.3", - "lodash": "^4.17.20", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/alipay-sdk/-/alipay-sdk-2.0.2.tgz", + "integrity": "sha512-G6HiOnVwo8rMkqBgqG30DR6KMDs5k3YXqIxP5yanRSl8br3iLHiwSJ9PqZCgN/HJ7zDpWZDMsAdQ2vtIGmAm1Q==", + "dependencies": { + "camelcase": "^4.0.0", + "decamelize": "^1.2.0", + "extend2": "^1.0.0", + "is-plain-object": "^2.0.1", "moment": "^2.16.0", - "request": "^2.86.0", - "snakecase-keys": "^1.1.1", "urllib": "^2.17.0" } }, - "node_modules/alipay-sdk/node_modules/@types/node": { - "version": "9.6.61", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.61.tgz", - "integrity": "sha512-/aKAdg5c8n468cYLy2eQrcR5k6chlbNwZNGUj3TboyPa2hcO2QAJcfymlqPzMiRj8B6nYKXjzQz36minFE0RwQ==" - }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2139,14 +2071,6 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, - "node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "engines": { - "node": "*" - } - }, "node_modules/block-stream2": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/block-stream2/-/block-stream2-2.1.0.tgz", @@ -2399,20 +2323,7 @@ "node_modules/camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", - "dependencies": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" - }, + "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", "engines": { "node": ">=4" } @@ -2593,19 +2504,6 @@ "sha.js": "^2.4.8" } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmmirror.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -2627,11 +2525,6 @@ "node": "*" } }, - "node_modules/crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" - }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -2696,14 +2589,11 @@ } }, "node_modules/decamelize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", - "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", - "dependencies": { - "xregexp": "4.0.0" - }, + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, "node_modules/decode-uri-component": { @@ -3036,28 +2926,6 @@ "safe-buffer": "^5.1.1" } }, - "node_modules/execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", - "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" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, "node_modules/express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", @@ -3134,6 +3002,11 @@ "node": ">=0.10.0" } }, + "node_modules/extend2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/extend2/-/extend2-1.0.1.tgz", + "integrity": "sha512-ISoKeVhtewd5YHzMo+r9KC3Zx0fdpNBqoRzot+6BeEQ3bWQYQQOt0jkkY5gLveI2e7j+vdCJKeszHJIbg2Uceg==" + }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -3426,17 +3299,6 @@ "has-symbols": "^1.0.1" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -3768,14 +3630,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "engines": { - "node": ">=10.17.0" - } - }, "node_modules/humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", @@ -3841,14 +3695,6 @@ "node": ">= 0.4" } }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -3862,14 +3708,6 @@ "node": ">= 0.10" } }, - "node_modules/is": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", - "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==", - "engines": { - "node": "*" - } - }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/is-arguments/-/is-arguments-1.1.1.tgz", @@ -3910,17 +3748,6 @@ "node": ">= 0.4" } }, - "node_modules/is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmmirror.com/is-date-object/-/is-date-object-1.0.5.tgz", @@ -3951,11 +3778,6 @@ "node": ">= 0.4" } }, - "node_modules/is-json": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz", - "integrity": "sha1-a+Fm0USCihMdaGiRuYPfYsOUkf8=" - }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -3975,6 +3797,17 @@ "node": ">= 0.4" } }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", @@ -4000,17 +3833,6 @@ "call-bind": "^1.0.2" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-string": { "version": "1.0.7", "resolved": "https://registry.npmmirror.com/is-string/-/is-string-1.0.7.tgz", @@ -4066,15 +3888,18 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } }, "node_modules/isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", "peerDependencies": { "ws": "*" } @@ -4084,14 +3909,6 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, - "node_modules/isuri": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/isuri/-/isuri-2.0.3.tgz", - "integrity": "sha1-NDcSHbL+Za8LoIC34ahjb2MsypE=", - "dependencies": { - "rfc-3986": "1.0.1" - } - }, "node_modules/jake": { "version": "10.8.5", "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", @@ -4164,11 +3981,11 @@ } }, "node_modules/jsonpath-plus": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-0.19.0.tgz", - "integrity": "sha512-GSVwsrzW9LsA5lzsqe4CkuZ9wp+kxBb2GwNniaWzI2YFn5Ig42rSW8ZxVpWXaAfakXNrx5pgY5AbQq7kzX29kg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz", + "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==", "engines": { - "node": ">=6.0" + "node": ">=12.0.0" } }, "node_modules/jsonwebtoken": { @@ -4322,14 +4139,6 @@ "node": ">=10" } }, - "node_modules/map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", - "engines": { - "node": ">=4" - } - }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmmirror.com/md5.js/-/md5.js-1.3.5.tgz", @@ -4359,11 +4168,6 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -4419,14 +4223,6 @@ "node": ">= 0.6" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -4681,17 +4477,6 @@ "node": ">=6.0.0" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -4772,20 +4557,6 @@ "wrappy": "1" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/openid-client": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.3.1.tgz", @@ -4927,19 +4698,6 @@ "node": ">=0.10.0" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -5126,14 +4884,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/quick-lru": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", - "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", - "engines": { - "node": ">=4" - } - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz", @@ -5203,17 +4953,6 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmmirror.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -5266,30 +5005,6 @@ "node": ">=0.6" } }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/rfc-3986": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rfc-3986/-/rfc-3986-1.0.1.tgz", - "integrity": "sha1-7uuINC+tvoAnwPNq2pIaE+b5YgY=", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/rfc4648": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/rfc4648/-/rfc4648-1.5.2.tgz", @@ -5430,41 +5145,6 @@ "sha.js": "bin.js" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz", @@ -5475,11 +5155,6 @@ "object-inspect": "^1.9.0" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -5489,15 +5164,6 @@ "npm": ">= 3.0.0" } }, - "node_modules/snakecase-keys": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-1.2.0.tgz", - "integrity": "sha512-G5Faa3wQevGXcD5e4JKfmgofO+Fu4Jg4/nLyeZqWmBqVV0/3ORgervt3EjBi6PEFKhztPQWegZspteWnycx5dg==", - "dependencies": { - "map-obj": "~2.0.0", - "to-snake-case": "~0.1.2" - } - }, "node_modules/socks": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", @@ -5741,14 +5407,6 @@ "es-abstract": "^1.19.5" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "engines": { - "node": ">=6" - } - }, "node_modules/strnum": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", @@ -5765,17 +5423,6 @@ "node": ">=8" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/tar": { "version": "6.1.11", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", @@ -5855,27 +5502,6 @@ "tmp": "^0.2.0" } }, - "node_modules/to-no-case": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-0.1.1.tgz", - "integrity": "sha1-zzPHDg8oFo2V5BWavxUOjFQu+f4=" - }, - "node_modules/to-snake-case": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-0.1.2.tgz", - "integrity": "sha1-0Ee22/BI2uG9wmCzwpb1TKNO7Xw=", - "dependencies": { - "to-space-case": "0.1.2" - } - }, - "node_modules/to-space-case": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-0.1.2.tgz", - "integrity": "sha1-mma+Pr5T8nefaH8CYu/9H8W20V4=", - "dependencies": { - "to-no-case": "0.1.1" - } - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -5923,11 +5549,6 @@ "node": "*" } }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, "node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -5957,16 +5578,16 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=12.20" } }, "node_modules/unbox-primitive": { @@ -6181,20 +5802,6 @@ "node": ">=12" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/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", @@ -6292,11 +5899,6 @@ "node": ">=4.0" } }, - "node_modules/xregexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", - "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==" - }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -7553,71 +7155,34 @@ "tslib": "^2.3.1" } }, - "@fidm/asn1": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@fidm/asn1/-/asn1-1.0.4.tgz", - "integrity": "sha512-esd1jyNvRb2HVaQGq2Gg8Z0kbQPXzV9Tq5Z14KNIov6KfFD6PTaRIO8UpcsYiTNzOqJpmyzWgVTrUwFV3UF4TQ==" - }, - "@fidm/x509": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@fidm/x509/-/x509-1.2.1.tgz", - "integrity": "sha512-nwc2iesjyc9hkuzcrMCBXQRn653XuAUKorfWM8PZyJawiy1QzLj4vahwzaI25+pfpwOLvMzbJ0uKpWLDNmo16w==", - "requires": { - "@fidm/asn1": "^1.0.4", - "tweetnacl": "^1.0.1" - } - }, "@kubernetes/client-node": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.18.0.tgz", - "integrity": "sha512-Mp6q0OkZQBp+HslIgvHYpsPJk8z6mch231QWtIZQHvs+PaTE6mkUfusYE8fNw3jMjru5mVO/JDz6PTjB9YT2rQ==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.18.1.tgz", + "integrity": "sha512-F3JiK9iZnbh81O/da1tD0h8fQMi/MDttWc/JydyUVnjPEom55wVfnpl4zQ/sWD4uKB8FlxYRPiLwV2ZXB+xPKw==", "requires": { "@types/js-yaml": "^4.0.1", - "@types/node": "^10.12.0", + "@types/node": "^18.11.17", "@types/request": "^2.47.1", - "@types/ws": "^6.0.1", + "@types/ws": "^8.5.3", "byline": "^5.0.0", - "execa": "5.0.0", - "isomorphic-ws": "^4.0.1", + "isomorphic-ws": "^5.0.0", "js-yaml": "^4.1.0", - "jsonpath-plus": "^0.19.0", + "jsonpath-plus": "^7.2.0", "openid-client": "^5.3.0", "request": "^2.88.0", "rfc4648": "^1.3.0", - "shelljs": "^0.8.5", "stream-buffers": "^3.0.2", "tar": "^6.1.11", "tmp-promise": "^3.0.2", "tslib": "^2.4.1", "underscore": "^1.13.6", - "ws": "^7.3.1" - }, - "dependencies": { - "@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" - }, - "@types/ws": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz", - "integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==", - "requires": { - "@types/node": "*" - } - }, - "ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "requires": {} - } + "ws": "^8.11.0" } }, "@lafjs/cloud": { - "version": "1.0.0-beta.4", - "resolved": "https://registry.npmjs.org/@lafjs/cloud/-/cloud-1.0.0-beta.4.tgz", - "integrity": "sha512-NRFLRL0ZkvPLl/0qUZS7kEt+ZoK7NOVkM/zFfKbxsBMjSOAjzlofDNSR3xulQl3AV+/SEiRENnlBxH/L08XD1Q==", + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@lafjs/cloud/-/cloud-1.0.0-beta.7.tgz", + "integrity": "sha512-JyVIon9sxq7fqROCU/4pn/2xcORKEZfZ65MwpUSf7yvXYv/BvhRMHFj98N9r6mGFLyfwJXfzGDNdjqMlGUKGPg==", "requires": { "@types/express": "^4.17.15", "@types/ws": "^8.5.3", @@ -7759,9 +7324,9 @@ } }, "@types/node": { - "version": "18.11.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.15.tgz", - "integrity": "sha512-VkhBbVo2+2oozlkdHXLrb3zjsRkpdnaU2bXmX8Wgle3PUi569eLRaHGlgETQHR7lLL1w7GiG3h9SnePhxNDecw==" + "version": "18.15.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.5.tgz", + "integrity": "sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==" }, "@types/nodemailer": { "version": "6.4.4", @@ -7921,31 +7486,16 @@ } }, "alipay-sdk": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/alipay-sdk/-/alipay-sdk-3.2.0.tgz", - "integrity": "sha512-JnTXyn+t+3mkQReWvw6n56e1QlxXlJ/jg1G2Q6/Rbf6aBABaC7VlMhIPs9OTBLFnVbIADM95goTigtoGQYVjyA==", - "requires": { - "@fidm/x509": "^1.2.1", - "@types/node": "^9.6.0", - "bignumber.js": "^9.0.0", - "camelcase-keys": "^4.2.0", - "crypto-js": "^4.0.0", - "decamelize": "^2.0.0", - "is": "^3.2.1", - "is-json": "^2.0.1", - "isuri": "^2.0.3", - "lodash": "^4.17.20", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/alipay-sdk/-/alipay-sdk-2.0.2.tgz", + "integrity": "sha512-G6HiOnVwo8rMkqBgqG30DR6KMDs5k3YXqIxP5yanRSl8br3iLHiwSJ9PqZCgN/HJ7zDpWZDMsAdQ2vtIGmAm1Q==", + "requires": { + "camelcase": "^4.0.0", + "decamelize": "^1.2.0", + "extend2": "^1.0.0", + "is-plain-object": "^2.0.1", "moment": "^2.16.0", - "request": "^2.86.0", - "snakecase-keys": "^1.1.1", "urllib": "^2.17.0" - }, - "dependencies": { - "@types/node": { - "version": "9.6.61", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.61.tgz", - "integrity": "sha512-/aKAdg5c8n468cYLy2eQrcR5k6chlbNwZNGUj3TboyPa2hcO2QAJcfymlqPzMiRj8B6nYKXjzQz36minFE0RwQ==" - } } }, "ansi-styles": { @@ -8087,11 +7637,6 @@ } } }, - "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" - }, "block-stream2": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/block-stream2/-/block-stream2-2.1.0.tgz", @@ -8308,17 +7853,7 @@ "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" - }, - "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", - "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" - } + "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==" }, "caseless": { "version": "0.12.0", @@ -8468,16 +8003,6 @@ "sha.js": "^2.4.8" } }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmmirror.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -8496,11 +8021,6 @@ "randomfill": "^1.0.3" } }, - "crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" - }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -8556,12 +8076,9 @@ } }, "decamelize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", - "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", - "requires": { - "xregexp": "4.0.0" - } + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==" }, "decode-uri-component": { "version": "0.2.2", @@ -8825,22 +8342,6 @@ "safe-buffer": "^5.1.1" } }, - "execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", - "requires": { - "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" - } - }, "express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", @@ -8907,6 +8408,11 @@ "is-extendable": "^0.1.0" } }, + "extend2": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/extend2/-/extend2-1.0.1.tgz", + "integrity": "sha512-ISoKeVhtewd5YHzMo+r9KC3Zx0fdpNBqoRzot+6BeEQ3bWQYQQOt0jkkY5gLveI2e7j+vdCJKeszHJIbg2Uceg==" + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -9138,11 +8644,6 @@ "has-symbols": "^1.0.1" } }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" - }, "get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -9401,11 +8902,6 @@ } } }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" - }, "humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", @@ -9451,11 +8947,6 @@ "side-channel": "^1.0.4" } }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" - }, "ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -9466,11 +8957,6 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, - "is": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", - "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==" - }, "is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/is-arguments/-/is-arguments-1.1.1.tgz", @@ -9502,14 +8988,6 @@ "resolved": "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.4.tgz", "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" }, - "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", - "requires": { - "has": "^1.0.3" - } - }, "is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmmirror.com/is-date-object/-/is-date-object-1.0.5.tgz", @@ -9531,11 +9009,6 @@ "has-tostringtag": "^1.0.0" } }, - "is-json": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-json/-/is-json-2.0.1.tgz", - "integrity": "sha1-a+Fm0USCihMdaGiRuYPfYsOUkf8=" - }, "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmmirror.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -9549,6 +9022,14 @@ "has-tostringtag": "^1.0.0" } }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, "is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", @@ -9571,11 +9052,6 @@ "call-bind": "^1.0.2" } }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" - }, "is-string": { "version": "1.0.7", "resolved": "https://registry.npmmirror.com/is-string/-/is-string-1.0.7.tgz", @@ -9622,15 +9098,15 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" }, "isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", "requires": {} }, "isstream": { @@ -9638,14 +9114,6 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, - "isuri": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/isuri/-/isuri-2.0.3.tgz", - "integrity": "sha1-NDcSHbL+Za8LoIC34ahjb2MsypE=", - "requires": { - "rfc-3986": "1.0.1" - } - }, "jake": { "version": "10.8.5", "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", @@ -9706,9 +9174,9 @@ } }, "jsonpath-plus": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-0.19.0.tgz", - "integrity": "sha512-GSVwsrzW9LsA5lzsqe4CkuZ9wp+kxBb2GwNniaWzI2YFn5Ig42rSW8ZxVpWXaAfakXNrx5pgY5AbQq7kzX29kg==" + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz", + "integrity": "sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==" }, "jsonwebtoken": { "version": "9.0.0", @@ -9835,11 +9303,6 @@ "yallist": "^4.0.0" } }, - "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=" - }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmmirror.com/md5.js/-/md5.js-1.3.5.tgz", @@ -9866,11 +9329,6 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -9910,11 +9368,6 @@ "mime-db": "1.52.0" } }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -10119,14 +9572,6 @@ "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.8.0.tgz", "integrity": "sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ==" }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "requires": { - "path-key": "^3.0.0" - } - }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -10186,14 +9631,6 @@ "wrappy": "1" } }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, "openid-client": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.3.1.tgz", @@ -10299,16 +9736,6 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -10464,11 +9891,6 @@ "strict-uri-encode": "^2.0.0" } }, - "quick-lru": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", - "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=" - }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz", @@ -10533,14 +9955,6 @@ } } }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "requires": { - "resolve": "^1.1.6" - } - }, "regexp.prototype.flags": { "version": "1.4.3", "resolved": "https://registry.npmmirror.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", @@ -10585,21 +9999,6 @@ } } }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "rfc-3986": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rfc-3986/-/rfc-3986-1.0.1.tgz", - "integrity": "sha1-7uuINC+tvoAnwPNq2pIaE+b5YgY=" - }, "rfc4648": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/rfc4648/-/rfc4648-1.5.2.tgz", @@ -10718,29 +10117,6 @@ "safe-buffer": "^5.0.1" } }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz", @@ -10751,25 +10127,11 @@ "object-inspect": "^1.9.0" } }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, "smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" }, - "snakecase-keys": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-1.2.0.tgz", - "integrity": "sha512-G5Faa3wQevGXcD5e4JKfmgofO+Fu4Jg4/nLyeZqWmBqVV0/3ORgervt3EjBi6PEFKhztPQWegZspteWnycx5dg==", - "requires": { - "map-obj": "~2.0.0", - "to-snake-case": "~0.1.2" - } - }, "socks": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", @@ -10962,11 +10324,6 @@ "es-abstract": "^1.19.5" } }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" - }, "strnum": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", @@ -10980,11 +10337,6 @@ "has-flag": "^4.0.0" } }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, "tar": { "version": "6.1.11", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", @@ -11051,27 +10403,6 @@ "tmp": "^0.2.0" } }, - "to-no-case": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-0.1.1.tgz", - "integrity": "sha1-zzPHDg8oFo2V5BWavxUOjFQu+f4=" - }, - "to-snake-case": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-0.1.2.tgz", - "integrity": "sha1-0Ee22/BI2uG9wmCzwpb1TKNO7Xw=", - "requires": { - "to-space-case": "0.1.2" - } - }, - "to-space-case": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-0.1.2.tgz", - "integrity": "sha1-mma+Pr5T8nefaH8CYu/9H8W20V4=", - "requires": { - "to-no-case": "0.1.1" - } - }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -11107,11 +10438,6 @@ "safe-buffer": "^5.0.1" } }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -11135,9 +10461,9 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true }, "unbox-primitive": { @@ -11306,14 +10632,6 @@ "webidl-conversions": "^7.0.0" } }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, "which-boxed-primitive": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", @@ -11382,11 +10700,6 @@ "resolved": "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz", "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" }, - "xregexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", - "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==" - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/runtimes/nodejs/package.json b/runtimes/nodejs/package.json index 7fadaa2f13..410572612b 100644 --- a/runtimes/nodejs/package.json +++ b/runtimes/nodejs/package.json @@ -1,6 +1,6 @@ { "name": "runtime-nodejs", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "description": "the node runtime for laf", "main": "./dist/index.js", "typings": "./dist/index.d.ts", @@ -12,7 +12,8 @@ "watch": "tsc -p tsconfig.json -w", "prepublishOnly": "npm run build", "trace-gc": "node --trace_gc --trace_gc_verbose ./dist/index.js", - "init": "node ./dist/init.js" + "init": "node ./dist/init.js", + "prettier": "npx prettier --write ./src" }, "keywords": [ "laf", @@ -26,8 +27,8 @@ "@aws-sdk/client-sts": "^3.231.0", "@aws-sdk/s3-request-presigner": "^3.231.0", "@kubernetes/client-node": "^0.18.0", - "@lafjs/cloud": "^1.0.0-beta.4", - "alipay-sdk": "^3.2.0", + "@lafjs/cloud": "^1.0.0-beta.7", + "alipay-sdk": "^2.0.2", "axios": "^1.2.1", "cors": "^2.8.5", "database-proxy": "^1.0.0-beta.2", @@ -63,7 +64,7 @@ "@types/nodemailer": "^6.4.4", "@types/validator": "^13.1.3", "@types/ws": "^8.5.3", - "typescript": "^4.9.5" + "typescript": "^5.0.2" }, "nodemonConfig": { "ignore": [ diff --git a/runtimes/nodejs/src/config.ts b/runtimes/nodejs/src/config.ts index 1c81685933..d920382e4f 100644 --- a/runtimes/nodejs/src/config.ts +++ b/runtimes/nodejs/src/config.ts @@ -1,9 +1,9 @@ -import * as dotenv from "dotenv"; +import * as dotenv from 'dotenv' /** * parse environment vars from the `.env` file if existing */ -dotenv.config(); +dotenv.config() /** * configuration management @@ -13,80 +13,78 @@ export default class Config { * mongodb connection configuration */ static get DB_URI() { - if (!process.env["DB_URI"]) { - throw new Error("env: `DB_URI` is missing"); + if (!process.env['DB_URI']) { + throw new Error('env: `DB_URI` is missing') } - return process.env["DB_URI"]; + return process.env['DB_URI'] } /** * the server secret salt, mainly used for generating tokens */ static get SERVER_SECRET(): string { - const secret_salt = process.env["SERVER_SECRET"]; + const secret_salt = process.env['SERVER_SECRET'] if (!secret_salt) { - throw new Error("env: `SERVER_SECRET` is missing"); + throw new Error('env: `SERVER_SECRET` is missing') } - return secret_salt; + return secret_salt } /** * the logger level : 'fatal', 'error', 'warning', 'info', 'debug', 'trace' */ static get LOG_LEVEL(): - | "fatal" - | "error" - | "warning" - | "info" - | "debug" - | "trace" { - return ( - (process.env["LOG_LEVEL"] as any) ?? (this.isProd ? "info" : "debug") - ); + | 'fatal' + | 'error' + | 'warning' + | 'info' + | 'debug' + | 'trace' { + return (process.env['LOG_LEVEL'] as any) ?? (this.isProd ? 'info' : 'debug') } /** * the serving port, default is 8000 */ static get PORT(): number { - return (process.env.PORT ?? 8000) as number; + return (process.env.PORT ?? 8000) as number } /** * in production deploy or not */ static get isProd(): boolean { - return process.env.NODE_ENV === "production"; + return process.env.NODE_ENV === 'production' } /** * Expired time of function logs, in seconds */ static get FUNCTION_LOG_EXPIRED_TIME(): number { - return (process.env.FUNCTION_LOG_EXPIRED_TIME ?? 3600 * 24 * 3) as number; + return (process.env.FUNCTION_LOG_EXPIRED_TIME ?? 3600 * 24 * 3) as number } static get RUNTIME_IMAGE(): string { - return process.env.RUNTIME_IMAGE; + return process.env.RUNTIME_IMAGE } static get RUNTIME_VERSION(): string { - return require("../package.json")?.version; + return require('../package.json')?.version } static get APP_ID(): string { - return process.env.APP_ID; + return process.env.APP_ID } static get NPM_INSTALL_FLAGS(): string { - return process.env.NPM_INSTALL_FLAGS || ""; + return process.env.NPM_INSTALL_FLAGS || '' } static get REQUEST_LIMIT_SIZE(): string { - return process.env.REQUEST_LIMIT_SIZE || "10mb"; + return process.env.REQUEST_LIMIT_SIZE || '10mb' } static get PACKAGES(): string { - return process.env.PACKAGES || ""; + return process.env.PACKAGES || '' } } diff --git a/runtimes/nodejs/src/constants.ts b/runtimes/nodejs/src/constants.ts index ad3ff3a0bc..a773c49958 100644 --- a/runtimes/nodejs/src/constants.ts +++ b/runtimes/nodejs/src/constants.ts @@ -1,14 +1,12 @@ - /** * Collection names */ export const CLOUD_FUNCTION_COLLECTION = '__functions__' export const POLICY_COLLECTION = '__policies__' export const FUNCTION_LOG_COLLECTION = '__function_logs__' -export const CONFIG_COLLECTION = '__config__' - +export const CONFIG_COLLECTION = '__conf__' export const WEBSOCKET_FUNCTION_NAME = '__websocket__' export const INTERCEPTOR_FUNCTION_NAME = '__interceptor__' export const DEFAULT_FUNCTION_NAME = '__default__' -export const INIT_FUNCTION_NAME = '__init__' \ No newline at end of file +export const INIT_FUNCTION_NAME = '__init__' diff --git a/runtimes/nodejs/src/db.ts b/runtimes/nodejs/src/db.ts index 9373beb81f..1899917dca 100644 --- a/runtimes/nodejs/src/db.ts +++ b/runtimes/nodejs/src/db.ts @@ -2,16 +2,14 @@ * @Author: Maslow * @Date: 2021-08-16 15:29:15 * @LastEditTime: 2022-02-03 00:42:33 - * @Description: + * @Description: */ - import { MongoAccessor } from 'database-proxy' import Config from './config' import { createLogger, logger } from './support/logger' import * as mongodb_uri from 'mongodb-uri' - /** * Database Management */ @@ -34,18 +32,19 @@ export class DatabaseAgent { /** * Create MongoAccessor instance - * @returns + * @returns */ private static _createAccessor() { const { database } = mongodb_uri.parse(Config.DB_URI) const accessor = new MongoAccessor(database, Config.DB_URI) accessor.setLogger(createLogger('accessor', 'warning')) - accessor.init() + accessor + .init() .then(async () => { logger.info('db connected') }) - .catch(error => { + .catch((error) => { logger.error(error) setTimeout(() => process.exit(101), 0) }) diff --git a/runtimes/nodejs/src/handler/db-proxy.ts b/runtimes/nodejs/src/handler/db-proxy.ts index 2a9d9008c1..bf158efc7d 100644 --- a/runtimes/nodejs/src/handler/db-proxy.ts +++ b/runtimes/nodejs/src/handler/db-proxy.ts @@ -1,4 +1,3 @@ - import { Response } from 'express' import { Proxy } from 'database-proxy' import Config from '../config' @@ -7,7 +6,6 @@ import { logger } from '../support/logger' import { PolicyAgent } from '../support/policy' import { IRequest } from '../support/types' - export async function handleDatabaseProxy(req: IRequest, res: Response) { const accessor = DatabaseAgent.accessor @@ -37,7 +35,7 @@ export async function handleDatabaseProxy(req: IRequest, res: Response) { return res.status(403).send({ code: 'permission denied', error: result.errors, - injections: Config.isProd ? undefined : injections + injections: Config.isProd ? undefined : injections, }) } @@ -49,14 +47,14 @@ export async function handleDatabaseProxy(req: IRequest, res: Response) { return res.send({ code: 0, - data + data, }) } catch (error) { logger.error(requestId, 'execute query got error: ', error) return res.send({ code: 1, error: error.toString(), - injections: Config.isProd ? undefined : injections + injections: Config.isProd ? undefined : injections, }) } -} \ No newline at end of file +} diff --git a/runtimes/nodejs/src/handler/debug-func.ts b/runtimes/nodejs/src/handler/debug-func.ts index 5737a9c832..87c593097b 100644 --- a/runtimes/nodejs/src/handler/debug-func.ts +++ b/runtimes/nodejs/src/handler/debug-func.ts @@ -26,11 +26,10 @@ export async function handleDebugFunction(req: IRequest, res: Response) { return res.status(400).send('x-laf-func-data is required') } - // parse func_data let func_data: ICloudFunctionData try { - const decoded = decodeURIComponent(func_str) + const decoded = decodeURIComponent(func_str) func_data = JSON.parse(decoded) } catch (error) { return res.status(400).send('x-laf-func-data is invalid') diff --git a/runtimes/nodejs/src/handler/invoke-func.ts b/runtimes/nodejs/src/handler/invoke-func.ts index a16c6073f9..0ed26f6169 100644 --- a/runtimes/nodejs/src/handler/invoke-func.ts +++ b/runtimes/nodejs/src/handler/invoke-func.ts @@ -32,10 +32,10 @@ export async function handleInvokeFunction(req: IRequest, res: Response) { const func_name = req.params?.name // load function data from db - let funcData = await CloudFunction.getFunctionByName(func_name) + let funcData = CloudFunction.getFunctionByName(func_name) if (!funcData) { // load default function from db - funcData = await CloudFunction.getFunctionByName(DEFAULT_FUNCTION_NAME) + funcData = CloudFunction.getFunctionByName(DEFAULT_FUNCTION_NAME) if (!funcData) { return res.status(404).send('Function Not Found') } @@ -103,7 +103,7 @@ async function invokeInterceptor(req: IRequest, res: Response) { const func_name = INTERCEPTOR_FUNCTION_NAME // load function data from db - const funcData = await CloudFunction.getFunctionByName(func_name) + const funcData = CloudFunction.getFunctionByName(func_name) // pass if no interceptor if (!funcData) { return true diff --git a/runtimes/nodejs/src/handler/router.ts b/runtimes/nodejs/src/handler/router.ts index 2e22aeb4a5..7ddbbb77f7 100644 --- a/runtimes/nodejs/src/handler/router.ts +++ b/runtimes/nodejs/src/handler/router.ts @@ -2,7 +2,7 @@ * @Author: Maslow * @Date: 2021-07-30 10:30:29 * @LastEditTime: 2022-02-03 00:32:16 - * @Description: + * @Description: */ import { Router } from 'express' @@ -13,7 +13,6 @@ import { handlePackageTypings } from './typings' import { generateUUID } from '../support/utils' import { handleInvokeFunction } from './invoke-func' - /** * multer uploader config */ @@ -22,18 +21,19 @@ const uploader = multer({ filename: (_req, file, cb) => { const { ext } = path.parse(file.originalname) cb(null, generateUUID() + ext) - } + }, }), fileFilter(_req, file, callback) { // solve the problem of garbled unicode names - file.originalname = Buffer.from(file.originalname, 'latin1').toString('utf8') + file.originalname = Buffer.from(file.originalname, 'latin1').toString( + 'utf8', + ) callback(null, true) }, }) export const router = Router() - router.post('/proxy/:policy', handleDatabaseProxy) router.get('/_/typing/package', handlePackageTypings) router.get('/_/healthz', (_req, res) => res.status(200).send('ok')) @@ -42,4 +42,4 @@ router.get('/_/healthz', (_req, res) => res.status(200).send('ok')) * Invoke cloud function through HTTP request. * @method * */ -router.all('/:name', uploader.any(), handleInvokeFunction) \ No newline at end of file +router.all('/:name', uploader.any(), handleInvokeFunction) diff --git a/runtimes/nodejs/src/handler/typings.ts b/runtimes/nodejs/src/handler/typings.ts index 74ee38d56c..a16516ae22 100644 --- a/runtimes/nodejs/src/handler/typings.ts +++ b/runtimes/nodejs/src/handler/typings.ts @@ -2,7 +2,7 @@ * @Author: Maslow * @Date: 2021-07-30 10:30:29 * @LastEditTime: 2021-08-18 16:49:35 - * @Description: + * @Description: */ import { Response } from 'express' @@ -10,6 +10,7 @@ import { PackageDeclaration, NodePackageDeclarations } from 'node-modules-utils' import path = require('path') import { logger } from '../support/logger' import { IRequest } from '../support/types' +import { FunctionCache } from '../support/function-engine/cache' const nodeModulesRoot = path.resolve(__dirname, '../../node_modules') @@ -35,7 +36,7 @@ export async function handlePackageTypings(req: IRequest, res: Response) { return res.send({ code: 0, - data: rets + data: rets, }) } @@ -46,7 +47,22 @@ export async function handlePackageTypings(req: IRequest, res: Response) { return res.send({ code: 0, - data: [r] + data: [r], + }) + } + + // get cloud function types + if (packageName.startsWith('@/')) { + const func = FunctionCache.getFunctionByName(packageName.replace('@/', '')) + const r = { + packageName: packageName, + content: func.source.code, + path: `${packageName}/index.ts`, + from: 'node', + } + return res.send({ + code: 0, + data: [r], }) } @@ -56,13 +72,13 @@ export async function handlePackageTypings(req: IRequest, res: Response) { await pkd.load() return res.send({ code: 0, - data: pkd.declarations + data: pkd.declarations, }) } catch (error) { logger.error(requestId, 'failed to get package typings', error) return res.send({ code: 1, - error: error.toString() + error: error.toString(), }) } } diff --git a/runtimes/nodejs/src/index.ts b/runtimes/nodejs/src/index.ts index 12bb5a539a..2a59e6140c 100644 --- a/runtimes/nodejs/src/index.ts +++ b/runtimes/nodejs/src/index.ts @@ -20,9 +20,18 @@ import xmlparser from 'express-xml-bodyparser' // init static method of class import './support/function-log' import './support/cloud-sdk' +import { FunctionCache } from './support/function-engine/cache' +import { DatabaseChangeStream } from './support/db-change-stream' +import { InitHook } from './support/init-hook' const app = express() +DatabaseAgent.accessor.ready.then(() => { + FunctionCache.initialize() + DatabaseChangeStream.initialize() + InitHook.invoke() +}) + if (process.env.NODE_ENV === 'development') { app.use(cors()) } diff --git a/runtimes/nodejs/src/support/cloud-sdk.ts b/runtimes/nodejs/src/support/cloud-sdk.ts index 4f61770dee..78afd98f77 100644 --- a/runtimes/nodejs/src/support/cloud-sdk.ts +++ b/runtimes/nodejs/src/support/cloud-sdk.ts @@ -26,11 +26,10 @@ function createCloudSdk() { }, sockets: WebSocketAgent.clients, appid: Config.APP_ID, - env: { - DB_URI: Config.DB_URI, - SERVER_SECRET: Config.SERVER_SECRET, - RUNTIME_IMAGE: Config.RUNTIME_IMAGE, - ...process.env, + get env() { + return { + ...process.env, + } }, } @@ -52,7 +51,7 @@ function createCloudSdk() { * @returns */ async function invokeInFunction(name: string, param?: FunctionContext) { - const data = await CloudFunction.getFunctionByName(name) + const data = CloudFunction.getFunctionByName(name) const func = new CloudFunction(data) if (!func) { diff --git a/runtimes/nodejs/src/support/db-change-stream.ts b/runtimes/nodejs/src/support/db-change-stream.ts new file mode 100644 index 0000000000..ed12576bdb --- /dev/null +++ b/runtimes/nodejs/src/support/db-change-stream.ts @@ -0,0 +1,41 @@ +import { CONFIG_COLLECTION } from '../constants' +import { DatabaseAgent } from '../db' + +import { logger } from './logger' + +export class DatabaseChangeStream { + static async initialize() { + this.watchConf() + } + + /** + * stream the change of cloud function + * @param + * @returns + */ + static async watchConf() { + logger.info('Listening for changes in conf collection...') + this.updateEnvironments() + + const stream = DatabaseAgent.db.collection(CONFIG_COLLECTION).watch() + + stream.on('change', async (_change) => { + this.updateEnvironments() + }) + } + + private static async updateEnvironments() { + const conf = await DatabaseAgent.db + .collection(CONFIG_COLLECTION) + .findOne({}) + + if (!conf) { + return + } + + const environments = conf.environments || [] + for (const env of environments) { + process.env[env.name] = env.value + } + } +} diff --git a/runtimes/nodejs/src/support/function-engine/cache.ts b/runtimes/nodejs/src/support/function-engine/cache.ts new file mode 100644 index 0000000000..b91804113e --- /dev/null +++ b/runtimes/nodejs/src/support/function-engine/cache.ts @@ -0,0 +1,90 @@ +import { CLOUD_FUNCTION_COLLECTION } from '../../constants' +import { DatabaseAgent } from '../../db' +import { ICloudFunctionData, RequireFuncType } from './types' +import { FunctionRequire } from './require' +import { logger } from '../logger' +import assert from 'assert' + +export class FunctionCache { + private static cache: Map = new Map() + + static async initialize() { + logger.info('initialize function cache') + const funcs = await DatabaseAgent.db + .collection(CLOUD_FUNCTION_COLLECTION) + .find() + .toArray() + + for (const func of funcs) { + FunctionCache.cache.set(func.name, func) + } + + this.streamChange() + logger.info('Function cache initialized.') + } + + /** + * require a module from cloud function + * @param module + * @returns + */ + static requireCloudFunction(moduleName: string): any { + const func = FunctionCache.cache.get(moduleName) + assert( + func, + `require cloud function failed: function ${moduleName} not found`, + ) + const funcRequire = new FunctionRequire(this.requireFunc) + const module = funcRequire.load(func.name, func.source.compiled) + return module + } + + /** + * stream the change of cloud function + * @param + * @returns + */ + static async streamChange() { + logger.info('Listening for changes in cloud function collection...') + const stream = DatabaseAgent.db + .collection(CLOUD_FUNCTION_COLLECTION) + .watch() + stream.on('change', async (change) => { + if (change.operationType === 'insert') { + const func = await DatabaseAgent.db + .collection(CLOUD_FUNCTION_COLLECTION) + .findOne({ _id: change.documentKey._id }) + + // add func in map + FunctionCache.cache.set(func.name, func) + } else if (change.operationType == 'delete') { + // remove this func + for (const [funcName, func] of this.cache) { + if (change.documentKey._id.equals(func._id)) { + this.cache.delete(funcName) + } + } + } + }) + } + + /** + * Custom require function in cloud function + * @see FunctionEngine.require_func + * @param module the module id. ex. `path`, `lodash` + * @returns + */ + static requireFunc: RequireFuncType = (module: string): any => { + if (module === '@/cloud-sdk') { + return require('@lafjs/cloud') + } + if (module.startsWith('@/')) { + return FunctionCache.requireCloudFunction(module.replace('@/', '')) + } + return require(module) as any + } + + static getFunctionByName(funcName: string): ICloudFunctionData { + return FunctionCache.cache.get(funcName) + } +} diff --git a/runtimes/nodejs/src/support/function-engine/engine.ts b/runtimes/nodejs/src/support/function-engine/engine.ts index 63b5799618..077da4f7d2 100644 --- a/runtimes/nodejs/src/support/function-engine/engine.ts +++ b/runtimes/nodejs/src/support/function-engine/engine.ts @@ -1,13 +1,7 @@ -import { URL } from 'node:url' import * as vm from 'vm' import { nanosecond2ms } from '../utils' -import { FunctionConsole } from './console' -import { - FunctionContext, - FunctionResult, - RequireFuncType, - RuntimeContext, -} from './types' +import { FunctionContext, FunctionResult, RequireFuncType } from './types' +import { FunctionVm } from './vm' /** * Default require function @@ -20,10 +14,13 @@ const defaultRequireFunction: RequireFuncType = (module): any => { * Function engine */ export class FunctionEngine { - require_func: RequireFuncType + requireFunc: RequireFuncType - constructor(require_func?: RequireFuncType) { - this.require_func = require_func ?? defaultRequireFunction + script: vm.Script + + constructor(code: string, require_func?: RequireFuncType) { + this.script = FunctionVm.createVM(this.wrap(code), {}) + this.requireFunc = require_func ?? defaultRequireFunction } /** @@ -31,29 +28,15 @@ export class FunctionEngine { * @returns */ async run( - code: string, context: FunctionContext, options: vm.RunningScriptOptions, ): Promise { - const sandbox = this.buildSandbox(context) - const wrapped = this.wrap(code) + const sandbox = FunctionVm.buildSandbox(context, this.requireFunc) const fconsole = sandbox.console const _start_time = process.hrtime.bigint() try { - const script = new vm.Script(wrapped, { - ...options, - importModuleDynamically: async ( - specifier: string, - _: vm.Script, - _importAssertions: any, - ) => { - return await import(specifier) - }, - } as any) - - const result = script.runInNewContext(sandbox, options) - + const result = this.script.runInNewContext(sandbox, options) let data = result if (typeof result?.then === 'function') { data = await result @@ -78,40 +61,6 @@ export class FunctionEngine { } } - /** - * build sandbox - * @returns - */ - buildSandbox(functionContext: FunctionContext): RuntimeContext { - const fconsole = new FunctionConsole(functionContext) - - const _module = { - exports: {}, - } - const sandbox = { - __context__: functionContext, - __filename: functionContext.__function_name, - module: _module, - exports: _module.exports, - console: fconsole, - require: this.require_func, - Buffer: Buffer, - setImmediate: setImmediate, - clearImmediate: clearImmediate, - setInterval: setInterval, - clearInterval: clearInterval, - setTimeout: setTimeout, - clearTimeout: clearTimeout, - process: { env: {} }, - URL: URL, - fetch: globalThis.fetch, - global: null, - } - - sandbox.global = sandbox - return sandbox - } - /** * wrap function code */ diff --git a/runtimes/nodejs/src/support/function-engine/function.ts b/runtimes/nodejs/src/support/function-engine/function.ts index 565476eebe..42b03015fc 100644 --- a/runtimes/nodejs/src/support/function-engine/function.ts +++ b/runtimes/nodejs/src/support/function-engine/function.ts @@ -1,13 +1,9 @@ -import { FunctionEngine } from '.' -import { - ICloudFunctionData, - FunctionContext, - FunctionResult, - RequireFuncType, -} from './types' +import { ICloudFunctionData, FunctionContext, FunctionResult } from './types' import * as assert from 'assert' import { DatabaseAgent } from '../../db' import { CLOUD_FUNCTION_COLLECTION } from '../../constants' +import { FunctionCache } from './cache' +import { FunctionEngine } from '.' /** * CloudFunction Class @@ -18,20 +14,6 @@ export class CloudFunction { */ static _shared_preference = new Map() - /** - * Custom require function in cloud function - * @see FunctionEngine.require_func - * @param module the module id. ex. `path`, `lodash` - * @returns - */ - static require_func: RequireFuncType = (module: string): any => { - if (module === '@/cloud-sdk') { - return require('@lafjs/cloud') - } - - return require(module) as any - } - /** * execution timeout */ @@ -97,9 +79,12 @@ export class CloudFunction { async invoke(param: FunctionContext) { this.param = param - const engine = new FunctionEngine(CloudFunction.require_func) + const engine = new FunctionEngine( + this._data.source.compiled, + FunctionCache.requireFunc, + ) - this.result = await engine.run(this.compiledCode, param, { + this.result = await engine.run(param, { filename: `CloudFunction.${this.name}`, timeout: this.timeout, displayErrors: true, @@ -116,14 +101,8 @@ export class CloudFunction { * @param func_name * @returns */ - static async getFunctionByName(func_name: string) { - const db = DatabaseAgent.db - - const doc = await db - .collection(CLOUD_FUNCTION_COLLECTION) - .findOne({ name: func_name }) - - return doc + static getFunctionByName(func_name: string) { + return FunctionCache.getFunctionByName(func_name) } /** diff --git a/runtimes/nodejs/src/support/function-engine/index.ts b/runtimes/nodejs/src/support/function-engine/index.ts index e0c2e3a8e6..506476a373 100644 --- a/runtimes/nodejs/src/support/function-engine/index.ts +++ b/runtimes/nodejs/src/support/function-engine/index.ts @@ -1,4 +1,3 @@ - export * from './engine' export * from './function' @@ -6,4 +5,3 @@ export * from './function' export * from './types' export * from './console' - diff --git a/runtimes/nodejs/src/support/function-engine/require.ts b/runtimes/nodejs/src/support/function-engine/require.ts new file mode 100644 index 0000000000..6767020ec1 --- /dev/null +++ b/runtimes/nodejs/src/support/function-engine/require.ts @@ -0,0 +1,45 @@ +import { RequireFuncType } from './types' +import { FunctionVm } from './vm' + +const defaultRequireFunction: RequireFuncType = (module): any => { + return require(module) as any +} + +export class FunctionRequire { + requireFunc: RequireFuncType + + constructor(requireFunc?: RequireFuncType) { + this.requireFunc = requireFunc ?? defaultRequireFunction + } + + /** + * load cloud funcion as module + * @param name + * @param code + * @returns + */ + load(name: string, code: string): any { + const context = { + __function_name: name, + requestId: '', + } + + const sandbox = FunctionVm.buildSandbox(context, this.requireFunc) + const wrapped = this.warp(code) + const script = FunctionVm.createVM(wrapped, {}) + return script.runInNewContext(sandbox, {}) + } + + /** + * warp function code + * @param code + * @returns + */ + warp(code: string): string { + return ` + const exports = {}; + ${code} + exports; + ` + } +} diff --git a/runtimes/nodejs/src/support/function-engine/types.ts b/runtimes/nodejs/src/support/function-engine/types.ts index e60be30a6a..656b6afcc9 100644 --- a/runtimes/nodejs/src/support/function-engine/types.ts +++ b/runtimes/nodejs/src/support/function-engine/types.ts @@ -1,6 +1,7 @@ import { FunctionConsole } from './console' import { IncomingHttpHeaders } from 'http' import { Request, Response } from 'express' +import { ObjectId } from 'mongodb' import WebSocket = require('ws') export type RequireFuncType = (module: string) => any @@ -81,6 +82,7 @@ export type CloudFunctionSource = { * cloud function data structure */ export interface ICloudFunctionData { + _id?: ObjectId id: string appid: string name: string diff --git a/runtimes/nodejs/src/support/function-engine/vm.ts b/runtimes/nodejs/src/support/function-engine/vm.ts new file mode 100644 index 0000000000..e59ec8f986 --- /dev/null +++ b/runtimes/nodejs/src/support/function-engine/vm.ts @@ -0,0 +1,68 @@ +import { FunctionConsole } from './console' +import { FunctionContext, RuntimeContext } from './types' +import * as vm from 'vm' + +export class FunctionVm { + /** + * create vm.Script + * @param code + * @param options + * @returns + */ + + static createVM(code: string, options: vm.RunningScriptOptions): vm.Script { + const script = new vm.Script(code, { + ...options, + importModuleDynamically: async ( + specifier: string, + _: vm.Script, + _importAssertions: any, + ) => { + return await import(specifier) + }, + } as any) + return script + } + + /** + * build sandbox + * @param functionContext + * @param requireFunc + * @returns + */ + + static buildSandbox( + functionContext: FunctionContext, + requireFunc: any, + ): RuntimeContext { + const fconsole = new FunctionConsole(functionContext) + + const _module = { + exports: {}, + } + const sandbox = { + __context__: functionContext, + __filename: functionContext.__function_name, + module: _module, + exports: _module.exports, + console: fconsole, + require: requireFunc, + Buffer: Buffer, + setImmediate: setImmediate, + clearImmediate: clearImmediate, + setInterval: setInterval, + clearInterval: clearInterval, + setTimeout: setTimeout, + clearTimeout: clearTimeout, + process: { + env: { ...process.env }, + }, + URL: URL, + fetch: globalThis.fetch, + global: null, + } + + sandbox.global = sandbox + return sandbox + } +} diff --git a/runtimes/nodejs/src/support/function-log.ts b/runtimes/nodejs/src/support/function-log.ts index 1ae88c96d4..a89df2947c 100644 --- a/runtimes/nodejs/src/support/function-log.ts +++ b/runtimes/nodejs/src/support/function-log.ts @@ -9,11 +9,10 @@ export interface IFunctionLog { created_at: Date } -FunctionConsole.write = async (message: string, ctx: FunctionContext) => { +FunctionConsole.write = (message: string, ctx: FunctionContext) => { const db = DatabaseAgent.db if (!db) return - const collection = db.collection(FUNCTION_LOG_COLLECTION) const doc = { request_id: ctx.requestId, func: ctx.__function_name, @@ -21,5 +20,5 @@ FunctionConsole.write = async (message: string, ctx: FunctionContext) => { created_at: new Date(), } - await collection.insertOne(doc) + db.collection(FUNCTION_LOG_COLLECTION).insertOne(doc) } diff --git a/runtimes/nodejs/src/support/init-hook.ts b/runtimes/nodejs/src/support/init-hook.ts new file mode 100644 index 0000000000..5ba8fa2e58 --- /dev/null +++ b/runtimes/nodejs/src/support/init-hook.ts @@ -0,0 +1,41 @@ +import { CLOUD_FUNCTION_COLLECTION, INIT_FUNCTION_NAME } from '../constants' +import { DatabaseAgent } from '../db' +import { CloudFunction, ICloudFunctionData } from './function-engine' +import { logger } from './logger' +import { generateUUID } from './utils' + +/** + * Init hook for `__init__` cloud function + */ +export class InitHook { + static async invoke() { + const func = await this.getInitCloudFunction() + if (!func) { + return + } + + const cf = new CloudFunction(func) + await cf.invoke({ + method: 'INIT', + requestId: generateUUID(), + __function_name: func.name, + }) + + logger.info('Init hook invoked') + } + + /** + * Get init hook cloud function + * @returns + */ + private static async getInitCloudFunction() { + const db = DatabaseAgent.db + const doc = await db + .collection(CLOUD_FUNCTION_COLLECTION) + .findOne({ + name: INIT_FUNCTION_NAME, + }) + + return doc + } +} diff --git a/runtimes/nodejs/src/support/logger.ts b/runtimes/nodejs/src/support/logger.ts index a7814150d7..5402dd01cf 100644 --- a/runtimes/nodejs/src/support/logger.ts +++ b/runtimes/nodejs/src/support/logger.ts @@ -2,7 +2,7 @@ * @Author: Maslow * @Date: 2021-07-30 10:30:29 * @LastEditTime: 2021-10-06 19:26:58 - * @Description: + * @Description: */ import { LoggerInterface } from 'database-proxy' @@ -13,9 +13,12 @@ import Config from '../config' * Create logger instance * @param category log category * @param level the logger level : 'fatal', 'error', 'warning', 'info', 'debug', 'trace' - * @returns + * @returns */ -export function createLogger(category: string, level?: string): LoggerInterface { +export function createLogger( + category: string, + level?: string, +): LoggerInterface { const logger = log4js.getLogger(category) logger.level = level ?? Config.LOG_LEVEL @@ -25,4 +28,4 @@ export function createLogger(category: string, level?: string): LoggerInterface /** * The global logger instance */ -export const logger = createLogger('server') \ No newline at end of file +export const logger = createLogger('server') diff --git a/runtimes/nodejs/src/support/policy.ts b/runtimes/nodejs/src/support/policy.ts index cf1c6f2b3a..010d105fee 100644 --- a/runtimes/nodejs/src/support/policy.ts +++ b/runtimes/nodejs/src/support/policy.ts @@ -95,7 +95,7 @@ export class PolicyAgent { } try { - const func_data = await CloudFunction.getFunctionByName(injectorName) + const func_data = CloudFunction.getFunctionByName(injectorName) assert.ok(func_data, 'getFunctionByName(): function not found') const func = new CloudFunction(func_data) diff --git a/runtimes/nodejs/src/support/token.ts b/runtimes/nodejs/src/support/token.ts index d0bbd36a05..92e6940ab9 100644 --- a/runtimes/nodejs/src/support/token.ts +++ b/runtimes/nodejs/src/support/token.ts @@ -5,9 +5,9 @@ * @Description: */ -import Config from "../config"; -import * as jwt from "jsonwebtoken"; -const DEFAULT_SALT = Config.SERVER_SECRET; +import Config from '../config' +import * as jwt from 'jsonwebtoken' +const DEFAULT_SALT = Config.SERVER_SECRET /** * Generate a JWT token @@ -16,7 +16,7 @@ const DEFAULT_SALT = Config.SERVER_SECRET; * @returns */ export function getToken(payload: any, secret?: string): string { - return jwt.sign(payload, secret ?? DEFAULT_SALT); + return jwt.sign(payload, secret ?? DEFAULT_SALT) } /** @@ -25,12 +25,12 @@ export function getToken(payload: any, secret?: string): string { * @returns */ export function parseToken(token: string, secret?: string): any | null { - if (!token) return null; + if (!token) return null try { - const ret = jwt.verify(token, secret ?? DEFAULT_SALT); - return ret; + const ret = jwt.verify(token, secret ?? DEFAULT_SALT) + return ret } catch (error) { - return null; + return null } } @@ -40,9 +40,9 @@ export function parseToken(token: string, secret?: string): any | null { * @returns */ export function splitBearerToken(bearer: string): string | null { - if (!bearer) return null; + if (!bearer) return null - const splitted = bearer?.split(" "); - const token = splitted?.length === 2 ? splitted[1] : null; - return token; + const splitted = bearer?.split(' ') + const token = splitted?.length === 2 ? splitted[1] : null + return token } diff --git a/runtimes/nodejs/src/support/utils.ts b/runtimes/nodejs/src/support/utils.ts index 1bc4a774b5..a28a3c620d 100644 --- a/runtimes/nodejs/src/support/utils.ts +++ b/runtimes/nodejs/src/support/utils.ts @@ -2,7 +2,7 @@ import * as crypto from 'crypto' /** * Generate UUID v4 - * @returns + * @returns */ export function generateUUID() { return crypto.randomUUID() @@ -13,9 +13,13 @@ export function generateUUID() { * @param length the length of password, default is 8 * @param hasNumbers add numbers to password, [0-9] * @param hasSymbols add symbols to password, [!@#$%^&*_-=+] - * @returns + * @returns */ -export function generatePassword(length = 8, hasNumbers = true, hasSymbols = true) { +export function generatePassword( + length = 8, + hasNumbers = true, + hasSymbols = true, +) { return generateRandString(length, hasNumbers, hasSymbols) } @@ -24,9 +28,13 @@ export function generatePassword(length = 8, hasNumbers = true, hasSymbols = tru * @param length the length of password, default is 8 * @param hasNumbers add numbers to password, [0-9] * @param hasSymbols add symbols to password, [!@#$%^&*_-=+] - * @returns + * @returns */ -export function generateRandString(length = 8, hasNumbers = true, hasSymbols = true) { +export function generateRandString( + length = 8, + hasNumbers = true, + hasSymbols = true, +) { const alpha = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM' const numbers = '0123456789' const symbols = '!@#$%^&*_-=+' @@ -42,19 +50,14 @@ export function generateRandString(length = 8, hasNumbers = true, hasSymbols = t return str } - export function hashPassword(content: string) { - return crypto - .createHash('sha256') - .update(content) - .digest('hex') + return crypto.createHash('sha256').update(content).digest('hex') } - /** * Recursively deeply freeze objects - * @param object - * @returns + * @param object + * @returns */ export function deepFreeze(object: Object) { // Retrieve the property names defined on object @@ -65,7 +68,7 @@ export function deepFreeze(object: Object) { for (const name of propNames) { const value = object[name] - if (value && typeof value === "object") { + if (value && typeof value === 'object') { deepFreeze(value) } } @@ -73,11 +76,10 @@ export function deepFreeze(object: Object) { return Object.freeze(object) } - /** * nanosecond to ms - * @param nanoseconds - * @returns + * @param nanoseconds + * @returns */ export function nanosecond2ms(nanoseconds: bigint): number { // trim the decimal point by devide 1000 @@ -87,4 +89,20 @@ export function nanosecond2ms(nanoseconds: bigint): number { return ret } +/** + * sleep + * @param ms milliseconds + * @returns + */ +export function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)) +} +/** + * generate md5 + * @param content md5 content + * @returns + */ +export function md5(content: string) { + return crypto.createHash('md5').update(content).digest('hex') +} diff --git a/runtimes/nodejs/tsconfig.json b/runtimes/nodejs/tsconfig.json index 8615870dcc..09f8b9bcfe 100644 --- a/runtimes/nodejs/tsconfig.json +++ b/runtimes/nodejs/tsconfig.json @@ -4,7 +4,6 @@ "allowJs": false, "allowUnreachableCode": false, "allowUnusedLabels": false, - "charset": "utf8", "declaration": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, diff --git a/server/.vscode/settings.json b/server/.vscode/settings.json deleted file mode 100644 index 996855088c..0000000000 --- a/server/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "cSpell.words": [ - "casdoor" - ] -} \ No newline at end of file diff --git a/server/Dockerfile.alpine b/server/Dockerfile.alpine deleted file mode 100644 index 0c4693819c..0000000000 --- a/server/Dockerfile.alpine +++ /dev/null @@ -1,27 +0,0 @@ -# @see https://github.com/prisma/prisma/issues/8478#issuecomment-1095544159 -FROM positivly/prisma-binaries:latest as prisma - -FROM node:18-slim - -RUN apt-get update -RUN apt-get install -y openssl - -## Your normal build steps here - -# Set prisma environment: -ENV PRISMA_QUERY_ENGINE_BINARY=/prisma-engines/query-engine \ - PRISMA_MIGRATION_ENGINE_BINARY=/prisma-engines/migration-engine \ - PRISMA_INTROSPECTION_ENGINE_BINARY=/prisma-engines/introspection-engine \ - PRISMA_FMT_BINARY=/prisma-engines/prisma-fmt \ - PRISMA_CLI_QUERY_ENGINE_TYPE=binary \ - PRISMA_CLIENT_ENGINE_TYPE=binary -COPY --from=prisma /prisma-engines/query-engine /prisma-engines/migration-engine /prisma-engines/introspection-engine /prisma-engines/prisma-fmt /prisma-engines/ - - -EXPOSE 3000 -WORKDIR /app -COPY . /app -RUN npm install -RUN npx prisma generate --schema ./prisma/schema.prisma -RUN npm run build -CMD [ "node", "dist/main" ] \ No newline at end of file diff --git a/server/README.md b/server/README.md index 55df5d1c1c..27bf478362 100644 --- a/server/README.md +++ b/server/README.md @@ -23,7 +23,6 @@ - [Prisma](https://www.prisma.io) - [MinIO](https://min.io) object storage - [APISIX](https://apisix.apache.org) gateway -- [Casdoor](https://casdoor.org/) ## Prerequisites diff --git a/server/fix-local-envs.sh b/server/fix-local-envs.sh new file mode 100644 index 0000000000..8734c09115 --- /dev/null +++ b/server/fix-local-envs.sh @@ -0,0 +1,12 @@ + +# remove MINIO_CLIENT_PATH line +sed -i '' '/MINIO_CLIENT_PATH/d' .env + +# replace 'mongo.laf-system.svc.cluster.local' with '127.0.0.1' +sed -i '' 's/mongodb-0.mongo.laf-system.svc.cluster.local/127.0.0.1/g' .env + +# replace 'w=majority' with 'w=majority&directConnection=true' +sed -i '' 's/w=majority/w=majority\&directConnection=true/g' .env + +# port forward mongo +kubectl port-forward mongodb-0 27017:27017 -n laf-system \ No newline at end of file diff --git a/server/package-lock.json b/server/package-lock.json index 4c2244fb0d..16e3146fc9 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -1,14 +1,17 @@ { "name": "laf-server", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "laf-server", - "version": "1.0.0-beta.4", - "license": "UNLICENSED", + "version": "1.0.0-beta.7", + "license": "Apache-2.0", "dependencies": { + "@alicloud/dysmsapi20170525": "^2.0.23", + "@alicloud/openapi-client": "^0.4.5", + "@alicloud/tea-util": "^1.4.5", "@aws-sdk/client-s3": "^3.245.0", "@aws-sdk/client-sts": "^3.226.0", "@kubernetes/client-node": "^0.17.1", @@ -28,6 +31,7 @@ "compression": "^1.7.4", "cron-validate": "^1.4.5", "database-proxy": "^1.0.0-beta.2", + "dayjs": "^1.11.7", "dotenv": "^16.0.3", "fast-json-patch": "^3.1.1", "lodash": "^4.17.21", @@ -39,11 +43,12 @@ "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.2.0", - "typescript": "^4.9.3" + "typescript": "^4.9.3", + "wechatpay-node-v3": "^2.1.1" }, "devDependencies": { "@compodoc/compodoc": "^1.1.19", - "@nestjs/cli": "^9.0.0", + "@nestjs/cli": "^9.2.0", "@nestjs/schematics": "^9.0.0", "@nestjs/testing": "^9.2.0", "@types/compression": "^1.7.2", @@ -79,6 +84,104 @@ "integrity": "sha512-20Pk2Z98fbPLkECcrZSJszKos/OgtvJJR3NcbVfgCJ6EQjDNzW2P1BKqImOz3tJ952dvO2DWEhcLhQ1Wz1e9ng==", "dev": true }, + "node_modules/@alicloud/credentials": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@alicloud/credentials/-/credentials-2.2.6.tgz", + "integrity": "sha512-jG+msY77dHmAF3x+8VTy7fEgORyXLHmDci8t92HeipBdCHsPptDegA++GEwKgR7f6G4wvafYt+aqMZ1iligdrQ==", + "dependencies": { + "@alicloud/tea-typescript": "^1.5.3", + "httpx": "^2.2.0", + "ini": "^1.3.5", + "kitx": "^2.0.0" + } + }, + "node_modules/@alicloud/dysmsapi20170525": { + "version": "2.0.23", + "resolved": "https://registry.npmjs.org/@alicloud/dysmsapi20170525/-/dysmsapi20170525-2.0.23.tgz", + "integrity": "sha512-C02xj9S2ZPL13SciChlIY3s5+PiOM13jEGZSn+L92aiWYCBqTlpx9UMwNKBNWImMSOlG71IOSYfsQggaoIY+4Q==", + "dependencies": { + "@alicloud/endpoint-util": "^0.0.1", + "@alicloud/openapi-client": "^0.4.4", + "@alicloud/openapi-util": "^0.3.0", + "@alicloud/tea-typescript": "^1.7.1", + "@alicloud/tea-util": "^1.4.5" + } + }, + "node_modules/@alicloud/endpoint-util": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@alicloud/endpoint-util/-/endpoint-util-0.0.1.tgz", + "integrity": "sha512-+pH7/KEXup84cHzIL6UJAaPqETvln4yXlD9JzlrqioyCSaWxbug5FUobsiI6fuUOpw5WwoB3fWAtGbFnJ1K3Yg==", + "dependencies": { + "@alicloud/tea-typescript": "^1.5.1", + "kitx": "^2.0.0" + } + }, + "node_modules/@alicloud/gateway-spi": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@alicloud/gateway-spi/-/gateway-spi-0.0.8.tgz", + "integrity": "sha512-KM7fu5asjxZPmrz9sJGHJeSU+cNQNOxW+SFmgmAIrITui5hXL2LB+KNRuzWmlwPjnuA2X3/keq9h6++S9jcV5g==", + "dependencies": { + "@alicloud/credentials": "^2", + "@alicloud/tea-typescript": "^1.7.1" + } + }, + "node_modules/@alicloud/openapi-client": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@alicloud/openapi-client/-/openapi-client-0.4.5.tgz", + "integrity": "sha512-x1blwhfPOVkH/JCLWFssFRWDL0C75RToun9AwhNV+84gqJB2/GUipm3quHGLon8JiQ0DQ9YBUho2rukSoAvhJQ==", + "dependencies": { + "@alicloud/credentials": "^2", + "@alicloud/gateway-spi": "^0.0.8", + "@alicloud/openapi-util": "^0.3.1", + "@alicloud/tea-typescript": "^1.7.1", + "@alicloud/tea-util": "^1.4.5", + "@alicloud/tea-xml": "0.0.2" + } + }, + "node_modules/@alicloud/openapi-util": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@alicloud/openapi-util/-/openapi-util-0.3.1.tgz", + "integrity": "sha512-6mGT+hs+SXismZi/CEkjPhhbn2U3qTT/Qv/RXAYFA1DC3Jk4/YaX3N7RtpgdzOhdD7uI8XtNkaULKHZY3BrtxQ==", + "dependencies": { + "@alicloud/tea-typescript": "^1.7.1", + "@alicloud/tea-util": "^1.3.0", + "kitx": "^2.1.0", + "sm3": "^1.0.3" + } + }, + "node_modules/@alicloud/tea-typescript": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@alicloud/tea-typescript/-/tea-typescript-1.8.0.tgz", + "integrity": "sha512-CWXWaquauJf0sW30mgJRVu9aaXyBth5uMBCUc+5vKTK1zlgf3hIqRUjJZbjlwHwQ5y9anwcu18r48nOZb7l2QQ==", + "dependencies": { + "@types/node": "^12.0.2", + "httpx": "^2.2.6" + } + }, + "node_modules/@alicloud/tea-typescript/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + }, + "node_modules/@alicloud/tea-util": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@alicloud/tea-util/-/tea-util-1.4.5.tgz", + "integrity": "sha512-7NuThYUi90/ivT/ORKusm0NVKlc1khPTtlzTR77xEqSBt7d24Ee/Lo70hx9PWP28nHpIZ1gM0NKYBtpq7HUDlg==", + "dependencies": { + "@alicloud/tea-typescript": "^1.5.1", + "kitx": "^2.0.0" + } + }, + "node_modules/@alicloud/tea-xml": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@alicloud/tea-xml/-/tea-xml-0.0.2.tgz", + "integrity": "sha512-Xs7v5y7YSNSDDYmiDWAC0/013VWPjS3dQU4KezSLva9VGiTVPaL3S7Nk4NrTmAYCG6MKcrRj/nGEDIWL5KRoPg==", + "dependencies": { + "@alicloud/tea-typescript": "^1", + "@types/xml2js": "^0.4.5", + "xml2js": "^0.4.22" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -93,19 +196,19 @@ } }, "node_modules/@angular-devkit/core": { - "version": "14.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.2.tgz", - "integrity": "sha512-ofDhTmJqoAkmkJP0duwUaCxDBMxPlc+AWYwgs3rKKZeJBb0d+tchEXHXevD5bYbbRfXtnwM+Vye2XYHhA4nWAA==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-15.1.4.tgz", + "integrity": "sha512-PW5MRmd9DHJR4FaXchwQtj9pXnsghSTnwRvfZeCRNYgU2sv0DKyTV+YTSJB+kNXnoPNG1Je6amDEkiXecpspXg==", "dev": true, "dependencies": { - "ajv": "8.11.0", + "ajv": "8.12.0", "ajv-formats": "2.1.1", - "jsonc-parser": "3.1.0", + "jsonc-parser": "3.2.0", "rxjs": "6.6.7", "source-map": "0.7.4" }, "engines": { - "node": "^14.15.0 || >=16.10.0", + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, @@ -118,6 +221,28 @@ } } }, + "node_modules/@angular-devkit/core/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@angular-devkit/core/node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "node_modules/@angular-devkit/core/node_modules/rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", @@ -137,31 +262,31 @@ "dev": true }, "node_modules/@angular-devkit/schematics": { - "version": "14.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.2.tgz", - "integrity": "sha512-90hseNg1yQ2AR+lVr/NByZRHnYAlzCL6hr9p9q1KPHxA3Owo04yX6n6dvR/xf27hCopXInXKPsasR59XCx5ZOQ==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-15.1.4.tgz", + "integrity": "sha512-jpddxo9Qd2yRQ1t9FLhAx5S+luz6HkyhDytq0LFKbxf9ikf1J4oy9riPBFl4pRmrNARWcHZ6GbD20/Ky8PjmXQ==", "dev": true, "dependencies": { - "@angular-devkit/core": "14.2.2", - "jsonc-parser": "3.1.0", - "magic-string": "0.26.2", + "@angular-devkit/core": "15.1.4", + "jsonc-parser": "3.2.0", + "magic-string": "0.27.0", "ora": "5.4.1", "rxjs": "6.6.7" }, "engines": { - "node": "^14.15.0 || >=16.10.0", + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, "node_modules/@angular-devkit/schematics-cli": { - "version": "14.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-14.2.2.tgz", - "integrity": "sha512-timCty5tO1A5VOcy8nVJ+jL98i6+ct5/Hg+4rQxc3J6agmmNL9fALboJBEz1ckTt7MewlGtrpohMMy+YGhuWOg==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-15.1.4.tgz", + "integrity": "sha512-qkM5Mfs28jZzNcJnSM6RlyrKkYvzhQmWFTxBXnn15k5T4EnSs1gI6O054Xn7jo/senfwNNt7h2Mlz2OmBLo6+w==", "dev": true, "dependencies": { - "@angular-devkit/core": "14.2.2", - "@angular-devkit/schematics": "14.2.2", + "@angular-devkit/core": "15.1.4", + "@angular-devkit/schematics": "15.1.4", "ansi-colors": "4.1.3", "inquirer": "8.2.4", "symbol-observable": "4.0.0", @@ -171,7 +296,7 @@ "schematics": "bin/schematics.js" }, "engines": { - "node": "^14.15.0 || >=16.10.0", + "node": "^14.20.0 || ^16.13.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } @@ -218,6 +343,24 @@ "node": ">=12.0.0" } }, + "node_modules/@angular-devkit/schematics/node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "node_modules/@angular-devkit/schematics/node_modules/magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.13" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@angular-devkit/schematics/node_modules/rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", @@ -5469,12 +5612,6 @@ "node": "^12.20.0 || >=14" } }, - "node_modules/@compodoc/compodoc/node_modules/jsonc-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", - "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", - "dev": true - }, "node_modules/@compodoc/compodoc/node_modules/magic-string": { "version": "0.25.7", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", @@ -5674,6 +5811,31 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "node_modules/@fidm/asn1": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@fidm/asn1/-/asn1-1.0.4.tgz", + "integrity": "sha512-esd1jyNvRb2HVaQGq2Gg8Z0kbQPXzV9Tq5Z14KNIov6KfFD6PTaRIO8UpcsYiTNzOqJpmyzWgVTrUwFV3UF4TQ==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@fidm/x509": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@fidm/x509/-/x509-1.2.1.tgz", + "integrity": "sha512-nwc2iesjyc9hkuzcrMCBXQRn653XuAUKorfWM8PZyJawiy1QzLj4vahwzaI25+pfpwOLvMzbJ0uKpWLDNmo16w==", + "dependencies": { + "@fidm/asn1": "^1.0.4", + "tweetnacl": "^1.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@fidm/x509/node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, "node_modules/@foliojs-fork/fontkit": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@foliojs-fork/fontkit/-/fontkit-1.9.1.tgz", @@ -6373,32 +6535,32 @@ } }, "node_modules/@nestjs/cli": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.1.5.tgz", - "integrity": "sha512-rSp26+Nv7PFtYrRSP18Gv5ZK8rRSc2SCCF5wh4SdZaVGgkxShpNq9YEfI+ik/uziN3KC5o74ppYRXGj+aHGVsA==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.2.0.tgz", + "integrity": "sha512-6B1IjDcJbrOu55oMF67L1x5lDUOZ3Zs9l7bKCBH9D78965m8wq/2rlEWl/gJto5TABLQWy3hVvV/s8VzUlRMxw==", "dev": true, "dependencies": { - "@angular-devkit/core": "14.2.2", - "@angular-devkit/schematics": "14.2.2", - "@angular-devkit/schematics-cli": "14.2.2", + "@angular-devkit/core": "15.1.4", + "@angular-devkit/schematics": "15.1.4", + "@angular-devkit/schematics-cli": "15.1.4", "@nestjs/schematics": "^9.0.0", "chalk": "3.0.0", "chokidar": "3.5.3", - "cli-table3": "0.6.2", + "cli-table3": "0.6.3", "commander": "4.1.1", - "fork-ts-checker-webpack-plugin": "7.2.13", + "fork-ts-checker-webpack-plugin": "7.3.0", "inquirer": "7.3.3", "node-emoji": "1.11.0", "ora": "5.4.1", "os-name": "4.0.1", - "rimraf": "3.0.2", + "rimraf": "4.1.2", "shelljs": "0.8.5", "source-map-support": "0.5.21", "tree-kill": "1.2.2", - "tsconfig-paths": "4.1.0", + "tsconfig-paths": "4.1.2", "tsconfig-paths-webpack-plugin": "4.0.0", - "typescript": "4.8.4", - "webpack": "5.74.0", + "typescript": "4.9.5", + "webpack": "5.75.0", "webpack-node-externals": "3.0.0" }, "bin": { @@ -6408,17 +6570,90 @@ "node": ">= 12.9.0" } }, - "node_modules/@nestjs/cli/node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "node_modules/@nestjs/cli/node_modules/rimraf": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.2.tgz", + "integrity": "sha512-BlIbgFryTbw3Dz6hyoWFhKk+unCcHMSkZGrTFVAx2WmttdBSonsdtRlwiuTbDqTKr+UlXIUqJVS4QT5tUzGENQ==", + "deprecated": "Please upgrade to 4.3.1 or higher to fix a potentially damaging issue regarding symbolic link following. See https://github.com/isaacs/rimraf/issues/259 for details.", "dev": true, "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "rimraf": "dist/cjs/src/bin.js" }, "engines": { - "node": ">=4.2.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nestjs/cli/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nestjs/cli/node_modules/tsconfig-paths": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.2.tgz", + "integrity": "sha512-uhxiMgnXQp1IR622dUXI+9Ehnws7i/y6xvpZB9IbUVOPy0muvdvgXeZOn88UcGPiT98Vp3rJPTa8bFoalZ3Qhw==", + "dev": true, + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@nestjs/cli/node_modules/webpack": { + "version": "5.75.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", + "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "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.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } } }, "node_modules/@nestjs/common": { @@ -7308,6 +7543,14 @@ "@types/webidl-conversions": "*" } }, + "node_modules/@types/xml2js": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.11.tgz", + "integrity": "sha512-JdigeAKmCyoJUiQljjr7tQG3if9NkqGUgwEUqBvV0N7LM4HyQk7UXCnusRa1lnvXAEYJ8mw8GtZWioagNztOwA==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/yargs": { "version": "17.0.13", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", @@ -7947,8 +8190,7 @@ "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, "node_modules/asn1": { "version": "0.2.6", @@ -8764,9 +9006,9 @@ } }, "node_modules/cli-table3": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", - "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "dev": true, "dependencies": { "string-width": "^4.2.0" @@ -8889,8 +9131,7 @@ "node_modules/component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "node_modules/compressible": { "version": "2.0.18", @@ -9080,8 +9321,7 @@ "node_modules/cookiejar": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "dev": true + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" }, "node_modules/core-js-compat": { "version": "3.26.0", @@ -9273,11 +9513,15 @@ "lodash.unset": "4.5.2" } }, + "node_modules/dayjs": { + "version": "1.11.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", + "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -9293,8 +9537,7 @@ "node_modules/debug/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/decache": { "version": "4.6.1", @@ -9426,7 +9669,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", - "dev": true, "dependencies": { "asap": "^2.0.0", "wrappy": "1" @@ -10603,9 +10845,9 @@ } }, "node_modules/fork-ts-checker-webpack-plugin": { - "version": "7.2.13", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.13.tgz", - "integrity": "sha512-fR3WRkOb4bQdWB/y7ssDUlVdrclvwtyCUIHCfivAoYxq9dF7XfrDKbMdZIfwJ7hxIAqkYSGeU7lLJE6xrxIBdg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.3.0.tgz", + "integrity": "sha512-IN+XTzusCjR5VgntYFgxbxVx3WraPRnKehBFrf00cMSrtUuW9MsG9dhL6MWpY6MkjC3wVwoujfCDgZZCQwbswA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.16.7", @@ -10666,10 +10908,9 @@ } }, "node_modules/formidable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.1.tgz", - "integrity": "sha512-0EcS9wCFEzLvfiks7omJ+SiYJAiD+TzK4Pcw1UlUoGnhUxDcMKjt0P7x8wEb0u6OHu8Nb98WG3nxtlF5C7bvUQ==", - "dev": true, + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", + "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", "dependencies": { "dezalgo": "^1.0.4", "hexoid": "^1.0.0", @@ -11055,7 +11296,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", - "dev": true, "engines": { "node": ">=8" } @@ -11178,6 +11418,20 @@ "npm": ">=1.3.7" } }, + "node_modules/httpx": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/httpx/-/httpx-2.2.7.tgz", + "integrity": "sha512-Wjh2JOAah0pdczfqL8NC5378G7jMt0Zcpn8U+yyxAiejjlagzSTQgJHuVvka2VNPQlKfoGehYRc79WKq9E4gDw==", + "dependencies": { + "@types/node": "^14", + "debug": "^4.1.1" + } + }, + "node_modules/httpx/node_modules/@types/node": { + "version": "14.18.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.37.tgz", + "integrity": "sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg==" + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -11306,6 +11560,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, "node_modules/inquirer": { "version": "7.3.3", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", @@ -12601,9 +12860,9 @@ } }, "node_modules/jsonc-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.1.0.tgz", - "integrity": "sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", "dev": true }, "node_modules/jsonfile": { @@ -12659,6 +12918,19 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/kitx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/kitx/-/kitx-2.1.0.tgz", + "integrity": "sha512-C/5v9MtIX7aHGOjwn5BmrrbNkJSf7i0R5mRzmh13GSAdRqQ7bYQo/Su2pTYNylFicqKNTVX3HML9k1u8k51+pQ==", + "dependencies": { + "@types/node": "^12.0.2" + } + }, + "node_modules/kitx/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -12949,9 +13221,9 @@ } }, "node_modules/memfs": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.10.tgz", - "integrity": "sha512-0bCUP+L79P4am30yP1msPzApwuMQG23TjwlwdHeEV5MxioDR1a0AgB0T9FfggU52eJuDCq8WVwb5ekznFyWiTQ==", + "version": "3.4.13", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz", + "integrity": "sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==", "dev": true, "dependencies": { "fs-monkey": "^1.0.3" @@ -13377,9 +13649,9 @@ "dev": true }, "node_modules/node-abort-controller": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.0.1.tgz", - "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", "dev": true }, "node_modules/node-emoji": { @@ -14751,8 +15023,7 @@ "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "node_modules/schema-utils": { "version": "3.1.1", @@ -15053,6 +15324,11 @@ "node": ">=8" } }, + "node_modules/sm3": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sm3/-/sm3-1.0.3.tgz", + "integrity": "sha512-KyFkIfr8QBlFG3uc3NaljaXdYcsbRy1KrSfc4tsQV8jW68jAktGeOcifu530Vx/5LC+PULHT0Rv8LiI8Gw+c1g==" + }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -15516,17 +15792,16 @@ "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" }, "node_modules/superagent": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.3.tgz", - "integrity": "sha512-oBC+aNsCjzzjmO5AOPBPFS+Z7HPzlx+DQr/aHwM08kI+R24gsDmAS1LMfza1fK+P+SKlTAoNZpOvooE/pRO1HA==", - "dev": true, + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.9.tgz", + "integrity": "sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==", "dependencies": { "component-emitter": "^1.3.0", - "cookiejar": "^2.1.3", + "cookiejar": "^2.1.4", "debug": "^4.3.4", "fast-safe-stringify": "^2.1.1", "form-data": "^4.0.0", - "formidable": "^2.0.1", + "formidable": "^2.1.2", "methods": "^1.1.2", "mime": "2.6.0", "qs": "^6.11.0", @@ -15540,7 +15815,6 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true, "bin": { "mime": "cli.js" }, @@ -16189,9 +16463,9 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "node_modules/typescript": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", - "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -16467,10 +16741,11 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/webpack": { - "version": "5.74.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", - "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "version": "5.76.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.1.tgz", + "integrity": "sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==", "dev": true, + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -16554,6 +16829,15 @@ "node": ">=0.8.0" } }, + "node_modules/wechatpay-node-v3": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/wechatpay-node-v3/-/wechatpay-node-v3-2.1.1.tgz", + "integrity": "sha512-pAWxzXd7xz4YonFDXvJTG4hc5o+3NPWDwKrC8wykQ0yCTltHFfrPwrEqvMFq28aqz69jp223gY6At3taDkpdCg==", + "dependencies": { + "@fidm/x509": "^1.2.1", + "superagent": "^8.0.6" + } + }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -16709,6 +16993,26 @@ } } }, + "node_modules/xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, "node_modules/xmldoc": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.2.0.tgz", @@ -16822,6 +17126,106 @@ "integrity": "sha512-20Pk2Z98fbPLkECcrZSJszKos/OgtvJJR3NcbVfgCJ6EQjDNzW2P1BKqImOz3tJ952dvO2DWEhcLhQ1Wz1e9ng==", "dev": true }, + "@alicloud/credentials": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@alicloud/credentials/-/credentials-2.2.6.tgz", + "integrity": "sha512-jG+msY77dHmAF3x+8VTy7fEgORyXLHmDci8t92HeipBdCHsPptDegA++GEwKgR7f6G4wvafYt+aqMZ1iligdrQ==", + "requires": { + "@alicloud/tea-typescript": "^1.5.3", + "httpx": "^2.2.0", + "ini": "^1.3.5", + "kitx": "^2.0.0" + } + }, + "@alicloud/dysmsapi20170525": { + "version": "2.0.23", + "resolved": "https://registry.npmjs.org/@alicloud/dysmsapi20170525/-/dysmsapi20170525-2.0.23.tgz", + "integrity": "sha512-C02xj9S2ZPL13SciChlIY3s5+PiOM13jEGZSn+L92aiWYCBqTlpx9UMwNKBNWImMSOlG71IOSYfsQggaoIY+4Q==", + "requires": { + "@alicloud/endpoint-util": "^0.0.1", + "@alicloud/openapi-client": "^0.4.4", + "@alicloud/openapi-util": "^0.3.0", + "@alicloud/tea-typescript": "^1.7.1", + "@alicloud/tea-util": "^1.4.5" + } + }, + "@alicloud/endpoint-util": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@alicloud/endpoint-util/-/endpoint-util-0.0.1.tgz", + "integrity": "sha512-+pH7/KEXup84cHzIL6UJAaPqETvln4yXlD9JzlrqioyCSaWxbug5FUobsiI6fuUOpw5WwoB3fWAtGbFnJ1K3Yg==", + "requires": { + "@alicloud/tea-typescript": "^1.5.1", + "kitx": "^2.0.0" + } + }, + "@alicloud/gateway-spi": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@alicloud/gateway-spi/-/gateway-spi-0.0.8.tgz", + "integrity": "sha512-KM7fu5asjxZPmrz9sJGHJeSU+cNQNOxW+SFmgmAIrITui5hXL2LB+KNRuzWmlwPjnuA2X3/keq9h6++S9jcV5g==", + "requires": { + "@alicloud/credentials": "^2", + "@alicloud/tea-typescript": "^1.7.1" + } + }, + "@alicloud/openapi-client": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@alicloud/openapi-client/-/openapi-client-0.4.5.tgz", + "integrity": "sha512-x1blwhfPOVkH/JCLWFssFRWDL0C75RToun9AwhNV+84gqJB2/GUipm3quHGLon8JiQ0DQ9YBUho2rukSoAvhJQ==", + "requires": { + "@alicloud/credentials": "^2", + "@alicloud/gateway-spi": "^0.0.8", + "@alicloud/openapi-util": "^0.3.1", + "@alicloud/tea-typescript": "^1.7.1", + "@alicloud/tea-util": "^1.4.5", + "@alicloud/tea-xml": "0.0.2" + } + }, + "@alicloud/openapi-util": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@alicloud/openapi-util/-/openapi-util-0.3.1.tgz", + "integrity": "sha512-6mGT+hs+SXismZi/CEkjPhhbn2U3qTT/Qv/RXAYFA1DC3Jk4/YaX3N7RtpgdzOhdD7uI8XtNkaULKHZY3BrtxQ==", + "requires": { + "@alicloud/tea-typescript": "^1.7.1", + "@alicloud/tea-util": "^1.3.0", + "kitx": "^2.1.0", + "sm3": "^1.0.3" + } + }, + "@alicloud/tea-typescript": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@alicloud/tea-typescript/-/tea-typescript-1.8.0.tgz", + "integrity": "sha512-CWXWaquauJf0sW30mgJRVu9aaXyBth5uMBCUc+5vKTK1zlgf3hIqRUjJZbjlwHwQ5y9anwcu18r48nOZb7l2QQ==", + "requires": { + "@types/node": "^12.0.2", + "httpx": "^2.2.6" + }, + "dependencies": { + "@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + } + } + }, + "@alicloud/tea-util": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@alicloud/tea-util/-/tea-util-1.4.5.tgz", + "integrity": "sha512-7NuThYUi90/ivT/ORKusm0NVKlc1khPTtlzTR77xEqSBt7d24Ee/Lo70hx9PWP28nHpIZ1gM0NKYBtpq7HUDlg==", + "requires": { + "@alicloud/tea-typescript": "^1.5.1", + "kitx": "^2.0.0" + } + }, + "@alicloud/tea-xml": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@alicloud/tea-xml/-/tea-xml-0.0.2.tgz", + "integrity": "sha512-Xs7v5y7YSNSDDYmiDWAC0/013VWPjS3dQU4KezSLva9VGiTVPaL3S7Nk4NrTmAYCG6MKcrRj/nGEDIWL5KRoPg==", + "requires": { + "@alicloud/tea-typescript": "^1", + "@types/xml2js": "^0.4.5", + "xml2js": "^0.4.22" + } + }, "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -16833,18 +17237,36 @@ } }, "@angular-devkit/core": { - "version": "14.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.2.tgz", - "integrity": "sha512-ofDhTmJqoAkmkJP0duwUaCxDBMxPlc+AWYwgs3rKKZeJBb0d+tchEXHXevD5bYbbRfXtnwM+Vye2XYHhA4nWAA==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-15.1.4.tgz", + "integrity": "sha512-PW5MRmd9DHJR4FaXchwQtj9pXnsghSTnwRvfZeCRNYgU2sv0DKyTV+YTSJB+kNXnoPNG1Je6amDEkiXecpspXg==", "dev": true, "requires": { - "ajv": "8.11.0", + "ajv": "8.12.0", "ajv-formats": "2.1.1", - "jsonc-parser": "3.1.0", + "jsonc-parser": "3.2.0", "rxjs": "6.6.7", "source-map": "0.7.4" }, "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", @@ -16863,18 +17285,33 @@ } }, "@angular-devkit/schematics": { - "version": "14.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.2.tgz", - "integrity": "sha512-90hseNg1yQ2AR+lVr/NByZRHnYAlzCL6hr9p9q1KPHxA3Owo04yX6n6dvR/xf27hCopXInXKPsasR59XCx5ZOQ==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-15.1.4.tgz", + "integrity": "sha512-jpddxo9Qd2yRQ1t9FLhAx5S+luz6HkyhDytq0LFKbxf9ikf1J4oy9riPBFl4pRmrNARWcHZ6GbD20/Ky8PjmXQ==", "dev": true, "requires": { - "@angular-devkit/core": "14.2.2", - "jsonc-parser": "3.1.0", - "magic-string": "0.26.2", + "@angular-devkit/core": "15.1.4", + "jsonc-parser": "3.2.0", + "magic-string": "0.27.0", "ora": "5.4.1", "rxjs": "6.6.7" }, "dependencies": { + "jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.13" + } + }, "rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", @@ -16893,13 +17330,13 @@ } }, "@angular-devkit/schematics-cli": { - "version": "14.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-14.2.2.tgz", - "integrity": "sha512-timCty5tO1A5VOcy8nVJ+jL98i6+ct5/Hg+4rQxc3J6agmmNL9fALboJBEz1ckTt7MewlGtrpohMMy+YGhuWOg==", + "version": "15.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-15.1.4.tgz", + "integrity": "sha512-qkM5Mfs28jZzNcJnSM6RlyrKkYvzhQmWFTxBXnn15k5T4EnSs1gI6O054Xn7jo/senfwNNt7h2Mlz2OmBLo6+w==", "dev": true, "requires": { - "@angular-devkit/core": "14.2.2", - "@angular-devkit/schematics": "14.2.2", + "@angular-devkit/core": "15.1.4", + "@angular-devkit/schematics": "15.1.4", "ansi-colors": "4.1.3", "inquirer": "8.2.4", "symbol-observable": "4.0.0", @@ -21066,12 +21503,6 @@ "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", "dev": true }, - "jsonc-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", - "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", - "dev": true - }, "magic-string": { "version": "0.25.7", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", @@ -21241,6 +21672,27 @@ } } }, + "@fidm/asn1": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@fidm/asn1/-/asn1-1.0.4.tgz", + "integrity": "sha512-esd1jyNvRb2HVaQGq2Gg8Z0kbQPXzV9Tq5Z14KNIov6KfFD6PTaRIO8UpcsYiTNzOqJpmyzWgVTrUwFV3UF4TQ==" + }, + "@fidm/x509": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@fidm/x509/-/x509-1.2.1.tgz", + "integrity": "sha512-nwc2iesjyc9hkuzcrMCBXQRn653XuAUKorfWM8PZyJawiy1QzLj4vahwzaI25+pfpwOLvMzbJ0uKpWLDNmo16w==", + "requires": { + "@fidm/asn1": "^1.0.4", + "tweetnacl": "^1.0.1" + }, + "dependencies": { + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + } + } + }, "@foliojs-fork/fontkit": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@foliojs-fork/fontkit/-/fontkit-1.9.1.tgz", @@ -21810,40 +22262,89 @@ } }, "@nestjs/cli": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.1.5.tgz", - "integrity": "sha512-rSp26+Nv7PFtYrRSP18Gv5ZK8rRSc2SCCF5wh4SdZaVGgkxShpNq9YEfI+ik/uziN3KC5o74ppYRXGj+aHGVsA==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-9.2.0.tgz", + "integrity": "sha512-6B1IjDcJbrOu55oMF67L1x5lDUOZ3Zs9l7bKCBH9D78965m8wq/2rlEWl/gJto5TABLQWy3hVvV/s8VzUlRMxw==", "dev": true, "requires": { - "@angular-devkit/core": "14.2.2", - "@angular-devkit/schematics": "14.2.2", - "@angular-devkit/schematics-cli": "14.2.2", + "@angular-devkit/core": "15.1.4", + "@angular-devkit/schematics": "15.1.4", + "@angular-devkit/schematics-cli": "15.1.4", "@nestjs/schematics": "^9.0.0", "chalk": "3.0.0", "chokidar": "3.5.3", - "cli-table3": "0.6.2", + "cli-table3": "0.6.3", "commander": "4.1.1", - "fork-ts-checker-webpack-plugin": "7.2.13", + "fork-ts-checker-webpack-plugin": "7.3.0", "inquirer": "7.3.3", "node-emoji": "1.11.0", "ora": "5.4.1", "os-name": "4.0.1", - "rimraf": "3.0.2", + "rimraf": "4.1.2", "shelljs": "0.8.5", "source-map-support": "0.5.21", "tree-kill": "1.2.2", - "tsconfig-paths": "4.1.0", + "tsconfig-paths": "4.1.2", "tsconfig-paths-webpack-plugin": "4.0.0", - "typescript": "4.8.4", - "webpack": "5.74.0", + "typescript": "4.9.5", + "webpack": "5.75.0", "webpack-node-externals": "3.0.0" }, "dependencies": { - "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "rimraf": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.2.tgz", + "integrity": "sha512-BlIbgFryTbw3Dz6hyoWFhKk+unCcHMSkZGrTFVAx2WmttdBSonsdtRlwiuTbDqTKr+UlXIUqJVS4QT5tUzGENQ==", "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "tsconfig-paths": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.2.tgz", + "integrity": "sha512-uhxiMgnXQp1IR622dUXI+9Ehnws7i/y6xvpZB9IbUVOPy0muvdvgXeZOn88UcGPiT98Vp3rJPTa8bFoalZ3Qhw==", + "dev": true, + "requires": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "webpack": { + "version": "5.75.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", + "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "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.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + } } } }, @@ -22547,6 +23048,14 @@ "@types/webidl-conversions": "*" } }, + "@types/xml2js": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.11.tgz", + "integrity": "sha512-JdigeAKmCyoJUiQljjr7tQG3if9NkqGUgwEUqBvV0N7LM4HyQk7UXCnusRa1lnvXAEYJ8mw8GtZWioagNztOwA==", + "requires": { + "@types/node": "*" + } + }, "@types/yargs": { "version": "17.0.13", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", @@ -23019,8 +23528,7 @@ "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "dev": true + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" }, "asn1": { "version": "0.2.6", @@ -23645,9 +24153,9 @@ "dev": true }, "cli-table3": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.2.tgz", - "integrity": "sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "dev": true, "requires": { "@colors/colors": "1.5.0", @@ -23737,8 +24245,7 @@ "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "compressible": { "version": "2.0.18", @@ -23899,8 +24406,7 @@ "cookiejar": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", - "dev": true + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" }, "core-js-compat": { "version": "3.26.0", @@ -24061,11 +24567,15 @@ "lodash.unset": "4.5.2" } }, + "dayjs": { + "version": "1.11.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", + "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "requires": { "ms": "2.1.2" }, @@ -24073,8 +24583,7 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -24174,7 +24683,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", - "dev": true, "requires": { "asap": "^2.0.0", "wrappy": "1" @@ -25086,9 +25594,9 @@ "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" }, "fork-ts-checker-webpack-plugin": { - "version": "7.2.13", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.13.tgz", - "integrity": "sha512-fR3WRkOb4bQdWB/y7ssDUlVdrclvwtyCUIHCfivAoYxq9dF7XfrDKbMdZIfwJ7hxIAqkYSGeU7lLJE6xrxIBdg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.3.0.tgz", + "integrity": "sha512-IN+XTzusCjR5VgntYFgxbxVx3WraPRnKehBFrf00cMSrtUuW9MsG9dhL6MWpY6MkjC3wVwoujfCDgZZCQwbswA==", "dev": true, "requires": { "@babel/code-frame": "^7.16.7", @@ -25128,10 +25636,9 @@ } }, "formidable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.1.tgz", - "integrity": "sha512-0EcS9wCFEzLvfiks7omJ+SiYJAiD+TzK4Pcw1UlUoGnhUxDcMKjt0P7x8wEb0u6OHu8Nb98WG3nxtlF5C7bvUQ==", - "dev": true, + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz", + "integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==", "requires": { "dezalgo": "^1.0.4", "hexoid": "^1.0.0", @@ -25413,8 +25920,7 @@ "hexoid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", - "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==", - "dev": true + "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==" }, "hosted-git-info": { "version": "6.1.1", @@ -25509,6 +26015,22 @@ "sshpk": "^1.7.0" } }, + "httpx": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/httpx/-/httpx-2.2.7.tgz", + "integrity": "sha512-Wjh2JOAah0pdczfqL8NC5378G7jMt0Zcpn8U+yyxAiejjlagzSTQgJHuVvka2VNPQlKfoGehYRc79WKq9E4gDw==", + "requires": { + "@types/node": "^14", + "debug": "^4.1.1" + }, + "dependencies": { + "@types/node": { + "version": "14.18.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.37.tgz", + "integrity": "sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg==" + } + } + }, "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -25582,6 +26104,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, "inquirer": { "version": "7.3.3", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", @@ -26562,9 +27089,9 @@ "dev": true }, "jsonc-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.1.0.tgz", - "integrity": "sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", "dev": true }, "jsonfile": { @@ -26612,6 +27139,21 @@ "safe-buffer": "^5.0.1" } }, + "kitx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/kitx/-/kitx-2.1.0.tgz", + "integrity": "sha512-C/5v9MtIX7aHGOjwn5BmrrbNkJSf7i0R5mRzmh13GSAdRqQ7bYQo/Su2pTYNylFicqKNTVX3HML9k1u8k51+pQ==", + "requires": { + "@types/node": "^12.0.2" + }, + "dependencies": { + "@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + } + } + }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -26836,9 +27378,9 @@ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "memfs": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.10.tgz", - "integrity": "sha512-0bCUP+L79P4am30yP1msPzApwuMQG23TjwlwdHeEV5MxioDR1a0AgB0T9FfggU52eJuDCq8WVwb5ekznFyWiTQ==", + "version": "3.4.13", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz", + "integrity": "sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==", "dev": true, "requires": { "fs-monkey": "^1.0.3" @@ -27168,9 +27710,9 @@ "dev": true }, "node-abort-controller": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.0.1.tgz", - "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", "dev": true }, "node-emoji": { @@ -28167,8 +28709,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "schema-utils": { "version": "3.1.1", @@ -28422,6 +28963,11 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "sm3": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sm3/-/sm3-1.0.3.tgz", + "integrity": "sha512-KyFkIfr8QBlFG3uc3NaljaXdYcsbRy1KrSfc4tsQV8jW68jAktGeOcifu530Vx/5LC+PULHT0Rv8LiI8Gw+c1g==" + }, "smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", @@ -28783,17 +29329,16 @@ "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" }, "superagent": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.3.tgz", - "integrity": "sha512-oBC+aNsCjzzjmO5AOPBPFS+Z7HPzlx+DQr/aHwM08kI+R24gsDmAS1LMfza1fK+P+SKlTAoNZpOvooE/pRO1HA==", - "dev": true, + "version": "8.0.9", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.0.9.tgz", + "integrity": "sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==", "requires": { "component-emitter": "^1.3.0", - "cookiejar": "^2.1.3", + "cookiejar": "^2.1.4", "debug": "^4.3.4", "fast-safe-stringify": "^2.1.1", "form-data": "^4.0.0", - "formidable": "^2.0.1", + "formidable": "^2.1.2", "methods": "^1.1.2", "mime": "2.6.0", "qs": "^6.11.0", @@ -28803,8 +29348,7 @@ "mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" } } }, @@ -29262,9 +29806,9 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "typescript": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", - "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==" + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==" }, "uglify-js": { "version": "3.17.4", @@ -29468,10 +30012,11 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "webpack": { - "version": "5.74.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", - "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "version": "5.76.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.1.tgz", + "integrity": "sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==", "dev": true, + "peer": true, "requires": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -29528,6 +30073,15 @@ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "dev": true }, + "wechatpay-node-v3": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/wechatpay-node-v3/-/wechatpay-node-v3-2.1.1.tgz", + "integrity": "sha512-pAWxzXd7xz4YonFDXvJTG4hc5o+3NPWDwKrC8wykQ0yCTltHFfrPwrEqvMFq28aqz69jp223gY6At3taDkpdCg==", + "requires": { + "@fidm/x509": "^1.2.1", + "superagent": "^8.0.6" + } + }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -29632,6 +30186,20 @@ "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", "requires": {} }, + "xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + }, "xmldoc": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.2.0.tgz", diff --git a/server/package.json b/server/package.json index c0900ead94..885441a6c2 100644 --- a/server/package.json +++ b/server/package.json @@ -1,11 +1,13 @@ { "name": "laf-server", - "version": "1.0.0-beta.4", - "description": "", + "version": "1.0.0-beta.7", + "description": "laf server", "author": "maslow(wangfugen@126.com)", "private": true, - "license": "UNLICENSED", + "license": "Apache-2.0", "scripts": { + "intercept": "telepresence intercept laf-server -n laf-system -p 3000:3000 -e $(pwd)/.env", + "leave": "telepresence leave laf-server-laf-system", "prebuild": "npm run generate && rimraf dist", "generate": "prisma generate", "build": "nest build", @@ -24,6 +26,9 @@ "test:e2e": "jest --config ./test/jest-e2e.json" }, "dependencies": { + "@alicloud/dysmsapi20170525": "^2.0.23", + "@alicloud/openapi-client": "^0.4.5", + "@alicloud/tea-util": "^1.4.5", "@aws-sdk/client-s3": "^3.245.0", "@aws-sdk/client-sts": "^3.226.0", "@kubernetes/client-node": "^0.17.1", @@ -43,6 +48,7 @@ "compression": "^1.7.4", "cron-validate": "^1.4.5", "database-proxy": "^1.0.0-beta.2", + "dayjs": "^1.11.7", "dotenv": "^16.0.3", "fast-json-patch": "^3.1.1", "lodash": "^4.17.21", @@ -54,11 +60,12 @@ "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.2.0", - "typescript": "^4.9.3" + "typescript": "^4.9.3", + "wechatpay-node-v3": "^2.1.1" }, "devDependencies": { "@compodoc/compodoc": "^1.1.19", - "@nestjs/cli": "^9.0.0", + "@nestjs/cli": "^9.2.0", "@nestjs/schematics": "^9.0.0", "@nestjs/testing": "^9.2.0", "@types/compression": "^1.7.2", diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml deleted file mode 100644 index 8e41ea47cb..0000000000 --- a/server/pnpm-lock.yaml +++ /dev/null @@ -1,8886 +0,0 @@ -lockfileVersion: 5.4 - -specifiers: - '@compodoc/compodoc': ^1.1.19 - '@kubernetes/client-node': ^0.17.1 - '@nestjs/axios': ^1.0.0 - '@nestjs/cli': ^9.0.0 - '@nestjs/common': ^9.0.0 - '@nestjs/config': ^2.2.0 - '@nestjs/core': ^9.0.0 - '@nestjs/jwt': ^9.0.0 - '@nestjs/mapped-types': '*' - '@nestjs/passport': ^9.0.0 - '@nestjs/platform-express': ^9.0.0 - '@nestjs/schematics': ^9.0.0 - '@nestjs/swagger': ^6.1.3 - '@nestjs/terminus': ^9.1.2 - '@nestjs/testing': ^9.2.0 - '@nestjs/throttler': ^3.1.0 - '@prisma/client': ^4.6.1 - '@types/compression': ^1.7.2 - '@types/express': ^4.17.13 - '@types/jest': 28.1.8 - '@types/node': ^16.0.0 - '@types/passport-jwt': ^3.0.7 - '@types/passport-local': ^1.0.34 - '@types/supertest': ^2.0.11 - '@typescript-eslint/eslint-plugin': ^5.0.0 - '@typescript-eslint/parser': ^5.0.0 - casdoor-nodejs-sdk: ^1.3.0 - class-transformer: ^0.5.1 - class-validator: ^0.13.2 - compression: ^1.7.4 - dotenv: ^16.0.3 - eslint: ^8.0.1 - eslint-config-prettier: ^8.3.0 - eslint-plugin-prettier: ^4.0.0 - fast-json-patch: ^3.1.1 - helmet: ^6.0.0 - jest: 28.1.3 - mongodb: ^4.12.1 - nanoid: ^3.3.4 - passport: ^0.6.0 - passport-jwt: ^4.0.0 - passport-local: ^1.0.0 - prettier: ^2.3.2 - prisma: ^4.6.1 - reflect-metadata: ^0.1.13 - rimraf: ^3.0.2 - rxjs: ^7.2.0 - source-map-support: ^0.5.20 - supertest: ^6.1.3 - ts-jest: 28.0.8 - ts-loader: ^9.2.3 - ts-node: ^10.0.0 - tsconfig-paths: 4.1.0 - typescript: ^4.7.4 - -dependencies: - '@kubernetes/client-node': 0.17.1 - '@nestjs/axios': 1.0.0_2kbkxfsrhtatemqz6dhv2pefvq - '@nestjs/common': 9.2.0_x6yqyveuahcdef4z4mxykmuv6a - '@nestjs/config': 2.2.0_2kbkxfsrhtatemqz6dhv2pefvq - '@nestjs/core': 9.2.0_jfowmhmgk7kwjudosrpv7e7liy - '@nestjs/jwt': 9.0.0_@nestjs+common@9.2.0 - '@nestjs/mapped-types': 1.2.0_qdpnjncnmntjmcz6x55b5h3mje - '@nestjs/passport': 9.0.0_s6va3jdeufsye4wwu25es3p4om - '@nestjs/platform-express': 9.2.0_pf2fb646rsvo5szivgkaevcpvi - '@nestjs/swagger': 6.1.3_n5tlzb6gajrp65xewlgrtvzeqy - '@nestjs/terminus': 9.1.4_obmctlgxqjsh2bae2xsl4estea - '@nestjs/throttler': 3.1.0_v5qdouhazba6t4koo63x35nolu - '@prisma/client': 4.6.1_prisma@4.6.1 - casdoor-nodejs-sdk: 1.3.0 - class-transformer: 0.5.1 - class-validator: 0.13.2 - compression: 1.7.4 - dotenv: 16.0.3 - fast-json-patch: 3.1.1 - helmet: 6.0.1 - mongodb: 4.12.1 - nanoid: 3.3.4 - passport: 0.6.0 - passport-jwt: 4.0.0 - passport-local: 1.0.0 - reflect-metadata: 0.1.13 - rimraf: 3.0.2 - rxjs: 7.5.7 - -devDependencies: - '@compodoc/compodoc': 1.1.19 - '@nestjs/cli': 9.1.5 - '@nestjs/schematics': 9.0.3_typescript@4.9.3 - '@nestjs/testing': 9.2.0_3jiwpo56qab566j5kwfezyelg4 - '@types/compression': 1.7.2 - '@types/express': 4.17.14 - '@types/jest': 28.1.8 - '@types/node': 16.18.3 - '@types/passport-jwt': 3.0.7 - '@types/passport-local': 1.0.34 - '@types/supertest': 2.0.12 - '@typescript-eslint/eslint-plugin': 5.44.0_fnsv2sbzcckq65bwfk7a5xwslu - '@typescript-eslint/parser': 5.44.0_hsf322ms6xhhd4b5ne6lb74y4a - eslint: 8.28.0 - eslint-config-prettier: 8.5.0_eslint@8.28.0 - eslint-plugin-prettier: 4.2.1_cwlo2dingkvfydnaculr42urve - jest: 28.1.3_dnlfjp7n5lpfgnj4digwzn5fhe - prettier: 2.8.0 - prisma: 4.6.1 - source-map-support: 0.5.21 - supertest: 6.3.1 - ts-jest: 28.0.8_l4uz7kl2eeclic7mumfbeqbwgi - ts-loader: 9.4.1_typescript@4.9.3 - ts-node: 10.9.1_fvpuwgkpfe3dm3hnpcpbcxmb3y - tsconfig-paths: 4.1.0 - typescript: 4.9.3 - -packages: - - /@aduh95/viz.js/3.7.0: - resolution: {integrity: sha512-20Pk2Z98fbPLkECcrZSJszKos/OgtvJJR3NcbVfgCJ6EQjDNzW2P1BKqImOz3tJ952dvO2DWEhcLhQ1Wz1e9ng==} - dev: true - - /@ampproject/remapping/2.2.0: - resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/gen-mapping': 0.1.1 - '@jridgewell/trace-mapping': 0.3.17 - dev: true - - /@angular-devkit/core/13.3.10_chokidar@3.5.3: - resolution: {integrity: sha512-NSjyrccES+RkVL/wt1t1jNmJOV9z5H4/DtVjJQbAt/tDE5Mo0ygnhELd/QiUmjVfzfSkhr75LqQD8NtURoGBwQ==} - engines: {node: ^12.20.0 || ^14.15.0 || >=16.10.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - peerDependencies: - chokidar: ^3.5.2 - peerDependenciesMeta: - chokidar: - optional: true - dependencies: - ajv: 8.9.0 - ajv-formats: 2.1.1 - chokidar: 3.5.3 - fast-json-stable-stringify: 2.1.0 - magic-string: 0.25.7 - rxjs: 6.6.7 - source-map: 0.7.3 - dev: true - - /@angular-devkit/core/14.2.1: - resolution: {integrity: sha512-lW8oNGuJqr4r31FWBjfWQYkSXdiOHBGOThIEtHvUVBKfPF/oVrupLueCUgBPel+NvxENXdo93uPsqHN7bZbmsQ==} - engines: {node: ^14.15.0 || >=16.10.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - peerDependencies: - chokidar: ^3.5.2 - peerDependenciesMeta: - chokidar: - optional: true - dependencies: - ajv: 8.11.0 - ajv-formats: 2.1.1 - jsonc-parser: 3.1.0 - rxjs: 6.6.7 - source-map: 0.7.4 - dev: true - - /@angular-devkit/core/14.2.1_chokidar@3.5.3: - resolution: {integrity: sha512-lW8oNGuJqr4r31FWBjfWQYkSXdiOHBGOThIEtHvUVBKfPF/oVrupLueCUgBPel+NvxENXdo93uPsqHN7bZbmsQ==} - engines: {node: ^14.15.0 || >=16.10.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - peerDependencies: - chokidar: ^3.5.2 - peerDependenciesMeta: - chokidar: - optional: true - dependencies: - ajv: 8.11.0 - ajv-formats: 2.1.1 - chokidar: 3.5.3 - jsonc-parser: 3.1.0 - rxjs: 6.6.7 - source-map: 0.7.4 - dev: true - - /@angular-devkit/core/14.2.2_chokidar@3.5.3: - resolution: {integrity: sha512-ofDhTmJqoAkmkJP0duwUaCxDBMxPlc+AWYwgs3rKKZeJBb0d+tchEXHXevD5bYbbRfXtnwM+Vye2XYHhA4nWAA==} - engines: {node: ^14.15.0 || >=16.10.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - peerDependencies: - chokidar: ^3.5.2 - peerDependenciesMeta: - chokidar: - optional: true - dependencies: - ajv: 8.11.0 - ajv-formats: 2.1.1 - chokidar: 3.5.3 - jsonc-parser: 3.1.0 - rxjs: 6.6.7 - source-map: 0.7.4 - dev: true - - /@angular-devkit/schematics-cli/14.2.2_chokidar@3.5.3: - resolution: {integrity: sha512-timCty5tO1A5VOcy8nVJ+jL98i6+ct5/Hg+4rQxc3J6agmmNL9fALboJBEz1ckTt7MewlGtrpohMMy+YGhuWOg==} - engines: {node: ^14.15.0 || >=16.10.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - hasBin: true - dependencies: - '@angular-devkit/core': 14.2.2_chokidar@3.5.3 - '@angular-devkit/schematics': 14.2.2_chokidar@3.5.3 - ansi-colors: 4.1.3 - inquirer: 8.2.4 - symbol-observable: 4.0.0 - yargs-parser: 21.1.1 - transitivePeerDependencies: - - chokidar - dev: true - - /@angular-devkit/schematics/13.3.10_chokidar@3.5.3: - resolution: {integrity: sha512-/G0xInGBfFiJJQET3nKMe8V7Ny+fcxAZsXxFuOpuH2jfKqty9JMmuJw6ll5qEP0h3NnKPsF+9J1Gvq8Bmb4uDQ==} - engines: {node: ^12.20.0 || ^14.15.0 || >=16.10.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - dependencies: - '@angular-devkit/core': 13.3.10_chokidar@3.5.3 - jsonc-parser: 3.0.0 - magic-string: 0.25.7 - ora: 5.4.1 - rxjs: 6.6.7 - transitivePeerDependencies: - - chokidar - dev: true - - /@angular-devkit/schematics/14.2.1: - resolution: {integrity: sha512-0U18FwDYt4zROBPrvewH6iBTkf2ozVHN4/gxUb9jWrqVw8mPU5AWc/iYxQLHBSinkr2Egjo1H/i9aBqgJSeh3g==} - engines: {node: ^14.15.0 || >=16.10.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - dependencies: - '@angular-devkit/core': 14.2.1 - jsonc-parser: 3.1.0 - magic-string: 0.26.2 - ora: 5.4.1 - rxjs: 6.6.7 - transitivePeerDependencies: - - chokidar - dev: true - - /@angular-devkit/schematics/14.2.1_chokidar@3.5.3: - resolution: {integrity: sha512-0U18FwDYt4zROBPrvewH6iBTkf2ozVHN4/gxUb9jWrqVw8mPU5AWc/iYxQLHBSinkr2Egjo1H/i9aBqgJSeh3g==} - engines: {node: ^14.15.0 || >=16.10.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - dependencies: - '@angular-devkit/core': 14.2.1_chokidar@3.5.3 - jsonc-parser: 3.1.0 - magic-string: 0.26.2 - ora: 5.4.1 - rxjs: 6.6.7 - transitivePeerDependencies: - - chokidar - dev: true - - /@angular-devkit/schematics/14.2.2_chokidar@3.5.3: - resolution: {integrity: sha512-90hseNg1yQ2AR+lVr/NByZRHnYAlzCL6hr9p9q1KPHxA3Owo04yX6n6dvR/xf27hCopXInXKPsasR59XCx5ZOQ==} - engines: {node: ^14.15.0 || >=16.10.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - dependencies: - '@angular-devkit/core': 14.2.2_chokidar@3.5.3 - jsonc-parser: 3.1.0 - magic-string: 0.26.2 - ora: 5.4.1 - rxjs: 6.6.7 - transitivePeerDependencies: - - chokidar - dev: true - - /@aws-crypto/ie11-detection/2.0.2: - resolution: {integrity: sha512-5XDMQY98gMAf/WRTic5G++jfmS/VLM0rwpiOpaainKi4L0nqWMSB1SzsrEG5rjFZGYN6ZAefO+/Yta2dFM0kMw==} - dependencies: - tslib: 1.14.1 - dev: false - optional: true - - /@aws-crypto/sha256-browser/2.0.0: - resolution: {integrity: sha512-rYXOQ8BFOaqMEHJrLHul/25ckWH6GTJtdLSajhlqGMx0PmSueAuvboCuZCTqEKlxR8CQOwRarxYMZZSYlhRA1A==} - dependencies: - '@aws-crypto/ie11-detection': 2.0.2 - '@aws-crypto/sha256-js': 2.0.0 - '@aws-crypto/supports-web-crypto': 2.0.2 - '@aws-crypto/util': 2.0.2 - '@aws-sdk/types': 3.215.0 - '@aws-sdk/util-locate-window': 3.208.0 - '@aws-sdk/util-utf8-browser': 3.188.0 - tslib: 1.14.1 - dev: false - optional: true - - /@aws-crypto/sha256-js/2.0.0: - resolution: {integrity: sha512-VZY+mCY4Nmrs5WGfitmNqXzaE873fcIZDu54cbaDaaamsaTOP1DBImV9F4pICc3EHjQXujyE8jig+PFCaew9ig==} - dependencies: - '@aws-crypto/util': 2.0.2 - '@aws-sdk/types': 3.215.0 - tslib: 1.14.1 - dev: false - optional: true - - /@aws-crypto/supports-web-crypto/2.0.2: - resolution: {integrity: sha512-6mbSsLHwZ99CTOOswvCRP3C+VCWnzBf+1SnbWxzzJ9lR0mA0JnY2JEAhp8rqmTE0GPFy88rrM27ffgp62oErMQ==} - dependencies: - tslib: 1.14.1 - dev: false - optional: true - - /@aws-crypto/util/2.0.2: - resolution: {integrity: sha512-Lgu5v/0e/BcrZ5m/IWqzPUf3UYFTy/PpeED+uc9SWUR1iZQL8XXbGQg10UfllwwBryO3hFF5dizK+78aoXC1eA==} - dependencies: - '@aws-sdk/types': 3.215.0 - '@aws-sdk/util-utf8-browser': 3.188.0 - tslib: 1.14.1 - dev: false - optional: true - - /@aws-sdk/abort-controller/3.215.0: - resolution: {integrity: sha512-HTvL542nawhVqe0oC1AJchdcomEOmPivJEzYUT1LqiG3e8ikxMNa2KWSqqLPeKi2t0A/cfQy7wDUyg9+BZhDSQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/client-cognito-identity/3.218.0: - resolution: {integrity: sha512-IHzM9jpLqdeqj2w7YA7FrmLCQyKaun7eXtu1OJYMFbJT5XHx6B4jlQ1T/N8xivSSzDfjpJxG6/MMmjec4pI+CA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-crypto/sha256-browser': 2.0.0 - '@aws-crypto/sha256-js': 2.0.0 - '@aws-sdk/client-sts': 3.218.0 - '@aws-sdk/config-resolver': 3.215.0 - '@aws-sdk/credential-provider-node': 3.218.0 - '@aws-sdk/fetch-http-handler': 3.215.0 - '@aws-sdk/hash-node': 3.215.0 - '@aws-sdk/invalid-dependency': 3.215.0 - '@aws-sdk/middleware-content-length': 3.215.0 - '@aws-sdk/middleware-endpoint': 3.215.0 - '@aws-sdk/middleware-host-header': 3.215.0 - '@aws-sdk/middleware-logger': 3.215.0 - '@aws-sdk/middleware-recursion-detection': 3.215.0 - '@aws-sdk/middleware-retry': 3.215.0 - '@aws-sdk/middleware-serde': 3.215.0 - '@aws-sdk/middleware-signing': 3.215.0 - '@aws-sdk/middleware-stack': 3.215.0 - '@aws-sdk/middleware-user-agent': 3.215.0 - '@aws-sdk/node-config-provider': 3.215.0 - '@aws-sdk/node-http-handler': 3.215.0 - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/smithy-client': 3.215.0 - '@aws-sdk/types': 3.215.0 - '@aws-sdk/url-parser': 3.215.0 - '@aws-sdk/util-base64': 3.208.0 - '@aws-sdk/util-body-length-browser': 3.188.0 - '@aws-sdk/util-body-length-node': 3.208.0 - '@aws-sdk/util-defaults-mode-browser': 3.215.0 - '@aws-sdk/util-defaults-mode-node': 3.215.0 - '@aws-sdk/util-endpoints': 3.216.0 - '@aws-sdk/util-user-agent-browser': 3.215.0 - '@aws-sdk/util-user-agent-node': 3.215.0 - '@aws-sdk/util-utf8-browser': 3.188.0 - '@aws-sdk/util-utf8-node': 3.208.0 - tslib: 2.4.1 - transitivePeerDependencies: - - aws-crt - dev: false - optional: true - - /@aws-sdk/client-sso-oidc/3.216.0: - resolution: {integrity: sha512-O8kmM86BHwiSwyNoIe+iHXuSpUE9PBWl3re8u+/igt/w5W5VmMVz+zQr7gRUDQ1FDgLWNEdAJa0r+JFx3pZdzA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-crypto/sha256-browser': 2.0.0 - '@aws-crypto/sha256-js': 2.0.0 - '@aws-sdk/config-resolver': 3.215.0 - '@aws-sdk/fetch-http-handler': 3.215.0 - '@aws-sdk/hash-node': 3.215.0 - '@aws-sdk/invalid-dependency': 3.215.0 - '@aws-sdk/middleware-content-length': 3.215.0 - '@aws-sdk/middleware-endpoint': 3.215.0 - '@aws-sdk/middleware-host-header': 3.215.0 - '@aws-sdk/middleware-logger': 3.215.0 - '@aws-sdk/middleware-recursion-detection': 3.215.0 - '@aws-sdk/middleware-retry': 3.215.0 - '@aws-sdk/middleware-serde': 3.215.0 - '@aws-sdk/middleware-stack': 3.215.0 - '@aws-sdk/middleware-user-agent': 3.215.0 - '@aws-sdk/node-config-provider': 3.215.0 - '@aws-sdk/node-http-handler': 3.215.0 - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/smithy-client': 3.215.0 - '@aws-sdk/types': 3.215.0 - '@aws-sdk/url-parser': 3.215.0 - '@aws-sdk/util-base64': 3.208.0 - '@aws-sdk/util-body-length-browser': 3.188.0 - '@aws-sdk/util-body-length-node': 3.208.0 - '@aws-sdk/util-defaults-mode-browser': 3.215.0 - '@aws-sdk/util-defaults-mode-node': 3.215.0 - '@aws-sdk/util-endpoints': 3.216.0 - '@aws-sdk/util-user-agent-browser': 3.215.0 - '@aws-sdk/util-user-agent-node': 3.215.0 - '@aws-sdk/util-utf8-browser': 3.188.0 - '@aws-sdk/util-utf8-node': 3.208.0 - tslib: 2.4.1 - transitivePeerDependencies: - - aws-crt - dev: false - optional: true - - /@aws-sdk/client-sso/3.218.0: - resolution: {integrity: sha512-kVMlpjaVblxgb1G8q3wD65mKxO3RzKwnjUjIBmOHpmseXzlSkAdAvYcikaDoJP+CRmys4uXk5DN8c7ZdL0OmgA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-crypto/sha256-browser': 2.0.0 - '@aws-crypto/sha256-js': 2.0.0 - '@aws-sdk/config-resolver': 3.215.0 - '@aws-sdk/fetch-http-handler': 3.215.0 - '@aws-sdk/hash-node': 3.215.0 - '@aws-sdk/invalid-dependency': 3.215.0 - '@aws-sdk/middleware-content-length': 3.215.0 - '@aws-sdk/middleware-endpoint': 3.215.0 - '@aws-sdk/middleware-host-header': 3.215.0 - '@aws-sdk/middleware-logger': 3.215.0 - '@aws-sdk/middleware-recursion-detection': 3.215.0 - '@aws-sdk/middleware-retry': 3.215.0 - '@aws-sdk/middleware-serde': 3.215.0 - '@aws-sdk/middleware-stack': 3.215.0 - '@aws-sdk/middleware-user-agent': 3.215.0 - '@aws-sdk/node-config-provider': 3.215.0 - '@aws-sdk/node-http-handler': 3.215.0 - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/smithy-client': 3.215.0 - '@aws-sdk/types': 3.215.0 - '@aws-sdk/url-parser': 3.215.0 - '@aws-sdk/util-base64': 3.208.0 - '@aws-sdk/util-body-length-browser': 3.188.0 - '@aws-sdk/util-body-length-node': 3.208.0 - '@aws-sdk/util-defaults-mode-browser': 3.215.0 - '@aws-sdk/util-defaults-mode-node': 3.215.0 - '@aws-sdk/util-endpoints': 3.216.0 - '@aws-sdk/util-user-agent-browser': 3.215.0 - '@aws-sdk/util-user-agent-node': 3.215.0 - '@aws-sdk/util-utf8-browser': 3.188.0 - '@aws-sdk/util-utf8-node': 3.208.0 - tslib: 2.4.1 - transitivePeerDependencies: - - aws-crt - dev: false - optional: true - - /@aws-sdk/client-sts/3.218.0: - resolution: {integrity: sha512-0A81eHvryKFEPq7IeY34Opzh5b9bVhhLlf2fDy5VuZjCFf4R9vD2ceOANvFSJeMsmdlqVDq8U1mHYl0E6FRUug==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-crypto/sha256-browser': 2.0.0 - '@aws-crypto/sha256-js': 2.0.0 - '@aws-sdk/config-resolver': 3.215.0 - '@aws-sdk/credential-provider-node': 3.218.0 - '@aws-sdk/fetch-http-handler': 3.215.0 - '@aws-sdk/hash-node': 3.215.0 - '@aws-sdk/invalid-dependency': 3.215.0 - '@aws-sdk/middleware-content-length': 3.215.0 - '@aws-sdk/middleware-endpoint': 3.215.0 - '@aws-sdk/middleware-host-header': 3.215.0 - '@aws-sdk/middleware-logger': 3.215.0 - '@aws-sdk/middleware-recursion-detection': 3.215.0 - '@aws-sdk/middleware-retry': 3.215.0 - '@aws-sdk/middleware-sdk-sts': 3.215.0 - '@aws-sdk/middleware-serde': 3.215.0 - '@aws-sdk/middleware-signing': 3.215.0 - '@aws-sdk/middleware-stack': 3.215.0 - '@aws-sdk/middleware-user-agent': 3.215.0 - '@aws-sdk/node-config-provider': 3.215.0 - '@aws-sdk/node-http-handler': 3.215.0 - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/smithy-client': 3.215.0 - '@aws-sdk/types': 3.215.0 - '@aws-sdk/url-parser': 3.215.0 - '@aws-sdk/util-base64': 3.208.0 - '@aws-sdk/util-body-length-browser': 3.188.0 - '@aws-sdk/util-body-length-node': 3.208.0 - '@aws-sdk/util-defaults-mode-browser': 3.215.0 - '@aws-sdk/util-defaults-mode-node': 3.215.0 - '@aws-sdk/util-endpoints': 3.216.0 - '@aws-sdk/util-user-agent-browser': 3.215.0 - '@aws-sdk/util-user-agent-node': 3.215.0 - '@aws-sdk/util-utf8-browser': 3.188.0 - '@aws-sdk/util-utf8-node': 3.208.0 - fast-xml-parser: 4.0.11 - tslib: 2.4.1 - transitivePeerDependencies: - - aws-crt - dev: false - optional: true - - /@aws-sdk/config-resolver/3.215.0: - resolution: {integrity: sha512-DxX4R+YYLQOtg0qfceKBrjVD4t1mQBG1eb7IVr2QSlckFCX8ztUNymFMuaSEo3938Jyy/NpgfUDpFqPDaSKnng==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/signature-v4': 3.215.0 - '@aws-sdk/types': 3.215.0 - '@aws-sdk/util-config-provider': 3.208.0 - '@aws-sdk/util-middleware': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/credential-provider-cognito-identity/3.218.0: - resolution: {integrity: sha512-ndhlPBvnxUgje23TnVw0fkDgTZHh0GVapKSgeEIxmxAy3IVLN15iMs7dCV7LWvb7z1P0cYx9cwvxa0nTrVxjtg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/client-cognito-identity': 3.218.0 - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - transitivePeerDependencies: - - aws-crt - dev: false - optional: true - - /@aws-sdk/credential-provider-env/3.215.0: - resolution: {integrity: sha512-n5G7I7Pxfsn81+tNsSOzspKp9SYai78oRfImsfFY4JLTcWutv7szMgFUbtEzBfUUINHpOxLiO2Lk5yu5K1C7IQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/credential-provider-imds/3.215.0: - resolution: {integrity: sha512-/4FUUR6u9gkNfxB6mEwBr0kk0myIkrDcXbAocWN3fPd/t7otzxpx/JqPZXgM6kcVP7M4T/QT75l1E1RRHLWCCQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/node-config-provider': 3.215.0 - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/types': 3.215.0 - '@aws-sdk/url-parser': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/credential-provider-ini/3.218.0: - resolution: {integrity: sha512-tDDrGW+4A+PQThVJ+l9ee03CsDoD0XLpOB5dcf+dr/dCHjcQ7x/CeVFZ8eM+XUtGQnZVvuzXZGwzS8bUWEdJIg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/credential-provider-env': 3.215.0 - '@aws-sdk/credential-provider-imds': 3.215.0 - '@aws-sdk/credential-provider-sso': 3.218.0 - '@aws-sdk/credential-provider-web-identity': 3.215.0 - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/shared-ini-file-loader': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - transitivePeerDependencies: - - aws-crt - dev: false - optional: true - - /@aws-sdk/credential-provider-node/3.218.0: - resolution: {integrity: sha512-J9PB6XFA+V0mgxleuY5W6Jjh5WejV8HjMViTJQpp2JN+NWZP3bGvquUSQHRqWGRGg2fSJy6Z/J4zQ8fpPbGsdQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/credential-provider-env': 3.215.0 - '@aws-sdk/credential-provider-imds': 3.215.0 - '@aws-sdk/credential-provider-ini': 3.218.0 - '@aws-sdk/credential-provider-process': 3.215.0 - '@aws-sdk/credential-provider-sso': 3.218.0 - '@aws-sdk/credential-provider-web-identity': 3.215.0 - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/shared-ini-file-loader': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - transitivePeerDependencies: - - aws-crt - dev: false - optional: true - - /@aws-sdk/credential-provider-process/3.215.0: - resolution: {integrity: sha512-JNvj4L5B7W8byoFdfn/8Y4scoPiwCi+Ha/fRsFCrdSC7C+snDuxM/oQj33HI8DpKY1cjuigzEnpnxiNWaA09EA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/shared-ini-file-loader': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/credential-provider-sso/3.218.0: - resolution: {integrity: sha512-HecWvmxD+xffmY8G4SfLRfCOgSoLFki45wOOU8ESgRM9fQp2+3CfRSyiThKZI5PTmE+xhPTRvmR61HUmQjEv8w==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/client-sso': 3.218.0 - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/shared-ini-file-loader': 3.215.0 - '@aws-sdk/token-providers': 3.216.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - transitivePeerDependencies: - - aws-crt - dev: false - optional: true - - /@aws-sdk/credential-provider-web-identity/3.215.0: - resolution: {integrity: sha512-AWaDDEE3VU1HeLrXvyUrkQ6Wb3PQij5bvvrMil9L0da3b1yrcpoDanQQy7wBFBXcZIVmcmSFe5MMA/nyh2Le4g==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/credential-providers/3.218.0: - resolution: {integrity: sha512-MWpb5k+Oq56NrHA5fYPIDX8QRYUAw4Jp8ErTELBd83kLhTgqTw025YQ05YbhIzAs84+viMeWKif0z/5kNshphw==} - engines: {node: '>=14.0.0'} - requiresBuild: true - dependencies: - '@aws-sdk/client-cognito-identity': 3.218.0 - '@aws-sdk/client-sso': 3.218.0 - '@aws-sdk/client-sts': 3.218.0 - '@aws-sdk/credential-provider-cognito-identity': 3.218.0 - '@aws-sdk/credential-provider-env': 3.215.0 - '@aws-sdk/credential-provider-imds': 3.215.0 - '@aws-sdk/credential-provider-ini': 3.218.0 - '@aws-sdk/credential-provider-node': 3.218.0 - '@aws-sdk/credential-provider-process': 3.215.0 - '@aws-sdk/credential-provider-sso': 3.218.0 - '@aws-sdk/credential-provider-web-identity': 3.215.0 - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/shared-ini-file-loader': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - transitivePeerDependencies: - - aws-crt - dev: false - optional: true - - /@aws-sdk/fetch-http-handler/3.215.0: - resolution: {integrity: sha512-JfZyrJOE+0ik1PumsIUZd0NfgEx4sZ43VSdPCD9GRhssRWudNsSF1B5fz3xA5v+1y5oQPjXZyaWCzKtnYruiWw==} - dependencies: - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/querystring-builder': 3.215.0 - '@aws-sdk/types': 3.215.0 - '@aws-sdk/util-base64': 3.208.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/hash-node/3.215.0: - resolution: {integrity: sha512-MkSRuZvo1RCRmI0VNEmRYCGGD/DkMd9lqnLtOyglMPnSX1mhyD4/DyXmcc3rYa7PsjDRAfykGWJRiMqpoMLjiQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.215.0 - '@aws-sdk/util-buffer-from': 3.208.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/invalid-dependency/3.215.0: - resolution: {integrity: sha512-++bK4BUQe8/CL/YcLZcQB8qPOhiXxhbuhYzfFS7PNVvW1QOLqKRZL/lKs24gzjcOmw7IhAbCybDZwvu2TM4DAg==} - dependencies: - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/is-array-buffer/3.201.0: - resolution: {integrity: sha512-UPez5qLh3dNgt0DYnPD/q0mVJY84rA17QE26hVNOW3fAji8W2wrwrxdacWOxyXvlxWsVRcKmr+lay1MDqpAMfg==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/middleware-content-length/3.215.0: - resolution: {integrity: sha512-zKJRb6jDLFl9nl/muSFbiQHA4uK3skinuDRcyLbpMvvzhuK/PVodv9QI1+wIUsFdXkaSxAlva1oG4bL8ZFi+sQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/middleware-endpoint/3.215.0: - resolution: {integrity: sha512-W0QXL5emcN9IXtMbnWT/abLxBFH2tGIfnre2jPNmZ9M7uVFxUwwv5OTUXxNLGNehJHKhiJPwhfQvMy20IDzVcw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/middleware-serde': 3.215.0 - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/signature-v4': 3.215.0 - '@aws-sdk/types': 3.215.0 - '@aws-sdk/url-parser': 3.215.0 - '@aws-sdk/util-config-provider': 3.208.0 - '@aws-sdk/util-middleware': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/middleware-host-header/3.215.0: - resolution: {integrity: sha512-GOqI7VwoENZwn+6tIMrrJ4SipIqL2JCh+BNvORVcy7CQxn1ViKkna7iaCx+QMjpg/kn9cR6kfY0n1FmgZR1w9A==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/middleware-logger/3.215.0: - resolution: {integrity: sha512-0h4GGF0rV3jnY3jxmcAWsOdqHCYf25s0biSjmgTei+l/5S+geOGrovRPCNep0LLg0i9D8bkZsXISojilETbf+g==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/middleware-recursion-detection/3.215.0: - resolution: {integrity: sha512-KQ+kiEsaluM4i6opjusUukxY78+UhfR7vzXHDkzZK/GplQ1hY0B+rwVO1eaULmlnmf3FK+Wd6lwrPV7xS2W+EA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/middleware-retry/3.215.0: - resolution: {integrity: sha512-I/dnUPVg2Kp3lW+MywBoPp06EOng8IfuaS9ph4bcJpQKrhNU5ekRgCHH2C4k1A6GcP8uyHxQ5TVV6j+l0QPIsA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/service-error-classification': 3.215.0 - '@aws-sdk/types': 3.215.0 - '@aws-sdk/util-middleware': 3.215.0 - tslib: 2.4.1 - uuid: 8.3.2 - dev: false - optional: true - - /@aws-sdk/middleware-sdk-sts/3.215.0: - resolution: {integrity: sha512-wJRxoDf+2egbRgochaQL8+zzADx8FM/2W0spKNj8x+t/3iqw70QwxCfuEKW/uFQ3ph6eaIrv7gYc8RRjwhD8rg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/middleware-signing': 3.215.0 - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/signature-v4': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/middleware-serde/3.215.0: - resolution: {integrity: sha512-+uhLXdKvvQZcRRFc3UmemSr/YUHA4Jc+1YMjHxc3v8vvfztFJBb0wgBx999myOi8PmkYThlRBQDzXy9UCIhIJw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/middleware-signing/3.215.0: - resolution: {integrity: sha512-3BqzYqkmdPeOxjI8DVQE7Bm7J5QIvDy30abglXqrDg6npw6KonKI2Q3FIPFf+oLpZTMStwkoQOnwXHTPrSZ6Tg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/signature-v4': 3.215.0 - '@aws-sdk/types': 3.215.0 - '@aws-sdk/util-middleware': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/middleware-stack/3.215.0: - resolution: {integrity: sha512-rdSVL7LxRgjlvoluqwODD4ypBy2k/YVl6FrDplyCMSi8m2WHZG99FzdmR9bpnWK+0DGzYZSMRYx6ynJ9N9PsSw==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/middleware-user-agent/3.215.0: - resolution: {integrity: sha512-X6GfoMNoEITTw7rGL/gWs8UZ0cmmmezvKcl+KtHsA642R05OR4mY5G7LdbWAw0bcrwKsuKOGmwUrC9lzGqbWUw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/node-config-provider/3.215.0: - resolution: {integrity: sha512-notckD94QwwxC0GsfpTxB7VH8SREIIlMsUSddqGtpModa0cq/wRb9rqnydZSoznbYpK1ND6h0C9hr/2PNz89zw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/shared-ini-file-loader': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/node-http-handler/3.215.0: - resolution: {integrity: sha512-btKWSR7m0UuWIN3p5MfSIvhqeYik7xri7U6nWuVI5GVzIYjzxEZOMvPAinDLDxL5wipodi0ZvTUNdDJdm7BcGQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/abort-controller': 3.215.0 - '@aws-sdk/protocol-http': 3.215.0 - '@aws-sdk/querystring-builder': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/property-provider/3.215.0: - resolution: {integrity: sha512-dDPjMCCopkRURAmOJCMSlpIQ5BGWCpYj0+FIfZ5qWQs24fn1PAkQHecOiBhJO0ZSVuQy3xcIyWsAp1NE5e+7ug==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/protocol-http/3.215.0: - resolution: {integrity: sha512-qp6Y6v4S534LAjadiVl9p7ErK7ImphOKq6yhFyQwxko6iITLcz8ib3yU27fs4QJcnNj5ZooqW/YlL/0EikDxCQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/querystring-builder/3.215.0: - resolution: {integrity: sha512-eilk8CqG37BVhQklLif00K2dOJgDzacUi8h3KVQ72ry1V3h345i4HsmaFIxvnz8XtNyDvV8qFAzeYg9n2P9RQA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.215.0 - '@aws-sdk/util-uri-escape': 3.201.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/querystring-parser/3.215.0: - resolution: {integrity: sha512-8h/9H8dWM4fZO27UGzo8W5JXln4yJMugPyUl4qFA437gzPgNFN95+oLJWXtHMlfCHC5T/PDKetY9TarMDgBD0Q==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/service-error-classification/3.215.0: - resolution: {integrity: sha512-SKBvClGFGzMPsjBBKjneaUazLCNr6bSxe9eFvOr3gCwuwE2jPQwW3VE1mb62howuvm6cLthEDwLQp/FsT1gMsw==} - engines: {node: '>=14.0.0'} - dev: false - optional: true - - /@aws-sdk/shared-ini-file-loader/3.215.0: - resolution: {integrity: sha512-unzQeLOyUiYHr8WxxandHo0OaCj31gx0wpt8dn2cZcHm/MdCqHcHcsQqOVnQsWQrrxY/XZ27cPyMVQeicNKYwQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/signature-v4/3.215.0: - resolution: {integrity: sha512-Rc73uUCi3eJneO25DydLTfJYamXeuKS9YIhNMTKlpvcN1UQAmAnUbAmCuEmqvkYOiGD1i4/kd8kBga708iIikQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/is-array-buffer': 3.201.0 - '@aws-sdk/types': 3.215.0 - '@aws-sdk/util-hex-encoding': 3.201.0 - '@aws-sdk/util-middleware': 3.215.0 - '@aws-sdk/util-uri-escape': 3.201.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/smithy-client/3.215.0: - resolution: {integrity: sha512-PiZfCdZkPohzMPrRmJ46TPOf2Tr/dhKYdwQArRnOOIsJABUGXjlzCUE8vysDN35XZYRx5f9hd+/U7kayhniq2w==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/middleware-stack': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/token-providers/3.216.0: - resolution: {integrity: sha512-cEmOfG7njWl0OA5lR65Sp2SW1i8ZLjf7C95TZ1e6t2Oo5aUFeN3aKBxMOV//1yc+BNzcFBnoHP/f29GhWxUOxA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/client-sso-oidc': 3.216.0 - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/shared-ini-file-loader': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - transitivePeerDependencies: - - aws-crt - dev: false - optional: true - - /@aws-sdk/types/3.215.0: - resolution: {integrity: sha512-eRbCVjwzTYd9C5e2mceScJ6D2kYDDEC3PLkYfJa+1wH9iiF2JlbiYozAokyeYBHQ+AjmD93MK58RBoM8iZfH0Q==} - engines: {node: '>=14.0.0'} - dev: false - optional: true - - /@aws-sdk/url-parser/3.215.0: - resolution: {integrity: sha512-r/qIk3TUlV36JvoRjTErFm0LzzgNKLB1YUG8zVZCGAc2TEATi8OVEmsZvi+KfTmsbszulITJVcjZKbHLbGoUzg==} - dependencies: - '@aws-sdk/querystring-parser': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-base64/3.208.0: - resolution: {integrity: sha512-PQniZph5A6N7uuEOQi+1hnMz/FSOK/8kMFyFO+4DgA1dZ5pcKcn5wiFwHkcTb/BsgVqQa3Jx0VHNnvhlS8JyTg==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/util-buffer-from': 3.208.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-body-length-browser/3.188.0: - resolution: {integrity: sha512-8VpnwFWXhnZ/iRSl9mTf+VKOX9wDE8QtN4bj9pBfxwf90H1X7E8T6NkiZD3k+HubYf2J94e7DbeHs7fuCPW5Qg==} - dependencies: - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-body-length-node/3.208.0: - resolution: {integrity: sha512-3zj50e5g7t/MQf53SsuuSf0hEELzMtD8RX8C76f12OSRo2Bca4FLLYHe0TZbxcfQHom8/hOaeZEyTyMogMglqg==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-buffer-from/3.208.0: - resolution: {integrity: sha512-7L0XUixNEFcLUGPeBF35enCvB9Xl+K6SQsmbrPk1P3mlV9mguWSDQqbOBwY1Ir0OVbD6H/ZOQU7hI/9RtRI0Zw==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/is-array-buffer': 3.201.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-config-provider/3.208.0: - resolution: {integrity: sha512-DSRqwrERUsT34ug+anlMBIFooBEGwM8GejC7q00Y/9IPrQy50KnG5PW2NiTjuLKNi7pdEOlwTSEocJE15eDZIg==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-defaults-mode-browser/3.215.0: - resolution: {integrity: sha512-MiNfZgB0I4dR8CBxH163W7c9KvE38sgCHNPWopMqSX5ezz7cuCPohCU0XsWd4I7K31PvzuqmKgOiKBAZraQJMA==} - engines: {node: '>= 10.0.0'} - dependencies: - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/types': 3.215.0 - bowser: 2.11.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-defaults-mode-node/3.215.0: - resolution: {integrity: sha512-mSp3R8GljQ+4UT3QMOksQk9L0cWbFLvR7bBmAlt4+GobgTjpRfzFjBP3uwrCqFa3BKDUR3FeJq3qwo+xeY1Krg==} - engines: {node: '>= 10.0.0'} - dependencies: - '@aws-sdk/config-resolver': 3.215.0 - '@aws-sdk/credential-provider-imds': 3.215.0 - '@aws-sdk/node-config-provider': 3.215.0 - '@aws-sdk/property-provider': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-endpoints/3.216.0: - resolution: {integrity: sha512-uHje4H6Qj/z/op8UZoSuvGpEZhz/r+AGY0rCihFo7XjhT4RYVxb2Eb9uHRK/IAeHU4kjHAdpQiWGMSmnT/UacA==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-hex-encoding/3.201.0: - resolution: {integrity: sha512-7t1vR1pVxKx0motd3X9rI3m/xNp78p3sHtP5yo4NP4ARpxyJ0fokBomY8ScaH2D/B+U5o9ARxldJUdMqyBlJcA==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-locate-window/3.208.0: - resolution: {integrity: sha512-iua1A2+P7JJEDHVgvXrRJSvsnzG7stYSGQnBVphIUlemwl6nN5D+QrgbjECtrbxRz8asYFHSzhdhECqN+tFiBg==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-middleware/3.215.0: - resolution: {integrity: sha512-DfHGlFlQCr+T/xhjS36HH8JEThDVB5lg5NZ6x4Cibhyeps9YX/4ovLAIx3B19H34sdWhZi7q6LfslCHLRu2+7Q==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-uri-escape/3.201.0: - resolution: {integrity: sha512-TeTWbGx4LU2c5rx0obHeDFeO9HvwYwQtMh1yniBz00pQb6Qt6YVOETVQikRZ+XRQwEyCg/dA375UplIpiy54mA==} - engines: {node: '>=14.0.0'} - dependencies: - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-user-agent-browser/3.215.0: - resolution: {integrity: sha512-uZz6BJWr8sJcA+onveS1lFqnbIXBHwvkyHLgCuuGhAxd5yY6YNLhpJBnhy9Fb8/aSbk6yao3qxlokqw9gthmAw==} - dependencies: - '@aws-sdk/types': 3.215.0 - bowser: 2.11.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-user-agent-node/3.215.0: - resolution: {integrity: sha512-4lrdd1oGRwJEwfvgvg1jcJ2O0bwElsvtiqZfTRHN6MNTFUqsKl0xHlgFChQsz3Hfrc1niWtZCmbqQKGdO5ARpw==} - engines: {node: '>=14.0.0'} - peerDependencies: - aws-crt: '>=1.0.0' - peerDependenciesMeta: - aws-crt: - optional: true - dependencies: - '@aws-sdk/node-config-provider': 3.215.0 - '@aws-sdk/types': 3.215.0 - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-utf8-browser/3.188.0: - resolution: {integrity: sha512-jt627x0+jE+Ydr9NwkFstg3cUvgWh56qdaqAMDsqgRlKD21md/6G226z/Qxl7lb1VEW2LlmCx43ai/37Qwcj2Q==} - dependencies: - tslib: 2.4.1 - dev: false - optional: true - - /@aws-sdk/util-utf8-node/3.208.0: - resolution: {integrity: sha512-jKY87Acv0yWBdFxx6bveagy5FYjz+dtV8IPT7ay1E2WPWH1czoIdMAkc8tSInK31T6CRnHWkLZ1qYwCbgRfERQ==} - engines: {node: '>=14.0.0'} - dependencies: - '@aws-sdk/util-buffer-from': 3.208.0 - tslib: 2.4.1 - dev: false - optional: true - - /@babel/code-frame/7.18.6: - resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.18.6 - dev: true - - /@babel/compat-data/7.20.1: - resolution: {integrity: sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/core/7.20.2: - resolution: {integrity: sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==} - engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.2.0 - '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.4 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.2 - '@babel/helper-module-transforms': 7.20.2 - '@babel/helpers': 7.20.1 - '@babel/parser': 7.20.3 - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 - convert-source-map: 1.9.0 - debug: 4.3.4 - gensync: 1.0.0-beta.2 - json5: 2.2.1 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/generator/7.20.4: - resolution: {integrity: sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.2 - '@jridgewell/gen-mapping': 0.3.2 - jsesc: 2.5.2 - dev: true - - /@babel/helper-annotate-as-pure/7.18.6: - resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.2 - dev: true - - /@babel/helper-builder-binary-assignment-operator-visitor/7.18.9: - resolution: {integrity: sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-explode-assignable-expression': 7.18.6 - '@babel/types': 7.20.2 - dev: true - - /@babel/helper-compilation-targets/7.20.0_@babel+core@7.20.2: - resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/compat-data': 7.20.1 - '@babel/core': 7.20.2 - '@babel/helper-validator-option': 7.18.6 - browserslist: 4.21.4 - semver: 6.3.0 - dev: true - - /@babel/helper-create-class-features-plugin/7.20.2_@babel+core@7.20.2: - resolution: {integrity: sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-member-expression-to-functions': 7.18.9 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-replace-supers': 7.19.1 - '@babel/helper-split-export-declaration': 7.18.6 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-create-regexp-features-plugin/7.19.0_@babel+core@7.20.2: - resolution: {integrity: sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-annotate-as-pure': 7.18.6 - regexpu-core: 5.2.2 - dev: true - - /@babel/helper-define-polyfill-provider/0.3.3_@babel+core@7.20.2: - resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} - peerDependencies: - '@babel/core': ^7.4.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - debug: 4.3.4 - lodash.debounce: 4.0.8 - resolve: 1.22.1 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-environment-visitor/7.18.9: - resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-explode-assignable-expression/7.18.6: - resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.2 - dev: true - - /@babel/helper-function-name/7.19.0: - resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.18.10 - '@babel/types': 7.20.2 - dev: true - - /@babel/helper-hoist-variables/7.18.6: - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.2 - dev: true - - /@babel/helper-member-expression-to-functions/7.18.9: - resolution: {integrity: sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.2 - dev: true - - /@babel/helper-module-imports/7.18.6: - resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.2 - dev: true - - /@babel/helper-module-transforms/7.20.2: - resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-simple-access': 7.20.2 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/helper-validator-identifier': 7.19.1 - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-optimise-call-expression/7.18.6: - resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.2 - dev: true - - /@babel/helper-plugin-utils/7.20.2: - resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-remap-async-to-generator/7.18.9_@babel+core@7.20.2: - resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-wrap-function': 7.19.0 - '@babel/types': 7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-replace-supers/7.19.1: - resolution: {integrity: sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-member-expression-to-functions': 7.18.9 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-simple-access/7.20.2: - resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.2 - dev: true - - /@babel/helper-skip-transparent-expression-wrappers/7.20.0: - resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.2 - dev: true - - /@babel/helper-split-export-declaration/7.18.6: - resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.2 - dev: true - - /@babel/helper-string-parser/7.19.4: - resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-identifier/7.19.1: - resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-option/7.18.6: - resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-wrap-function/7.19.0: - resolution: {integrity: sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-function-name': 7.19.0 - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helpers/7.20.1: - resolution: {integrity: sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/highlight/7.18.6: - resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.19.1 - chalk: 2.4.2 - js-tokens: 4.0.0 - dev: true - - /@babel/parser/7.20.3: - resolution: {integrity: sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.20.2 - dev: true - - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.18.9_@babel+core@7.20.2: - resolution: {integrity: sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.13.0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.20.2 - dev: true - - /@babel/plugin-proposal-async-generator-functions/7.20.1_@babel+core@7.20.2: - resolution: {integrity: sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-proposal-class-properties/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-class-features-plugin': 7.20.2_@babel+core@7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-proposal-class-static-block/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.12.0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-class-features-plugin': 7.20.2_@babel+core@7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-proposal-dynamic-import/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.2 - dev: true - - /@babel/plugin-proposal-export-namespace-from/7.18.9_@babel+core@7.20.2: - resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.2 - dev: true - - /@babel/plugin-proposal-json-strings/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.2 - dev: true - - /@babel/plugin-proposal-logical-assignment-operators/7.18.9_@babel+core@7.20.2: - resolution: {integrity: sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.2 - dev: true - - /@babel/plugin-proposal-nullish-coalescing-operator/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.2 - dev: true - - /@babel/plugin-proposal-numeric-separator/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.2 - dev: true - - /@babel/plugin-proposal-object-rest-spread/7.20.2_@babel+core@7.20.2: - resolution: {integrity: sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.20.1 - '@babel/core': 7.20.2 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-transform-parameters': 7.20.3_@babel+core@7.20.2 - dev: true - - /@babel/plugin-proposal-optional-catch-binding/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.2 - dev: true - - /@babel/plugin-proposal-optional-chaining/7.18.9_@babel+core@7.20.2: - resolution: {integrity: sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.2 - dev: true - - /@babel/plugin-proposal-private-methods/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-class-features-plugin': 7.20.2_@babel+core@7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-proposal-private-property-in-object/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.20.2_@babel+core@7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-proposal-unicode-property-regex/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} - engines: {node: '>=4'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.20.2: - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.20.2: - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.20.2: - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.20.2: - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.20.2: - resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.20.2: - resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-import-assertions/7.20.0_@babel+core@7.20.2: - resolution: {integrity: sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.20.2: - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.20.2: - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.20.2: - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.20.2: - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.20.2: - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.20.2: - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.20.2: - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.20.2: - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.20.2: - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.20.2: - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-typescript/7.20.0_@babel+core@7.20.2: - resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-arrow-functions/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-async-to-generator/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-block-scoped-functions/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-block-scoping/7.20.2_@babel+core@7.20.2: - resolution: {integrity: sha512-y5V15+04ry69OV2wULmwhEA6jwSWXO1TwAtIwiPXcvHcoOQUqpyMVd2bDsQJMW8AurjulIyUV8kDqtjSwHy1uQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-classes/7.20.2_@babel+core@7.20.2: - resolution: {integrity: sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.2 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.19.1 - '@babel/helper-split-export-declaration': 7.18.6 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-computed-properties/7.18.9_@babel+core@7.20.2: - resolution: {integrity: sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-destructuring/7.20.2_@babel+core@7.20.2: - resolution: {integrity: sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-dotall-regex/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-duplicate-keys/7.18.9_@babel+core@7.20.2: - resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-exponentiation-operator/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-for-of/7.18.8_@babel+core@7.20.2: - resolution: {integrity: sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-function-name/7.18.9_@babel+core@7.20.2: - resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.2 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-literals/7.18.9_@babel+core@7.20.2: - resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-member-expression-literals/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-modules-amd/7.19.6_@babel+core@7.20.2: - resolution: {integrity: sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-module-transforms': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-modules-commonjs/7.19.6_@babel+core@7.20.2: - resolution: {integrity: sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-module-transforms': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-simple-access': 7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-modules-systemjs/7.19.6_@babel+core@7.20.2: - resolution: {integrity: sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-module-transforms': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-validator-identifier': 7.19.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-modules-umd/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-module-transforms': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-named-capturing-groups-regex/7.19.1_@babel+core@7.20.2: - resolution: {integrity: sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-new-target/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-object-super/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.19.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-parameters/7.20.3_@babel+core@7.20.2: - resolution: {integrity: sha512-oZg/Fpx0YDrj13KsLyO8I/CX3Zdw7z0O9qOd95SqcoIzuqy/WTGWvePeHAnZCN54SfdyjHcb1S30gc8zlzlHcA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-property-literals/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-regenerator/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - regenerator-transform: 0.15.1 - dev: true - - /@babel/plugin-transform-reserved-words/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-shorthand-properties/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-spread/7.19.0_@babel+core@7.20.2: - resolution: {integrity: sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - dev: true - - /@babel/plugin-transform-sticky-regex/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-template-literals/7.18.9_@babel+core@7.20.2: - resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-typeof-symbol/7.18.9_@babel+core@7.20.2: - resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-unicode-escapes/7.18.10_@babel+core@7.20.2: - resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-transform-unicode-regex/7.18.6_@babel+core@7.20.2: - resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-create-regexp-features-plugin': 7.19.0_@babel+core@7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/preset-env/7.20.2_@babel+core@7.20.2: - resolution: {integrity: sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.20.1 - '@babel/core': 7.20.2 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-validator-option': 7.18.6 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-proposal-async-generator-functions': 7.20.1_@babel+core@7.20.2 - '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-class-static-block': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-dynamic-import': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-export-namespace-from': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-logical-assignment-operators': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-object-rest-spread': 7.20.2_@babel+core@7.20.2 - '@babel/plugin-proposal-optional-catch-binding': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-private-property-in-object': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.2 - '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.20.2 - '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.2 - '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-import-assertions': 7.20.0_@babel+core@7.20.2 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.2 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.2 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.2 - '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.20.2 - '@babel/plugin-transform-arrow-functions': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-async-to-generator': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-block-scoped-functions': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-block-scoping': 7.20.2_@babel+core@7.20.2 - '@babel/plugin-transform-classes': 7.20.2_@babel+core@7.20.2 - '@babel/plugin-transform-computed-properties': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-transform-destructuring': 7.20.2_@babel+core@7.20.2 - '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-duplicate-keys': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-transform-exponentiation-operator': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-for-of': 7.18.8_@babel+core@7.20.2 - '@babel/plugin-transform-function-name': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-transform-literals': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-transform-member-expression-literals': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-modules-amd': 7.19.6_@babel+core@7.20.2 - '@babel/plugin-transform-modules-commonjs': 7.19.6_@babel+core@7.20.2 - '@babel/plugin-transform-modules-systemjs': 7.19.6_@babel+core@7.20.2 - '@babel/plugin-transform-modules-umd': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-named-capturing-groups-regex': 7.19.1_@babel+core@7.20.2 - '@babel/plugin-transform-new-target': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-object-super': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-parameters': 7.20.3_@babel+core@7.20.2 - '@babel/plugin-transform-property-literals': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-regenerator': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-reserved-words': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-shorthand-properties': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-spread': 7.19.0_@babel+core@7.20.2 - '@babel/plugin-transform-sticky-regex': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-template-literals': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-transform-typeof-symbol': 7.18.9_@babel+core@7.20.2 - '@babel/plugin-transform-unicode-escapes': 7.18.10_@babel+core@7.20.2 - '@babel/plugin-transform-unicode-regex': 7.18.6_@babel+core@7.20.2 - '@babel/preset-modules': 0.1.5_@babel+core@7.20.2 - '@babel/types': 7.20.2 - babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.20.2 - babel-plugin-polyfill-corejs3: 0.6.0_@babel+core@7.20.2 - babel-plugin-polyfill-regenerator: 0.4.1_@babel+core@7.20.2 - core-js-compat: 3.26.1 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/preset-modules/0.1.5_@babel+core@7.20.2: - resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.2 - '@babel/types': 7.20.2 - esutils: 2.0.3 - dev: true - - /@babel/runtime/7.20.1: - resolution: {integrity: sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.13.11 - dev: true - - /@babel/template/7.18.10: - resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.18.6 - '@babel/parser': 7.20.3 - '@babel/types': 7.20.2 - dev: true - - /@babel/traverse/7.20.1: - resolution: {integrity: sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.4 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.20.3 - '@babel/types': 7.20.2 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/types/7.20.2: - resolution: {integrity: sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.19.4 - '@babel/helper-validator-identifier': 7.19.1 - to-fast-properties: 2.0.0 - dev: true - - /@bcoe/v8-coverage/0.2.3: - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - dev: true - - /@colors/colors/1.5.0: - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} - engines: {node: '>=0.1.90'} - requiresBuild: true - dev: true - optional: true - - /@compodoc/compodoc/1.1.19: - resolution: {integrity: sha512-09vdSIgoAXWD1MiLZNhiljLNQ1XzHw/w5shw5IPcUImr/I+1Y52srUL46mEXN8AXo0hbHb5LZcgs70mmrOvY7Q==} - engines: {node: '>= 12.0.0'} - hasBin: true - requiresBuild: true - dependencies: - '@angular-devkit/schematics': 13.3.10_chokidar@3.5.3 - '@babel/core': 7.20.2 - '@babel/preset-env': 7.20.2_@babel+core@7.20.2 - '@compodoc/live-server': 1.2.3 - '@compodoc/ngd-transformer': 2.1.0 - chalk: 4.1.2 - cheerio: 1.0.0-rc.12 - chokidar: 3.5.3 - colors: 1.4.0 - commander: 9.4.1 - cosmiconfig: 7.1.0 - decache: 4.6.1 - fancy-log: 2.0.0 - findit2: 2.2.3 - fs-extra: 10.1.0 - glob: 7.2.3 - handlebars: 4.7.7 - html-entities: 2.3.3 - i18next: 21.10.0 - inside: 1.0.0 - json5: 2.2.1 - lodash: 4.17.21 - loglevel: 1.8.1 - loglevel-plugin-prefix: 0.8.4 - lunr: 2.3.9 - marked: 4.2.3 - minimist: 1.2.7 - opencollective-postinstall: 2.0.3 - os-name: 4.0.1 - pdfjs-dist: 2.16.105 - pdfmake: 0.2.6 - semver: 7.3.8 - traverse: 0.6.7 - ts-morph: 13.0.3 - uuid: 8.3.2 - transitivePeerDependencies: - - supports-color - - worker-loader - dev: true - - /@compodoc/live-server/1.2.3: - resolution: {integrity: sha512-hDmntVCyjjaxuJzPzBx68orNZ7TW4BtHWMnXlIVn5dqhK7vuFF/11hspO1cMmc+2QTYgqde1TBcb3127S7Zrow==} - engines: {node: '>=0.10.0'} - hasBin: true - dependencies: - chokidar: 3.5.3 - colors: 1.4.0 - connect: 3.7.0 - cors: 2.8.5 - event-stream: 4.0.1 - faye-websocket: 0.11.4 - http-auth: 4.1.9 - http-auth-connect: 1.0.6 - morgan: 1.10.0 - object-assign: 4.1.1 - open: 8.4.0 - proxy-middleware: 0.15.0 - send: 0.18.0 - serve-index: 1.9.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@compodoc/ngd-core/2.1.0: - resolution: {integrity: sha512-nyBH7J7SJJ2AV6OeZhJ02kRtVB7ALnZJKgShjoL9CNmOFEj8AkdhP9qTBIgjaDrbsW5pF4nx32KQL2fT7RFnqw==} - engines: {node: '>= 10.0.0'} - dependencies: - ansi-colors: 4.1.3 - fancy-log: 1.3.3 - typescript: 4.9.3 - dev: true - - /@compodoc/ngd-transformer/2.1.0: - resolution: {integrity: sha512-Jo4VCMzIUtgIAdRmhHhOoRRE01gCjc5CyrUERRx0VgEzkkCm1Wmu/XHSsQP6tSpCYHBjERghqaDqH5DabkR2oQ==} - engines: {node: '>= 10.0.0'} - dependencies: - '@aduh95/viz.js': 3.7.0 - '@compodoc/ngd-core': 2.1.0 - dot: 1.1.3 - fs-extra: 9.1.0 - dev: true - - /@cspotcode/source-map-support/0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - dev: true - - /@eslint/eslintrc/1.3.3: - resolution: {integrity: sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 9.4.1 - globals: 13.18.0 - ignore: 5.2.1 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@foliojs-fork/fontkit/1.9.1: - resolution: {integrity: sha512-U589voc2/ROnvx1CyH9aNzOQWJp127JGU1QAylXGQ7LoEAF6hMmahZLQ4eqAcgHUw+uyW4PjtCItq9qudPkK3A==} - dependencies: - '@foliojs-fork/restructure': 2.0.2 - brfs: 2.0.2 - brotli: 1.3.3 - browserify-optional: 1.0.1 - clone: 1.0.4 - deep-equal: 1.1.1 - dfa: 1.2.0 - tiny-inflate: 1.0.3 - unicode-properties: 1.4.1 - unicode-trie: 2.0.0 - dev: true - - /@foliojs-fork/linebreak/1.1.1: - resolution: {integrity: sha512-pgY/+53GqGQI+mvDiyprvPWgkTlVBS8cxqee03ejm6gKAQNsR1tCYCIvN9FHy7otZajzMqCgPOgC4cHdt4JPig==} - dependencies: - base64-js: 1.3.1 - brfs: 2.0.2 - unicode-trie: 2.0.0 - dev: true - - /@foliojs-fork/pdfkit/0.13.0: - resolution: {integrity: sha512-YXeG1fml9k97YNC9K8e292Pj2JzGt9uOIiBFuQFxHsdQ45BlxW+JU3RQK6JAvXU7kjhjP8rCcYvpk36JLD33sQ==} - dependencies: - '@foliojs-fork/fontkit': 1.9.1 - '@foliojs-fork/linebreak': 1.1.1 - crypto-js: 4.1.1 - png-js: 1.0.0 - dev: true - - /@foliojs-fork/restructure/2.0.2: - resolution: {integrity: sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA==} - dev: true - - /@humanwhocodes/config-array/0.11.7: - resolution: {integrity: sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==} - engines: {node: '>=10.10.0'} - dependencies: - '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@humanwhocodes/module-importer/1.0.1: - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - dev: true - - /@humanwhocodes/object-schema/1.2.1: - resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} - dev: true - - /@istanbuljs/load-nyc-config/1.1.0: - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - dev: true - - /@istanbuljs/schema/0.1.3: - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - dev: true - - /@jest/console/28.1.3: - resolution: {integrity: sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/node': 16.18.3 - chalk: 4.1.2 - jest-message-util: 28.1.3 - jest-util: 28.1.3 - slash: 3.0.0 - dev: true - - /@jest/core/28.1.3_ts-node@10.9.1: - resolution: {integrity: sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/console': 28.1.3 - '@jest/reporters': 28.1.3 - '@jest/test-result': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 16.18.3 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.7.0 - exit: 0.1.2 - graceful-fs: 4.2.10 - jest-changed-files: 28.1.3 - jest-config: 28.1.3_dnlfjp7n5lpfgnj4digwzn5fhe - jest-haste-map: 28.1.3 - jest-message-util: 28.1.3 - jest-regex-util: 28.0.2 - jest-resolve: 28.1.3 - jest-resolve-dependencies: 28.1.3 - jest-runner: 28.1.3 - jest-runtime: 28.1.3 - jest-snapshot: 28.1.3 - jest-util: 28.1.3 - jest-validate: 28.1.3 - jest-watcher: 28.1.3 - micromatch: 4.0.5 - pretty-format: 28.1.3 - rimraf: 3.0.2 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - supports-color - - ts-node - dev: true - - /@jest/environment/28.1.3: - resolution: {integrity: sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/fake-timers': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 16.18.3 - jest-mock: 28.1.3 - dev: true - - /@jest/expect-utils/28.1.3: - resolution: {integrity: sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - jest-get-type: 28.0.2 - dev: true - - /@jest/expect/28.1.3: - resolution: {integrity: sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - expect: 28.1.3 - jest-snapshot: 28.1.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/fake-timers/28.1.3: - resolution: {integrity: sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@sinonjs/fake-timers': 9.1.2 - '@types/node': 16.18.3 - jest-message-util: 28.1.3 - jest-mock: 28.1.3 - jest-util: 28.1.3 - dev: true - - /@jest/globals/28.1.3: - resolution: {integrity: sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/environment': 28.1.3 - '@jest/expect': 28.1.3 - '@jest/types': 28.1.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/reporters/28.1.3: - resolution: {integrity: sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 28.1.3 - '@jest/test-result': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - '@jridgewell/trace-mapping': 0.3.17 - '@types/node': 16.18.3 - chalk: 4.1.2 - collect-v8-coverage: 1.0.1 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.10 - istanbul-lib-coverage: 3.2.0 - istanbul-lib-instrument: 5.2.1 - istanbul-lib-report: 3.0.0 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.5 - jest-message-util: 28.1.3 - jest-util: 28.1.3 - jest-worker: 28.1.3 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - terminal-link: 2.1.1 - v8-to-istanbul: 9.0.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/schemas/28.1.3: - resolution: {integrity: sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@sinclair/typebox': 0.24.51 - dev: true - - /@jest/source-map/28.1.2: - resolution: {integrity: sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jridgewell/trace-mapping': 0.3.17 - callsites: 3.1.0 - graceful-fs: 4.2.10 - dev: true - - /@jest/test-result/28.1.3: - resolution: {integrity: sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/console': 28.1.3 - '@jest/types': 28.1.3 - '@types/istanbul-lib-coverage': 2.0.4 - collect-v8-coverage: 1.0.1 - dev: true - - /@jest/test-sequencer/28.1.3: - resolution: {integrity: sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/test-result': 28.1.3 - graceful-fs: 4.2.10 - jest-haste-map: 28.1.3 - slash: 3.0.0 - dev: true - - /@jest/transform/28.1.3: - resolution: {integrity: sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@babel/core': 7.20.2 - '@jest/types': 28.1.3 - '@jridgewell/trace-mapping': 0.3.17 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 1.9.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.10 - jest-haste-map: 28.1.3 - jest-regex-util: 28.0.2 - jest-util: 28.1.3 - micromatch: 4.0.5 - pirates: 4.0.5 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/types/28.1.3: - resolution: {integrity: sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/schemas': 28.1.3 - '@types/istanbul-lib-coverage': 2.0.4 - '@types/istanbul-reports': 3.0.1 - '@types/node': 16.18.3 - '@types/yargs': 17.0.14 - chalk: 4.1.2 - dev: true - - /@jridgewell/gen-mapping/0.1.1: - resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - - /@jridgewell/gen-mapping/0.3.2: - resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.14 - '@jridgewell/trace-mapping': 0.3.17 - dev: true - - /@jridgewell/resolve-uri/3.1.0: - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/set-array/1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/source-map/0.3.2: - resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} - dependencies: - '@jridgewell/gen-mapping': 0.3.2 - '@jridgewell/trace-mapping': 0.3.17 - dev: true - - /@jridgewell/sourcemap-codec/1.4.14: - resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true - - /@jridgewell/trace-mapping/0.3.17: - resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} - dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - - /@jridgewell/trace-mapping/0.3.9: - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - - /@kubernetes/client-node/0.17.1: - resolution: {integrity: sha512-qXANjukuTq/drb1hq1NCYZafpdRTvbyTzbliWO6RwW7eEb2b9qwINbw0DiVHpBQg3e9DeQd8+brI1sR1Fck5kQ==} - dependencies: - byline: 5.0.0 - execa: 5.0.0 - isomorphic-ws: 4.0.1_ws@7.5.9 - js-yaml: 4.1.0 - jsonpath-plus: 0.19.0 - request: 2.88.2 - rfc4648: 1.5.2 - shelljs: 0.8.5 - stream-buffers: 3.0.2 - tar: 6.1.12 - tmp-promise: 3.0.3 - tslib: 1.14.1 - underscore: 1.13.6 - ws: 7.5.9 - optionalDependencies: - openid-client: 5.3.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: false - - /@nestjs/axios/1.0.0_2kbkxfsrhtatemqz6dhv2pefvq: - resolution: {integrity: sha512-DzBIhmBPgPAf/Hf4oHVgNNrcYcmAwV6v1TeZFkEaotO5AtXEfCJ6c07Po4EmylAA0PFp+8+S77PBEcLNEMOCGQ==} - peerDependencies: - '@nestjs/common': ^7.0.0 || ^8.0.0 || ^9.0.0 - reflect-metadata: ^0.1.12 - rxjs: ^6.0.0 || ^7.0.0 - dependencies: - '@nestjs/common': 9.2.0_x6yqyveuahcdef4z4mxykmuv6a - axios: 1.1.3 - reflect-metadata: 0.1.13 - rxjs: 7.5.7 - transitivePeerDependencies: - - debug - dev: false - - /@nestjs/cli/9.1.5: - resolution: {integrity: sha512-rSp26+Nv7PFtYrRSP18Gv5ZK8rRSc2SCCF5wh4SdZaVGgkxShpNq9YEfI+ik/uziN3KC5o74ppYRXGj+aHGVsA==} - engines: {node: '>= 12.9.0'} - hasBin: true - dependencies: - '@angular-devkit/core': 14.2.2_chokidar@3.5.3 - '@angular-devkit/schematics': 14.2.2_chokidar@3.5.3 - '@angular-devkit/schematics-cli': 14.2.2_chokidar@3.5.3 - '@nestjs/schematics': 9.0.3_ar2on76c45aosuucycxzxivxgm - chalk: 3.0.0 - chokidar: 3.5.3 - cli-table3: 0.6.2 - commander: 4.1.1 - fork-ts-checker-webpack-plugin: 7.2.13_qqxisngxjbp7lstdk7boexbu3e - inquirer: 7.3.3 - node-emoji: 1.11.0 - ora: 5.4.1 - os-name: 4.0.1 - rimraf: 3.0.2 - shelljs: 0.8.5 - source-map-support: 0.5.21 - tree-kill: 1.2.2 - tsconfig-paths: 4.1.0 - tsconfig-paths-webpack-plugin: 4.0.0 - typescript: 4.8.4 - webpack: 5.74.0 - webpack-node-externals: 3.0.0 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - - vue-template-compiler - - webpack-cli - dev: true - - /@nestjs/common/9.2.0_x6yqyveuahcdef4z4mxykmuv6a: - resolution: {integrity: sha512-Ndcqak/ETYi+n1c5lFRPbxKLyUuM6DIOxcvfEFGfi0f6ad4dWDXRDx7z/n8V0l8+Y8djvvOHgf3t0e93w963Qg==} - peerDependencies: - cache-manager: <=5 - class-transformer: '*' - class-validator: '*' - reflect-metadata: ^0.1.12 - rxjs: ^7.1.0 - peerDependenciesMeta: - cache-manager: - optional: true - class-transformer: - optional: true - class-validator: - optional: true - dependencies: - class-transformer: 0.5.1 - class-validator: 0.13.2 - iterare: 1.2.1 - reflect-metadata: 0.1.13 - rxjs: 7.5.7 - tslib: 2.4.1 - uuid: 9.0.0 - - /@nestjs/config/2.2.0_2kbkxfsrhtatemqz6dhv2pefvq: - resolution: {integrity: sha512-78Eg6oMbCy3D/YvqeiGBTOWei1Jwi3f2pSIZcZ1QxY67kYsJzTRTkwRT8Iv30DbK0sGKc1mcloDLD5UXgZAZtg==} - peerDependencies: - '@nestjs/common': ^7.0.0 || ^8.0.0 || ^9.0.0 - reflect-metadata: ^0.1.13 - rxjs: ^6.0.0 || ^7.2.0 - dependencies: - '@nestjs/common': 9.2.0_x6yqyveuahcdef4z4mxykmuv6a - dotenv: 16.0.1 - dotenv-expand: 8.0.3 - lodash: 4.17.21 - reflect-metadata: 0.1.13 - rxjs: 7.5.7 - uuid: 8.3.2 - dev: false - - /@nestjs/core/9.2.0_jfowmhmgk7kwjudosrpv7e7liy: - resolution: {integrity: sha512-eVN7aXAavV+ImVt8mO+rQ5YyUP6lJtQKUtQHxHKzz6Wg+9Y67WWZS2uDcDX5NNcNijbWky5bqad86fgcK9Oqig==} - requiresBuild: true - peerDependencies: - '@nestjs/common': ^9.0.0 - '@nestjs/microservices': ^9.0.0 - '@nestjs/platform-express': ^9.0.0 - '@nestjs/websockets': ^9.0.0 - reflect-metadata: ^0.1.12 - rxjs: ^7.1.0 - peerDependenciesMeta: - '@nestjs/microservices': - optional: true - '@nestjs/platform-express': - optional: true - '@nestjs/websockets': - optional: true - dependencies: - '@nestjs/common': 9.2.0_x6yqyveuahcdef4z4mxykmuv6a - '@nestjs/platform-express': 9.2.0_pf2fb646rsvo5szivgkaevcpvi - '@nuxtjs/opencollective': 0.3.2 - fast-safe-stringify: 2.1.1 - iterare: 1.2.1 - object-hash: 3.0.0 - path-to-regexp: 3.2.0 - reflect-metadata: 0.1.13 - rxjs: 7.5.7 - tslib: 2.4.1 - uuid: 9.0.0 - transitivePeerDependencies: - - encoding - - /@nestjs/jwt/9.0.0_@nestjs+common@9.2.0: - resolution: {integrity: sha512-ZsXGY/wMYKzEhymw2+dxiwrHTRKIKrGszx6r2EjQqNLypdXMQu0QrujwZJ8k3+XQV4snmuJwwNakQoA2ILfq8w==} - peerDependencies: - '@nestjs/common': ^8.0.0 || ^9.0.0 - dependencies: - '@nestjs/common': 9.2.0_x6yqyveuahcdef4z4mxykmuv6a - '@types/jsonwebtoken': 8.5.8 - jsonwebtoken: 8.5.1 - dev: false - - /@nestjs/mapped-types/1.2.0_qdpnjncnmntjmcz6x55b5h3mje: - resolution: {integrity: sha512-NTFwPZkQWsArQH8QSyFWGZvJ08gR+R4TofglqZoihn/vU+ktHEJjMqsIsADwb7XD97DhiD+TVv5ac+jG33BHrg==} - peerDependencies: - '@nestjs/common': ^7.0.8 || ^8.0.0 || ^9.0.0 - class-transformer: ^0.2.0 || ^0.3.0 || ^0.4.0 || ^0.5.0 - class-validator: ^0.11.1 || ^0.12.0 || ^0.13.0 - reflect-metadata: ^0.1.12 - peerDependenciesMeta: - class-transformer: - optional: true - class-validator: - optional: true - dependencies: - '@nestjs/common': 9.2.0_x6yqyveuahcdef4z4mxykmuv6a - class-transformer: 0.5.1 - class-validator: 0.13.2 - reflect-metadata: 0.1.13 - dev: false - - /@nestjs/passport/9.0.0_s6va3jdeufsye4wwu25es3p4om: - resolution: {integrity: sha512-Gnh8n1wzFPOLSS/94X1sUP4IRAoXTgG4odl7/AO5h+uwscEGXxJFercrZfqdAwkWhqkKWbsntM3j5mRy/6ZQDA==} - peerDependencies: - '@nestjs/common': ^8.0.0 || ^9.0.0 - passport: ^0.4.0 || ^0.5.0 || ^0.6.0 - dependencies: - '@nestjs/common': 9.2.0_x6yqyveuahcdef4z4mxykmuv6a - passport: 0.6.0 - dev: false - - /@nestjs/platform-express/9.2.0_pf2fb646rsvo5szivgkaevcpvi: - resolution: {integrity: sha512-J1+nnzjC9ATSb0jSHBqAE6D4o+PIbGPItEfYTOZ0rkE5bvqnRfgO4q94SXhfri+5PaNx2vM8tOZsKaD0QmQRGQ==} - peerDependencies: - '@nestjs/common': ^9.0.0 - '@nestjs/core': ^9.0.0 - dependencies: - '@nestjs/common': 9.2.0_x6yqyveuahcdef4z4mxykmuv6a - '@nestjs/core': 9.2.0_jfowmhmgk7kwjudosrpv7e7liy - body-parser: 1.20.1 - cors: 2.8.5 - express: 4.18.2 - multer: 1.4.4-lts.1 - tslib: 2.4.1 - transitivePeerDependencies: - - supports-color - - /@nestjs/schematics/9.0.3_ar2on76c45aosuucycxzxivxgm: - resolution: {integrity: sha512-kZrU/lrpVd2cnK8I3ibDb3Wi1ppl3wX3U3lVWoL+DzRRoezWKkh8upEL4q0koKmuXnsmLiu3UPxFeMOrJV7TSA==} - peerDependencies: - typescript: ^4.3.5 - dependencies: - '@angular-devkit/core': 14.2.1_chokidar@3.5.3 - '@angular-devkit/schematics': 14.2.1_chokidar@3.5.3 - fs-extra: 10.1.0 - jsonc-parser: 3.2.0 - pluralize: 8.0.0 - typescript: 4.8.4 - transitivePeerDependencies: - - chokidar - dev: true - - /@nestjs/schematics/9.0.3_typescript@4.9.3: - resolution: {integrity: sha512-kZrU/lrpVd2cnK8I3ibDb3Wi1ppl3wX3U3lVWoL+DzRRoezWKkh8upEL4q0koKmuXnsmLiu3UPxFeMOrJV7TSA==} - peerDependencies: - typescript: ^4.3.5 - dependencies: - '@angular-devkit/core': 14.2.1 - '@angular-devkit/schematics': 14.2.1 - fs-extra: 10.1.0 - jsonc-parser: 3.2.0 - pluralize: 8.0.0 - typescript: 4.9.3 - transitivePeerDependencies: - - chokidar - dev: true - - /@nestjs/swagger/6.1.3_n5tlzb6gajrp65xewlgrtvzeqy: - resolution: {integrity: sha512-H9C/yRgLFb5QrAt6iGrYmIX9X7Q0zXkgZaTNUATljUBra+RCWrEUbLHBcGjTAOtcIyGV/vmyCLv68YSVcZoE0Q==} - peerDependencies: - '@fastify/static': ^6.0.0 - '@nestjs/common': ^9.0.0 - '@nestjs/core': ^9.0.0 - reflect-metadata: ^0.1.12 - peerDependenciesMeta: - '@fastify/static': - optional: true - dependencies: - '@nestjs/common': 9.2.0_x6yqyveuahcdef4z4mxykmuv6a - '@nestjs/core': 9.2.0_jfowmhmgk7kwjudosrpv7e7liy - '@nestjs/mapped-types': 1.2.0_qdpnjncnmntjmcz6x55b5h3mje - js-yaml: 4.1.0 - lodash: 4.17.21 - path-to-regexp: 3.2.0 - reflect-metadata: 0.1.13 - swagger-ui-dist: 4.15.1 - transitivePeerDependencies: - - class-transformer - - class-validator - dev: false - - /@nestjs/terminus/9.1.4_obmctlgxqjsh2bae2xsl4estea: - resolution: {integrity: sha512-VUkafKRK6uWzwyHPind3RejxQAFJxPaXjDtvHQRaNdJ5Pk9wVD4e6e8KLGhcrPGC8ZDorqBLZABnECIcGzkodA==} - peerDependencies: - '@grpc/grpc-js': '*' - '@grpc/proto-loader': '*' - '@mikro-orm/core': '*' - '@mikro-orm/nestjs': '*' - '@nestjs/axios': '*' - '@nestjs/common': 9.x - '@nestjs/core': 9.x - '@nestjs/microservices': '*' - '@nestjs/mongoose': '*' - '@nestjs/sequelize': '*' - '@nestjs/typeorm': '*' - mongoose: '*' - reflect-metadata: 0.1.x - rxjs: 7.x - sequelize: '*' - typeorm: '*' - peerDependenciesMeta: - '@grpc/grpc-js': - optional: true - '@grpc/proto-loader': - optional: true - '@mikro-orm/core': - optional: true - '@mikro-orm/nestjs': - optional: true - '@nestjs/axios': - optional: true - '@nestjs/microservices': - optional: true - '@nestjs/mongoose': - optional: true - '@nestjs/sequelize': - optional: true - '@nestjs/typeorm': - optional: true - mongoose: - optional: true - sequelize: - optional: true - typeorm: - optional: true - dependencies: - '@nestjs/axios': 1.0.0_2kbkxfsrhtatemqz6dhv2pefvq - '@nestjs/common': 9.2.0_x6yqyveuahcdef4z4mxykmuv6a - '@nestjs/core': 9.2.0_jfowmhmgk7kwjudosrpv7e7liy - boxen: 5.1.2 - check-disk-space: 3.3.1 - reflect-metadata: 0.1.13 - rxjs: 7.5.7 - dev: false - - /@nestjs/testing/9.2.0_3jiwpo56qab566j5kwfezyelg4: - resolution: {integrity: sha512-Lj6UXmBJKcXB16bZzu0IG7GpH7hl5Cn71OcPSrVVuPrFd5kDYqFbodfE9OkAKaHjEhOvZ2ynoo/i6cyfX4yOvQ==} - peerDependencies: - '@nestjs/common': ^9.0.0 - '@nestjs/core': ^9.0.0 - '@nestjs/microservices': ^9.0.0 - '@nestjs/platform-express': ^9.0.0 - peerDependenciesMeta: - '@nestjs/microservices': - optional: true - '@nestjs/platform-express': - optional: true - dependencies: - '@nestjs/common': 9.2.0_x6yqyveuahcdef4z4mxykmuv6a - '@nestjs/core': 9.2.0_jfowmhmgk7kwjudosrpv7e7liy - '@nestjs/platform-express': 9.2.0_pf2fb646rsvo5szivgkaevcpvi - tslib: 2.4.1 - dev: true - - /@nestjs/throttler/3.1.0_v5qdouhazba6t4koo63x35nolu: - resolution: {integrity: sha512-u9a5+rci6ybYtJ2is6gZWxE2dMZEpnK0qJ0C1OnchuNCvM21Bg6qym1TB6Uihhci+JfTv6E15WuASLXcIclsbA==} - peerDependencies: - '@nestjs/common': ^7.0.0 || ^8.0.0 || ^9.0.0 - '@nestjs/core': ^7.0.0 || ^8.0.0 || ^9.0.0 - reflect-metadata: ^0.1.13 - dependencies: - '@nestjs/common': 9.2.0_x6yqyveuahcdef4z4mxykmuv6a - '@nestjs/core': 9.2.0_jfowmhmgk7kwjudosrpv7e7liy - md5: 2.3.0 - reflect-metadata: 0.1.13 - dev: false - - /@nodelib/fs.scandir/2.1.5: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - dev: true - - /@nodelib/fs.stat/2.0.5: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - dev: true - - /@nodelib/fs.walk/1.2.8: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.13.0 - dev: true - - /@nuxtjs/opencollective/0.3.2: - resolution: {integrity: sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==} - engines: {node: '>=8.0.0', npm: '>=5.0.0'} - hasBin: true - dependencies: - chalk: 4.1.2 - consola: 2.15.3 - node-fetch: 2.6.7 - transitivePeerDependencies: - - encoding - - /@prisma/client/4.6.1_prisma@4.6.1: - resolution: {integrity: sha512-M1+NNrMzqaOIxT7PBGcTs3IZo7d1EW/+gVQd4C4gUgWBDGgD9AcIeZnUSidgWClmpMSgVUdnVORjsWWGUameYA==} - engines: {node: '>=14.17'} - requiresBuild: true - peerDependencies: - prisma: '*' - peerDependenciesMeta: - prisma: - optional: true - dependencies: - '@prisma/engines-version': 4.6.1-3.694eea289a8462c80264df36757e4fdc129b1b32 - prisma: 4.6.1 - dev: false - - /@prisma/engines-version/4.6.1-3.694eea289a8462c80264df36757e4fdc129b1b32: - resolution: {integrity: sha512-HUCmkXAU2jqp2O1RvNtbE+seLGLyJGEABZS/R38rZjSAafAy0WzBuHq+tbZMnD+b5OSCsTVtIPVcuvx1ySxcWQ==} - dev: false - - /@prisma/engines/4.6.1: - resolution: {integrity: sha512-3u2/XxvxB+Q7cMXHnKU0CpBiUK1QWqpgiBv28YDo1zOIJE3FCF8DI2vrp6vuwjGt5h0JGXDSvmSf4D4maVjJdw==} - requiresBuild: true - - /@sinclair/typebox/0.24.51: - resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} - dev: true - - /@sinonjs/commons/1.8.5: - resolution: {integrity: sha512-rTpCA0wG1wUxglBSFdMMY0oTrKYvgf4fNgv/sXbfCVAdf+FnPBdKJR/7XbpTCwbCrvCbdPYnlWaUUYz4V2fPDA==} - dependencies: - type-detect: 4.0.8 - dev: true - - /@sinonjs/fake-timers/9.1.2: - resolution: {integrity: sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==} - dependencies: - '@sinonjs/commons': 1.8.5 - dev: true - - /@ts-morph/common/0.12.3: - resolution: {integrity: sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w==} - dependencies: - fast-glob: 3.2.12 - minimatch: 3.1.2 - mkdirp: 1.0.4 - path-browserify: 1.0.1 - dev: true - - /@tsconfig/node10/1.0.9: - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} - dev: true - - /@tsconfig/node12/1.0.11: - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true - - /@tsconfig/node14/1.0.3: - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true - - /@tsconfig/node16/1.0.3: - resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} - dev: true - - /@types/babel__core/7.1.20: - resolution: {integrity: sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==} - dependencies: - '@babel/parser': 7.20.3 - '@babel/types': 7.20.2 - '@types/babel__generator': 7.6.4 - '@types/babel__template': 7.4.1 - '@types/babel__traverse': 7.18.2 - dev: true - - /@types/babel__generator/7.6.4: - resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} - dependencies: - '@babel/types': 7.20.2 - dev: true - - /@types/babel__template/7.4.1: - resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} - dependencies: - '@babel/parser': 7.20.3 - '@babel/types': 7.20.2 - dev: true - - /@types/babel__traverse/7.18.2: - resolution: {integrity: sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==} - dependencies: - '@babel/types': 7.20.2 - dev: true - - /@types/body-parser/1.19.2: - resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} - dependencies: - '@types/connect': 3.4.35 - '@types/node': 16.18.3 - dev: true - - /@types/compression/1.7.2: - resolution: {integrity: sha512-lwEL4M/uAGWngWFLSG87ZDr2kLrbuR8p7X+QZB1OQlT+qkHsCPDVFnHPyXf4Vyl4yDDorNY+mAhosxkCvppatg==} - dependencies: - '@types/express': 4.17.14 - dev: true - - /@types/connect/3.4.35: - resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} - dependencies: - '@types/node': 16.18.3 - dev: true - - /@types/cookiejar/2.1.2: - resolution: {integrity: sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==} - dev: true - - /@types/eslint-scope/3.7.4: - resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==} - dependencies: - '@types/eslint': 8.4.10 - '@types/estree': 0.0.51 - dev: true - - /@types/eslint/8.4.10: - resolution: {integrity: sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==} - dependencies: - '@types/estree': 0.0.51 - '@types/json-schema': 7.0.11 - dev: true - - /@types/estree/0.0.51: - resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==} - dev: true - - /@types/express-serve-static-core/4.17.31: - resolution: {integrity: sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==} - dependencies: - '@types/node': 16.18.3 - '@types/qs': 6.9.7 - '@types/range-parser': 1.2.4 - dev: true - - /@types/express/4.17.14: - resolution: {integrity: sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==} - dependencies: - '@types/body-parser': 1.19.2 - '@types/express-serve-static-core': 4.17.31 - '@types/qs': 6.9.7 - '@types/serve-static': 1.15.0 - dev: true - - /@types/graceful-fs/4.1.5: - resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} - dependencies: - '@types/node': 16.18.3 - dev: true - - /@types/istanbul-lib-coverage/2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} - dev: true - - /@types/istanbul-lib-report/3.0.0: - resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} - dependencies: - '@types/istanbul-lib-coverage': 2.0.4 - dev: true - - /@types/istanbul-reports/3.0.1: - resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} - dependencies: - '@types/istanbul-lib-report': 3.0.0 - dev: true - - /@types/jest/28.1.8: - resolution: {integrity: sha512-8TJkV++s7B6XqnDrzR1m/TT0A0h948Pnl/097veySPN67VRAgQ4gZ7n2KfJo2rVq6njQjdxU3GCCyDvAeuHoiw==} - dependencies: - expect: 28.1.3 - pretty-format: 28.1.3 - dev: true - - /@types/json-schema/7.0.11: - resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} - dev: true - - /@types/jsonwebtoken/8.5.8: - resolution: {integrity: sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A==} - dependencies: - '@types/node': 16.18.3 - dev: false - - /@types/jsonwebtoken/8.5.9: - resolution: {integrity: sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==} - dependencies: - '@types/node': 16.18.3 - dev: true - - /@types/mime/3.0.1: - resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} - dev: true - - /@types/node/16.18.3: - resolution: {integrity: sha512-jh6m0QUhIRcZpNv7Z/rpN+ZWXOicUUQbSoWks7Htkbb9IjFQj4kzcX/xFCkjstCj5flMsN8FiSvt+q+Tcs4Llg==} - - /@types/parse-json/4.0.0: - resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} - dev: true - - /@types/passport-jwt/3.0.7: - resolution: {integrity: sha512-qRQ4qlww1Yhs3IaioDKrsDNmKy6gLDLgFsGwpCnc2YqWovO2Oxu9yCQdWHMJafQ7UIuOba4C4/TNXcGkQfEjlQ==} - dependencies: - '@types/express': 4.17.14 - '@types/jsonwebtoken': 8.5.9 - '@types/passport-strategy': 0.2.35 - dev: true - - /@types/passport-local/1.0.34: - resolution: {integrity: sha512-PSc07UdYx+jhadySxxIYWuv6sAnY5e+gesn/5lkPKfBeGuIYn9OPR+AAEDq73VRUh6NBTpvE/iPE62rzZUslog==} - dependencies: - '@types/express': 4.17.14 - '@types/passport': 1.0.11 - '@types/passport-strategy': 0.2.35 - dev: true - - /@types/passport-strategy/0.2.35: - resolution: {integrity: sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==} - dependencies: - '@types/express': 4.17.14 - '@types/passport': 1.0.11 - dev: true - - /@types/passport/1.0.11: - resolution: {integrity: sha512-pz1cx9ptZvozyGKKKIPLcVDVHwae4hrH5d6g5J+DkMRRjR3cVETb4jMabhXAUbg3Ov7T22nFHEgaK2jj+5CBpw==} - dependencies: - '@types/express': 4.17.14 - dev: true - - /@types/prettier/2.7.1: - resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==} - dev: true - - /@types/qs/6.9.7: - resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} - dev: true - - /@types/range-parser/1.2.4: - resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} - dev: true - - /@types/semver/7.3.13: - resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} - dev: true - - /@types/serve-static/1.15.0: - resolution: {integrity: sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==} - dependencies: - '@types/mime': 3.0.1 - '@types/node': 16.18.3 - dev: true - - /@types/stack-utils/2.0.1: - resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} - dev: true - - /@types/superagent/4.1.16: - resolution: {integrity: sha512-tLfnlJf6A5mB6ddqF159GqcDizfzbMUB1/DeT59/wBNqzRTNNKsaw79A/1TZ84X+f/EwWH8FeuSkjlCLyqS/zQ==} - dependencies: - '@types/cookiejar': 2.1.2 - '@types/node': 16.18.3 - dev: true - - /@types/supertest/2.0.12: - resolution: {integrity: sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ==} - dependencies: - '@types/superagent': 4.1.16 - dev: true - - /@types/webidl-conversions/7.0.0: - resolution: {integrity: sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==} - dev: false - - /@types/whatwg-url/8.2.2: - resolution: {integrity: sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==} - dependencies: - '@types/node': 16.18.3 - '@types/webidl-conversions': 7.0.0 - dev: false - - /@types/yargs-parser/21.0.0: - resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} - dev: true - - /@types/yargs/17.0.14: - resolution: {integrity: sha512-9Pj7abXoW1RSTcZaL2Hk6G2XyLMlp5ECdVC/Zf2p/KBjC3srijLGgRAXOBjtFrJoIrvxdTKyKDA14bEcbxBaWw==} - dependencies: - '@types/yargs-parser': 21.0.0 - dev: true - - /@typescript-eslint/eslint-plugin/5.44.0_fnsv2sbzcckq65bwfk7a5xwslu: - resolution: {integrity: sha512-j5ULd7FmmekcyWeArx+i8x7sdRHzAtXTkmDPthE4amxZOWKFK7bomoJ4r7PJ8K7PoMzD16U8MmuZFAonr1ERvw==} - 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 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/parser': 5.44.0_hsf322ms6xhhd4b5ne6lb74y4a - '@typescript-eslint/scope-manager': 5.44.0 - '@typescript-eslint/type-utils': 5.44.0_hsf322ms6xhhd4b5ne6lb74y4a - '@typescript-eslint/utils': 5.44.0_hsf322ms6xhhd4b5ne6lb74y4a - debug: 4.3.4 - eslint: 8.28.0 - ignore: 5.2.1 - natural-compare-lite: 1.4.0 - regexpp: 3.2.0 - semver: 7.3.8 - tsutils: 3.21.0_typescript@4.9.3 - typescript: 4.9.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/parser/5.44.0_hsf322ms6xhhd4b5ne6lb74y4a: - resolution: {integrity: sha512-H7LCqbZnKqkkgQHaKLGC6KUjt3pjJDx8ETDqmwncyb6PuoigYajyAwBGz08VU/l86dZWZgI4zm5k2VaKqayYyA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.44.0 - '@typescript-eslint/types': 5.44.0 - '@typescript-eslint/typescript-estree': 5.44.0_typescript@4.9.3 - debug: 4.3.4 - eslint: 8.28.0 - typescript: 4.9.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/scope-manager/5.44.0: - resolution: {integrity: sha512-2pKml57KusI0LAhgLKae9kwWeITZ7IsZs77YxyNyIVOwQ1kToyXRaJLl+uDEXzMN5hnobKUOo2gKntK9H1YL8g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.44.0 - '@typescript-eslint/visitor-keys': 5.44.0 - dev: true - - /@typescript-eslint/type-utils/5.44.0_hsf322ms6xhhd4b5ne6lb74y4a: - resolution: {integrity: sha512-A1u0Yo5wZxkXPQ7/noGkRhV4J9opcymcr31XQtOzcc5nO/IHN2E2TPMECKWYpM3e6olWEM63fq/BaL1wEYnt/w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 5.44.0_typescript@4.9.3 - '@typescript-eslint/utils': 5.44.0_hsf322ms6xhhd4b5ne6lb74y4a - debug: 4.3.4 - eslint: 8.28.0 - tsutils: 3.21.0_typescript@4.9.3 - typescript: 4.9.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/types/5.44.0: - resolution: {integrity: sha512-Tp+zDnHmGk4qKR1l+Y1rBvpjpm5tGXX339eAlRBDg+kgZkz9Bw+pqi4dyseOZMsGuSH69fYfPJCBKBrbPCxYFQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /@typescript-eslint/typescript-estree/5.44.0_typescript@4.9.3: - resolution: {integrity: sha512-M6Jr+RM7M5zeRj2maSfsZK2660HKAJawv4Ud0xT+yauyvgrsHu276VtXlKDFnEmhG+nVEd0fYZNXGoAgxwDWJw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.44.0 - '@typescript-eslint/visitor-keys': 5.44.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.3.8 - tsutils: 3.21.0_typescript@4.9.3 - typescript: 4.9.3 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/utils/5.44.0_hsf322ms6xhhd4b5ne6lb74y4a: - resolution: {integrity: sha512-fMzA8LLQ189gaBjS0MZszw5HBdZgVwxVFShCO3QN+ws3GlPkcy9YuS3U4wkT6su0w+Byjq3mS3uamy9HE4Yfjw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@types/json-schema': 7.0.11 - '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.44.0 - '@typescript-eslint/types': 5.44.0 - '@typescript-eslint/typescript-estree': 5.44.0_typescript@4.9.3 - eslint: 8.28.0 - eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.28.0 - semver: 7.3.8 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /@typescript-eslint/visitor-keys/5.44.0: - resolution: {integrity: sha512-a48tLG8/4m62gPFbJ27FxwCOqPKxsb8KC3HkmYoq2As/4YyjQl1jDbRr1s63+g4FS/iIehjmN3L5UjmKva1HzQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.44.0 - eslint-visitor-keys: 3.3.0 - dev: true - - /@webassemblyjs/ast/1.11.1: - resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==} - dependencies: - '@webassemblyjs/helper-numbers': 1.11.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.1 - dev: true - - /@webassemblyjs/floating-point-hex-parser/1.11.1: - resolution: {integrity: sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==} - dev: true - - /@webassemblyjs/helper-api-error/1.11.1: - resolution: {integrity: sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==} - dev: true - - /@webassemblyjs/helper-buffer/1.11.1: - resolution: {integrity: sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==} - dev: true - - /@webassemblyjs/helper-numbers/1.11.1: - resolution: {integrity: sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==} - dependencies: - '@webassemblyjs/floating-point-hex-parser': 1.11.1 - '@webassemblyjs/helper-api-error': 1.11.1 - '@xtuc/long': 4.2.2 - dev: true - - /@webassemblyjs/helper-wasm-bytecode/1.11.1: - resolution: {integrity: sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==} - dev: true - - /@webassemblyjs/helper-wasm-section/1.11.1: - resolution: {integrity: sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==} - dependencies: - '@webassemblyjs/ast': 1.11.1 - '@webassemblyjs/helper-buffer': 1.11.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.1 - '@webassemblyjs/wasm-gen': 1.11.1 - dev: true - - /@webassemblyjs/ieee754/1.11.1: - resolution: {integrity: sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==} - dependencies: - '@xtuc/ieee754': 1.2.0 - dev: true - - /@webassemblyjs/leb128/1.11.1: - resolution: {integrity: sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==} - dependencies: - '@xtuc/long': 4.2.2 - dev: true - - /@webassemblyjs/utf8/1.11.1: - resolution: {integrity: sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==} - dev: true - - /@webassemblyjs/wasm-edit/1.11.1: - resolution: {integrity: sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==} - dependencies: - '@webassemblyjs/ast': 1.11.1 - '@webassemblyjs/helper-buffer': 1.11.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.1 - '@webassemblyjs/helper-wasm-section': 1.11.1 - '@webassemblyjs/wasm-gen': 1.11.1 - '@webassemblyjs/wasm-opt': 1.11.1 - '@webassemblyjs/wasm-parser': 1.11.1 - '@webassemblyjs/wast-printer': 1.11.1 - dev: true - - /@webassemblyjs/wasm-gen/1.11.1: - resolution: {integrity: sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==} - dependencies: - '@webassemblyjs/ast': 1.11.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.1 - '@webassemblyjs/ieee754': 1.11.1 - '@webassemblyjs/leb128': 1.11.1 - '@webassemblyjs/utf8': 1.11.1 - dev: true - - /@webassemblyjs/wasm-opt/1.11.1: - resolution: {integrity: sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==} - dependencies: - '@webassemblyjs/ast': 1.11.1 - '@webassemblyjs/helper-buffer': 1.11.1 - '@webassemblyjs/wasm-gen': 1.11.1 - '@webassemblyjs/wasm-parser': 1.11.1 - dev: true - - /@webassemblyjs/wasm-parser/1.11.1: - resolution: {integrity: sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==} - dependencies: - '@webassemblyjs/ast': 1.11.1 - '@webassemblyjs/helper-api-error': 1.11.1 - '@webassemblyjs/helper-wasm-bytecode': 1.11.1 - '@webassemblyjs/ieee754': 1.11.1 - '@webassemblyjs/leb128': 1.11.1 - '@webassemblyjs/utf8': 1.11.1 - dev: true - - /@webassemblyjs/wast-printer/1.11.1: - resolution: {integrity: sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==} - dependencies: - '@webassemblyjs/ast': 1.11.1 - '@xtuc/long': 4.2.2 - dev: true - - /@xtuc/ieee754/1.2.0: - resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} - dev: true - - /@xtuc/long/4.2.2: - resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} - dev: true - - /accepts/1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - - /acorn-import-assertions/1.8.0_acorn@8.8.1: - resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==} - peerDependencies: - acorn: ^8 - dependencies: - acorn: 8.8.1 - dev: true - - /acorn-jsx/5.3.2_acorn@8.8.1: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.8.1 - dev: true - - /acorn-node/1.8.2: - resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==} - dependencies: - acorn: 7.4.1 - acorn-walk: 7.2.0 - xtend: 4.0.2 - dev: true - - /acorn-walk/7.2.0: - resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} - engines: {node: '>=0.4.0'} - dev: true - - /acorn-walk/8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} - engines: {node: '>=0.4.0'} - dev: true - - /acorn/7.4.1: - resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /acorn/8.8.1: - resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /ajv-formats/2.1.1: - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependenciesMeta: - ajv: - optional: true - dependencies: - ajv: 8.11.0 - dev: true - - /ajv-keywords/3.5.2_ajv@6.12.6: - resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} - peerDependencies: - ajv: ^6.9.1 - dependencies: - ajv: 6.12.6 - dev: true - - /ajv/6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - /ajv/8.11.0: - resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==} - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js: 4.4.1 - dev: true - - /ajv/8.9.0: - resolution: {integrity: sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==} - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js: 4.4.1 - dev: true - - /amdefine/1.0.1: - resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} - engines: {node: '>=0.4.2'} - dev: true - optional: true - - /ansi-align/3.0.1: - resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} - dependencies: - string-width: 4.2.3 - dev: false - - /ansi-colors/4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - dev: true - - /ansi-escapes/4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.21.3 - dev: true - - /ansi-gray/0.1.1: - resolution: {integrity: sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: true - - /ansi-regex/5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - /ansi-styles/3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - dependencies: - color-convert: 1.9.3 - dev: true - - /ansi-styles/4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - - /ansi-styles/5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - dev: true - - /ansi-wrap/0.1.0: - resolution: {integrity: sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==} - engines: {node: '>=0.10.0'} - dev: true - - /anymatch/3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - dev: true - - /apache-crypt/1.2.6: - resolution: {integrity: sha512-072WetlM4blL8PREJVeY+WHiUh1R5VNt2HfceGS8aKqttPHcmqE5pkKuXPz/ULmJOFkc8Hw3kfKl6vy7Qka6DA==} - engines: {node: '>=8'} - dependencies: - unix-crypt-td-js: 1.1.4 - dev: true - - /apache-md5/1.1.8: - resolution: {integrity: sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==} - engines: {node: '>=8'} - dev: true - - /append-field/1.0.0: - resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} - - /arg/4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true - - /argparse/1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - dev: true - - /argparse/2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - /array-flatten/1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - - /array-from/2.1.1: - resolution: {integrity: sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg==} - dev: true - - /array-union/2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - dev: true - - /asap/2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - dev: true - - /asn1/0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - dependencies: - safer-buffer: 2.1.2 - dev: false - - /assert-plus/1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} - dev: false - - /ast-transform/0.0.0: - resolution: {integrity: sha512-e/JfLiSoakfmL4wmTGPjv0HpTICVmxwXgYOB8x+mzozHL8v+dSfCbrJ8J8hJ0YBP0XcYu1aLZ6b/3TnxNK3P2A==} - dependencies: - escodegen: 1.2.0 - esprima: 1.0.4 - through: 2.3.8 - dev: true - - /ast-types/0.7.8: - resolution: {integrity: sha512-RIOpVnVlltB6PcBJ5BMLx+H+6JJ/zjDGU0t7f0L6c2M1dqcK92VQopLBlPQ9R80AVXelfqYgjcPLtHtDbNFg0Q==} - engines: {node: '>= 0.6'} - dev: true - - /asynckit/0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - /at-least-node/1.0.0: - resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} - engines: {node: '>= 4.0.0'} - dev: true - - /aws-sign2/0.7.0: - resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - dev: false - - /aws4/1.11.0: - resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==} - dev: false - - /axios/0.22.0: - resolution: {integrity: sha512-Z0U3uhqQeg1oNcihswf4ZD57O3NrR1+ZXhxaROaWpDmsDTx7T2HNBV2ulBtie2hwJptu8UvgnJoK+BIqdzh/1w==} - dependencies: - follow-redirects: 1.15.2 - transitivePeerDependencies: - - debug - dev: false - - /axios/1.1.3: - resolution: {integrity: sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==} - dependencies: - follow-redirects: 1.15.2 - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - dev: false - - /babel-jest/28.1.3_@babel+core@7.20.2: - resolution: {integrity: sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - '@babel/core': ^7.8.0 - dependencies: - '@babel/core': 7.20.2 - '@jest/transform': 28.1.3 - '@types/babel__core': 7.1.20 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 28.1.3_@babel+core@7.20.2 - chalk: 4.1.2 - graceful-fs: 4.2.10 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-istanbul/6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} - dependencies: - '@babel/helper-plugin-utils': 7.20.2 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-jest-hoist/28.1.3: - resolution: {integrity: sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@babel/template': 7.18.10 - '@babel/types': 7.20.2 - '@types/babel__core': 7.1.20 - '@types/babel__traverse': 7.18.2 - dev: true - - /babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.20.2: - resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.20.1 - '@babel/core': 7.20.2 - '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.2 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-polyfill-corejs3/0.6.0_@babel+core@7.20.2: - resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.2 - core-js-compat: 3.26.1 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-polyfill-regenerator/0.4.1_@babel+core@7.20.2: - resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.20.2 - '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-preset-current-node-syntax/1.0.1_@babel+core@7.20.2: - resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.20.2 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.2 - '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.20.2 - '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.20.2 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.2 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.2 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.2 - '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.20.2 - dev: true - - /babel-preset-jest/28.1.3_@babel+core@7.20.2: - resolution: {integrity: sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.20.2 - babel-plugin-jest-hoist: 28.1.3 - babel-preset-current-node-syntax: 1.0.1_@babel+core@7.20.2 - dev: true - - /balanced-match/1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - /base64-js/1.3.1: - resolution: {integrity: sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==} - dev: true - - /base64-js/1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - /basic-auth/2.0.1: - resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} - engines: {node: '>= 0.8'} - dependencies: - safe-buffer: 5.1.2 - dev: true - - /batch/0.6.1: - resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} - dev: true - - /bcrypt-pbkdf/1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - dependencies: - tweetnacl: 0.14.5 - dev: false - - /bcryptjs/2.4.3: - resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==} - dev: true - - /binary-extensions/2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} - engines: {node: '>=8'} - dev: true - - /bl/4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.0 - dev: true - - /body-parser/1.20.1: - resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dependencies: - bytes: 3.1.2 - content-type: 1.0.4 - 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.1 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - - /boolbase/1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - dev: true - - /bowser/2.11.0: - resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} - dev: false - optional: true - - /boxen/5.1.2: - resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} - engines: {node: '>=10'} - dependencies: - ansi-align: 3.0.1 - camelcase: 6.3.0 - chalk: 4.1.2 - cli-boxes: 2.2.1 - string-width: 4.2.3 - type-fest: 0.20.2 - widest-line: 3.1.0 - wrap-ansi: 7.0.0 - dev: false - - /brace-expansion/1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - /braces/3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - dependencies: - fill-range: 7.0.1 - dev: true - - /brfs/2.0.2: - resolution: {integrity: sha512-IrFjVtwu4eTJZyu8w/V2gxU7iLTtcHih67sgEdzrhjLBMHp2uYefUBfdM4k2UvcuWMgV7PQDZHSLeNWnLFKWVQ==} - hasBin: true - dependencies: - quote-stream: 1.0.2 - resolve: 1.22.1 - static-module: 3.0.4 - through2: 2.0.5 - dev: true - - /brotli/1.3.3: - resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} - dependencies: - base64-js: 1.5.1 - dev: true - - /browser-resolve/1.11.3: - resolution: {integrity: sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==} - dependencies: - resolve: 1.1.7 - dev: true - - /browserify-optional/1.0.1: - resolution: {integrity: sha512-VrhjbZ+Ba5mDiSYEuPelekQMfTbhcA2DhLk2VQWqdcCROWeFqlTcXZ7yfRkXCIl8E+g4gINJYJiRB7WEtfomAQ==} - dependencies: - ast-transform: 0.0.0 - ast-types: 0.7.8 - browser-resolve: 1.11.3 - dev: true - - /browserslist/4.21.4: - resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001434 - electron-to-chromium: 1.4.284 - node-releases: 2.0.6 - update-browserslist-db: 1.0.10_browserslist@4.21.4 - dev: true - - /bs-logger/0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} - dependencies: - fast-json-stable-stringify: 2.1.0 - dev: true - - /bser/2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - dependencies: - node-int64: 0.4.0 - dev: true - - /bson/4.7.0: - resolution: {integrity: sha512-VrlEE4vuiO1WTpfof4VmaVolCVYkYTgB9iWgYNOrVlnifpME/06fhFRmONgBhClD5pFC1t9ZWqFUQEQAzY43bA==} - engines: {node: '>=6.9.0'} - dependencies: - buffer: 5.7.1 - dev: false - - /buffer-equal-constant-time/1.0.1: - resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} - dev: false - - /buffer-equal/0.0.1: - resolution: {integrity: sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==} - engines: {node: '>=0.4.0'} - dev: true - - /buffer-from/1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - /buffer/5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - /busboy/1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} - dependencies: - streamsearch: 1.1.0 - - /byline/5.0.0: - resolution: {integrity: sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==} - engines: {node: '>=0.10.0'} - dev: false - - /bytes/3.0.0: - resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} - engines: {node: '>= 0.8'} - dev: false - - /bytes/3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - - /call-bind/1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.1.3 - - /callsite/1.0.0: - resolution: {integrity: sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==} - dev: true - - /callsites/3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - dev: true - - /camelcase/5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - dev: true - - /camelcase/6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - - /caniuse-lite/1.0.30001434: - resolution: {integrity: sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA==} - dev: true - - /casdoor-nodejs-sdk/1.3.0: - resolution: {integrity: sha512-Yyf90wEQp10DfiZ8EoshgrLoBrBh5gFRheVR8a/imwugEcFWVVdHYBx3OuTi6PE2KHzNUgQLSJeKuhrGRiyZ4A==} - dependencies: - axios: 0.22.0 - jsonwebtoken: 8.5.1 - transitivePeerDependencies: - - debug - dev: false - - /caseless/0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - dev: false - - /chalk/2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - dev: true - - /chalk/3.0.0: - resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} - engines: {node: '>=8'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - dev: true - - /chalk/4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - /char-regex/1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - dev: true - - /chardet/0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - dev: true - - /charenc/0.0.2: - resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} - dev: false - - /check-disk-space/3.3.1: - resolution: {integrity: sha512-iOrT8yCZjSnyNZ43476FE2rnssvgw5hnuwOM0hm8Nj1qa0v4ieUUEbCyxxsEliaoDUb/75yCOL71zkDiDBLbMQ==} - engines: {node: '>=12'} - dev: false - - /cheerio-select/2.1.0: - resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - dependencies: - boolbase: 1.0.0 - css-select: 5.1.0 - css-what: 6.1.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.0.1 - dev: true - - /cheerio/1.0.0-rc.12: - resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} - engines: {node: '>= 6'} - dependencies: - cheerio-select: 2.1.0 - dom-serializer: 2.0.0 - domhandler: 5.0.3 - domutils: 3.0.1 - htmlparser2: 8.0.1 - parse5: 7.1.2 - parse5-htmlparser2-tree-adapter: 7.0.0 - dev: true - - /chokidar/3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} - dependencies: - anymatch: 3.1.3 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /chownr/2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} - dev: false - - /chrome-trace-event/1.0.3: - resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} - engines: {node: '>=6.0'} - dev: true - - /ci-info/3.7.0: - resolution: {integrity: sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==} - engines: {node: '>=8'} - dev: true - - /cjs-module-lexer/1.2.2: - resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} - dev: true - - /class-transformer/0.5.1: - resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} - - /class-validator/0.13.2: - resolution: {integrity: sha512-yBUcQy07FPlGzUjoLuUfIOXzgynnQPPruyK1Ge2B74k9ROwnle1E+NxLWnUv5OLU8hA/qL5leAE9XnXq3byaBw==} - dependencies: - libphonenumber-js: 1.10.14 - validator: 13.7.0 - - /cli-boxes/2.2.1: - resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} - engines: {node: '>=6'} - dev: false - - /cli-cursor/3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - dependencies: - restore-cursor: 3.1.0 - dev: true - - /cli-spinners/2.7.0: - resolution: {integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==} - engines: {node: '>=6'} - dev: true - - /cli-table3/0.6.2: - resolution: {integrity: sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==} - engines: {node: 10.* || >= 12.*} - dependencies: - string-width: 4.2.3 - optionalDependencies: - '@colors/colors': 1.5.0 - dev: true - - /cli-width/3.0.0: - resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} - engines: {node: '>= 10'} - dev: true - - /cliui/8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - - /clone/1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - dev: true - - /co/4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - dev: true - - /code-block-writer/11.0.3: - resolution: {integrity: sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==} - dev: true - - /collect-v8-coverage/1.0.1: - resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} - dev: true - - /color-convert/1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - dependencies: - color-name: 1.1.3 - dev: true - - /color-convert/2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - - /color-name/1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: true - - /color-name/1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - /color-support/1.1.3: - resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} - hasBin: true - dev: true - - /colors/1.4.0: - resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} - engines: {node: '>=0.1.90'} - dev: true - - /combined-stream/1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - - /commander/2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: true - - /commander/4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - dev: true - - /commander/9.4.1: - resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==} - engines: {node: ^12.20.0 || >=14} - dev: true - - /component-emitter/1.3.0: - resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} - dev: true - - /compressible/2.0.18: - resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: false - - /compression/1.7.4: - resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} - engines: {node: '>= 0.8.0'} - dependencies: - accepts: 1.3.8 - bytes: 3.0.0 - compressible: 2.0.18 - debug: 2.6.9 - on-headers: 1.0.2 - safe-buffer: 5.1.2 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - dev: false - - /concat-map/0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - /concat-stream/1.6.2: - resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} - engines: {'0': node >= 0.8} - dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 2.3.7 - typedarray: 0.0.6 - - /connect/3.7.0: - resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} - engines: {node: '>= 0.10.0'} - dependencies: - debug: 2.6.9 - finalhandler: 1.1.2 - parseurl: 1.3.3 - utils-merge: 1.0.1 - transitivePeerDependencies: - - supports-color - dev: true - - /consola/2.15.3: - resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} - - /content-disposition/0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} - dependencies: - safe-buffer: 5.2.1 - - /content-type/1.0.4: - resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} - engines: {node: '>= 0.6'} - - /convert-source-map/1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: true - - /cookie-signature/1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - - /cookie/0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} - - /cookiejar/2.1.3: - resolution: {integrity: sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==} - dev: true - - /core-js-compat/3.26.1: - resolution: {integrity: sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==} - dependencies: - browserslist: 4.21.4 - dev: true - - /core-util-is/1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - dev: false - - /core-util-is/1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - - /cors/2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - - /cosmiconfig/7.1.0: - resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} - engines: {node: '>=10'} - dependencies: - '@types/parse-json': 4.0.0 - import-fresh: 3.3.0 - parse-json: 5.2.0 - path-type: 4.0.0 - yaml: 1.10.2 - dev: true - - /create-require/1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true - - /cross-spawn/7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - /crypt/0.0.2: - resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} - dev: false - - /crypto-js/4.1.1: - resolution: {integrity: sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==} - dev: true - - /css-select/5.1.0: - resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} - dependencies: - boolbase: 1.0.0 - css-what: 6.1.0 - domhandler: 5.0.3 - domutils: 3.0.1 - nth-check: 2.1.1 - dev: true - - /css-what/6.1.0: - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} - engines: {node: '>= 6'} - dev: true - - /d/1.0.1: - resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} - dependencies: - es5-ext: 0.10.62 - type: 1.2.0 - dev: true - - /dash-ast/2.0.1: - resolution: {integrity: sha512-5TXltWJGc+RdnabUGzhRae1TRq6m4gr+3K2wQX0is5/F2yS6MJXJvLyI3ErAnsAXuJoGqvfVD5icRgim07DrxQ==} - dev: true - - /dashdash/1.14.1: - resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} - engines: {node: '>=0.10'} - dependencies: - assert-plus: 1.0.0 - dev: false - - /debug/2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - - /debug/4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: true - - /decache/4.6.1: - resolution: {integrity: sha512-ohApBM8u9ygepJCjgBrEZSSxPjc0T/PJkD+uNyxXPkqudyUpdXpwJYp0VISm2WrPVzASU6DZyIi6BWdyw7uJ2Q==} - dependencies: - callsite: 1.0.0 - dev: true - - /dedent/0.7.0: - resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} - dev: true - - /deep-equal/1.1.1: - resolution: {integrity: sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==} - dependencies: - is-arguments: 1.1.1 - is-date-object: 1.0.5 - is-regex: 1.1.4 - object-is: 1.1.5 - object-keys: 1.1.1 - regexp.prototype.flags: 1.4.3 - dev: true - - /deep-is/0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dev: true - - /deepmerge/4.2.2: - resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} - engines: {node: '>=0.10.0'} - dev: true - - /defaults/1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - dependencies: - clone: 1.0.4 - dev: true - - /define-lazy-prop/2.0.0: - resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} - engines: {node: '>=8'} - dev: true - - /define-properties/1.1.4: - resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} - engines: {node: '>= 0.4'} - dependencies: - has-property-descriptors: 1.0.0 - object-keys: 1.1.1 - dev: true - - /delayed-stream/1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - /depd/1.1.2: - resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} - engines: {node: '>= 0.6'} - dev: true - - /depd/2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - - /destroy/1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - - /detect-newline/3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} - dev: true - - /dezalgo/1.0.3: - resolution: {integrity: sha512-K7i4zNfT2kgQz3GylDw40ot9GAE47sFZ9EXHFSPP6zONLgH6kWXE0KWJchkbQJLBkRazq4APwZ4OwiFFlT95OQ==} - dependencies: - asap: 2.0.6 - wrappy: 1.0.2 - dev: true - - /dfa/1.2.0: - resolution: {integrity: sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==} - dev: true - - /diff-sequences/28.1.1: - resolution: {integrity: sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dev: true - - /diff/4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - dev: true - - /dir-glob/3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dependencies: - path-type: 4.0.0 - dev: true - - /doctrine/3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dependencies: - esutils: 2.0.3 - dev: true - - /dom-serializer/2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.4.0 - dev: true - - /domelementtype/2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - dev: true - - /domhandler/5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - dependencies: - domelementtype: 2.3.0 - dev: true - - /dommatrix/1.0.3: - resolution: {integrity: sha512-l32Xp/TLgWb8ReqbVJAFIvXmY7go4nTxxlWiAFyhoQw9RKEOHBZNnyGvJWqDVSPmq3Y9HlM4npqF/T6VMOXhww==} - dev: true - - /domutils/3.0.1: - resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==} - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - dev: true - - /dot/1.1.3: - resolution: {integrity: sha512-/nt74Rm+PcfnirXGEdhZleTwGC2LMnuKTeeTIlI82xb5loBBoXNYzr2ezCroPSMtilK8EZIfcNZwOcHN+ib1Lg==} - engines: {'0': node >=0.2.6} - hasBin: true - dev: true - - /dotenv-expand/8.0.3: - resolution: {integrity: sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==} - engines: {node: '>=12'} - dev: false - - /dotenv/16.0.1: - resolution: {integrity: sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==} - engines: {node: '>=12'} - dev: false - - /dotenv/16.0.3: - resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} - engines: {node: '>=12'} - dev: false - - /duplexer/0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - dev: true - - /duplexer2/0.1.4: - resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} - dependencies: - readable-stream: 2.3.7 - dev: true - - /ecc-jsbn/0.1.2: - resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} - dependencies: - jsbn: 0.1.1 - safer-buffer: 2.1.2 - dev: false - - /ecdsa-sig-formatter/1.0.11: - resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /ee-first/1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - /electron-to-chromium/1.4.284: - resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} - dev: true - - /emittery/0.10.2: - resolution: {integrity: sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==} - engines: {node: '>=12'} - dev: true - - /emoji-regex/8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - /encodeurl/1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} - - /end-of-stream/1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - dependencies: - once: 1.4.0 - dev: true - - /enhanced-resolve/5.12.0: - resolution: {integrity: sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==} - engines: {node: '>=10.13.0'} - dependencies: - graceful-fs: 4.2.10 - tapable: 2.2.1 - dev: true - - /entities/4.4.0: - resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} - engines: {node: '>=0.12'} - dev: true - - /error-ex/1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - dependencies: - is-arrayish: 0.2.1 - dev: true - - /es-module-lexer/0.9.3: - resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==} - dev: true - - /es5-ext/0.10.62: - resolution: {integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==} - engines: {node: '>=0.10'} - requiresBuild: true - dependencies: - es6-iterator: 2.0.3 - es6-symbol: 3.1.3 - next-tick: 1.1.0 - dev: true - - /es6-iterator/2.0.3: - resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} - dependencies: - d: 1.0.1 - es5-ext: 0.10.62 - es6-symbol: 3.1.3 - dev: true - - /es6-map/0.1.5: - resolution: {integrity: sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==} - dependencies: - d: 1.0.1 - es5-ext: 0.10.62 - es6-iterator: 2.0.3 - es6-set: 0.1.6 - es6-symbol: 3.1.3 - event-emitter: 0.3.5 - dev: true - - /es6-set/0.1.6: - resolution: {integrity: sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==} - engines: {node: '>=0.12'} - dependencies: - d: 1.0.1 - es5-ext: 0.10.62 - es6-iterator: 2.0.3 - es6-symbol: 3.1.3 - event-emitter: 0.3.5 - type: 2.7.2 - dev: true - - /es6-symbol/3.1.3: - resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} - dependencies: - d: 1.0.1 - ext: 1.7.0 - dev: true - - /escalade/3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} - dev: true - - /escape-html/1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - /escape-string-regexp/1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - dev: true - - /escape-string-regexp/2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - dev: true - - /escape-string-regexp/4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - dev: true - - /escodegen/1.14.3: - resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==} - engines: {node: '>=4.0'} - hasBin: true - dependencies: - esprima: 4.0.1 - estraverse: 4.3.0 - esutils: 2.0.3 - optionator: 0.8.3 - optionalDependencies: - source-map: 0.6.1 - dev: true - - /escodegen/1.2.0: - resolution: {integrity: sha512-yLy3Cc+zAC0WSmoT2fig3J87TpQ8UaZGx8ahCAs9FL8qNbyV7CVyPKS74DG4bsHiL5ew9sxdYx131OkBQMFnvA==} - engines: {node: '>=0.4.0'} - hasBin: true - dependencies: - esprima: 1.0.4 - estraverse: 1.5.1 - esutils: 1.0.0 - optionalDependencies: - source-map: 0.1.43 - dev: true - - /eslint-config-prettier/8.5.0_eslint@8.28.0: - resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - dependencies: - eslint: 8.28.0 - dev: true - - /eslint-plugin-prettier/4.2.1_cwlo2dingkvfydnaculr42urve: - resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} - engines: {node: '>=12.0.0'} - peerDependencies: - eslint: '>=7.28.0' - eslint-config-prettier: '*' - prettier: '>=2.0.0' - peerDependenciesMeta: - eslint-config-prettier: - optional: true - dependencies: - eslint: 8.28.0 - eslint-config-prettier: 8.5.0_eslint@8.28.0 - prettier: 2.8.0 - prettier-linter-helpers: 1.0.0 - dev: true - - /eslint-scope/5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - dev: true - - /eslint-scope/7.1.1: - resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - dev: true - - /eslint-utils/3.0.0_eslint@8.28.0: - resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} - engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} - peerDependencies: - eslint: '>=5' - dependencies: - eslint: 8.28.0 - eslint-visitor-keys: 2.1.0 - dev: true - - /eslint-visitor-keys/2.1.0: - resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} - engines: {node: '>=10'} - dev: true - - /eslint-visitor-keys/3.3.0: - resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /eslint/8.28.0: - resolution: {integrity: sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - dependencies: - '@eslint/eslintrc': 1.3.3 - '@humanwhocodes/config-array': 0.11.7 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.28.0 - eslint-visitor-keys: 3.3.0 - espree: 9.4.1 - esquery: 1.4.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.18.0 - grapheme-splitter: 1.0.4 - ignore: 5.2.1 - import-fresh: 3.3.0 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-sdsl: 4.2.0 - 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.1 - regexpp: 3.2.0 - strip-ansi: 6.0.1 - strip-json-comments: 3.1.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - dev: true - - /espree/9.4.1: - resolution: {integrity: sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - acorn: 8.8.1 - acorn-jsx: 5.3.2_acorn@8.8.1 - eslint-visitor-keys: 3.3.0 - dev: true - - /esprima/1.0.4: - resolution: {integrity: sha512-rp5dMKN8zEs9dfi9g0X1ClLmV//WRyk/R15mppFNICIFRG5P92VP7Z04p8pk++gABo9W2tY+kHyu6P1mEHgmTA==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /esprima/4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /esquery/1.4.0: - resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} - engines: {node: '>=0.10'} - dependencies: - estraverse: 5.3.0 - dev: true - - /esrecurse/4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - dependencies: - estraverse: 5.3.0 - dev: true - - /estraverse/1.5.1: - resolution: {integrity: sha512-FpCjJDfmo3vsc/1zKSeqR5k42tcIhxFIlvq+h9j0fO2q/h2uLKyweq7rYJ+0CoVvrGQOxIS5wyBrW/+vF58BUQ==} - engines: {node: '>=0.4.0'} - dev: true - - /estraverse/4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - dev: true - - /estraverse/5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - dev: true - - /estree-is-function/1.0.0: - resolution: {integrity: sha512-nSCWn1jkSq2QAtkaVLJZY2ezwcFO161HVc174zL1KPW3RJ+O6C3eJb8Nx7OXzvhoEv+nLgSR1g71oWUHUDTrJA==} - dev: true - - /esutils/1.0.0: - resolution: {integrity: sha512-x/iYH53X3quDwfHRz4y8rn4XcEwwCJeWsul9pF1zldMbGtgOtMNBEOuYWwB1EQlK2LRa1fev3YAgym/RElp5Cg==} - engines: {node: '>=0.10.0'} - dev: true - - /esutils/2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - dev: true - - /etag/1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - - /event-emitter/0.3.5: - resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} - dependencies: - d: 1.0.1 - es5-ext: 0.10.62 - dev: true - - /event-stream/4.0.1: - resolution: {integrity: sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==} - dependencies: - duplexer: 0.1.2 - from: 0.1.7 - map-stream: 0.0.7 - pause-stream: 0.0.11 - split: 1.0.1 - stream-combiner: 0.2.2 - through: 2.3.8 - dev: true - - /events/3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} - dev: true - - /execa/4.1.0: - resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} - engines: {node: '>=10'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 5.2.0 - human-signals: 1.1.1 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - dev: true - - /execa/5.0.0: - resolution: {integrity: sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==} - engines: {node: '>=10'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - dev: false - - /execa/5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - dev: true - - /exit/0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - dev: true - - /expect/28.1.3: - resolution: {integrity: sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/expect-utils': 28.1.3 - jest-get-type: 28.0.2 - jest-matcher-utils: 28.1.3 - jest-message-util: 28.1.3 - jest-util: 28.1.3 - dev: true - - /express/4.18.2: - resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} - engines: {node: '>= 0.10.0'} - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.1 - 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 - transitivePeerDependencies: - - supports-color - - /ext/1.7.0: - resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} - dependencies: - type: 2.7.2 - dev: true - - /extend/3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - dev: false - - /external-editor/3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - dev: true - - /extsprintf/1.3.0: - resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} - engines: {'0': node >=0.6.0} - dev: false - - /fancy-log/1.3.3: - resolution: {integrity: sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==} - engines: {node: '>= 0.10'} - dependencies: - ansi-gray: 0.1.1 - color-support: 1.1.3 - parse-node-version: 1.0.1 - time-stamp: 1.1.0 - dev: true - - /fancy-log/2.0.0: - resolution: {integrity: sha512-9CzxZbACXMUXW13tS0tI8XsGGmxWzO2DmYrGuBJOJ8k8q2K7hwfJA5qHjuPPe8wtsco33YR9wc+Rlr5wYFvhSA==} - engines: {node: '>=10.13.0'} - dependencies: - color-support: 1.1.3 - dev: true - - /fast-deep-equal/3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - /fast-diff/1.2.0: - resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} - dev: true - - /fast-glob/3.2.12: - resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} - engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - - /fast-json-patch/3.1.1: - resolution: {integrity: sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==} - dev: false - - /fast-json-stable-stringify/2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - /fast-levenshtein/2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - dev: true - - /fast-safe-stringify/2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - - /fast-xml-parser/4.0.11: - resolution: {integrity: sha512-4aUg3aNRR/WjQAcpceODG1C3x3lFANXRo8+1biqfieHmg9pyMt7qB4lQV/Ta6sJCTbA5vfD8fnA8S54JATiFUA==} - hasBin: true - dependencies: - strnum: 1.0.5 - dev: false - optional: true - - /fastq/1.13.0: - resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} - dependencies: - reusify: 1.0.4 - dev: true - - /faye-websocket/0.11.4: - resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} - engines: {node: '>=0.8.0'} - dependencies: - websocket-driver: 0.7.4 - dev: true - - /fb-watchman/2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - dependencies: - bser: 2.1.1 - dev: true - - /figures/3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - dependencies: - escape-string-regexp: 1.0.5 - dev: true - - /file-entry-cache/6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flat-cache: 3.0.4 - dev: true - - /fill-range/7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - dev: true - - /finalhandler/1.1.2: - resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} - engines: {node: '>= 0.8'} - dependencies: - debug: 2.6.9 - encodeurl: 1.0.2 - escape-html: 1.0.3 - on-finished: 2.3.0 - parseurl: 1.3.3 - statuses: 1.5.0 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /finalhandler/1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} - engines: {node: '>= 0.8'} - 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 - transitivePeerDependencies: - - supports-color - - /find-up/4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - dev: true - - /find-up/5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - dev: true - - /findit2/2.2.3: - resolution: {integrity: sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==} - engines: {node: '>=0.8.22'} - dev: true - - /flat-cache/3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flatted: 3.2.7 - rimraf: 3.0.2 - dev: true - - /flatted/3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} - dev: true - - /follow-redirects/1.15.2: - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - - /forever-agent/0.6.1: - resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - dev: false - - /fork-ts-checker-webpack-plugin/7.2.13_qqxisngxjbp7lstdk7boexbu3e: - resolution: {integrity: sha512-fR3WRkOb4bQdWB/y7ssDUlVdrclvwtyCUIHCfivAoYxq9dF7XfrDKbMdZIfwJ7hxIAqkYSGeU7lLJE6xrxIBdg==} - engines: {node: '>=12.13.0', yarn: '>=1.0.0'} - peerDependencies: - typescript: '>3.6.0' - vue-template-compiler: '*' - webpack: ^5.11.0 - peerDependenciesMeta: - vue-template-compiler: - optional: true - dependencies: - '@babel/code-frame': 7.18.6 - chalk: 4.1.2 - chokidar: 3.5.3 - cosmiconfig: 7.1.0 - deepmerge: 4.2.2 - fs-extra: 10.1.0 - memfs: 3.4.12 - minimatch: 3.1.2 - node-abort-controller: 3.0.1 - schema-utils: 3.1.1 - semver: 7.3.8 - tapable: 2.2.1 - typescript: 4.8.4 - webpack: 5.74.0 - dev: true - - /form-data/2.3.3: - resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} - engines: {node: '>= 0.12'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /form-data/4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - - /formidable/2.0.1: - resolution: {integrity: sha512-rjTMNbp2BpfQShhFbR3Ruk3qk2y9jKpvMW78nJgx8QKtxjDVrwbZG+wvDOmVbifHyOUOQJXxqEy6r0faRrPzTQ==} - dependencies: - dezalgo: 1.0.3 - hexoid: 1.0.0 - once: 1.4.0 - qs: 6.9.3 - dev: true - - /forwarded/0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - - /fresh/0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} - - /from/0.1.7: - resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} - dev: true - - /fs-extra/10.1.0: - resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} - engines: {node: '>=12'} - dependencies: - graceful-fs: 4.2.10 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: true - - /fs-extra/9.1.0: - resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} - engines: {node: '>=10'} - dependencies: - at-least-node: 1.0.0 - graceful-fs: 4.2.10 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: true - - /fs-minipass/2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.6 - dev: false - - /fs-monkey/1.0.3: - resolution: {integrity: sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==} - dev: true - - /fs.realpath/1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - /fsevents/2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /function-bind/1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - - /functions-have-names/1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - dev: true - - /gensync/1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - dev: true - - /get-assigned-identifiers/1.2.0: - resolution: {integrity: sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==} - dev: true - - /get-caller-file/2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true - - /get-intrinsic/1.1.3: - resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} - dependencies: - function-bind: 1.1.1 - has: 1.0.3 - has-symbols: 1.0.3 - - /get-package-type/0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - dev: true - - /get-stream/5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} - dependencies: - pump: 3.0.0 - dev: true - - /get-stream/6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - - /getpass/0.1.7: - resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} - dependencies: - assert-plus: 1.0.0 - dev: false - - /glob-parent/5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - dependencies: - is-glob: 4.0.3 - dev: true - - /glob-parent/6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - dependencies: - is-glob: 4.0.3 - dev: true - - /glob-to-regexp/0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - dev: true - - /glob/7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - /globals/11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - dev: true - - /globals/13.18.0: - resolution: {integrity: sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.20.2 - dev: true - - /globby/11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.2.12 - ignore: 5.2.1 - merge2: 1.4.1 - slash: 3.0.0 - dev: true - - /graceful-fs/4.2.10: - resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} - dev: true - - /grapheme-splitter/1.0.4: - resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} - dev: true - - /handlebars/4.7.7: - resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==} - engines: {node: '>=0.4.7'} - hasBin: true - dependencies: - minimist: 1.2.7 - neo-async: 2.6.2 - source-map: 0.6.1 - wordwrap: 1.0.0 - optionalDependencies: - uglify-js: 3.17.4 - dev: true - - /har-schema/2.0.0: - resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} - engines: {node: '>=4'} - dev: false - - /har-validator/5.1.5: - resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} - engines: {node: '>=6'} - deprecated: this library is no longer supported - dependencies: - ajv: 6.12.6 - har-schema: 2.0.0 - dev: false - - /has-flag/3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - dev: true - - /has-flag/4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - /has-property-descriptors/1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} - dependencies: - get-intrinsic: 1.1.3 - dev: true - - /has-symbols/1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - - /has-tostringtag/1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: true - - /has/1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - dependencies: - function-bind: 1.1.1 - - /helmet/6.0.1: - resolution: {integrity: sha512-8wo+VdQhTMVBMCITYZaGTbE4lvlthelPYSvoyNvk4RECTmrVjMerp9RfUOQXZWLvCcAn1pKj7ZRxK4lI9Alrcw==} - engines: {node: '>=14.0.0'} - dev: false - - /hexoid/1.0.0: - resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} - engines: {node: '>=8'} - dev: true - - /html-entities/2.3.3: - resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} - dev: true - - /html-escaper/2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - dev: true - - /htmlparser2/8.0.1: - resolution: {integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==} - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.0.1 - entities: 4.4.0 - dev: true - - /http-auth-connect/1.0.6: - resolution: {integrity: sha512-yaO0QSCPqGCjPrl3qEEHjJP+lwZ6gMpXLuCBE06eWwcXomkI5TARtu0kxf9teFuBj6iaV3Ybr15jaWUvbzNzHw==} - engines: {node: '>=8'} - dev: true - - /http-auth/4.1.9: - resolution: {integrity: sha512-kvPYxNGc9EKGTXvOMnTBQw2RZfuiSihK/mLw/a4pbtRueTE45S55Lw/3k5CktIf7Ak0veMKEIteDj4YkNmCzmQ==} - engines: {node: '>=8'} - dependencies: - apache-crypt: 1.2.6 - apache-md5: 1.1.8 - bcryptjs: 2.4.3 - uuid: 8.3.2 - dev: true - - /http-errors/1.6.3: - resolution: {integrity: sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==} - engines: {node: '>= 0.6'} - dependencies: - depd: 1.1.2 - inherits: 2.0.3 - setprototypeof: 1.1.0 - statuses: 1.5.0 - dev: true - - /http-errors/2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - - /http-parser-js/0.5.8: - resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==} - dev: true - - /http-signature/1.2.0: - resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} - engines: {node: '>=0.8', npm: '>=1.3.7'} - dependencies: - assert-plus: 1.0.0 - jsprim: 1.4.2 - sshpk: 1.17.0 - dev: false - - /human-signals/1.1.1: - resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} - engines: {node: '>=8.12.0'} - dev: true - - /human-signals/2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - - /i18next/21.10.0: - resolution: {integrity: sha512-YeuIBmFsGjUfO3qBmMOc0rQaun4mIpGKET5WDwvu8lU7gvwpcariZLNtL0Fzj+zazcHUrlXHiptcFhBMFaxzfg==} - dependencies: - '@babel/runtime': 7.20.1 - dev: true - - /iconv-lite/0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - - /iconv-lite/0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: true - - /ieee754/1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - /ignore/5.2.1: - resolution: {integrity: sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==} - engines: {node: '>= 4'} - dev: true - - /import-fresh/3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - dev: true - - /import-local/3.1.0: - resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} - engines: {node: '>=8'} - hasBin: true - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - dev: true - - /imurmurhash/0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true - - /inflight/1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - /inherits/2.0.3: - resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} - dev: true - - /inherits/2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - /inquirer/7.3.3: - resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==} - engines: {node: '>=8.0.0'} - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - run-async: 2.4.1 - rxjs: 6.6.7 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - dev: true - - /inquirer/8.2.4: - resolution: {integrity: sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==} - engines: {node: '>=12.0.0'} - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - ora: 5.4.1 - run-async: 2.4.1 - rxjs: 7.5.7 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - wrap-ansi: 7.0.0 - dev: true - - /inside/1.0.0: - resolution: {integrity: sha512-tvFwvS4g7q6iDot/4FjtWFHwwpv6TVvEumbTdLQilk1F07ojakbXPQcvf3kMAlyNDpzKRzn+d33O3RuXODuxZQ==} - dev: true - - /interpret/1.4.0: - resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} - engines: {node: '>= 0.10'} - - /ip/2.0.0: - resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} - dev: false - - /ipaddr.js/1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - - /is-arguments/1.1.1: - resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - dev: true - - /is-arrayish/0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true - - /is-binary-path/2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - dependencies: - binary-extensions: 2.2.0 - dev: true - - /is-buffer/1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - dev: false - - /is-core-module/2.11.0: - resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} - dependencies: - has: 1.0.3 - - /is-date-object/1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - - /is-docker/2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - dev: true - - /is-extglob/2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - dev: true - - /is-fullwidth-code-point/3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - /is-generator-fn/2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - dev: true - - /is-glob/4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - - /is-interactive/1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - dev: true - - /is-number/7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true - - /is-path-inside/3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - dev: true - - /is-regex/1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - dev: true - - /is-stream/2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - /is-typedarray/1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - dev: false - - /is-unicode-supported/0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - dev: true - - /is-wsl/2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - dependencies: - is-docker: 2.2.1 - dev: true - - /isarray/1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - - /isexe/2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - /isomorphic-ws/4.0.1_ws@7.5.9: - resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} - peerDependencies: - ws: '*' - dependencies: - ws: 7.5.9 - dev: false - - /isstream/0.1.2: - resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - dev: false - - /istanbul-lib-coverage/3.2.0: - resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} - engines: {node: '>=8'} - dev: true - - /istanbul-lib-instrument/5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} - dependencies: - '@babel/core': 7.20.2 - '@babel/parser': 7.20.3 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-lib-report/3.0.0: - resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} - engines: {node: '>=8'} - dependencies: - istanbul-lib-coverage: 3.2.0 - make-dir: 3.1.0 - supports-color: 7.2.0 - dev: true - - /istanbul-lib-source-maps/4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} - dependencies: - debug: 4.3.4 - istanbul-lib-coverage: 3.2.0 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-reports/3.1.5: - resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} - engines: {node: '>=8'} - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.0 - dev: true - - /iterare/1.2.1: - resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} - engines: {node: '>=6'} - - /jest-changed-files/28.1.3: - resolution: {integrity: sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - execa: 5.1.1 - p-limit: 3.1.0 - dev: true - - /jest-circus/28.1.3: - resolution: {integrity: sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/environment': 28.1.3 - '@jest/expect': 28.1.3 - '@jest/test-result': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 16.18.3 - chalk: 4.1.2 - co: 4.6.0 - dedent: 0.7.0 - is-generator-fn: 2.1.0 - jest-each: 28.1.3 - jest-matcher-utils: 28.1.3 - jest-message-util: 28.1.3 - jest-runtime: 28.1.3 - jest-snapshot: 28.1.3 - jest-util: 28.1.3 - p-limit: 3.1.0 - pretty-format: 28.1.3 - slash: 3.0.0 - stack-utils: 2.0.6 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-cli/28.1.3_dnlfjp7n5lpfgnj4digwzn5fhe: - resolution: {integrity: sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 28.1.3_ts-node@10.9.1 - '@jest/test-result': 28.1.3 - '@jest/types': 28.1.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.10 - import-local: 3.1.0 - jest-config: 28.1.3_dnlfjp7n5lpfgnj4digwzn5fhe - jest-util: 28.1.3 - jest-validate: 28.1.3 - prompts: 2.4.2 - yargs: 17.6.2 - transitivePeerDependencies: - - '@types/node' - - supports-color - - ts-node - dev: true - - /jest-config/28.1.3_dnlfjp7n5lpfgnj4digwzn5fhe: - resolution: {integrity: sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - dependencies: - '@babel/core': 7.20.2 - '@jest/test-sequencer': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 16.18.3 - babel-jest: 28.1.3_@babel+core@7.20.2 - chalk: 4.1.2 - ci-info: 3.7.0 - deepmerge: 4.2.2 - glob: 7.2.3 - graceful-fs: 4.2.10 - jest-circus: 28.1.3 - jest-environment-node: 28.1.3 - jest-get-type: 28.0.2 - jest-regex-util: 28.0.2 - jest-resolve: 28.1.3 - jest-runner: 28.1.3 - jest-util: 28.1.3 - jest-validate: 28.1.3 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 28.1.3 - slash: 3.0.0 - strip-json-comments: 3.1.1 - ts-node: 10.9.1_fvpuwgkpfe3dm3hnpcpbcxmb3y - transitivePeerDependencies: - - supports-color - dev: true - - /jest-diff/28.1.3: - resolution: {integrity: sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - chalk: 4.1.2 - diff-sequences: 28.1.1 - jest-get-type: 28.0.2 - pretty-format: 28.1.3 - dev: true - - /jest-docblock/28.1.1: - resolution: {integrity: sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - detect-newline: 3.1.0 - dev: true - - /jest-each/28.1.3: - resolution: {integrity: sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - chalk: 4.1.2 - jest-get-type: 28.0.2 - jest-util: 28.1.3 - pretty-format: 28.1.3 - dev: true - - /jest-environment-node/28.1.3: - resolution: {integrity: sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/environment': 28.1.3 - '@jest/fake-timers': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 16.18.3 - jest-mock: 28.1.3 - jest-util: 28.1.3 - dev: true - - /jest-get-type/28.0.2: - resolution: {integrity: sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dev: true - - /jest-haste-map/28.1.3: - resolution: {integrity: sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/graceful-fs': 4.1.5 - '@types/node': 16.18.3 - anymatch: 3.1.3 - fb-watchman: 2.0.2 - graceful-fs: 4.2.10 - jest-regex-util: 28.0.2 - jest-util: 28.1.3 - jest-worker: 28.1.3 - micromatch: 4.0.5 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /jest-leak-detector/28.1.3: - resolution: {integrity: sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - jest-get-type: 28.0.2 - pretty-format: 28.1.3 - dev: true - - /jest-matcher-utils/28.1.3: - resolution: {integrity: sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - chalk: 4.1.2 - jest-diff: 28.1.3 - jest-get-type: 28.0.2 - pretty-format: 28.1.3 - dev: true - - /jest-message-util/28.1.3: - resolution: {integrity: sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@babel/code-frame': 7.18.6 - '@jest/types': 28.1.3 - '@types/stack-utils': 2.0.1 - chalk: 4.1.2 - graceful-fs: 4.2.10 - micromatch: 4.0.5 - pretty-format: 28.1.3 - slash: 3.0.0 - stack-utils: 2.0.6 - dev: true - - /jest-mock/28.1.3: - resolution: {integrity: sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/node': 16.18.3 - dev: true - - /jest-pnp-resolver/1.2.3_jest-resolve@28.1.3: - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true - dependencies: - jest-resolve: 28.1.3 - dev: true - - /jest-regex-util/28.0.2: - resolution: {integrity: sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dev: true - - /jest-resolve-dependencies/28.1.3: - resolution: {integrity: sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - jest-regex-util: 28.0.2 - jest-snapshot: 28.1.3 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-resolve/28.1.3: - resolution: {integrity: sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.10 - jest-haste-map: 28.1.3 - jest-pnp-resolver: 1.2.3_jest-resolve@28.1.3 - jest-util: 28.1.3 - jest-validate: 28.1.3 - resolve: 1.22.1 - resolve.exports: 1.1.0 - slash: 3.0.0 - dev: true - - /jest-runner/28.1.3: - resolution: {integrity: sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/console': 28.1.3 - '@jest/environment': 28.1.3 - '@jest/test-result': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 16.18.3 - chalk: 4.1.2 - emittery: 0.10.2 - graceful-fs: 4.2.10 - jest-docblock: 28.1.1 - jest-environment-node: 28.1.3 - jest-haste-map: 28.1.3 - jest-leak-detector: 28.1.3 - jest-message-util: 28.1.3 - jest-resolve: 28.1.3 - jest-runtime: 28.1.3 - jest-util: 28.1.3 - jest-watcher: 28.1.3 - jest-worker: 28.1.3 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-runtime/28.1.3: - resolution: {integrity: sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/environment': 28.1.3 - '@jest/fake-timers': 28.1.3 - '@jest/globals': 28.1.3 - '@jest/source-map': 28.1.2 - '@jest/test-result': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - chalk: 4.1.2 - cjs-module-lexer: 1.2.2 - collect-v8-coverage: 1.0.1 - execa: 5.1.1 - glob: 7.2.3 - graceful-fs: 4.2.10 - jest-haste-map: 28.1.3 - jest-message-util: 28.1.3 - jest-mock: 28.1.3 - jest-regex-util: 28.0.2 - jest-resolve: 28.1.3 - jest-snapshot: 28.1.3 - jest-util: 28.1.3 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-snapshot/28.1.3: - resolution: {integrity: sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@babel/core': 7.20.2 - '@babel/generator': 7.20.4 - '@babel/plugin-syntax-typescript': 7.20.0_@babel+core@7.20.2 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 - '@jest/expect-utils': 28.1.3 - '@jest/transform': 28.1.3 - '@jest/types': 28.1.3 - '@types/babel__traverse': 7.18.2 - '@types/prettier': 2.7.1 - babel-preset-current-node-syntax: 1.0.1_@babel+core@7.20.2 - chalk: 4.1.2 - expect: 28.1.3 - graceful-fs: 4.2.10 - jest-diff: 28.1.3 - jest-get-type: 28.0.2 - jest-haste-map: 28.1.3 - jest-matcher-utils: 28.1.3 - jest-message-util: 28.1.3 - jest-util: 28.1.3 - natural-compare: 1.4.0 - pretty-format: 28.1.3 - semver: 7.3.8 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-util/28.1.3: - resolution: {integrity: sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/node': 16.18.3 - chalk: 4.1.2 - ci-info: 3.7.0 - graceful-fs: 4.2.10 - picomatch: 2.3.1 - dev: true - - /jest-validate/28.1.3: - resolution: {integrity: sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 28.0.2 - leven: 3.1.0 - pretty-format: 28.1.3 - dev: true - - /jest-watcher/28.1.3: - resolution: {integrity: sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/test-result': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 16.18.3 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.10.2 - jest-util: 28.1.3 - string-length: 4.0.2 - dev: true - - /jest-worker/27.5.1: - resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} - engines: {node: '>= 10.13.0'} - dependencies: - '@types/node': 16.18.3 - merge-stream: 2.0.0 - supports-color: 8.1.1 - dev: true - - /jest-worker/28.1.3: - resolution: {integrity: sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@types/node': 16.18.3 - merge-stream: 2.0.0 - supports-color: 8.1.1 - dev: true - - /jest/28.1.3_dnlfjp7n5lpfgnj4digwzn5fhe: - resolution: {integrity: sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 28.1.3_ts-node@10.9.1 - '@jest/types': 28.1.3 - import-local: 3.1.0 - jest-cli: 28.1.3_dnlfjp7n5lpfgnj4digwzn5fhe - transitivePeerDependencies: - - '@types/node' - - supports-color - - ts-node - dev: true - - /jose/4.11.1: - resolution: {integrity: sha512-YRv4Tk/Wlug8qicwqFNFVEZSdbROCHRAC6qu/i0dyNKr5JQdoa2pIGoS04lLO/jXQX7Z9omoNewYIVIxqZBd9Q==} - dev: false - optional: true - - /js-sdsl/4.2.0: - resolution: {integrity: sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==} - dev: true - - /js-tokens/4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true - - /js-yaml/3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - dev: true - - /js-yaml/4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - dependencies: - argparse: 2.0.1 - - /jsbn/0.1.1: - resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - dev: false - - /jsesc/0.5.0: - resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} - hasBin: true - dev: true - - /jsesc/2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /json-parse-even-better-errors/2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true - - /json-schema-traverse/0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - /json-schema-traverse/1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - dev: true - - /json-schema/0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - dev: false - - /json-stable-stringify-without-jsonify/1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - dev: true - - /json-stringify-safe/5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - dev: false - - /json5/2.2.1: - resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} - engines: {node: '>=6'} - hasBin: true - dev: true - - /jsonc-parser/3.0.0: - resolution: {integrity: sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==} - dev: true - - /jsonc-parser/3.1.0: - resolution: {integrity: sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==} - dev: true - - /jsonc-parser/3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - dev: true - - /jsonfile/6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - dependencies: - universalify: 2.0.0 - optionalDependencies: - graceful-fs: 4.2.10 - dev: true - - /jsonpath-plus/0.19.0: - resolution: {integrity: sha512-GSVwsrzW9LsA5lzsqe4CkuZ9wp+kxBb2GwNniaWzI2YFn5Ig42rSW8ZxVpWXaAfakXNrx5pgY5AbQq7kzX29kg==} - engines: {node: '>=6.0'} - dev: false - - /jsonwebtoken/8.5.1: - resolution: {integrity: sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==} - engines: {node: '>=4', npm: '>=1.4.28'} - dependencies: - jws: 3.2.2 - lodash.includes: 4.3.0 - lodash.isboolean: 3.0.3 - lodash.isinteger: 4.0.4 - lodash.isnumber: 3.0.3 - lodash.isplainobject: 4.0.6 - lodash.isstring: 4.0.1 - lodash.once: 4.1.1 - ms: 2.1.3 - semver: 5.7.1 - dev: false - - /jsprim/1.4.2: - resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} - engines: {node: '>=0.6.0'} - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - dev: false - - /jwa/1.4.1: - resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} - dependencies: - buffer-equal-constant-time: 1.0.1 - ecdsa-sig-formatter: 1.0.11 - safe-buffer: 5.2.1 - dev: false - - /jws/3.2.2: - resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} - dependencies: - jwa: 1.4.1 - safe-buffer: 5.2.1 - dev: false - - /kleur/3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - dev: true - - /leven/3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - dev: true - - /levn/0.3.0: - resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.1.2 - type-check: 0.3.2 - dev: true - - /levn/0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - dev: true - - /libphonenumber-js/1.10.14: - resolution: {integrity: sha512-McGS7GV/WjJ2KjfOGhJU1oJn29RYeo7Q+RpANRbUNMQ9gj5XArpbjurSuyYPTejFwbaUojstQ4XyWCrAzGOUXw==} - - /lines-and-columns/1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true - - /loader-runner/4.3.0: - resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} - engines: {node: '>=6.11.5'} - dev: true - - /locate-path/5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - dependencies: - p-locate: 4.1.0 - dev: true - - /locate-path/6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - dependencies: - p-locate: 5.0.0 - dev: true - - /lodash.debounce/4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - dev: true - - /lodash.includes/4.3.0: - resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} - dev: false - - /lodash.isboolean/3.0.3: - resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} - dev: false - - /lodash.isinteger/4.0.4: - resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} - dev: false - - /lodash.isnumber/3.0.3: - resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} - dev: false - - /lodash.isplainobject/4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - dev: false - - /lodash.isstring/4.0.1: - resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} - dev: false - - /lodash.memoize/4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - dev: true - - /lodash.merge/4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - dev: true - - /lodash.once/4.1.1: - resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} - dev: false - - /lodash/4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - /log-symbols/4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - dev: true - - /loglevel-plugin-prefix/0.8.4: - resolution: {integrity: sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==} - dev: true - - /loglevel/1.8.1: - resolution: {integrity: sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==} - engines: {node: '>= 0.6.0'} - dev: true - - /lru-cache/6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - dependencies: - yallist: 4.0.0 - - /lunr/2.3.9: - resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} - dev: true - - /macos-release/2.5.0: - resolution: {integrity: sha512-EIgv+QZ9r+814gjJj0Bt5vSLJLzswGmSUbUpbi9AIr/fsN2IWFBl2NucV9PAiek+U1STK468tEkxmVYUtuAN3g==} - engines: {node: '>=6'} - dev: true - - /magic-string/0.25.1: - resolution: {integrity: sha512-sCuTz6pYom8Rlt4ISPFn6wuFodbKMIHUMv4Qko9P17dpxb7s52KJTmRuZZqHdGmLCK9AOcDare039nRIcfdkEg==} - dependencies: - sourcemap-codec: 1.4.8 - dev: true - - /magic-string/0.25.7: - resolution: {integrity: sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==} - dependencies: - sourcemap-codec: 1.4.8 - dev: true - - /magic-string/0.26.2: - resolution: {integrity: sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A==} - engines: {node: '>=12'} - dependencies: - sourcemap-codec: 1.4.8 - dev: true - - /make-dir/3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} - dependencies: - semver: 6.3.0 - dev: true - - /make-error/1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true - - /makeerror/1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} - dependencies: - tmpl: 1.0.5 - dev: true - - /map-stream/0.0.7: - resolution: {integrity: sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==} - dev: true - - /marked/4.2.3: - resolution: {integrity: sha512-slWRdJkbTZ+PjkyJnE30Uid64eHwbwa1Q25INCAYfZlK4o6ylagBy/Le9eWntqJFoFT93ikUKMv47GZ4gTwHkw==} - engines: {node: '>= 12'} - hasBin: true - dev: true - - /md5/2.3.0: - resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} - dependencies: - charenc: 0.0.2 - crypt: 0.0.2 - is-buffer: 1.1.6 - dev: false - - /media-typer/0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - - /memfs/3.4.12: - resolution: {integrity: sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw==} - engines: {node: '>= 4.0.0'} - dependencies: - fs-monkey: 1.0.3 - dev: true - - /memory-pager/1.5.0: - resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} - dev: false - optional: true - - /merge-descriptors/1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - - /merge-source-map/1.0.4: - resolution: {integrity: sha512-PGSmS0kfnTnMJCzJ16BLLCEe6oeYCamKFFdQKshi4BmM6FUwipjVOcBFGxqtQtirtAG4iZvHlqST9CpZKqlRjA==} - dependencies: - source-map: 0.5.7 - dev: true - - /merge-stream/2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - - /merge2/1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - dev: true - - /methods/1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} - - /micromatch/4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - dev: true - - /mime-db/1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - /mime-types/2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - - /mime/1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - - /mime/2.6.0: - resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} - engines: {node: '>=4.0.0'} - hasBin: true - dev: true - - /mimic-fn/2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - /minimatch/3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - - /minimist/1.2.7: - resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} - - /minipass/3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} - dependencies: - yallist: 4.0.0 - dev: false - - /minizlib/2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.6 - yallist: 4.0.0 - dev: false - - /mkdirp/0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true - dependencies: - minimist: 1.2.7 - - /mkdirp/1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - - /mongodb-connection-string-url/2.5.4: - resolution: {integrity: sha512-SeAxuWs0ez3iI3vvmLk/j2y+zHwigTDKQhtdxTgt5ZCOQQS5+HW4g45/Xw5vzzbn7oQXCNQ24Z40AkJsizEy7w==} - dependencies: - '@types/whatwg-url': 8.2.2 - whatwg-url: 11.0.0 - dev: false - - /mongodb/4.12.1: - resolution: {integrity: sha512-koT87tecZmxPKtxRQD8hCKfn+ockEL2xBiUvx3isQGI6mFmagWt4f4AyCE9J4sKepnLhMacoCTQQA6SLAI2L6w==} - engines: {node: '>=12.9.0'} - dependencies: - bson: 4.7.0 - mongodb-connection-string-url: 2.5.4 - socks: 2.7.1 - optionalDependencies: - '@aws-sdk/credential-providers': 3.218.0 - saslprep: 1.0.3 - transitivePeerDependencies: - - aws-crt - dev: false - - /morgan/1.10.0: - resolution: {integrity: sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==} - engines: {node: '>= 0.8.0'} - dependencies: - basic-auth: 2.0.1 - debug: 2.6.9 - depd: 2.0.0 - on-finished: 2.3.0 - on-headers: 1.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /ms/2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - - /ms/2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true - - /ms/2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - /multer/1.4.4-lts.1: - resolution: {integrity: sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg==} - engines: {node: '>= 6.0.0'} - dependencies: - append-field: 1.0.0 - busboy: 1.6.0 - concat-stream: 1.6.2 - mkdirp: 0.5.6 - object-assign: 4.1.1 - type-is: 1.6.18 - xtend: 4.0.2 - - /mute-stream/0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - dev: true - - /nanoid/3.3.4: - resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - dev: false - - /natural-compare-lite/1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - dev: true - - /natural-compare/1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - dev: true - - /negotiator/0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - - /neo-async/2.6.2: - resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - dev: true - - /next-tick/1.1.0: - resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} - dev: true - - /node-abort-controller/3.0.1: - resolution: {integrity: sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==} - dev: true - - /node-emoji/1.11.0: - resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} - dependencies: - lodash: 4.17.21 - dev: true - - /node-fetch/2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - - /node-int64/0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - dev: true - - /node-releases/2.0.6: - resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} - dev: true - - /normalize-path/3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - dev: true - - /npm-run-path/4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - dependencies: - path-key: 3.1.1 - - /nth-check/2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - dependencies: - boolbase: 1.0.0 - dev: true - - /oauth-sign/0.9.0: - resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} - dev: false - - /object-assign/4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - /object-hash/2.2.0: - resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==} - engines: {node: '>= 6'} - dev: false - optional: true - - /object-hash/3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} - - /object-inspect/1.12.2: - resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} - - /object-is/1.1.5: - resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - dev: true - - /object-keys/1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - dev: true - - /oidc-token-hash/5.0.1: - resolution: {integrity: sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ==} - engines: {node: ^10.13.0 || >=12.0.0} - dev: false - optional: true - - /on-finished/2.3.0: - resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} - engines: {node: '>= 0.8'} - dependencies: - ee-first: 1.1.1 - dev: true - - /on-finished/2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - dependencies: - ee-first: 1.1.1 - - /on-headers/1.0.2: - resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} - engines: {node: '>= 0.8'} - - /once/1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - - /onetime/5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - dependencies: - mimic-fn: 2.1.0 - - /open/8.4.0: - resolution: {integrity: sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==} - engines: {node: '>=12'} - dependencies: - define-lazy-prop: 2.0.0 - is-docker: 2.2.1 - is-wsl: 2.2.0 - dev: true - - /opencollective-postinstall/2.0.3: - resolution: {integrity: sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==} - hasBin: true - dev: true - - /openid-client/5.3.0: - resolution: {integrity: sha512-SykPCeZBZ/SxiBH5AWynvFUIDX3//2pgwc/3265alUmGHeCN03+X8uP+pHOVnCXCKfX/XOhO90qttAQ76XcGxA==} - requiresBuild: true - dependencies: - jose: 4.11.1 - lru-cache: 6.0.0 - object-hash: 2.2.0 - oidc-token-hash: 5.0.1 - dev: false - optional: true - - /optionator/0.8.3: - resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} - engines: {node: '>= 0.8.0'} - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.3.0 - prelude-ls: 1.1.2 - type-check: 0.3.2 - word-wrap: 1.2.3 - dev: true - - /optionator/0.9.1: - resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} - engines: {node: '>= 0.8.0'} - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.3 - dev: true - - /ora/5.4.1: - resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} - engines: {node: '>=10'} - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.7.0 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - dev: true - - /os-name/4.0.1: - resolution: {integrity: sha512-xl9MAoU97MH1Xt5K9ERft2YfCAoaO6msy1OBA0ozxEC0x0TmIoE6K3QvgJMMZA9yKGLmHXNY/YZoDbiGDj4zYw==} - engines: {node: '>=10'} - dependencies: - macos-release: 2.5.0 - windows-release: 4.0.0 - dev: true - - /os-tmpdir/1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - dev: true - - /p-limit/2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - dependencies: - p-try: 2.2.0 - dev: true - - /p-limit/3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - dependencies: - yocto-queue: 0.1.0 - dev: true - - /p-locate/4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - dependencies: - p-limit: 2.3.0 - dev: true - - /p-locate/5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - dependencies: - p-limit: 3.1.0 - dev: true - - /p-try/2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - dev: true - - /pako/0.2.9: - resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} - dev: true - - /parent-module/1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - dependencies: - callsites: 3.1.0 - dev: true - - /parse-json/5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - dependencies: - '@babel/code-frame': 7.18.6 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - dev: true - - /parse-node-version/1.0.1: - resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} - engines: {node: '>= 0.10'} - dev: true - - /parse5-htmlparser2-tree-adapter/7.0.0: - resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} - dependencies: - domhandler: 5.0.3 - parse5: 7.1.2 - dev: true - - /parse5/7.1.2: - resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} - dependencies: - entities: 4.4.0 - dev: true - - /parseurl/1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - - /passport-jwt/4.0.0: - resolution: {integrity: sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg==} - dependencies: - jsonwebtoken: 8.5.1 - passport-strategy: 1.0.0 - dev: false - - /passport-local/1.0.0: - resolution: {integrity: sha512-9wCE6qKznvf9mQYYbgJ3sVOHmCWoUNMVFoZzNoznmISbhnNNPhN9xfY3sLmScHMetEJeoY7CXwfhCe7argfQow==} - engines: {node: '>= 0.4.0'} - dependencies: - passport-strategy: 1.0.0 - dev: false - - /passport-strategy/1.0.0: - resolution: {integrity: sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==} - engines: {node: '>= 0.4.0'} - dev: false - - /passport/0.6.0: - resolution: {integrity: sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==} - engines: {node: '>= 0.4.0'} - dependencies: - passport-strategy: 1.0.0 - pause: 0.0.1 - utils-merge: 1.0.1 - dev: false - - /path-browserify/1.0.1: - resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - dev: true - - /path-exists/4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true - - /path-is-absolute/1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - - /path-key/3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - /path-parse/1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - /path-to-regexp/0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} - - /path-to-regexp/3.2.0: - resolution: {integrity: sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==} - - /path-type/4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - dev: true - - /pause-stream/0.0.11: - resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} - dependencies: - through: 2.3.8 - dev: true - - /pause/0.0.1: - resolution: {integrity: sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==} - dev: false - - /pdfjs-dist/2.16.105: - resolution: {integrity: sha512-J4dn41spsAwUxCpEoVf6GVoz908IAA3mYiLmNxg8J9kfRXc2jxpbUepcP0ocp0alVNLFthTAM8DZ1RaHh8sU0A==} - peerDependencies: - worker-loader: ^3.0.8 - peerDependenciesMeta: - worker-loader: - optional: true - dependencies: - dommatrix: 1.0.3 - web-streams-polyfill: 3.2.1 - dev: true - - /pdfmake/0.2.6: - resolution: {integrity: sha512-gZARnKLJjTuHWKIkqF4G6dafIaPfH7NFqBz9U9wb26PV5koHQ5eeQ/0rgZmIdfJzMKqHzXB9aK25ykG2AnnzEQ==} - engines: {node: '>=12'} - dependencies: - '@foliojs-fork/linebreak': 1.1.1 - '@foliojs-fork/pdfkit': 0.13.0 - iconv-lite: 0.6.3 - xmldoc: 1.2.0 - dev: true - - /performance-now/2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} - dev: false - - /picocolors/1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true - - /picomatch/2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true - - /pirates/4.0.5: - resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} - engines: {node: '>= 6'} - dev: true - - /pkg-dir/4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - dependencies: - find-up: 4.1.0 - dev: true - - /pluralize/8.0.0: - resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} - engines: {node: '>=4'} - dev: true - - /png-js/1.0.0: - resolution: {integrity: sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g==} - dev: true - - /prelude-ls/1.1.2: - resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} - engines: {node: '>= 0.8.0'} - dev: true - - /prelude-ls/1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - dev: true - - /prettier-linter-helpers/1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - dependencies: - fast-diff: 1.2.0 - dev: true - - /prettier/2.8.0: - resolution: {integrity: sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==} - engines: {node: '>=10.13.0'} - hasBin: true - dev: true - - /pretty-format/28.1.3: - resolution: {integrity: sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/schemas': 28.1.3 - ansi-regex: 5.0.1 - ansi-styles: 5.2.0 - react-is: 18.2.0 - dev: true - - /prisma/4.6.1: - resolution: {integrity: sha512-BR4itMCuzrDV4tn3e2TF+nh1zIX/RVU0isKtKoN28ADeoJ9nYaMhiuRRkFd2TZN8+l/XfYzoRKyHzUFXLQhmBQ==} - engines: {node: '>=14.17'} - hasBin: true - requiresBuild: true - dependencies: - '@prisma/engines': 4.6.1 - - /process-nextick-args/2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - - /prompts/2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - dev: true - - /proxy-addr/2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - - /proxy-from-env/1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: false - - /proxy-middleware/0.15.0: - resolution: {integrity: sha512-EGCG8SeoIRVMhsqHQUdDigB2i7qU7fCsWASwn54+nPutYO8n4q6EiwMzyfWlC+dzRFExP+kvcnDFdBDHoZBU7Q==} - engines: {node: '>=0.8.0'} - dev: true - - /psl/1.9.0: - resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - dev: false - - /pump/3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - dev: true - - /punycode/2.1.1: - resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} - engines: {node: '>=6'} - - /qs/6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} - dependencies: - side-channel: 1.0.4 - - /qs/6.5.3: - resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} - engines: {node: '>=0.6'} - dev: false - - /qs/6.9.3: - resolution: {integrity: sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==} - engines: {node: '>=0.6'} - dev: true - - /queue-microtask/1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true - - /quote-stream/1.0.2: - resolution: {integrity: sha512-kKr2uQ2AokadPjvTyKJQad9xELbZwYzWlNfI3Uz2j/ib5u6H9lDP7fUUR//rMycd0gv4Z5P1qXMfXR8YpIxrjQ==} - hasBin: true - dependencies: - buffer-equal: 0.0.1 - minimist: 1.2.7 - through2: 2.0.5 - dev: true - - /randombytes/2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - dependencies: - safe-buffer: 5.2.1 - dev: true - - /range-parser/1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - - /raw-body/2.5.1: - resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} - engines: {node: '>= 0.8'} - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - - /react-is/18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - dev: true - - /readable-stream/2.3.7: - resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - - /readable-stream/3.6.0: - resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} - engines: {node: '>= 6'} - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - dev: true - - /readdirp/3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - dependencies: - picomatch: 2.3.1 - dev: true - - /rechoir/0.6.2: - resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} - engines: {node: '>= 0.10'} - dependencies: - resolve: 1.22.1 - - /reflect-metadata/0.1.13: - resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} - - /regenerate-unicode-properties/10.1.0: - resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} - engines: {node: '>=4'} - dependencies: - regenerate: 1.4.2 - dev: true - - /regenerate/1.4.2: - resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} - dev: true - - /regenerator-runtime/0.13.11: - resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - dev: true - - /regenerator-transform/0.15.1: - resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} - dependencies: - '@babel/runtime': 7.20.1 - dev: true - - /regexp.prototype.flags/1.4.3: - resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - functions-have-names: 1.2.3 - dev: true - - /regexpp/3.2.0: - resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} - engines: {node: '>=8'} - dev: true - - /regexpu-core/5.2.2: - resolution: {integrity: sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==} - engines: {node: '>=4'} - dependencies: - regenerate: 1.4.2 - regenerate-unicode-properties: 10.1.0 - regjsgen: 0.7.1 - regjsparser: 0.9.1 - unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.1.0 - dev: true - - /regjsgen/0.7.1: - resolution: {integrity: sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==} - dev: true - - /regjsparser/0.9.1: - resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} - hasBin: true - dependencies: - jsesc: 0.5.0 - dev: true - - /request/2.88.2: - resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} - engines: {node: '>= 6'} - deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 - dependencies: - aws-sign2: 0.7.0 - aws4: 1.11.0 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 2.3.3 - har-validator: 5.1.5 - http-signature: 1.2.0 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.35 - oauth-sign: 0.9.0 - performance-now: 2.1.0 - qs: 6.5.3 - safe-buffer: 5.2.1 - tough-cookie: 2.5.0 - tunnel-agent: 0.6.0 - uuid: 3.4.0 - dev: false - - /require-directory/2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true - - /require-from-string/2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - dev: true - - /resolve-cwd/3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - dependencies: - resolve-from: 5.0.0 - dev: true - - /resolve-from/4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - dev: true - - /resolve-from/5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - dev: true - - /resolve.exports/1.1.0: - resolution: {integrity: sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==} - engines: {node: '>=10'} - dev: true - - /resolve/1.1.7: - resolution: {integrity: sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==} - dev: true - - /resolve/1.22.1: - resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} - hasBin: true - dependencies: - is-core-module: 2.11.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - /restore-cursor/3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - dev: true - - /reusify/1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true - - /rfc4648/1.5.2: - resolution: {integrity: sha512-tLOizhR6YGovrEBLatX1sdcuhoSCXddw3mqNVAcKxGJ+J0hFeJ+SjeWCv5UPA/WU3YzWPPuCVYgXBKZUPGpKtg==} - dev: false - - /rimraf/3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - dependencies: - glob: 7.2.3 - - /run-async/2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} - dev: true - - /run-parallel/1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - dependencies: - queue-microtask: 1.2.3 - dev: true - - /rxjs/6.6.7: - resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} - engines: {npm: '>=2.0.0'} - dependencies: - tslib: 1.14.1 - dev: true - - /rxjs/7.5.7: - resolution: {integrity: sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==} - dependencies: - tslib: 2.4.1 - - /safe-buffer/5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - - /safe-buffer/5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - /safer-buffer/2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - /saslprep/1.0.3: - resolution: {integrity: sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==} - engines: {node: '>=6'} - requiresBuild: true - dependencies: - sparse-bitfield: 3.0.3 - dev: false - optional: true - - /sax/1.2.4: - resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} - dev: true - - /schema-utils/3.1.1: - resolution: {integrity: sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==} - engines: {node: '>= 10.13.0'} - dependencies: - '@types/json-schema': 7.0.11 - ajv: 6.12.6 - ajv-keywords: 3.5.2_ajv@6.12.6 - dev: true - - /scope-analyzer/2.1.2: - resolution: {integrity: sha512-5cfCmsTYV/wPaRIItNxatw02ua/MThdIUNnUOCYp+3LSEJvnG804ANw2VLaavNILIfWXF1D1G2KNANkBBvInwQ==} - dependencies: - array-from: 2.1.1 - dash-ast: 2.0.1 - es6-map: 0.1.5 - es6-set: 0.1.6 - es6-symbol: 3.1.3 - estree-is-function: 1.0.0 - get-assigned-identifiers: 1.2.0 - dev: true - - /semver/5.7.1: - resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} - hasBin: true - dev: false - - /semver/6.3.0: - resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} - hasBin: true - dev: true - - /semver/7.3.8: - resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: true - - /send/0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} - engines: {node: '>= 0.8.0'} - 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 - transitivePeerDependencies: - - supports-color - - /serialize-javascript/6.0.0: - resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} - dependencies: - randombytes: 2.1.0 - dev: true - - /serve-index/1.9.1: - resolution: {integrity: sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==} - engines: {node: '>= 0.8.0'} - dependencies: - accepts: 1.3.8 - batch: 0.6.1 - debug: 2.6.9 - escape-html: 1.0.3 - http-errors: 1.6.3 - mime-types: 2.1.35 - parseurl: 1.3.3 - transitivePeerDependencies: - - supports-color - dev: true - - /serve-static/1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} - engines: {node: '>= 0.8.0'} - dependencies: - encodeurl: 1.0.2 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.18.0 - transitivePeerDependencies: - - supports-color - - /setprototypeof/1.1.0: - resolution: {integrity: sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==} - dev: true - - /setprototypeof/1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - - /shallow-copy/0.0.1: - resolution: {integrity: sha512-b6i4ZpVuUxB9h5gfCxPiusKYkqTMOjEbBs4wMaFbkfia4yFv92UKZ6Df8WXcKbn08JNL/abvg3FnMAOfakDvUw==} - dev: true - - /shebang-command/2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - - /shebang-regex/3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - /shelljs/0.8.5: - resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} - engines: {node: '>=4'} - hasBin: true - dependencies: - glob: 7.2.3 - interpret: 1.4.0 - rechoir: 0.6.2 - - /side-channel/1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.1.3 - object-inspect: 1.12.2 - - /signal-exit/3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - /sisteransi/1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: true - - /slash/3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - dev: true - - /smart-buffer/4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - dev: false - - /socks/2.7.1: - resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} - engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} - dependencies: - ip: 2.0.0 - smart-buffer: 4.2.0 - dev: false - - /source-map-support/0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: true - - /source-map-support/0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: true - - /source-map/0.1.43: - resolution: {integrity: sha512-VtCvB9SIQhk3aF6h+N85EaqIaBFIAfZ9Cu+NJHHVvc8BbEcnvDcFw6sqQ2dQrT6SlOrZq3tIvyD9+EGq/lJryQ==} - engines: {node: '>=0.8.0'} - requiresBuild: true - dependencies: - amdefine: 1.0.1 - dev: true - optional: true - - /source-map/0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} - engines: {node: '>=0.10.0'} - dev: true - - /source-map/0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true - - /source-map/0.7.3: - resolution: {integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==} - engines: {node: '>= 8'} - dev: true - - /source-map/0.7.4: - resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} - engines: {node: '>= 8'} - dev: true - - /sourcemap-codec/1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - dev: true - - /sparse-bitfield/3.0.3: - resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==} - dependencies: - memory-pager: 1.5.0 - dev: false - optional: true - - /split/1.0.1: - resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} - dependencies: - through: 2.3.8 - dev: true - - /sprintf-js/1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: true - - /sshpk/1.17.0: - resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==} - engines: {node: '>=0.10.0'} - hasBin: true - dependencies: - asn1: 0.2.6 - assert-plus: 1.0.0 - bcrypt-pbkdf: 1.0.2 - dashdash: 1.14.1 - ecc-jsbn: 0.1.2 - getpass: 0.1.7 - jsbn: 0.1.1 - safer-buffer: 2.1.2 - tweetnacl: 0.14.5 - dev: false - - /stack-utils/2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} - dependencies: - escape-string-regexp: 2.0.0 - dev: true - - /static-eval/2.1.0: - resolution: {integrity: sha512-agtxZ/kWSsCkI5E4QifRwsaPs0P0JmZV6dkLz6ILYfFYQGn+5plctanRN+IC8dJRiFkyXHrwEE3W9Wmx67uDbw==} - dependencies: - escodegen: 1.14.3 - dev: true - - /static-module/3.0.4: - resolution: {integrity: sha512-gb0v0rrgpBkifXCa3yZXxqVmXDVE+ETXj6YlC/jt5VzOnGXR2C15+++eXuMDUYsePnbhf+lwW0pE1UXyOLtGCw==} - dependencies: - acorn-node: 1.8.2 - concat-stream: 1.6.2 - convert-source-map: 1.9.0 - duplexer2: 0.1.4 - escodegen: 1.14.3 - has: 1.0.3 - magic-string: 0.25.1 - merge-source-map: 1.0.4 - object-inspect: 1.12.2 - readable-stream: 2.3.7 - scope-analyzer: 2.1.2 - shallow-copy: 0.0.1 - static-eval: 2.1.0 - through2: 2.0.5 - dev: true - - /statuses/1.5.0: - resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} - engines: {node: '>= 0.6'} - dev: true - - /statuses/2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - - /stream-buffers/3.0.2: - resolution: {integrity: sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==} - engines: {node: '>= 0.10.0'} - dev: false - - /stream-combiner/0.2.2: - resolution: {integrity: sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==} - dependencies: - duplexer: 0.1.2 - through: 2.3.8 - dev: true - - /streamsearch/1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - - /string-length/4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} - dependencies: - char-regex: 1.0.2 - strip-ansi: 6.0.1 - dev: true - - /string-width/4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - /string_decoder/1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - dependencies: - safe-buffer: 5.1.2 - - /string_decoder/1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - dependencies: - safe-buffer: 5.2.1 - dev: true - - /strip-ansi/6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - - /strip-bom/3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: true - - /strip-bom/4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - dev: true - - /strip-final-newline/2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - - /strip-json-comments/3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true - - /strnum/1.0.5: - resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} - dev: false - optional: true - - /superagent/8.0.4: - resolution: {integrity: sha512-yaQB7YqAHhutt8yU7XIRKXGXtkxKidVuiDJ8FJPBG7JPd7Ckv4X9cOdxVGH5DFsPXodsCrOSzdUi2xL+o9z1qw==} - engines: {node: '>=6.4.0 <13 || >=14'} - dependencies: - component-emitter: 1.3.0 - cookiejar: 2.1.3 - debug: 4.3.4 - fast-safe-stringify: 2.1.1 - form-data: 4.0.0 - formidable: 2.0.1 - methods: 1.1.2 - mime: 2.6.0 - qs: 6.11.0 - semver: 7.3.8 - transitivePeerDependencies: - - supports-color - dev: true - - /supertest/6.3.1: - resolution: {integrity: sha512-hRohNeIfk/cA48Cxpa/w48hktP6ZaRqXb0QV5rLvW0C7paRsBU3Q5zydzYrslOJtj/gd48qx540jKtcs6vG1fQ==} - engines: {node: '>=6.4.0'} - dependencies: - methods: 1.1.2 - superagent: 8.0.4 - transitivePeerDependencies: - - supports-color - dev: true - - /supports-color/5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - dependencies: - has-flag: 3.0.0 - dev: true - - /supports-color/7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - - /supports-color/8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - dependencies: - has-flag: 4.0.0 - dev: true - - /supports-hyperlinks/2.3.0: - resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - supports-color: 7.2.0 - dev: true - - /supports-preserve-symlinks-flag/1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - /swagger-ui-dist/4.15.1: - resolution: {integrity: sha512-DlZARu6ckUFqDe0j5IPayO4k0gQvYQw9Un02MhxAgaMtVnTH2vmyyDe+yKeV0r1LiiPx3JbasdS/5Yyb/AV3iw==} - dev: false - - /symbol-observable/4.0.0: - resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} - engines: {node: '>=0.10'} - dev: true - - /tapable/2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} - engines: {node: '>=6'} - dev: true - - /tar/6.1.12: - resolution: {integrity: sha512-jU4TdemS31uABHd+Lt5WEYJuzn+TJTCBLljvIAHZOz6M9Os5pJ4dD+vRFLxPa/n3T0iEFzpi+0x1UfuDZYbRMw==} - engines: {node: '>=10'} - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 3.3.6 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - dev: false - - /terminal-link/2.1.1: - resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} - engines: {node: '>=8'} - dependencies: - ansi-escapes: 4.3.2 - supports-hyperlinks: 2.3.0 - dev: true - - /terser-webpack-plugin/5.3.6_webpack@5.74.0: - resolution: {integrity: sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==} - engines: {node: '>= 10.13.0'} - peerDependencies: - '@swc/core': '*' - esbuild: '*' - uglify-js: '*' - webpack: ^5.1.0 - peerDependenciesMeta: - '@swc/core': - optional: true - esbuild: - optional: true - uglify-js: - optional: true - dependencies: - '@jridgewell/trace-mapping': 0.3.17 - jest-worker: 27.5.1 - schema-utils: 3.1.1 - serialize-javascript: 6.0.0 - terser: 5.16.0 - webpack: 5.74.0 - dev: true - - /terser/5.16.0: - resolution: {integrity: sha512-KjTV81QKStSfwbNiwlBXfcgMcOloyuRdb62/iLFPGBcVNF4EXjhdYBhYHmbJpiBrVxZhDvltE11j+LBQUxEEJg==} - engines: {node: '>=10'} - hasBin: true - dependencies: - '@jridgewell/source-map': 0.3.2 - acorn: 8.8.1 - commander: 2.20.3 - source-map-support: 0.5.21 - dev: true - - /test-exclude/6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 - dev: true - - /text-table/0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - dev: true - - /through/2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true - - /through2/2.0.5: - resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} - dependencies: - readable-stream: 2.3.7 - xtend: 4.0.2 - dev: true - - /time-stamp/1.1.0: - resolution: {integrity: sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==} - engines: {node: '>=0.10.0'} - dev: true - - /tiny-inflate/1.0.3: - resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} - dev: true - - /tmp-promise/3.0.3: - resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} - dependencies: - tmp: 0.2.1 - dev: false - - /tmp/0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - dependencies: - os-tmpdir: 1.0.2 - dev: true - - /tmp/0.2.1: - resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} - engines: {node: '>=8.17.0'} - dependencies: - rimraf: 3.0.2 - dev: false - - /tmpl/1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - dev: true - - /to-fast-properties/2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - dev: true - - /to-regex-range/5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - dependencies: - is-number: 7.0.0 - dev: true - - /toidentifier/1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - /tough-cookie/2.5.0: - resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} - engines: {node: '>=0.8'} - dependencies: - psl: 1.9.0 - punycode: 2.1.1 - dev: false - - /tr46/0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - /tr46/3.0.0: - resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} - engines: {node: '>=12'} - dependencies: - punycode: 2.1.1 - dev: false - - /traverse/0.6.7: - resolution: {integrity: sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==} - dev: true - - /tree-kill/1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} - hasBin: true - dev: true - - /ts-jest/28.0.8_l4uz7kl2eeclic7mumfbeqbwgi: - resolution: {integrity: sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - hasBin: true - peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/types': ^28.0.0 - babel-jest: ^28.0.0 - esbuild: '*' - jest: ^28.0.0 - typescript: '>=4.3' - peerDependenciesMeta: - '@babel/core': - optional: true - '@jest/types': - optional: true - babel-jest: - optional: true - esbuild: - optional: true - dependencies: - bs-logger: 0.2.6 - fast-json-stable-stringify: 2.1.0 - jest: 28.1.3_dnlfjp7n5lpfgnj4digwzn5fhe - jest-util: 28.1.3 - json5: 2.2.1 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.3.8 - typescript: 4.9.3 - yargs-parser: 21.1.1 - dev: true - - /ts-loader/9.4.1_typescript@4.9.3: - resolution: {integrity: sha512-384TYAqGs70rn9F0VBnh6BPTfhga7yFNdC5gXbQpDrBj9/KsT4iRkGqKXhziofHOlE2j6YEaiTYVGKKvPhGWvw==} - engines: {node: '>=12.0.0'} - peerDependencies: - typescript: '*' - webpack: ^5.0.0 - dependencies: - chalk: 4.1.2 - enhanced-resolve: 5.12.0 - micromatch: 4.0.5 - semver: 7.3.8 - typescript: 4.9.3 - dev: true - - /ts-morph/13.0.3: - resolution: {integrity: sha512-pSOfUMx8Ld/WUreoSzvMFQG5i9uEiWIsBYjpU9+TTASOeUa89j5HykomeqVULm1oqWtBdleI3KEFRLrlA3zGIw==} - dependencies: - '@ts-morph/common': 0.12.3 - code-block-writer: 11.0.3 - dev: true - - /ts-node/10.9.1_fvpuwgkpfe3dm3hnpcpbcxmb3y: - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.3 - '@types/node': 16.18.3 - acorn: 8.8.1 - acorn-walk: 8.2.0 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 4.9.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - - /tsconfig-paths-webpack-plugin/4.0.0: - resolution: {integrity: sha512-fw/7265mIWukrSHd0i+wSwx64kYUSAKPfxRDksjKIYTxSAp9W9/xcZVBF4Kl0eqQd5eBpAQ/oQrc5RyM/0c1GQ==} - engines: {node: '>=10.13.0'} - dependencies: - chalk: 4.1.2 - enhanced-resolve: 5.12.0 - tsconfig-paths: 4.1.0 - dev: true - - /tsconfig-paths/4.1.0: - resolution: {integrity: sha512-AHx4Euop/dXFC+Vx589alFba8QItjF+8hf8LtmuiCwHyI4rHXQtOOENaM8kvYf5fR0dRChy3wzWIZ9WbB7FWow==} - engines: {node: '>=6'} - dependencies: - json5: 2.2.1 - minimist: 1.2.7 - strip-bom: 3.0.0 - dev: true - - /tslib/1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - - /tslib/2.4.1: - resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} - - /tsutils/3.21.0_typescript@4.9.3: - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - 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' - dependencies: - tslib: 1.14.1 - typescript: 4.9.3 - dev: true - - /tunnel-agent/0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - dependencies: - safe-buffer: 5.2.1 - dev: false - - /tweetnacl/0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} - dev: false - - /type-check/0.3.2: - resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.1.2 - dev: true - - /type-check/0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - dev: true - - /type-detect/4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - dev: true - - /type-fest/0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - - /type-fest/0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - dev: true - - /type-is/1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - - /type/1.2.0: - resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} - dev: true - - /type/2.7.2: - resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} - dev: true - - /typedarray/0.0.6: - resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - - /typescript/4.8.4: - resolution: {integrity: sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: true - - /typescript/4.9.3: - resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: true - - /uglify-js/3.17.4: - resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} - engines: {node: '>=0.8.0'} - hasBin: true - requiresBuild: true - dev: true - optional: true - - /underscore/1.13.6: - resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} - dev: false - - /unicode-canonical-property-names-ecmascript/2.0.0: - resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} - engines: {node: '>=4'} - dev: true - - /unicode-match-property-ecmascript/2.0.0: - resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} - engines: {node: '>=4'} - dependencies: - unicode-canonical-property-names-ecmascript: 2.0.0 - unicode-property-aliases-ecmascript: 2.1.0 - dev: true - - /unicode-match-property-value-ecmascript/2.1.0: - resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} - engines: {node: '>=4'} - dev: true - - /unicode-properties/1.4.1: - resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} - dependencies: - base64-js: 1.5.1 - unicode-trie: 2.0.0 - dev: true - - /unicode-property-aliases-ecmascript/2.1.0: - resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} - engines: {node: '>=4'} - dev: true - - /unicode-trie/2.0.0: - resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} - dependencies: - pako: 0.2.9 - tiny-inflate: 1.0.3 - dev: true - - /universalify/2.0.0: - resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} - engines: {node: '>= 10.0.0'} - dev: true - - /unix-crypt-td-js/1.1.4: - resolution: {integrity: sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==} - dev: true - - /unpipe/1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - /update-browserslist-db/1.0.10_browserslist@4.21.4: - resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.21.4 - escalade: 3.1.1 - picocolors: 1.0.0 - dev: true - - /uri-js/4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - dependencies: - punycode: 2.1.1 - - /util-deprecate/1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - /utils-merge/1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - - /uuid/3.4.0: - resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} - deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. - hasBin: true - dev: false - - /uuid/8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - - /uuid/9.0.0: - resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} - hasBin: true - - /v8-compile-cache-lib/3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true - - /v8-to-istanbul/9.0.1: - resolution: {integrity: sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==} - engines: {node: '>=10.12.0'} - dependencies: - '@jridgewell/trace-mapping': 0.3.17 - '@types/istanbul-lib-coverage': 2.0.4 - convert-source-map: 1.9.0 - dev: true - - /validator/13.7.0: - resolution: {integrity: sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==} - engines: {node: '>= 0.10'} - - /vary/1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - - /verror/1.10.0: - resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - engines: {'0': node >=0.6.0} - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - dev: false - - /walker/1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - dependencies: - makeerror: 1.0.12 - dev: true - - /watchpack/2.4.0: - resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} - engines: {node: '>=10.13.0'} - dependencies: - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.10 - dev: true - - /wcwidth/1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - dependencies: - defaults: 1.0.4 - dev: true - - /web-streams-polyfill/3.2.1: - resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} - engines: {node: '>= 8'} - dev: true - - /webidl-conversions/3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - /webidl-conversions/7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} - dev: false - - /webpack-node-externals/3.0.0: - resolution: {integrity: sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==} - engines: {node: '>=6'} - dev: true - - /webpack-sources/3.2.3: - resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} - engines: {node: '>=10.13.0'} - dev: true - - /webpack/5.74.0: - resolution: {integrity: sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - dependencies: - '@types/eslint-scope': 3.7.4 - '@types/estree': 0.0.51 - '@webassemblyjs/ast': 1.11.1 - '@webassemblyjs/wasm-edit': 1.11.1 - '@webassemblyjs/wasm-parser': 1.11.1 - acorn: 8.8.1 - acorn-import-assertions: 1.8.0_acorn@8.8.1 - browserslist: 4.21.4 - chrome-trace-event: 1.0.3 - enhanced-resolve: 5.12.0 - es-module-lexer: 0.9.3 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.10 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.1.1 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.6_webpack@5.74.0 - watchpack: 2.4.0 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - dev: true - - /websocket-driver/0.7.4: - resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} - engines: {node: '>=0.8.0'} - dependencies: - http-parser-js: 0.5.8 - safe-buffer: 5.2.1 - websocket-extensions: 0.1.4 - dev: true - - /websocket-extensions/0.1.4: - resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} - engines: {node: '>=0.8.0'} - dev: true - - /whatwg-url/11.0.0: - resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} - engines: {node: '>=12'} - dependencies: - tr46: 3.0.0 - webidl-conversions: 7.0.0 - dev: false - - /whatwg-url/5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - /which/2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - dependencies: - isexe: 2.0.0 - - /widest-line/3.1.0: - resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} - engines: {node: '>=8'} - dependencies: - string-width: 4.2.3 - dev: false - - /windows-release/4.0.0: - resolution: {integrity: sha512-OxmV4wzDKB1x7AZaZgXMVsdJ1qER1ed83ZrTYd5Bwq2HfJVg3DJS8nqlAG4sMoJ7mu8cuRmLEYyU13BKwctRAg==} - engines: {node: '>=10'} - dependencies: - execa: 4.1.0 - dev: true - - /word-wrap/1.2.3: - resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} - engines: {node: '>=0.10.0'} - dev: true - - /wordwrap/1.0.0: - resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - dev: true - - /wrap-ansi/7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - /wrappy/1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - /write-file-atomic/4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - dev: true - - /ws/7.5.9: - resolution: {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 - dev: false - - /xmldoc/1.2.0: - resolution: {integrity: sha512-2eN8QhjBsMW2uVj7JHLHkMytpvGHLHxKXBy4J3fAT/HujsEtM6yU84iGjpESYGHg6XwK0Vu4l+KgqQ2dv2cCqg==} - dependencies: - sax: 1.2.4 - dev: true - - /xtend/4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - - /y18n/5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: true - - /yallist/4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - /yaml/1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} - engines: {node: '>= 6'} - dev: true - - /yargs-parser/21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - dev: true - - /yargs/17.6.2: - resolution: {integrity: sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==} - engines: {node: '>=12'} - dependencies: - cliui: 8.0.1 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - dev: true - - /yn/3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - dev: true - - /yocto-queue/0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - dev: true diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma index 988131688f..29503c2ace 100644 --- a/server/prisma/schema.prisma +++ b/server/prisma/schema.prisma @@ -1,10 +1,36 @@ // This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema +// These models cover multiple aspects, such as subscriptions, accounts, applications, +// storage, databases, cloud functions, gateways, and SMS verification codes. +// Here's a brief description: +// +// 1. Subscription models (Subscription and SubscriptionRenewal): Represent the state +// and plans of subscriptions and their renewals. +// 2. Account models (Account and AccountChargeOrder): Track account balances and +// recharge records. +// 3. Application models (Application and ApplicationConfiguration): Represent +// application configurations and states. +// 4. Storage models (StorageUser and StorageBucket): Represent the state and policies +// of storage users and buckets. +// 5. Database models (Database, DatabasePolicy, and DatabasePolicyRule): Represent the +// state, policies, and rules of databases. +// 6. Cloud Function models (CloudFunction and CronTrigger): Represent the configuration +// and state of cloud functions and scheduled triggers. +// 7. Gateway models (RuntimeDomain, BucketDomain, and WebsiteHosting): Represent the +// state and configuration of runtime domains, bucket domains, and website hosting. +// 8. Authentication provider models (AuthProvider): Represent the configuration and state +// of authentication providers. +// 9. SMS verification code models (SmsVerifyCode): Represent the type, state, and +// related information of SMS verification codes. +// +// These models together form a complete cloud service system, covering subscription +// management, account management, application deployment, storage management, database +// management, cloud function deployment and execution, gateway configuration, and SMS +// verification, among other functionalities. + generator client { provider = "prisma-client-js" - // previewFeatures = ["interactiveTransactions"] - // binaryTargets = ["native", "linux-arm64-openssl-1.1.x"] binaryTargets = ["native"] } @@ -13,6 +39,21 @@ datasource db { url = env("DATABASE_URL") } +enum NoteLevel { + Info + Warning + Danger + Error +} + +type Note { + title String? + content String? + link String? + lang String? + level NoteLevel @default(Info) +} + // user schemas model User { @@ -27,11 +68,21 @@ model User { personalAccessTokens PersonalAccessToken[] } +model UserPassword { + id String @id @default(auto()) @map("_id") @db.ObjectId + uid String @db.ObjectId + password String + state String @default("Active") // Active, Inactive + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + model UserProfile { id String @id @default(auto()) @map("_id") @db.ObjectId uid String @unique @db.ObjectId openid String? from String? + openData Json? avatar String? name String? createdAt DateTime @default(now()) @@ -51,7 +102,7 @@ model PersonalAccessToken { user User @relation(fields: [uid], references: [id]) } -// region schemas +// region schemas type RegionClusterConf { driver String // kubernetes @@ -59,8 +110,9 @@ type RegionClusterConf { } type RegionDatabaseConf { - driver String // mongodb - connectionUri String + driver String // mongodb + connectionUri String + controlConnectionUri String } type RegionGatewayConf { @@ -79,6 +131,7 @@ type RegionStorageConf { internalEndpoint String accessKey String secretKey String + controlEndpoint String } model Region { @@ -92,6 +145,8 @@ model Region { tls Boolean @default(false) state String @default("Active") // Active, Inactive + notes Note[] + createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@ -109,27 +164,41 @@ type BundleResource { storageCapacity Int // in MB networkTrafficOutbound Int // in MB - limitCountPerUser Int // limit count of application per user could create limitCountOfCloudFunction Int // limit count of cloud function per application limitCountOfBucket Int // limit count of bucket per application limitCountOfDatabasePolicy Int // limit count of database policy per application limitCountOfTrigger Int // limit count of trigger per application limitCountOfWebsiteHosting Int // limit count of website hosting per application + reservedTimeAfterExpired Int // in seconds limitDatabaseTPS Int // limit count of database TPS per application limitStorageTPS Int // limit count of storage TPS per application } -model Bundle { - id String @id @default(auto()) @map("_id") @db.ObjectId +type BundleSubscriptionOption { name String displayName String - regionId String @db.ObjectId - resource BundleResource - priority Int @default(0) - state String @default("Active") // Active, Inactive - price Int @default(0) - specialPrice Int @default(0) + duration Int // in seconds + price Int + specialPrice Int +} + +model Bundle { + id String @id @default(auto()) @map("_id") @db.ObjectId + name String + displayName String + regionId String @db.ObjectId + priority Int @default(0) + state String @default("Active") // Active, Inactive + limitCountPerUser Int // limit count of application per user could create + subscriptionOptions BundleSubscriptionOption[] + maxRenewalTime Int // in seconds + + resource BundleResource + notes Note[] + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt region Region @relation(fields: [regionId], references: [id]) @@ -137,14 +206,12 @@ model Bundle { } model ApplicationBundle { - id String @id @default(auto()) @map("_id") @db.ObjectId - appid String @unique - bundleId String @db.ObjectId - name String - displayName String - resource BundleResource - price Int @default(0) - specialPrice Int @default(0) + id String @id @default(auto()) @map("_id") @db.ObjectId + appid String @unique + bundleId String @db.ObjectId + name String + displayName String + resource BundleResource createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@ -169,6 +236,169 @@ model Runtime { Application Application[] } +// subscriptions schemas + +// Subscription section mainly consists of two models: Subscription and SubscriptionRenewal. +// +// 1. Subscription: Represents the state, phase, and renewal plan of a subscription. It includes +// the created, updated, and deleted states (SubscriptionState enum); the pending, valid, expired, +// expired and stopped, and deleted phases (SubscriptionPhase enum); and manual, monthly, or +// yearly renewal plans (SubscriptionRenewalPlan enum). This model also contains the associated +// application (Application). +// +// 2. SubscriptionRenewal: Represents the state, duration, and amount of a subscription renewal. +// It includes the pending, paid, and failed renewal phases (SubscriptionRenewalPhase enum). + +enum SubscriptionState { + Created + Deleted +} + +enum SubscriptionPhase { + Pending + Valid + Expired + ExpiredAndStopped + Deleted +} + +enum SubscriptionRenewalPlan { + Manual + Monthly + Yearly +} + +type SubscriptionApplicationCreateInput { + name String + state String + runtimeId String + regionId String +} + +model Subscription { + id String @id @default(auto()) @map("_id") @db.ObjectId + input SubscriptionApplicationCreateInput + bundleId String @db.ObjectId + appid String @unique + state SubscriptionState @default(Created) + phase SubscriptionPhase @default(Pending) + renewalPlan SubscriptionRenewalPlan @default(Manual) + expiredAt DateTime + lockedAt DateTime + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + createdBy String @db.ObjectId + + application Application? +} + +enum SubscriptionRenewalPhase { + Pending + Paid + Failed +} + +model SubscriptionRenewal { + id String @id @default(auto()) @map("_id") @db.ObjectId + subscriptionId String @db.ObjectId + duration Int // in seconds + amount Int + phase SubscriptionRenewalPhase @default(Pending) + message String? + lockedAt DateTime + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + createdBy String @db.ObjectId +} + +// desired state of resource +enum SubscriptionUpgradePhase { + Pending + Completed + Failed +} + +model SubscriptionUpgrade { + id String @id @default(auto()) @map("_id") @db.ObjectId + appid String + subscriptionId String + originalBundleId String @db.ObjectId + targetBundleId String @db.ObjectId + phase SubscriptionUpgradePhase @default(Pending) + restart Boolean @default(false) + message String? + lockedAt DateTime + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +// accounts schemas + +model Account { + id String @id @default(auto()) @map("_id") @db.ObjectId + balance Int @default(0) + state String @default("Active") // Active, Inactive + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + createdBy String @unique @db.ObjectId +} + +model AccountTransaction { + id String @id @default(auto()) @map("_id") @db.ObjectId + accountId String @db.ObjectId + amount Int + balance Int + message String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +enum AccountChargePhase { + Pending + Paid + Failed +} + +enum Currency { + CNY + USD +} + +model AccountChargeOrder { + id String @id @default(auto()) @map("_id") @db.ObjectId + accountId String @db.ObjectId + amount Int + currency Currency + phase AccountChargePhase @default(Pending) + channel PaymentChannelType + result Json? + message String? + createdAt DateTime @default(now()) + lockedAt DateTime + updatedAt DateTime @updatedAt + createdBy String @db.ObjectId +} + +enum PaymentChannelType { + Manual + Alipay + WeChat + Stripe + Paypal + Google +} + +model PaymentChannel { + id String @id @default(auto()) @map("_id") @db.ObjectId + type PaymentChannelType + name String + spec Json + state String @default("Active") // Active, Inactive + notes Note[] + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + // application schemas // desired state of application @@ -213,6 +443,7 @@ model Application { database Database? domain RuntimeDomain? bundle ApplicationBundle? + subscription Subscription @relation(fields: [appid], references: [appid]) } type EnvironmentVariable { @@ -367,6 +598,7 @@ model CloudFunction { desc String tags String[] methods HttpMethod[] + params Json? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt createdBy String @db.ObjectId @@ -443,9 +675,9 @@ model BucketDomain { domain String @unique state DomainState @default(Active) phase DomainPhase @default(Creating) + lockedAt DateTime createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - lockedAt DateTime bucket StorageBucket @relation(fields: [bucketName], references: [name]) } @@ -464,3 +696,42 @@ model WebsiteHosting { bucket StorageBucket @relation(fields: [bucketName], references: [name]) } + +enum AuthProviderState { + Enabled + Disabled +} + +model AuthProvider { + id String @id @default(auto()) @map("_id") @db.ObjectId + name String @unique + bind Json + register Boolean + default Boolean + state AuthProviderState + config Json + notes Note[] + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +// Sms schemas +enum SmsVerifyCodeType { + Signin + Signup + ResetPassword + Bind + Unbind + ChangePhone +} + +model SmsVerifyCode { + id String @id @default(auto()) @map("_id") @db.ObjectId + phone String + code String + ip String + type SmsVerifyCodeType + state Int @default(0) // 0: created, 1: used + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/server/src/account/account.controller.ts b/server/src/account/account.controller.ts new file mode 100644 index 0000000000..920de193b9 --- /dev/null +++ b/server/src/account/account.controller.ts @@ -0,0 +1,195 @@ +import { + Body, + Controller, + Get, + Logger, + Param, + Post, + Req, + Res, + UseGuards, +} from '@nestjs/common' +import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger' +import { AccountChargePhase } from '@prisma/client' +import { JwtAuthGuard } from 'src/auth/jwt.auth.guard' +import { PrismaService } from 'src/prisma/prisma.service' +import { IRequest } from 'src/utils/interface' +import { ResponseUtil } from 'src/utils/response' +import { AccountService } from './account.service' +import { CreateChargeOrderDto } from './dto/create-charge-order.dto' +import { PaymentChannelService } from './payment/payment-channel.service' +import { WeChatPayOrderResponse, WeChatPayTradeState } from './payment/types' +import { WeChatPayService } from './payment/wechat-pay.service' +import { Response } from 'express' +import * as assert from 'assert' +import { ServerConfig } from 'src/constants' + +@ApiTags('Account') +@Controller('accounts') +@ApiBearerAuth('Authorization') +export class AccountController { + private readonly logger = new Logger(AccountController.name) + + constructor( + private readonly accountService: AccountService, + private readonly paymentService: PaymentChannelService, + private readonly wechatPayService: WeChatPayService, + private readonly prisma: PrismaService, + ) {} + + /** + * Get account info + */ + @ApiOperation({ summary: 'Get account info' }) + @UseGuards(JwtAuthGuard) + @Get() + async findOne(@Req() req: IRequest) { + const user = req.user + const data = await this.accountService.findOne(user.id) + return data + } + + /** + * Get charge order + */ + @ApiOperation({ summary: 'Get charge order' }) + @UseGuards(JwtAuthGuard) + @Get('charge-order/:id') + async getChargeOrder(@Req() req: IRequest, @Param('id') id: string) { + const user = req.user + const data = await this.accountService.findOneChargeOrder(user.id, id) + return data + } + + /** + * Create charge order + */ + @ApiOperation({ summary: 'Create charge order' }) + @UseGuards(JwtAuthGuard) + @Post('charge-order') + async charge(@Req() req: IRequest, @Body() dto: CreateChargeOrderDto) { + const user = req.user + const { amount, currency, channel } = dto + + // create charge order + const order = await this.accountService.createChargeOrder( + user.id, + amount, + currency, + channel, + ) + + // invoke payment + const result = await this.accountService.pay( + channel, + order.id, + amount, + currency, + `${ServerConfig.SITE_NAME} recharge`, + ) + + return ResponseUtil.ok({ + order, + result, + }) + } + + /** + * WeChat payment notify + */ + @Post('payment/wechat-notify') + async wechatNotify(@Req() req: IRequest, @Res() res: Response) { + try { + // get headers + const headers = req.headers + const nonce = headers['wechatpay-nonce'] as string + const timestamp = headers['wechatpay-timestamp'] as string + const signature = headers['wechatpay-signature'] as string + const serial = headers['wechatpay-serial'] as string + + // get body + const body = req.body as WeChatPayOrderResponse + + const spec = await this.paymentService.getWeChatPaySpec() + const result = await this.wechatPayService.getWeChatPayNotifyResult( + spec, + { + timestamp, + nonce, + body, + serial, + signature, + }, + ) + + this.logger.debug(result) + + const tradeOrderId = result.out_trade_no + if (result.trade_state !== WeChatPayTradeState.SUCCESS) { + await this.prisma.accountChargeOrder.update({ + where: { id: tradeOrderId }, + data: { + phase: AccountChargePhase.Failed, + result: result as any, + }, + }) + this.logger.log( + `wechatpay order failed: ${tradeOrderId} ${result.trade_state}`, + ) + return res.status(200).send() + } + + // start transaction + await this.prisma.$transaction(async (tx) => { + // get order + const order = await tx.accountChargeOrder.findFirst({ + where: { id: tradeOrderId, phase: AccountChargePhase.Pending }, + }) + if (!order) { + this.logger.error(`wechatpay order not found: ${tradeOrderId}`) + return + } + + // update order to success + const res = await tx.accountChargeOrder.updateMany({ + where: { id: tradeOrderId, phase: AccountChargePhase.Pending }, + data: { phase: AccountChargePhase.Paid, result: result as any }, + }) + + if (res.count === 0) { + this.logger.error(`wechatpay order not found: ${tradeOrderId}`) + return + } + + // get account + const account = await tx.account.findFirst({ + where: { id: order.accountId }, + }) + assert(account, `account not found ${order.accountId}`) + + // update account balance + await tx.account.update({ + where: { id: order.accountId }, + data: { balance: { increment: order.amount } }, + }) + + // create account transaction + await tx.accountTransaction.create({ + data: { + accountId: order.accountId, + amount: order.amount, + balance: order.amount + account.balance, + message: 'account charge', + }, + }) + + this.logger.log(`wechatpay order success: ${tradeOrderId}`) + }) + } catch (err) { + this.logger.error(err) + return res.status(400).send({ code: 'FAIL', message: 'ERROR' }) + } + + return res.status(200).send() + } +} diff --git a/server/src/account/account.module.ts b/server/src/account/account.module.ts new file mode 100644 index 0000000000..ef3b3b4b78 --- /dev/null +++ b/server/src/account/account.module.ts @@ -0,0 +1,14 @@ +import { Module } from '@nestjs/common' +import { AccountService } from './account.service' +import { AccountController } from './account.controller' +import { WeChatPayService } from './payment/wechat-pay.service' +import { PaymentChannelService } from './payment/payment-channel.service' +import { HttpModule } from '@nestjs/axios' + +@Module({ + imports: [HttpModule], + providers: [AccountService, WeChatPayService, PaymentChannelService], + controllers: [AccountController], + exports: [WeChatPayService, AccountService, PaymentChannelService], +}) +export class AccountModule {} diff --git a/server/src/account/account.service.ts b/server/src/account/account.service.ts new file mode 100644 index 0000000000..affb080c52 --- /dev/null +++ b/server/src/account/account.service.ts @@ -0,0 +1,105 @@ +import { Injectable, Logger } from '@nestjs/common' +import { PrismaService } from 'src/prisma/prisma.service' +import * as assert from 'assert' +import { + AccountChargePhase, + Currency, + PaymentChannelType, +} from '@prisma/client' +import { WeChatPayService } from './payment/wechat-pay.service' +import { PaymentChannelService } from './payment/payment-channel.service' +import { TASK_LOCK_INIT_TIME } from 'src/constants' + +@Injectable() +export class AccountService { + private readonly logger = new Logger(AccountService.name) + + constructor( + private readonly prisma: PrismaService, + private readonly wechatPayService: WeChatPayService, + private readonly chanelService: PaymentChannelService, + ) {} + + async create(userid: string) { + const account = await this.prisma.account.create({ + data: { + balance: 0, + createdBy: userid, + }, + }) + + return account + } + + async findOne(userid: string) { + const account = await this.prisma.account.findUnique({ + where: { createdBy: userid }, + }) + + if (account) { + return account + } + + return this.create(userid) + } + + async createChargeOrder( + userid: string, + amount: number, + currency: Currency, + channel: PaymentChannelType, + ) { + const account = await this.findOne(userid) + assert(account, 'Account not found') + + // create charge order + const order = await this.prisma.accountChargeOrder.create({ + data: { + accountId: account.id, + amount, + currency: currency, + phase: AccountChargePhase.Pending, + channel: channel, + createdBy: userid, + lockedAt: TASK_LOCK_INIT_TIME, + }, + }) + + return order + } + + async findOneChargeOrder(userid: string, id: string) { + const order = await this.prisma.accountChargeOrder.findFirst({ + where: { id, createdBy: userid }, + }) + + return order + } + + async pay( + channel: PaymentChannelType, + orderNumber: string, + amount: number, + currency: Currency, + description = 'laf account charge', + ) { + // webchat pay + if (channel === PaymentChannelType.WeChat) { + const spec = await this.chanelService.getWeChatPaySpec() + const result = await this.wechatPayService.send(spec, { + mchid: spec.mchid, + appid: spec.appid, + description, + out_trade_no: orderNumber, + notify_url: this.wechatPayService.getNotifyUrl(), + amount: { + total: amount, + currency: currency, + }, + }) + return result + } + + throw new Error('Unsupported payment channel') + } +} diff --git a/server/src/account/dto/create-charge-order.dto.ts b/server/src/account/dto/create-charge-order.dto.ts new file mode 100644 index 0000000000..91be6e7c3f --- /dev/null +++ b/server/src/account/dto/create-charge-order.dto.ts @@ -0,0 +1,22 @@ +import { ApiProperty } from '@nestjs/swagger' +import { Currency, PaymentChannelType } from '@prisma/client' +import { IsEnum, IsInt, IsPositive, IsString, Max, Min } from 'class-validator' + +export class CreateChargeOrderDto { + @ApiProperty({ example: 1000 }) + @IsPositive() + @IsInt() + @Min(1) + @Max(1000000000) + amount: number + + @ApiProperty({ example: PaymentChannelType.WeChat }) + @IsString() + @IsEnum(PaymentChannelType) + channel: PaymentChannelType + + @ApiProperty({ example: Currency.CNY }) + @IsString() + @IsEnum(Currency) + currency: Currency +} diff --git a/server/src/account/payment/payment-channel.service.ts b/server/src/account/payment/payment-channel.service.ts new file mode 100644 index 0000000000..d94eafd0f5 --- /dev/null +++ b/server/src/account/payment/payment-channel.service.ts @@ -0,0 +1,47 @@ +import { Injectable, Logger } from '@nestjs/common' +import { PaymentChannelType } from '@prisma/client' +import { PrismaService } from 'src/prisma/prisma.service' +import { WeChatPaySpec } from './types' + +@Injectable() +export class PaymentChannelService { + private readonly logger = new Logger(PaymentChannelService.name) + + constructor(private readonly prisma: PrismaService) {} + + /** + * Get all payment channels + * @returns + */ + async findAll() { + const res = await this.prisma.paymentChannel.findMany({ + where: { + state: 'Inactive', + }, + select: { + id: true, + type: true, + name: true, + state: true, + /** + * Security Warning: DO NOT response sensitive information to client. + * KEEP IT false! + */ + spec: false, + }, + }) + return res + } + + async getWeChatPaySpec(): Promise { + const res = await this.prisma.paymentChannel.findFirst({ + where: { type: PaymentChannelType.WeChat }, + }) + + if (!res) { + throw new Error('No WeChat Pay channel found') + } + + return res.spec as any + } +} diff --git a/server/src/account/payment/types.ts b/server/src/account/payment/types.ts new file mode 100644 index 0000000000..d3bc9aa6b8 --- /dev/null +++ b/server/src/account/payment/types.ts @@ -0,0 +1,65 @@ +export interface WeChatPaySpec { + mchid: string + appid: string + apiV3Key: string + certificateSerialNumber: string + publicKey: string + privateKey: string +} + +export interface WeChatPayOrder { + mchid: string + appid: string + description: string + out_trade_no: string + notify_url: string + amount: { + total: number + currency: string + } +} + +export interface WeChatPayOrderResponse { + id: string + create_time: string + resource_type: string + event_type: string + summary: string + resource: { + original_type: string + algorithm: string + ciphertext: string + associated_data: string + nonce: string + } +} + +export enum WeChatPayTradeState { + SUCCESS = 'SUCCESS', + REFUND = 'REFUND', + NOTPAY = 'NOTPAY', + CLOSED = 'CLOSED', + REVOKED = 'REVOKED', + USERPAYING = 'USERPAYING', + PAYERROR = 'PAYERROR', +} + +export interface WeChatPayDecryptedResult { + mchid: string + appid: string + out_trade_no: string + transaction_id: string + trade_type: string + trade_state: WeChatPayTradeState + trade_state_desc: string + bank_type: string + attach: string + success_time: string + payer: { openid: string } + amount: { + total: number + payer_total: number + currency: string + payer_currency: string + } +} diff --git a/server/src/account/payment/wechat-pay.service.ts b/server/src/account/payment/wechat-pay.service.ts new file mode 100644 index 0000000000..5a7afcbc10 --- /dev/null +++ b/server/src/account/payment/wechat-pay.service.ts @@ -0,0 +1,133 @@ +import { Injectable } from '@nestjs/common' +import { + WeChatPaySpec, + WeChatPayOrder, + WeChatPayOrderResponse, + WeChatPayDecryptedResult, +} from './types' +import * as crypto from 'crypto' +import { HttpService } from '@nestjs/axios' +import { ServerConfig } from 'src/constants' +// import * as WxPay from 'wechatpay-node-v3' +// eslint-disable-next-line @typescript-eslint/no-var-requires +const WxPay = require('wechatpay-node-v3') + +@Injectable() +export class WeChatPayService { + static readonly API_BASE_URL = 'https://api.mch.weixin.qq.com' + + constructor(private readonly httpService: HttpService) {} + + async send(spec: WeChatPaySpec, order: WeChatPayOrder) { + // sign the order + const timestamp = Math.floor(Date.now() / 1000) + const nonceStr = crypto.randomUUID() + const method = 'POST' + const apiUrl = '/v3/pay/transactions/native' + const signature = this.createSign( + spec, + method, + apiUrl, + timestamp, + nonceStr, + order, + ) + + // send the request + const serialNo = spec.certificateSerialNumber + const token = `WECHATPAY2-SHA256-RSA2048 mchid="${spec.mchid}",nonce_str="${nonceStr}",timestamp="${timestamp}",signature="${signature}",serial_no="${serialNo}"` + const fullUrl = `${WeChatPayService.API_BASE_URL}${apiUrl}` + const res = await this.httpService.axiosRef.post(fullUrl, order, { + headers: { Authorization: token }, + }) + + return res.data + } + + private createSign( + spec: WeChatPaySpec, + method: string, + url: string, + timestamp: number, + nonceStr: string, + order: WeChatPayOrder, + ) { + let orderStr = '' + if (method === 'POST' && order) { + orderStr = JSON.stringify(order) + } + const signStr = `${method}\n${url}\n${timestamp}\n${nonceStr}\n${orderStr}\n` + const cert = spec.privateKey + const sign = crypto.createSign('RSA-SHA256') + sign.update(signStr) + return sign.sign(cert, 'base64') + } + + getClient(spec: WeChatPaySpec) { + const client = new WxPay({ + appid: spec.appid, + mchid: spec.mchid, + serial_no: spec.certificateSerialNumber, + key: spec.apiV3Key, + publicKey: Buffer.from(spec.publicKey, 'utf8'), + privateKey: Buffer.from(spec.privateKey, 'utf8'), + }) + + return client + } + + async getWeChatPayNotifyResult( + spec: WeChatPaySpec, + params: { + timestamp: string | number + nonce: string + body: WeChatPayOrderResponse + serial: string + signature: string + }, + ) { + const valid = await this.verifyNotify(spec, params) + if (!valid) { + throw new Error('Invalid wechat pay notify') + } + + const resource = params.body.resource + const result = this.decryptNotify( + spec, + resource.ciphertext, + resource.associated_data, + resource.nonce, + ) + + return result as WeChatPayDecryptedResult + } + + async verifyNotify( + spec: WeChatPaySpec, + params: { + timestamp: string | number + nonce: string + body: string | Record + serial: string + signature: string + }, + ) { + const client = this.getClient(spec) + return await client.verifySign(params) + } + + decryptNotify( + spec: WeChatPaySpec, + ciphertext: string, + associated_data: string, + nonce: string, + ) { + const client = this.getClient(spec) + return client.decipher_gcm(ciphertext, associated_data, nonce) + } + + getNotifyUrl() { + const apiUrl = ServerConfig.API_SERVER_URL + return `${apiUrl}/v1/accounts/payment/wechat-notify` + } +} diff --git a/server/src/app.module.ts b/server/src/app.module.ts index 777792ac23..b45d78994e 100644 --- a/server/src/app.module.ts +++ b/server/src/app.module.ts @@ -18,6 +18,8 @@ import { TriggerModule } from './trigger/trigger.module' import { RegionModule } from './region/region.module' import { GatewayModule } from './gateway/gateway.module' import { PrismaModule } from './prisma/prisma.module' +import { SubscriptionModule } from './subscription/subscription.module' +import { AccountModule } from './account/account.module' @Module({ imports: [ @@ -41,6 +43,8 @@ import { PrismaModule } from './prisma/prisma.module' RegionModule, GatewayModule, PrismaModule, + SubscriptionModule, + AccountModule, ], controllers: [AppController], providers: [AppService], diff --git a/server/src/application/application-task.service.ts b/server/src/application/application-task.service.ts index c353ceccac..82bd64f4be 100644 --- a/server/src/application/application-task.service.ts +++ b/server/src/application/application-task.service.ts @@ -51,15 +51,19 @@ export class ApplicationTaskService { } // Phase `Creating` -> `Created` - this.handleCreatingPhase() + this.handleCreatingPhase().catch((err) => { + this.logger.error(err) + }) // Phase `Deleting` -> `Deleted` - this.handleDeletingPhase() + this.handleDeletingPhase().catch((err) => { + this.logger.error(err) + }) // State `Deleted` - this.handleDeletedState() - - this.clearTimeoutLocks() + this.handleDeletedState().catch((err) => { + this.logger.error(err) + }) } /** @@ -78,20 +82,12 @@ export class ApplicationTaskService { .findOneAndUpdate( { phase: ApplicationPhase.Creating, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) - if (!res.value) { - return - } + if (!res.value) return const app = res.value const appid = app.appid @@ -145,11 +141,8 @@ export class ApplicationTaskService { } // update application phase to `Created` - const updated = await db.collection('Application').updateOne( - { - _id: app._id, - phase: ApplicationPhase.Creating, - }, + await db.collection('Application').updateOne( + { _id: app._id, phase: ApplicationPhase.Creating }, { $set: { phase: ApplicationPhase.Created, @@ -157,8 +150,8 @@ export class ApplicationTaskService { }, }, ) - if (updated.modifiedCount > 0) - this.logger.debug('app phase updated to `Created`:', app.appid) + + this.logger.log('app phase updated to `Created`: ' + app.appid) } /** @@ -184,16 +177,11 @@ export class ApplicationTaskService { .findOneAndUpdate( { phase: ApplicationPhase.Deleting, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) + if (!res.value) return // get region by appid @@ -280,11 +268,8 @@ export class ApplicationTaskService { } // update phase to `Deleted` - const updated = await db.collection('Application').updateOne( - { - _id: app._id, - phase: ApplicationPhase.Deleting, - }, + await db.collection('Application').updateOne( + { _id: app._id, phase: ApplicationPhase.Deleting }, { $set: { phase: ApplicationPhase.Deleted, @@ -292,8 +277,8 @@ export class ApplicationTaskService { }, }, ) - if (updated.modifiedCount > 0) - this.logger.debug('app phase updated to `Deleted`:', app.appid) + + this.logger.log('app phase updated to `Deleted`: ' + app.appid) } /** @@ -324,8 +309,7 @@ export class ApplicationTaskService { ) await db.collection('Application').deleteMany({ - // TODO: support reset app or not? keep this line now. - // state: ApplicationState.Deleted, + state: ApplicationState.Deleted, phase: ApplicationPhase.Deleted, }) } @@ -335,35 +319,8 @@ export class ApplicationTaskService { */ async unlock(appid: string) { const db = SystemDatabase.db - await db.collection('Application').updateOne( - { - appid: appid, - }, - { - $set: { - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, - ) - } - - /** - * Clear timeout locks - */ - async clearTimeoutLocks() { - const db = SystemDatabase.db - - await db.collection('Application').updateMany( - { - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, - ) + await db + .collection('Application') + .updateOne({ appid: appid }, { $set: { lockedAt: TASK_LOCK_INIT_TIME } }) } } diff --git a/server/src/application/application.controller.ts b/server/src/application/application.controller.ts index a97f93db27..683d9dc91e 100644 --- a/server/src/application/application.controller.ts +++ b/server/src/application/application.controller.ts @@ -1,87 +1,38 @@ import { Controller, Get, - Post, Body, Patch, Param, - Delete, UseGuards, Req, Logger, } from '@nestjs/common' -import { - ApiBearerAuth, - ApiOperation, - ApiResponse, - ApiTags, -} from '@nestjs/swagger' +import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger' import { IRequest } from '../utils/interface' import { JwtAuthGuard } from '../auth/jwt.auth.guard' import { ResponseUtil } from '../utils/response' import { ApplicationAuthGuard } from '../auth/application.auth.guard' -import { CreateApplicationDto } from './dto/create-application.dto' import { UpdateApplicationDto } from './dto/update-application.dto' import { ApplicationService } from './application.service' import { FunctionService } from '../function/function.service' import { StorageService } from 'src/storage/storage.service' import { RegionService } from 'src/region/region.service' -import { BundleService } from 'src/region/bundle.service' -import { PrismaService } from 'src/prisma/prisma.service' +import { SubscriptionPhase } from '@prisma/client' @ApiTags('Application') @Controller('applications') @ApiBearerAuth('Authorization') export class ApplicationController { private logger = new Logger(ApplicationController.name) + constructor( private readonly appService: ApplicationService, private readonly funcService: FunctionService, private readonly regionService: RegionService, private readonly storageService: StorageService, - private readonly bundleService: BundleService, - private readonly prisma: PrismaService, ) {} - /** - * Create application - * @returns - */ - @ApiOperation({ summary: 'Create a new application' }) - @UseGuards(JwtAuthGuard) - @Post() - async create(@Body() dto: CreateApplicationDto, @Req() req: IRequest) { - const user = req.user - const error = dto.validate() - if (error) { - return ResponseUtil.error(error) - } - - // check app count limit - const bundle = await this.bundleService.findOne(dto.bundleId) - const LIMIT_COUNT = bundle?.resource?.limitCountPerUser || 0 - const count = await this.prisma.application.count({ - where: { - createdBy: user.id, - bundle: { - bundleId: dto.bundleId, - }, - }, - }) - if (count >= LIMIT_COUNT) { - return ResponseUtil.error( - `application count limit is ${LIMIT_COUNT} for bundle ${bundle.name}`, - ) - } - - // create app - const app = await this.appService.create(user.id, dto) - if (!app) { - return ResponseUtil.error('create app error') - } - return ResponseUtil.ok(app) - } - /** * Get user application list * @param req @@ -108,9 +59,11 @@ export class ApplicationController { const data = await this.appService.findOne(appid, { configuration: true, domain: true, + subscription: true, }) - // [SECURITY ALERT] Do NOT response this region object to client since it contains sensitive information + // SECURITY ALERT!!! + // DO NOT response this region object to client since it contains sensitive information const region = await this.regionService.findOne(data.regionId) // TODO: remove these storage related code to standalone api @@ -178,6 +131,14 @@ export class ApplicationController { return ResponseUtil.error(error) } + // check if the corresponding subscription status has expired + const app = await this.appService.findOne(appid, { + subscription: true, + }) + if (app.subscription.phase !== SubscriptionPhase.Valid) { + return ResponseUtil.error('subscription has expired, you can not update') + } + // update app const res = await this.appService.update(appid, dto) if (res === null) { @@ -185,22 +146,4 @@ export class ApplicationController { } return ResponseUtil.ok(res) } - - /** - * Delete an application - * @returns - */ - @ApiResponse({ type: ResponseUtil }) - @ApiOperation({ summary: 'Delete an application' }) - @Delete(':appid') - @UseGuards(JwtAuthGuard, ApplicationAuthGuard) - async remove(@Param('appid') appid: string) { - const res = await this.appService.remove(appid) - if (res === null) { - this.logger.error('delete application error') - return ResponseUtil.error('delete application error') - } - - return ResponseUtil.ok(res) - } } diff --git a/server/src/application/application.service.ts b/server/src/application/application.service.ts index 42e4a44f6b..0ac0c946dd 100644 --- a/server/src/application/application.service.ts +++ b/server/src/application/application.service.ts @@ -1,6 +1,5 @@ import { Injectable, Logger } from '@nestjs/common' import * as nanoid from 'nanoid' -import { CreateApplicationDto } from './dto/create-application.dto' import { ApplicationPhase, ApplicationState, Prisma } from '@prisma/client' import { PrismaService } from '../prisma/prisma.service' import { UpdateApplicationDto } from './dto/update-application.dto' @@ -10,13 +9,14 @@ import { TASK_LOCK_INIT_TIME, } from '../constants' import { GenerateAlphaNumericPassword } from '../utils/random' +import { CreateSubscriptionDto } from 'src/subscription/dto/create-subscription.dto' @Injectable() export class ApplicationService { private readonly logger = new Logger(ApplicationService.name) constructor(private readonly prisma: PrismaService) {} - async create(userid: string, dto: CreateApplicationDto) { + async create(userid: string, appid: string, dto: CreateSubscriptionDto) { try { // get bundle const bundle = await this.prisma.bundle.findFirstOrThrow({ @@ -28,16 +28,16 @@ export class ApplicationService { }, }) + console.log(bundle, dto.bundleId) + // create app in db const appSecret = { name: APPLICATION_SECRET_KEY, value: GenerateAlphaNumericPassword(64), } - const appid = await this.tryGenerateUniqueAppid() const data: Prisma.ApplicationCreateInput = { name: dto.name, - appid, state: dto.state || ApplicationState.Running, phase: ApplicationPhase.Creating, tags: [], @@ -53,7 +53,6 @@ export class ApplicationService { bundleId: bundle.id, name: bundle.name, displayName: bundle.displayName, - price: bundle.price, resource: { ...bundle.resource }, }, }, @@ -68,6 +67,11 @@ export class ApplicationService { dependencies: [], }, }, + subscription: { + connect: { + appid, + }, + }, } const application = await this.prisma.application.create({ data }) @@ -90,6 +94,12 @@ export class ApplicationService { not: ApplicationPhase.Deleted, }, }, + include: { + region: false, + bundle: true, + runtime: true, + subscription: true, + }, }) } @@ -102,6 +112,7 @@ export class ApplicationService { runtime: include?.runtime, configuration: include?.configuration, domain: include?.domain, + subscription: include?.subscription, }, }) @@ -141,15 +152,8 @@ export class ApplicationService { async remove(appid: string) { try { const res = await this.prisma.application.updateMany({ - where: { - appid, - phase: { - in: [ApplicationPhase.Started, ApplicationPhase.Stopped], - }, - }, - data: { - state: ApplicationState.Deleted, - }, + where: { appid }, + data: { state: ApplicationState.Deleted }, }) return res diff --git a/server/src/application/configuration.service.ts b/server/src/application/configuration.service.ts index b96789b93f..cc7974b3de 100644 --- a/server/src/application/configuration.service.ts +++ b/server/src/application/configuration.service.ts @@ -1,25 +1,37 @@ import { Injectable, Logger } from '@nestjs/common' +import { ApplicationConfiguration } from '@prisma/client' +import { CN_PUBLISHED_CONF } from 'src/constants' +import { DatabaseService } from 'src/database/database.service' import { PrismaService } from 'src/prisma/prisma.service' @Injectable() export class ApplicationConfigurationService { private readonly logger = new Logger(ApplicationConfigurationService.name) - constructor(private readonly prisma: PrismaService) {} + constructor( + private readonly prisma: PrismaService, + private readonly databaseService: DatabaseService, + ) {} async count(appid: string) { - return this.prisma.applicationConfiguration.count({ - where: { - appid, - }, - }) + return this.prisma.applicationConfiguration.count({ where: { appid } }) } async remove(appid: string) { - return this.prisma.applicationConfiguration.delete({ - where: { - appid, - }, - }) + return this.prisma.applicationConfiguration.delete({ where: { appid } }) + } + + async publish(conf: ApplicationConfiguration) { + const { db, client } = await this.databaseService.findAndConnect(conf.appid) + const session = client.startSession() + try { + await session.withTransaction(async () => { + const coll = db.collection(CN_PUBLISHED_CONF) + await coll.deleteOne({ appid: conf.appid }, { session }) + await coll.insertOne(conf, { session }) + }) + } finally { + await client.close() + } } } diff --git a/server/src/application/dto/create-env.dto.ts b/server/src/application/dto/create-env.dto.ts index 16d5bc24a3..e0150229fc 100644 --- a/server/src/application/dto/create-env.dto.ts +++ b/server/src/application/dto/create-env.dto.ts @@ -1,11 +1,12 @@ import { ApiProperty } from '@nestjs/swagger' -import { IsNotEmpty, IsString, Length } from 'class-validator' +import { IsNotEmpty, IsString, Length, Matches } from 'class-validator' export class CreateEnvironmentDto { @ApiProperty() @IsNotEmpty() @IsString() @Length(1, 64) + @Matches(/^[a-zA-Z_][a-zA-Z0-9_]{1,64}$/) name: string @ApiProperty() diff --git a/server/src/application/environment.controller.ts b/server/src/application/environment.controller.ts index dd64da1128..fb665bfd8d 100644 --- a/server/src/application/environment.controller.ts +++ b/server/src/application/environment.controller.ts @@ -5,11 +5,13 @@ import { Get, Logger, Param, + Patch, Post, UseGuards, } from '@nestjs/common' import { ApiBearerAuth, + ApiBody, ApiOperation, ApiResponse, ApiTags, @@ -29,6 +31,47 @@ export class EnvironmentVariableController { constructor(private readonly confService: EnvironmentVariableService) {} + /** + * Update environment variables (replace all) + * @param appid + * @param dto + * @returns + */ + @ApiResponse({ type: ResponseUtil }) + @ApiOperation({ summary: 'Update environment variables (replace all)' }) + @UseGuards(JwtAuthGuard, ApplicationAuthGuard) + @Post() + @ApiBody({ + type: [CreateEnvironmentDto], + description: 'The environment variables', + }) + async updateAll( + @Param('appid') appid: string, + @Body() dto: CreateEnvironmentDto[], + ) { + // check env name and value (since validation decorator not work if dto is array) + for (const item of dto) { + if (/^[a-zA-Z_][a-zA-Z0-9_]{1,64}$/g.test(item.name) === false) { + return ResponseUtil.error( + 'name must match /^[a-zA-Z_][a-zA-Z0-9_]{1,64}$/ : ' + item.name, + ) + } + + if (item.value.length > 4096) { + return ResponseUtil.error('value must less than 4096: ' + item.name) + } + } + + // app secret can not missing or empty + const secret = dto.find((item) => item.name === APPLICATION_SECRET_KEY) + if (!secret || !secret.value) { + return ResponseUtil.error(APPLICATION_SECRET_KEY + ' can not be empty') + } + + const res = await this.confService.updateAll(appid, dto) + return ResponseUtil.ok(res) + } + /** * Set a environment variable * @param appid @@ -38,14 +81,14 @@ export class EnvironmentVariableController { @ApiResponse({ type: ResponseUtil }) @ApiOperation({ summary: 'Set a environment variable (create/update)' }) @UseGuards(JwtAuthGuard, ApplicationAuthGuard) - @Post() + @Patch() async add(@Param('appid') appid: string, @Body() dto: CreateEnvironmentDto) { // can not set empty app secret if (dto.name === APPLICATION_SECRET_KEY && !dto.value) { return ResponseUtil.error(APPLICATION_SECRET_KEY + ' can not be empty') } - const res = await this.confService.set(appid, dto) + const res = await this.confService.setOne(appid, dto) return ResponseUtil.ok(res) } @@ -59,7 +102,7 @@ export class EnvironmentVariableController { @UseGuards(JwtAuthGuard, ApplicationAuthGuard) @Get() async get(@Param('appid') appid: string) { - const res = await this.confService.find(appid) + const res = await this.confService.findAll(appid) return ResponseUtil.ok(res) } @@ -79,7 +122,7 @@ export class EnvironmentVariableController { return ResponseUtil.error(APPLICATION_SECRET_KEY + ' can not be deleted') } - const res = await this.confService.delete(appid, name) + const res = await this.confService.deleteOne(appid, name) return ResponseUtil.ok(res) } } diff --git a/server/src/application/environment.service.ts b/server/src/application/environment.service.ts index 105f79597e..d837e0cf21 100644 --- a/server/src/application/environment.service.ts +++ b/server/src/application/environment.service.ts @@ -1,20 +1,34 @@ import { Injectable, Logger } from '@nestjs/common' import { PrismaService } from 'src/prisma/prisma.service' import { CreateEnvironmentDto } from './dto/create-env.dto' +import { ApplicationConfigurationService } from './configuration.service' @Injectable() export class EnvironmentVariableService { private readonly logger = new Logger(EnvironmentVariableService.name) - constructor(private readonly prisma: PrismaService) {} + constructor( + private readonly prisma: PrismaService, + private readonly confService: ApplicationConfigurationService, + ) {} + + async updateAll(appid: string, dto: CreateEnvironmentDto[]) { + const res = await this.prisma.applicationConfiguration.update({ + where: { appid }, + data: { environments: { set: dto } }, + }) + + await this.confService.publish(res) + return res.environments + } /** * if exists, update, else create * @param appid * @param dto */ - async set(appid: string, dto: CreateEnvironmentDto) { - const origin = await this.find(appid) + async setOne(appid: string, dto: CreateEnvironmentDto) { + const origin = await this.findAll(appid) // check if exists const exists = origin.find((item) => item.name === dto.name) if (exists) { @@ -25,42 +39,28 @@ export class EnvironmentVariableService { const res = await this.prisma.applicationConfiguration.update({ where: { appid }, - data: { - environments: { - set: origin, - }, - }, + data: { environments: { set: origin } }, }) + await this.confService.publish(res) return res.environments } - async find(appid: string) { + async findAll(appid: string) { const res = await this.prisma.applicationConfiguration.findUnique({ - where: { - appid, - }, + where: { appid }, }) return res.environments } - async delete(appid: string, name: string) { + async deleteOne(appid: string, name: string) { const res = await this.prisma.applicationConfiguration.update({ - where: { - appid, - }, - data: { - environments: { - deleteMany: { - where: { - name, - }, - }, - }, - }, + where: { appid }, + data: { environments: { deleteMany: { where: { name } } } }, }) + await this.confService.publish(res) return res } } diff --git a/server/src/auth/application.auth.guard.ts b/server/src/auth/application.auth.guard.ts index 8d46e302b4..a184862158 100644 --- a/server/src/auth/application.auth.guard.ts +++ b/server/src/auth/application.auth.guard.ts @@ -16,7 +16,6 @@ export class ApplicationAuthGuard implements CanActivate { const request = context.switchToHttp().getRequest() as IRequest const appid = request.params.appid const user = request.user as User - this.logger.debug(`check auth of: appid: ${appid}, user: ${user.id}`) const app = await this.appService.findOne(appid) if (!app) { diff --git a/server/src/auth/auth.controller.ts b/server/src/auth/auth.controller.ts index d5895d31ec..d1b4d03cbb 100644 --- a/server/src/auth/auth.controller.ts +++ b/server/src/auth/auth.controller.ts @@ -1,20 +1,10 @@ -import { - Body, - Controller, - Get, - Post, - Query, - Req, - Res, - UseGuards, -} from '@nestjs/common' +import { Body, Controller, Get, Post, Req, UseGuards } from '@nestjs/common' import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags, } from '@nestjs/swagger' -import { Response } from 'express' import { ApiResponseUtil, ResponseUtil } from '../utils/response' import { IRequest } from '../utils/interface' import { UserDto } from '../user/dto/user.response' @@ -27,47 +17,6 @@ import { Pat2TokenDto } from './dto/pat2token.dto' export class AuthController { constructor(private readonly authService: AuthService) {} - /** - * Redirect to login page - */ - @ApiResponse({ status: 302 }) - @ApiOperation({ summary: 'Redirect to login page' }) - @Get('login') - async getSigninUrl(@Res() res: Response): Promise { - const url = this.authService.getSignInUrl() - return res.redirect(url) - } - - /** - * Redirect to register page - * @param res - * @returns - */ - @ApiResponse({ status: 302 }) - @ApiOperation({ summary: 'Redirect to register page' }) - @Get('register') - async getSignupUrl(@Res() res: Response) { - const url = this.authService.getSignUpUrl() - return res.redirect(url) - } - - /** - * Get user token by auth code - * @param code - * @returns - */ - @ApiOperation({ summary: 'Get user token by auth code' }) - @ApiResponse({ type: ResponseUtil }) - @Get('code2token') - async code2token(@Query('code') code: string) { - const token = await this.authService.code2token(code) - if (!token) { - return ResponseUtil.error('invalid code') - } - - return ResponseUtil.ok(token) - } - /** * Get user token by PAT * @param pat diff --git a/server/src/auth/auth.module.ts b/server/src/auth/auth.module.ts index 4e75202d10..2291d03e9f 100644 --- a/server/src/auth/auth.module.ts +++ b/server/src/auth/auth.module.ts @@ -1,15 +1,22 @@ -import { Module } from '@nestjs/common' +import { SmsService } from 'src/auth/phone/sms.service' +import { Global, Module } from '@nestjs/common' import { JwtModule } from '@nestjs/jwt' import { PassportModule } from '@nestjs/passport' import { ServerConfig } from '../constants' import { UserModule } from '../user/user.module' import { AuthService } from './auth.service' -import { CasdoorService } from './casdoor.service' import { JwtStrategy } from './jwt.strategy' import { AuthController } from './auth.controller' import { HttpModule } from '@nestjs/axios' import { PatService } from 'src/user/pat.service' +import { UserPasswordController } from './user-passwd/user-password.controller' +import { UserPasswordService } from './user-passwd/user-password.service' +import { PhoneController } from './phone/phone.controller' +import { PhoneService } from './phone/phone.service' +import { AuthenticationController } from './authentication.controller' +import { AuthenticationService } from './authentication.service' +@Global() @Module({ imports: [ PassportModule, @@ -20,8 +27,21 @@ import { PatService } from 'src/user/pat.service' UserModule, HttpModule, ], - providers: [AuthService, JwtStrategy, CasdoorService, PatService], + providers: [ + AuthService, + JwtStrategy, + PatService, + UserPasswordService, + PhoneService, + SmsService, + AuthenticationService, + ], exports: [AuthService], - controllers: [AuthController], + controllers: [ + AuthController, + UserPasswordController, + PhoneController, + AuthenticationController, + ], }) export class AuthModule {} diff --git a/server/src/auth/auth.service.ts b/server/src/auth/auth.service.ts index 3f93f226a1..11f5e6cb99 100644 --- a/server/src/auth/auth.service.ts +++ b/server/src/auth/auth.service.ts @@ -1,9 +1,6 @@ import { Injectable, Logger } from '@nestjs/common' import { JwtService } from '@nestjs/jwt' -import { CasdoorService } from './casdoor.service' import { User } from '@prisma/client' -import { UserService } from '../user/user.service' -import { ServerConfig } from '../constants' import * as assert from 'node:assert' import { PatService } from 'src/user/pat.service' @@ -12,66 +9,9 @@ export class AuthService { logger: Logger = new Logger(AuthService.name) constructor( private readonly jwtService: JwtService, - private readonly casdoorService: CasdoorService, - private readonly userService: UserService, private readonly patService: PatService, ) {} - /** - * Get user token by casdoor code: - * - code is casdoor code - * - user token is laf server token, NOT casdoor token - * @param code - * @returns - */ - async code2token(code: string): Promise { - try { - const casdoorUser = await this.casdoorService.code2user(code) - if (!casdoorUser) return null - - // Get or create laf user - assert(casdoorUser.id, 'casdoor user id is empty') - const profile = await this.userService.getProfileByOpenid(casdoorUser.id) - let user = profile?.user - if (!user) { - user = await this.userService.create({ - username: casdoorUser.username, - email: casdoorUser.email, - phone: casdoorUser.phone, - profile: { - create: { - openid: casdoorUser.id, - name: casdoorUser.displayName, - avatar: casdoorUser.avatar, - from: ServerConfig.CASDOOR_CLIENT_ID, - }, - }, - }) - } else { - // update it - user = await this.userService.updateUser({ - where: { id: user.id }, - data: { - username: casdoorUser.username, - email: casdoorUser.email, - phone: casdoorUser.phone, - profile: { - update: { - name: casdoorUser.displayName, - avatar: casdoorUser.avatar, - }, - }, - }, - }) - } - - return this.getAccessTokenByUser(user) - } catch (error) { - this.logger.error(error) - return null - } - } - /** * Get token by PAT * @param user @@ -94,26 +34,8 @@ export class AuthService { * @returns */ getAccessTokenByUser(user: User): string { - const payload = { - sub: user.id, - } + const payload = { sub: user.id } const token = this.jwtService.sign(payload) return token } - - /** - * Generate login url - * @returns - */ - getSignInUrl(): string { - return this.casdoorService.getSignInUrl() - } - - /** - * Generate register url - * @returns - */ - getSignUpUrl(): string { - return this.casdoorService.getSignUpUrl() - } } diff --git a/server/src/auth/authentication.controller.ts b/server/src/auth/authentication.controller.ts new file mode 100644 index 0000000000..50d8ee6dd7 --- /dev/null +++ b/server/src/auth/authentication.controller.ts @@ -0,0 +1,105 @@ +import { AuthenticationService } from './authentication.service' +import { Body, Controller, Get, Post, Req, UseGuards } from '@nestjs/common' +import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger' +import { ResponseUtil } from 'src/utils/response' +import { JwtAuthGuard } from './jwt.auth.guard' +import { BindUsernameDto } from './dto/bind-username.dto' +import { IRequest } from 'src/utils/interface' +import { BindPhoneDto } from './dto/bind-phone.dto' +import { SmsService } from './phone/sms.service' +import { SmsVerifyCodeType } from '@prisma/client' +import { UserService } from 'src/user/user.service' + +@ApiTags('Authentication - New') +@Controller('auth') +export class AuthenticationController { + constructor( + private readonly authenticationService: AuthenticationService, + private readonly smsService: SmsService, + private readonly userService: UserService, + ) {} + + /** + * Auth providers + */ + @ApiOperation({ summary: 'Auth providers' }) + @ApiResponse({ type: ResponseUtil }) + @Get('providers') + async getProviders() { + const providers = await this.authenticationService.getProviders() + return ResponseUtil.ok(providers) + } + + /** + * Bind phone + */ + @ApiOperation({ summary: 'Bind username' }) + @ApiResponse({ type: ResponseUtil }) + @UseGuards(JwtAuthGuard) + @Post('bind/phone') + async bindPhone(@Body() dto: BindPhoneDto, @Req() req: IRequest) { + const { phone, code } = dto + // check code valid + const err = await this.smsService.validCode( + phone, + code, + SmsVerifyCodeType.Bind, + ) + if (err) { + return ResponseUtil.error(err) + } + + // check phone if have already been bound + const user = await this.userService.find(phone) + if (user) { + return ResponseUtil.error('phone already been bound') + } + + // bind phone + await this.userService.updateUser({ + where: { + id: req.user.id, + }, + data: { + phone, + }, + }) + } + + /** + * Bind username, not support bind existed username + */ + @ApiOperation({ summary: 'Bind username' }) + @ApiResponse({ type: ResponseUtil }) + @UseGuards(JwtAuthGuard) + @Post('bind/username') + async bindUsername(@Body() dto: BindUsernameDto, @Req() req: IRequest) { + const { username, phone, code } = dto + + // check code valid + const err = await this.smsService.validCode( + phone, + code, + SmsVerifyCodeType.Bind, + ) + if (err) { + return ResponseUtil.error(err) + } + + // check username if have already been bound + const user = await this.userService.find(username) + if (user) { + return ResponseUtil.error('username already been bound') + } + + // bind username + await this.userService.updateUser({ + where: { + id: req.user.id, + }, + data: { + username, + }, + }) + } +} diff --git a/server/src/auth/authentication.service.ts b/server/src/auth/authentication.service.ts new file mode 100644 index 0000000000..67d058a661 --- /dev/null +++ b/server/src/auth/authentication.service.ts @@ -0,0 +1,64 @@ +import { JwtService } from '@nestjs/jwt' +import { PrismaService } from 'src/prisma/prisma.service' +import { Injectable, Logger } from '@nestjs/common' +import { AuthProviderState, User } from '@prisma/client' +import { + PASSWORD_AUTH_PROVIDER_NAME, + PHONE_AUTH_PROVIDER_NAME, +} from 'src/constants' + +@Injectable() +export class AuthenticationService { + logger: Logger = new Logger(AuthenticationService.name) + constructor( + private readonly prismaService: PrismaService, + private readonly jwtService: JwtService, + ) {} + + /** + * Get all auth provides + * @returns + */ + async getProviders() { + return await this.prismaService.authProvider.findMany({ + where: { state: AuthProviderState.Enabled }, + select: { + id: false, + name: true, + bind: true, + register: true, + default: true, + state: true, + config: false, + }, + }) + } + + async getPhoneProvider() { + return await this.getProvider(PHONE_AUTH_PROVIDER_NAME) + } + + async getPasswdProvider() { + return await this.getProvider(PASSWORD_AUTH_PROVIDER_NAME) + } + + // Get auth provider by name + async getProvider(name: string) { + return await this.prismaService.authProvider.findUnique({ + where: { name }, + }) + } + + /** + * Get access token by user + * @param user + * @returns + */ + getAccessTokenByUser(user: User): string { + const payload = { + sub: user.id, + } + const token = this.jwtService.sign(payload) + return token + } +} diff --git a/server/src/auth/casdoor.service.ts b/server/src/auth/casdoor.service.ts deleted file mode 100644 index 841c8ade2c..0000000000 --- a/server/src/auth/casdoor.service.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { HttpService } from '@nestjs/axios' -import { Injectable, Logger } from '@nestjs/common' -import * as querystring from 'node:querystring' -import { ServerConfig } from '../constants' - -@Injectable() -export class CasdoorService { - private logger = new Logger() - constructor(private readonly httpService: HttpService) {} - - /** - * Get user from code directly - * @param code - * @returns - */ - async code2user(code: string) { - const token = await this.code2token(code) - const user = await this.getUserInfo(token) - return user - } - - /** - * Get user token by code - * @param code - * @returns - */ - async code2token(code: string): Promise { - try { - const url = `${ServerConfig.CASDOOR_ENDPOINT}/api/login/oauth/access_token` - const res = await this.httpService.axiosRef.post(url, { - client_id: ServerConfig.CASDOOR_CLIENT_ID, - client_secret: ServerConfig.CASDOOR_CLIENT_SECRET, - grant_type: 'authorization_code', - code, - }) - - const data = res.data as { - access_token: string - refresh_token: string - id_token: string - token_type: string - expires_in: number - scope: string - } - - return data?.access_token - } catch (error) { - return null - } - } - - /** - * Get user info by token - * @param token - * @returns - */ - async getUserInfo(token: string) { - try { - const url = `${ServerConfig.CASDOOR_ENDPOINT}/api/userinfo` - const res = await this.httpService.axiosRef.get(url, { - headers: { - Authorization: `Bearer ${token}`, - }, - }) - - const data = res.data - const user: CasdoorUserInfo = { - id: data.id || data.sub, - username: data.name, - displayName: data.displayName || data.preferred_username || '', - email: data.email || undefined, - phone: data.phone || undefined, - avatar: data.avatar || data.picture || '', - } - return user - } catch (err) { - this.logger.error(err) - return null - } - } - - /** - * Generate login url - * @returns - */ - getSignInUrl(): string { - const endpoint = ServerConfig.CASDOOR_ENDPOINT - const query = { - client_id: ServerConfig.CASDOOR_CLIENT_ID, - redirect_uri: ServerConfig.CASDOOR_REDIRECT_URI, - response_type: 'code', - scope: 'openid,profile,phone,email', - state: 'casdoor', - } - const encoded_query = querystring.encode(query) - const base_api = `${endpoint}/login/oauth/authorize` - const url = `${base_api}?${encoded_query}` - return url - } - - /** - * Generate register url - * @returns - */ - getSignUpUrl(): string { - const endpoint = ServerConfig.CASDOOR_ENDPOINT - const app_name = ServerConfig.CASDOOR_APP_NAME - const url = `${endpoint}/signup/${app_name}` - return url - } -} - -interface CasdoorUserInfo { - id: string - username: string - email?: string - phone?: string - displayName: string - avatar: string -} diff --git a/server/src/auth/dto/bind-phone.dto.ts b/server/src/auth/dto/bind-phone.dto.ts new file mode 100644 index 0000000000..3d558cd600 --- /dev/null +++ b/server/src/auth/dto/bind-phone.dto.ts @@ -0,0 +1,21 @@ +import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString, Length, Matches } from 'class-validator' + +export class BindPhoneDto { + @ApiProperty({ + description: 'phone number', + example: '13805718888', + }) + @IsString() + @IsNotEmpty() + @Matches(/^1[3-9]\d{9}$/) + phone: string + + @ApiProperty({ + description: 'sms verify code', + example: '032476', + }) + @IsNotEmpty() + @Length(6, 6) + code: string +} diff --git a/server/src/auth/dto/bind-username.dto.ts b/server/src/auth/dto/bind-username.dto.ts new file mode 100644 index 0000000000..ef760263f0 --- /dev/null +++ b/server/src/auth/dto/bind-username.dto.ts @@ -0,0 +1,30 @@ +import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString, Length, Matches } from 'class-validator' + +export class BindUsernameDto { + @ApiProperty({ + description: 'username', + example: 'laf-user', + }) + @IsString() + @IsNotEmpty() + @Length(3, 64) + username: string + + @ApiProperty({ + description: 'phone', + example: '13805718888', + }) + @IsString() + @IsNotEmpty() + @Matches(/^1[3-9]\d{9}$/) + phone: string + + @ApiProperty({ + description: 'sms verify code', + example: '032476', + }) + @IsNotEmpty() + @Length(6, 6) + code: string +} diff --git a/server/src/auth/dto/passwd-check.dto.ts b/server/src/auth/dto/passwd-check.dto.ts new file mode 100644 index 0000000000..ef829b7b06 --- /dev/null +++ b/server/src/auth/dto/passwd-check.dto.ts @@ -0,0 +1,13 @@ +import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString, Length } from 'class-validator' + +export class PasswdCheckDto { + @ApiProperty({ + description: 'username | phone | email', + example: 'laf-user | 13805718888 | laf-user@laf.com', + }) + @IsString() + @IsNotEmpty() + @Length(3, 64) + username: string +} diff --git a/server/src/auth/dto/passwd-reset.dto.ts b/server/src/auth/dto/passwd-reset.dto.ts new file mode 100644 index 0000000000..9ea7407548 --- /dev/null +++ b/server/src/auth/dto/passwd-reset.dto.ts @@ -0,0 +1,37 @@ +import { ApiProperty } from '@nestjs/swagger' +import { SmsVerifyCodeType } from '@prisma/client' +import { IsEnum, IsNotEmpty, IsString, Length, Matches } from 'class-validator' + +export class PasswdResetDto { + @ApiProperty({ + description: 'new password, 8-64 characters', + example: 'laf-user-password', + }) + @IsString() + @IsNotEmpty() + @Length(8, 64) + password: string + + @ApiProperty({ + description: 'phone', + example: '13805718888', + }) + @IsString() + @Matches(/^1[3-9]\d{9}$/) + phone: string + + @ApiProperty({ + description: 'verify code', + example: '032456', + }) + @IsString() + @Length(6, 6) + code: string + + @ApiProperty({ + description: 'type', + example: 'ResetPassword', + }) + @IsEnum(SmsVerifyCodeType) + type: SmsVerifyCodeType +} diff --git a/server/src/auth/dto/passwd-signin.dto.ts b/server/src/auth/dto/passwd-signin.dto.ts new file mode 100644 index 0000000000..df2e31b085 --- /dev/null +++ b/server/src/auth/dto/passwd-signin.dto.ts @@ -0,0 +1,22 @@ +import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString, Length } from 'class-validator' + +export class PasswdSigninDto { + @ApiProperty({ + description: 'username', + example: 'laf-user', + }) + @IsString() + @IsNotEmpty() + @Length(3, 64) + username: string + + @ApiProperty({ + description: 'password, 8-64 characters', + example: 'laf-user-password', + }) + @IsString() + @IsNotEmpty() + @Length(8, 64) + password: string +} diff --git a/server/src/auth/dto/passwd-signup.dto.ts b/server/src/auth/dto/passwd-signup.dto.ts new file mode 100644 index 0000000000..41df857b02 --- /dev/null +++ b/server/src/auth/dto/passwd-signup.dto.ts @@ -0,0 +1,56 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { SmsVerifyCodeType } from '@prisma/client' +import { + IsEnum, + IsNotEmpty, + IsOptional, + IsString, + Length, + Matches, +} from 'class-validator' + +export class PasswdSignupDto { + @ApiProperty({ + description: 'username, 3-64 characters', + example: 'laf-user', + }) + @IsString() + @IsNotEmpty() + @Length(3, 64) + username: string + + @ApiProperty({ + description: 'password, 8-64 characters', + example: 'laf-user-password', + }) + @IsString() + @IsNotEmpty() + @Length(8, 64) + password: string + + @ApiPropertyOptional({ + description: 'phone', + example: '13805718888', + }) + @IsOptional() + @IsString() + @Matches(/^1[3-9]\d{9}$/) + phone: string + + @ApiPropertyOptional({ + description: 'verify code', + example: '032456', + }) + @IsOptional() + @IsString() + @Length(6, 6) + code: string + + @ApiPropertyOptional({ + description: 'type', + example: 'Signup', + }) + @IsOptional() + @IsEnum(SmsVerifyCodeType) + type: SmsVerifyCodeType +} diff --git a/server/src/auth/dto/phone-signin.dto.ts b/server/src/auth/dto/phone-signin.dto.ts new file mode 100644 index 0000000000..ba136ce7ba --- /dev/null +++ b/server/src/auth/dto/phone-signin.dto.ts @@ -0,0 +1,42 @@ +import { ApiProperty } from '@nestjs/swagger' +import { + IsNotEmpty, + IsString, + Length, + IsOptional, + Matches, +} from 'class-validator' + +export class PhoneSigninDto { + @ApiProperty({ + description: 'phone', + example: '13805718888', + }) + @IsString() + @IsNotEmpty() + @Matches(/^1[3-9]\d{9}$/) + phone: string + + @ApiProperty({}) + @IsNotEmpty() + @Length(6, 6) + code: string + + @ApiProperty({ + description: 'username', + example: 'laf-user', + }) + @IsOptional() + @IsString() + @Length(3, 64) + username: string + + @ApiProperty({ + description: 'password, 8-64 characters', + example: 'laf-user-password', + }) + @IsOptional() + @IsString() + @Length(8, 64) + password: string +} diff --git a/server/src/auth/dto/send-phone-code.dto.ts b/server/src/auth/dto/send-phone-code.dto.ts new file mode 100644 index 0000000000..1d6dda8e06 --- /dev/null +++ b/server/src/auth/dto/send-phone-code.dto.ts @@ -0,0 +1,22 @@ +import { ApiProperty } from '@nestjs/swagger' +import { SmsVerifyCodeType } from '@prisma/client' +import { IsEnum, IsNotEmpty, IsString, Matches } from 'class-validator' + +export class SendPhoneCodeDto { + @ApiProperty({ + description: 'phone', + example: '13805718888', + }) + @IsString() + @IsNotEmpty() + @Matches(/^1[3-9]\d{9}$/) + phone: string + + @ApiProperty({ + description: 'verify code type', + example: 'Signin | Signup | ResetPassword | Bind | Unbind | ChangePhone', + }) + @IsNotEmpty() + @IsEnum(SmsVerifyCodeType) + type: SmsVerifyCodeType +} diff --git a/server/src/auth/phone/phone.controller.ts b/server/src/auth/phone/phone.controller.ts new file mode 100644 index 0000000000..b13b2d75c8 --- /dev/null +++ b/server/src/auth/phone/phone.controller.ts @@ -0,0 +1,88 @@ +import { SmsService } from 'src/auth/phone/sms.service' +import { SmsVerifyCodeType } from '@prisma/client' +import { IRequest } from 'src/utils/interface' +import { Body, Controller, Logger, Post, Req } from '@nestjs/common' +import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger' +import { ResponseUtil } from 'src/utils/response' +import { SendPhoneCodeDto } from '../dto/send-phone-code.dto' +import { PhoneService } from './phone.service' +import { PhoneSigninDto } from '../dto/phone-signin.dto' +import { AuthenticationService } from '../authentication.service' +import { UserService } from 'src/user/user.service' +import { AuthBindingType, AuthProviderBinding } from '../types' + +@ApiTags('Authentication - New') +@Controller('auth') +export class PhoneController { + private readonly logger = new Logger(PhoneController.name) + + constructor( + private readonly phoneService: PhoneService, + private readonly smsService: SmsService, + private readonly authService: AuthenticationService, + private readonly userService: UserService, + ) {} + + /** + * send phone code + */ + @ApiOperation({ summary: 'Send phone verify code' }) + @ApiResponse({ type: ResponseUtil }) + @Post('phone/sms/code') + async sendCode(@Req() req: IRequest, @Body() dto: SendPhoneCodeDto) { + const { phone, type } = dto + const ip = req.headers['x-real-ip'] as string + + const err = await this.phoneService.sendCode(phone, type, ip) + if (err) { + return ResponseUtil.error(err) + } + return ResponseUtil.ok('success') + } + + /** + * Signin by phone and verify code + */ + @ApiOperation({ summary: 'Signin by phone and verify code' }) + @ApiResponse({ type: ResponseUtil }) + @Post('phone/signin') + async signin(@Body() dto: PhoneSigninDto) { + const { phone, code } = dto + // check if code valid + const err = await this.smsService.validCode( + phone, + code, + SmsVerifyCodeType.Signin, + ) + if (err) return ResponseUtil.error(err) + + // check if user exists + const user = await this.userService.findByPhone(phone) + if (user) { + const token = this.phoneService.signin(user) + return ResponseUtil.ok(token) + } + + // user not exist + const provider = await this.authService.getPhoneProvider() + if (provider.register === false) { + return ResponseUtil.error('user not exists') + } + + // check if username and password is needed + let signupWithUsername = false + const bind = provider.bind as any as AuthProviderBinding + if (bind.username === AuthBindingType.Required) { + const { username, password } = dto + signupWithUsername = true + if (!username || !password) { + return ResponseUtil.error('username and password is required') + } + } + + // user not exist, signup and signin + const newUser = await this.phoneService.signup(dto, signupWithUsername) + const data = this.phoneService.signin(newUser) + return ResponseUtil.ok(data) + } +} diff --git a/server/src/auth/phone/phone.service.ts b/server/src/auth/phone/phone.service.ts new file mode 100644 index 0000000000..a5093a14b0 --- /dev/null +++ b/server/src/auth/phone/phone.service.ts @@ -0,0 +1,125 @@ +import { Injectable, Logger } from '@nestjs/common' +import { SmsVerifyCodeType, User } from '@prisma/client' +import { PrismaService } from 'src/prisma/prisma.service' +import { SmsService } from 'src/auth/phone/sms.service' +import { UserService } from 'src/user/user.service' +import { AuthenticationService } from '../authentication.service' +import { PhoneSigninDto } from '../dto/phone-signin.dto' +import { hashPassword } from 'src/utils/crypto' +import { SmsVerifyCodeState } from '../types' + +@Injectable() +export class PhoneService { + private readonly logger = new Logger(PhoneService.name) + constructor( + private readonly prisma: PrismaService, + private readonly smsService: SmsService, + private readonly userService: UserService, + private readonly authService: AuthenticationService, + ) {} + + /** + * Send phone verify code + * @param phone phone number + * @param type sms type Signin | Signup | ResetPassword + * @param ip client ip + * @returns + */ + async sendCode(phone: string, type: SmsVerifyCodeType, ip: string) { + // check if phone number satisfy the send condition + let err = await this.smsService.checkSendable(phone, ip) + if (err) { + return err + } + + // Send sms code + const code = Math.floor(Math.random() * 900000 + 100000).toString() + err = await this.smsService.sendPhoneCode(phone, code) + if (err) { + return err + } + + // disable previous sms code + await this.prisma.smsVerifyCode.updateMany({ + where: { + phone, + type, + state: SmsVerifyCodeState.Active, + }, + data: { + state: SmsVerifyCodeState.Used, + }, + }) + + // Save new sms code to database + await this.prisma.smsVerifyCode.create({ + data: { + phone, + code, + type, + ip, + }, + }) + + return null + } + + /** + * Signup a user by phone + * @param dto + * @returns + */ + async signup(dto: PhoneSigninDto, withUsername = false) { + const { phone, username, password } = dto + + // start transaction + const user = await this.prisma.$transaction(async (tx) => { + // create user + const user = await tx.user.create({ + data: { + phone, + username: username || phone, + profile: { create: { name: username || phone } }, + }, + }) + if (!withUsername) { + return user + } + // create password if need + await tx.userPassword.create({ + data: { + uid: user.id, + password: hashPassword(password), + state: 'Active', + }, + }) + return user + }) + return user + } + + /** + * signin a user, return token and if bind password + * @param user user + * @returns token and if bind password + */ + signin(user: User) { + const token = this.authService.getAccessTokenByUser(user) + return token + } + + // check if current user has bind password + async ifBindPassword(user: User) { + const count = await this.prisma.userPassword.count({ + where: { + uid: user.id, + state: 'Active', + }, + }) + + if (count === 0) { + return false + } + return true + } +} diff --git a/server/src/auth/phone/sms.service.ts b/server/src/auth/phone/sms.service.ts new file mode 100644 index 0000000000..5cf4ccda3e --- /dev/null +++ b/server/src/auth/phone/sms.service.ts @@ -0,0 +1,163 @@ +import { AuthenticationService } from '../authentication.service' +import { Injectable, Logger } from '@nestjs/common' +import { Prisma, SmsVerifyCodeType } from '@prisma/client' +import Dysmsapi, * as dysmsapi from '@alicloud/dysmsapi20170525' +import * as OpenApi from '@alicloud/openapi-client' +import * as Util from '@alicloud/tea-util' +import { + ALISMS_KEY, + LIMIT_CODE_PER_IP_PER_DAY, + MILLISECONDS_PER_DAY, + MILLISECONDS_PER_MINUTE, + CODE_VALIDITY, +} from 'src/constants' +import { PrismaService } from 'src/prisma/prisma.service' +import { SmsVerifyCodeState } from '../types' + +@Injectable() +export class SmsService { + private logger = new Logger(SmsService.name) + constructor( + private readonly prisma: PrismaService, + private readonly authService: AuthenticationService, + ) {} + + /** + * send sms login code to given phone number + * @param dto phone number + * @param ip client ip + */ + async sendPhoneCode(phone: string, code: string) { + try { + this.logger.debug(`send sms code: ${code} to ${phone}`) + + const res = await this.sendAlismsCode(phone, code.toString()) + if (res.body.code !== 'OK') { + return `ALISMS_ERROR: ${res.body.message}` + } + return null + } catch (error) { + this.logger.error(error, error.response?.body) + return error.message + } + } + + // check if phone number satisfy the send condition + async checkSendable(phone: string, ip: string) { + // Check if valid phone number + if (!/^1[3456789]\d{9}$/.test(phone)) { + return 'INVALID_PHONE' + } + + // Check if phone number has been send sms code in 1 minute + const count = await this.prisma.smsVerifyCode.count({ + where: { + phone: phone, + createdAt: { + gt: new Date(Date.now() - MILLISECONDS_PER_MINUTE), + }, + }, + }) + if (count > 0) { + return 'REQUEST_OVERLIMIT: phone number has been send sms code in 1 minute' + } + + // Check if ip has been send sms code beyond 30 times in 24 hours + const countIps = await this.prisma.smsVerifyCode.count({ + where: { + ip: ip, + createdAt: { + gt: new Date(Date.now() - MILLISECONDS_PER_DAY), + }, + }, + }) + if (countIps > LIMIT_CODE_PER_IP_PER_DAY) { + return `REQUEST_OVERLIMIT: ip has been send sms code beyond ${LIMIT_CODE_PER_IP_PER_DAY} times in 24 hours` + } + + return null + } + + // save sended code to database + async saveSmsCode(data: Prisma.SmsVerifyCodeCreateInput) { + await this.prisma.smsVerifyCode.create({ + data, + }) + } + + // Valid given phone and code with code type + async validCode(phone: string, code: string, type: SmsVerifyCodeType) { + const total = await this.prisma.smsVerifyCode.count({ + where: { + phone, + code, + type, + state: SmsVerifyCodeState.Active, + createdAt: { gte: new Date(Date.now() - CODE_VALIDITY) }, + }, + }) + + if (total === 0) return 'invalid code' + // Disable verify code after valid + await this.disableCode(phone, code, type) + return null + } + + // Disable verify code + async disableCode(phone: string, code: string, type: SmsVerifyCodeType) { + await this.prisma.smsVerifyCode.updateMany({ + where: { + phone, + code, + type, + state: SmsVerifyCodeState.Active, + }, + data: { + state: SmsVerifyCodeState.Used, + }, + }) + } + + // Disable same type verify code + async disableSameTypeCode(phone: string, type: SmsVerifyCodeType) { + await this.prisma.smsVerifyCode.updateMany({ + where: { + phone, + type, + state: SmsVerifyCodeState.Active, + }, + data: { + state: SmsVerifyCodeState.Used, + }, + }) + } + + // send sms code to phone using alisms + private async sendAlismsCode(phone: string, code: string) { + const { accessKeyId, accessKeySecret, templateCode, signName, endpoint } = + await this.loadAlismsConfig() + + const sendSmsRequest = new dysmsapi.SendSmsRequest({ + phoneNumbers: phone, + signName, + templateCode, + templateParam: `{"code":${code}}`, + }) + + const config = new OpenApi.Config({ + accessKeyId, + accessKeySecret, + endpoint, + }) + + const client = new Dysmsapi(config) + const runtime = new Util.RuntimeOptions({}) + return await client.sendSmsWithOptions(sendSmsRequest, runtime) + } + + // load alisms config from database + private async loadAlismsConfig() { + const phoneProvider = await this.authService.getPhoneProvider() + return phoneProvider.config[ALISMS_KEY] + } +} diff --git a/server/src/auth/types.ts b/server/src/auth/types.ts new file mode 100644 index 0000000000..fc7772f9df --- /dev/null +++ b/server/src/auth/types.ts @@ -0,0 +1,31 @@ +export enum AuthBindingType { + Required = 'required', + Optional = 'optional', + None = 'none', +} + +export enum SmsVerifyCodeState { + Active = 0, + Used = 1, +} + +export enum UserPasswordState { + Active = 'Active', + Inactive = 'Inactive', +} + +export interface AuthProviderBinding { + username: AuthBindingType + phone: AuthBindingType + email: AuthBindingType + github: AuthBindingType + wechat: AuthBindingType +} + +export interface AlismsConfig { + accessKeyId: string + accessKeySecret: string + endpoint: string + signName: string + templateCode: string +} diff --git a/server/src/auth/user-passwd/user-password.controller.ts b/server/src/auth/user-passwd/user-password.controller.ts new file mode 100644 index 0000000000..bcbf1090b7 --- /dev/null +++ b/server/src/auth/user-passwd/user-password.controller.ts @@ -0,0 +1,145 @@ +import { AuthenticationService } from '../authentication.service' +import { UserPasswordService } from './user-password.service' +import { Body, Controller, Logger, Post, Req } from '@nestjs/common' +import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger' +import { ResponseUtil } from 'src/utils/response' +import { UserService } from '../../user/user.service' +import { PasswdSignupDto } from '../dto/passwd-signup.dto' +import { PasswdSigninDto } from '../dto/passwd-signin.dto' +import { AuthBindingType, AuthProviderBinding } from '../types' +import { SmsService } from '../phone/sms.service' +import { PasswdResetDto } from '../dto/passwd-reset.dto' +import { PasswdCheckDto } from '../dto/passwd-check.dto' + +@ApiTags('Authentication - New') +@Controller('auth') +export class UserPasswordController { + private readonly logger = new Logger(UserPasswordService.name) + constructor( + private readonly userService: UserService, + private readonly passwdService: UserPasswordService, + private readonly authService: AuthenticationService, + private readonly smsService: SmsService, + ) {} + + /** + * Signup by username and password + */ + @ApiOperation({ summary: 'Signup by user-password' }) + @ApiResponse({ type: ResponseUtil }) + @Post('passwd/signup') + async signup(@Body() dto: PasswdSignupDto) { + const { username, password, phone } = dto + // check if user exists + const doc = await this.userService.user({ username }) + if (doc) { + return ResponseUtil.error('user already exists') + } + + // check if register is allowed + const provider = await this.authService.getPasswdProvider() + if (provider.register === false) { + return ResponseUtil.error('register is not allowed') + } + + // valid phone code if needed + const bind = provider.bind as any as AuthProviderBinding + if (bind.phone === AuthBindingType.Required) { + const { phone, code, type } = dto + // valid phone has been binded + const user = await this.userService.findByPhone(phone) + if (user) { + return ResponseUtil.error('phone has been binded') + } + const err = await this.smsService.validCode(phone, code, type) + if (err) { + return ResponseUtil.error(err) + } + } + + // signup user + const user = await this.passwdService.signup(username, password, phone) + + // signin for created user + const token = this.passwdService.signin(user) + if (!token) { + return ResponseUtil.error('failed to get access token') + } + return ResponseUtil.ok({ token, user }) + } + + /** + * Signin by username and password + */ + @ApiOperation({ summary: 'Signin by user-password' }) + @ApiResponse({ type: ResponseUtil }) + @Post('passwd/signin') + async signin(@Body() dto: PasswdSigninDto) { + // check if user exists + const user = await this.userService.find(dto.username) + if (!user) { + return ResponseUtil.error('user not found') + } + + // check if password is correct + const err = await this.passwdService.validPasswd(user.id, dto.password) + if (err) { + return ResponseUtil.error(err) + } + + // signin for user + const token = await this.passwdService.signin(user) + if (!token) { + return ResponseUtil.error('failed to get access token') + } + return ResponseUtil.ok(token) + } + + /** + * Reset password + */ + @ApiOperation({ summary: 'Reset password' }) + @ApiResponse({ type: ResponseUtil }) + @Post('passwd/reset') + async reset(@Body() dto: PasswdResetDto) { + // valid phone code + const { phone, code, type } = dto + let err = await this.smsService.validCode(phone, code, type) + if (err) { + return ResponseUtil.error(err) + } + + // find user by phone + const user = await this.userService.findByPhone(phone) + if (!user) { + return ResponseUtil.error('user not found') + } + + // reset password + err = await this.passwdService.resetPasswd(user.id, dto.password) + if (err) { + return ResponseUtil.error(err) + } + + return ResponseUtil.ok('success') + } + + /** + * Check if user-password is set + */ + @ApiOperation({ summary: 'Check if user-password is set' }) + @ApiResponse({ type: ResponseUtil }) + @Post('passwd/check') + async check(@Body() dto: PasswdCheckDto) { + const { username } = dto + // check if user exists + const user = await this.userService.find(username) + if (!user) { + return ResponseUtil.error('user not found') + } + // find if set password + const hasPasswd = await this.passwdService.hasPasswd(user.id) + + return ResponseUtil.ok(hasPasswd) + } +} diff --git a/server/src/auth/user-passwd/user-password.service.ts b/server/src/auth/user-passwd/user-password.service.ts new file mode 100644 index 0000000000..0e43bb606b --- /dev/null +++ b/server/src/auth/user-passwd/user-password.service.ts @@ -0,0 +1,100 @@ +import { Injectable, Logger } from '@nestjs/common' +import { PrismaService } from 'src/prisma/prisma.service' +import { User } from '@prisma/client' +import { hashPassword } from 'src/utils/crypto' +import { AuthenticationService } from '../authentication.service' +import { UserPasswordState } from '../types' + +@Injectable() +export class UserPasswordService { + private readonly logger = new Logger(UserPasswordService.name) + constructor( + private readonly prisma: PrismaService, + private readonly authService: AuthenticationService, + ) {} + + // Singup by username and password + async signup(username: string, password: string, phone: string) { + // start transaction + const user = await this.prisma.$transaction(async (tx) => { + // create user + const user = await tx.user.create({ + data: { + username, + phone, + profile: { create: { name: username } }, + }, + }) + + // create password + await tx.userPassword.create({ + data: { + uid: user.id, + password: hashPassword(password), + state: UserPasswordState.Active, + }, + }) + + return user + }) + + return user + } + + // Signin for user, means get access token + signin(user: User) { + return this.authService.getAccessTokenByUser(user) + } + + // valid if password is correct + async validPasswd(uid: string, passwd: string) { + const userPasswd = await this.prisma.userPassword.findFirst({ + where: { uid, state: UserPasswordState.Active }, + }) + if (!userPasswd) { + return 'password not exists' + } + + if (userPasswd.password !== hashPassword(passwd)) { + return 'password incorrect' + } + + return null + } + + // reset password + async resetPasswd(uid: string, passwd: string) { + // start transaction + const update = await this.prisma.$transaction(async (tx) => { + // disable old password + await tx.userPassword.updateMany({ + where: { uid }, + data: { state: UserPasswordState.Inactive }, + }) + + // create new password + const np = await tx.userPassword.create({ + data: { + uid, + password: hashPassword(passwd), + state: UserPasswordState.Active, + }, + }) + + return np + }) + if (!update) { + return 'reset password failed' + } + + return null + } + + // check if set password + async hasPasswd(uid: string) { + const userPasswd = await this.prisma.userPassword.findFirst({ + where: { uid, state: UserPasswordState.Active }, + }) + return userPasswd ? true : false // true means has password + } +} diff --git a/server/src/constants.ts b/server/src/constants.ts index 52df22a90f..6636a2b1e2 100644 --- a/server/src/constants.ts +++ b/server/src/constants.ts @@ -21,34 +21,6 @@ export class ServerConfig { return process.env.JWT_EXPIRES_IN || '7d' } - static get CASDOOR_ENDPOINT() { - return process.env.CASDOOR_ENDPOINT - } - - static get CASDOOR_APP_NAME() { - return process.env.CASDOOR_APP_NAME - } - - static get CASDOOR_CLIENT_ID() { - return process.env.CASDOOR_CLIENT_ID - } - - static get CASDOOR_CLIENT_SECRET() { - return process.env.CASDOOR_CLIENT_SECRET - } - - static get CASDOOR_REDIRECT_URI() { - return process.env.CASDOOR_REDIRECT_URI - } - - static get CASDOOR_PUBLIC_CERT() { - return process.env.CASDOOR_PUBLIC_CERT - } - - static get CASDOOR_ORG_NAME() { - return process.env.CASDOOR_ORG_NAME - } - static get SYSTEM_NAMESPACE() { return process.env.SYSTEM_NAMESPACE || 'laf-system' } @@ -67,6 +39,10 @@ export class ServerConfig { return process.env.DISABLED_GATEWAY_TASK === 'true' } + static get DISABLED_SUBSCRIPTION_TASK() { + return process.env.DISABLED_GATEWAY_TASK === 'true' + } + static get DISABLED_STORAGE_TASK() { return process.env.DISABLED_STORAGE_TASK === 'true' } @@ -92,10 +68,18 @@ export class ServerConfig { } } + static get SITE_NAME() { + return process.env.SITE_NAME || 'laf' + } + static get API_SERVER_URL() { return process.env.API_SERVER_URL || 'http://localhost:3000' } + static get CertManagerIssuerName() { + return process.env.CERT_MANAGER_ISSUER_NAME || 'laf-issuer' + } + /** default region conf */ static get DEFAULT_REGION_DATABASE_URL() { return process.env.DEFAULT_REGION_DATABASE_URL @@ -163,6 +147,7 @@ export const HTTP_METHODS = ['HEAD', 'GET', 'POST', 'PUT', 'DELETE', 'PATCH'] export const CN_PUBLISHED_FUNCTIONS = '__functions__' export const CN_PUBLISHED_POLICIES = '__policies__' export const CN_FUNCTION_LOGS = '__function_logs__' +export const CN_PUBLISHED_CONF = '__conf__' export const X_LAF_TRIGGER_TOKEN_KEY = 'x-laf-trigger-token' export const X_LAF_DEVELOP_TOKEN_KEY = 'x-laf-develop-token' @@ -173,11 +158,25 @@ export const MINIO_COMMON_USER_GROUP = 'laf_owner_by_prefix_group' export const MINIO_COMMON_USER_POLICY = 'laf_owner_by_prefix' // Date & times +export const ONE_DAY_IN_SECONDS = 60 * 60 * 24 // 1 day in seconds export const SEVEN_DAYS_IN_SECONDS = 60 * 60 * 24 * 7 // 7 days in seconds +export const ONE_MONTH_IN_SECONDS = 60 * 60 * 24 * 31 // 31 days in seconds export const FOREVER_IN_SECONDS = 60 * 60 * 24 * 365 * 1000 // 1000 years in seconds export const TASK_LOCK_INIT_TIME = new Date(0) // 1970-01-01 00:00:00 +export const MILLISECONDS_PER_DAY = 60 * 60 * 24 * 1000 // 1 day in milliseconds +export const MILLISECONDS_PER_MINUTE = 60 * 1000 // 1 minute in milliseconds // Resource units export const CPU_UNIT = 1000 export const MB = 1024 * 1024 export const GB = 1024 * MB + +// auth constants +export const PHONE_AUTH_PROVIDER_NAME = 'phone' +export const PASSWORD_AUTH_PROVIDER_NAME = 'user-password' + +// Sms constants +export const ALISMS_KEY = 'alisms' +export const LIMIT_CODE_FREQUENCY = 60 * 1000 // 60 seconds (in milliseconds) +export const LIMIT_CODE_PER_IP_PER_DAY = 30 // 30 times +export const CODE_VALIDITY = 10 * 60 * 1000 // 10 minutes (in milliseconds) diff --git a/server/src/database/database.service.ts b/server/src/database/database.service.ts index 343b4e9895..72c24924e2 100644 --- a/server/src/database/database.service.ts +++ b/server/src/database/database.service.ts @@ -55,9 +55,7 @@ export class DatabaseService { async findOne(appid: string) { const database = await this.prisma.database.findUnique({ - where: { - appid, - }, + where: { appid }, }) return database @@ -72,15 +70,14 @@ export class DatabaseService { // delete app database in database const doc = await this.prisma.database.delete({ - where: { - appid: database.appid, - }, + where: { appid: database.appid }, }) return doc } - getConnectionUri(region: Region, database: Database) { + // Get application internal database connection uri + getInternalConnectionUri(region: Region, database: Database) { // build app db connection uri from config const parsed = mongodb_uri.parse(region.databaseConf.connectionUri) parsed.database = database.name @@ -91,6 +88,18 @@ export class DatabaseService { return mongodb_uri.format(parsed) } + // Get application control database connection uri + getControlConnectionUri(region: Region, database: Database) { + // build app db connection uri from config + const parsed = mongodb_uri.parse(region.databaseConf.controlConnectionUri) + parsed.database = database.name + parsed.username = database.user + parsed.password = database.password + parsed.options['authSource'] = database.name + + return mongodb_uri.format(parsed) + } + /** * Get database accessor that used for `database-proxy` */ @@ -100,7 +109,7 @@ export class DatabaseService { assert(database, 'Database not found') const dbName = database.name - const connectionUri = this.getConnectionUri(region, database) + const connectionUri = this.getControlConnectionUri(region, database) assert(connectionUri, 'Database connection uri not found') const accessor = new MongoAccessor(dbName, connectionUri) @@ -116,7 +125,7 @@ export class DatabaseService { const database = await this.findOne(appid) assert(database, 'Database not found') - const connectionUri = this.getConnectionUri(region, database) + const connectionUri = this.getControlConnectionUri(region, database) const client = await this.mongoService.connectDatabase( connectionUri, diff --git a/server/src/function/dto/create-function.dto.ts b/server/src/function/dto/create-function.dto.ts index 24383e724b..0a86d79314 100644 --- a/server/src/function/dto/create-function.dto.ts +++ b/server/src/function/dto/create-function.dto.ts @@ -5,7 +5,7 @@ import { IsIn, IsNotEmpty, IsString, - Length, + Matches, MaxLength, } from 'class-validator' import { HTTP_METHODS } from '../../constants' @@ -15,7 +15,7 @@ export class CreateFunctionDto { description: 'Function name is unique in the application', }) @IsNotEmpty() - @Length(1, 128) + @Matches(/^[a-zA-Z0-9_.-]{1,128}$/) name: string @ApiPropertyOptional() diff --git a/server/src/function/dto/update-function.dto.ts b/server/src/function/dto/update-function.dto.ts index 0d12742ccc..f68798a463 100644 --- a/server/src/function/dto/update-function.dto.ts +++ b/server/src/function/dto/update-function.dto.ts @@ -1,6 +1,13 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { HttpMethod } from '@prisma/client' -import { IsArray, IsIn, IsNotEmpty, IsString, MaxLength } from 'class-validator' +import { + IsArray, + IsIn, + IsNotEmpty, + IsOptional, + IsString, + MaxLength, +} from 'class-validator' import { HTTP_METHODS } from '../../constants' export class UpdateFunctionDto { @@ -25,6 +32,10 @@ export class UpdateFunctionDto { @IsNotEmpty({ each: true }) tags: string[] + @ApiPropertyOptional() + @IsOptional() + params: any + validate() { return null } diff --git a/server/src/function/function.service.ts b/server/src/function/function.service.ts index 71bbaca21f..2ad96fb315 100644 --- a/server/src/function/function.service.ts +++ b/server/src/function/function.service.ts @@ -72,6 +72,7 @@ export class FunctionService { desc: dto.description, methods: dto.methods, tags: dto.tags || [], + params: dto.params, } const res = await this.prisma.cloudFunction.update({ where: { appid_name: { appid: func.appid, name: func.name } }, @@ -203,7 +204,7 @@ export class FunctionService { .find(query, { limit, skip: (page - 1) * limit, - sort: { created_at: -1 }, + sort: { _id: -1 }, }) .toArray() diff --git a/server/src/gateway/apisix-custom-cert.service.ts b/server/src/gateway/apisix-custom-cert.service.ts new file mode 100644 index 0000000000..cf067f4c11 --- /dev/null +++ b/server/src/gateway/apisix-custom-cert.service.ts @@ -0,0 +1,188 @@ +import { Injectable, Logger } from '@nestjs/common' +import { Region, WebsiteHosting } from '@prisma/client' +import { LABEL_KEY_APP_ID, ServerConfig } from 'src/constants' +import { ClusterService } from 'src/region/cluster/cluster.service' +import { GetApplicationNamespaceByAppId } from 'src/utils/getter' + +// This class handles the creation and deletion of website domain certificates +// and ApisixTls resources using Kubernetes Custom Resource Definitions (CRDs). +@Injectable() +export class ApisixCustomCertService { + private readonly logger = new Logger(ApisixCustomCertService.name) + constructor(private readonly clusterService: ClusterService) {} + + // Read a certificate for a given website using cert-manager.io CRD + async readWebsiteDomainCert(region: Region, website: WebsiteHosting) { + try { + // Get the namespace based on the application ID + const namespace = GetApplicationNamespaceByAppId(website.appid) + // Create a Kubernetes API client for the specified region + const api = this.clusterService.makeCustomObjectApi(region) + + // Make a request to read the Certificate resource + const res = await api.getNamespacedCustomObject( + 'cert-manager.io', + 'v1', + namespace, + 'certificates', + website.id, + ) + + return res.body + } catch (err) { + if (err?.response?.body?.reason === 'NotFound') return null + this.logger.error(err) + this.logger.error(err?.response?.body) + throw err + } + } + + // Create a certificate for a given website using cert-manager.io CRD + async createWebsiteDomainCert(region: Region, website: WebsiteHosting) { + // Get the namespace based on the application ID + const namespace = GetApplicationNamespaceByAppId(website.appid) + // Create a Kubernetes API client for the specified region + const api = this.clusterService.makeObjectApi(region) + + // Make a request to create the Certificate resource + const res = await api.create({ + apiVersion: 'cert-manager.io/v1', + kind: 'Certificate', + // Set the metadata for the Certificate resource + metadata: { + name: website.id, + namespace, + labels: { + 'laf.dev/website': website.id, + 'laf.dev/website-domain': website.domain, + [LABEL_KEY_APP_ID]: website.appid, + }, + }, + // Define the specification for the Certificate resource + spec: { + secretName: website.id, + dnsNames: [website.domain], + issuerRef: { + name: ServerConfig.CertManagerIssuerName, + kind: 'ClusterIssuer', + }, + }, + }) + return res.body + } + + // Delete a certificate for a given website using cert-manager.io CRD + async deleteWebsiteDomainCert(region: Region, website: WebsiteHosting) { + // Get the namespace based on the application ID + const namespace = GetApplicationNamespaceByAppId(website.appid) + // Create a Kubernetes API client for the specified region + const api = this.clusterService.makeObjectApi(region) + + // Make a request to delete the Certificate resource + const res = await api.delete({ + apiVersion: 'cert-manager.io/v1', + kind: 'Certificate', + metadata: { + name: website.id, + namespace, + }, + }) + + // GC the secret + await api + .delete({ + apiVersion: 'v1', + kind: 'Secret', + metadata: { + name: website.id, + namespace, + }, + }) + // Ignore errors, as the secret may not exist + .catch((err) => { + this.logger.error(err) + this.logger.error(err?.response?.body) + }) + + return res.body + } + + // Read an ApisixTls resource for a given website using apisix.apache.org CRD + async readWebsiteApisixTls(region: Region, website: WebsiteHosting) { + try { + // Get the namespace based on the application ID + const namespace = GetApplicationNamespaceByAppId(website.appid) + // Create an API object for the specified region + const api = this.clusterService.makeCustomObjectApi(region) + + // Make a request to read the ApisixTls resource + const res = await api.getNamespacedCustomObject( + 'apisix.apache.org', + 'v2', + namespace, + 'apisixtlses', + website.id, + ) + return res.body + } catch (err) { + if (err?.response?.body?.reason === 'NotFound') return null + this.logger.error(err) + this.logger.error(err?.response?.body) + throw err + } + } + + // Create an ApisixTls resource for a given website using apisix.apache.org CRD + async createWebsiteApisixTls(region: Region, website: WebsiteHosting) { + // Get the namespace based on the application ID + const namespace = GetApplicationNamespaceByAppId(website.appid) + // Create an API object for the specified region + const api = this.clusterService.makeObjectApi(region) + + // Make a request to create the ApisixTls resource + const res = await api.create({ + apiVersion: 'apisix.apache.org/v2', + kind: 'ApisixTls', + // Set the metadata for the ApisixTls resource + metadata: { + name: website.id, + namespace, + labels: { + 'laf.dev/website': website.id, + 'laf.dev/website-domain': website.domain, + [LABEL_KEY_APP_ID]: website.appid, + }, + }, + // Define the specification for the ApisixTls resource + spec: { + hosts: [website.domain], + secret: { + name: website.id, + namespace, + }, + }, + }) + return res.body + } + + // Deletes the APISIX TLS configuration for a specific website domain + async deleteWebsiteApisixTls(region: Region, website: WebsiteHosting) { + // Get the application namespace using the website's appid + const namespace = GetApplicationNamespaceByAppId(website.appid) + + // Create an API object for the specified region + const api = this.clusterService.makeObjectApi(region) + + // Send a delete request to remove the APISIX TLS configuration + const res = await api.delete({ + apiVersion: 'apisix.apache.org/v2', + kind: 'ApisixTls', + metadata: { + name: website.id, + namespace, + }, + }) + + return res.body + } +} diff --git a/server/src/gateway/apisix.service.ts b/server/src/gateway/apisix.service.ts index 9d43bade0f..19ef5a0455 100644 --- a/server/src/gateway/apisix.service.ts +++ b/server/src/gateway/apisix.service.ts @@ -14,6 +14,7 @@ export class ApisixService { const namespace = GetApplicationNamespaceByAppId(appid) const upstreamNode = `${appid}.${namespace}:8000` + // TODO: use appid as route id instead of `app-{appid} const id = `app-${appid}` const data = { name: id, @@ -46,6 +47,7 @@ export class ApisixService { } async deleteAppRoute(region: Region, appid: string) { + // TODO: use appid as route id instead of `app-{appid}` const id = `app-${appid}` const res = await this.deleteRoute(region, id) return res @@ -57,6 +59,7 @@ export class ApisixService { const minioUrl = new URL(region.storageConf.internalEndpoint) const upstreamNode = minioUrl.host + // TODO: use bucket object id as route id instead of bucket name const id = `bucket-${bucketName}` const data = { name: id, @@ -88,6 +91,7 @@ export class ApisixService { } async deleteBucketRoute(region: Region, bucketName: string) { + // TODO: use bucket object id as route id instead of bucket name const id = `bucket-${bucketName}` const res = await this.deleteRoute(region, id) return res @@ -148,8 +152,21 @@ export class ApisixService { const conf = region.gatewayConf const api_url = `${conf.apiUrl}/routes/${id}` + const res = await this.httpService.axiosRef.put(api_url, data, { + headers: { + 'X-API-KEY': conf.apiKey, + 'Content-Type': 'application/json', + }, + }) + return res.data + } + + async getRoute(region: Region, id: string) { + const conf = region.gatewayConf + const api_url = `${conf.apiUrl}/routes/${id}` + try { - const res = await this.httpService.axiosRef.put(api_url, data, { + const res = await this.httpService.axiosRef.get(api_url, { headers: { 'X-API-KEY': conf.apiKey, 'Content-Type': 'application/json', @@ -157,8 +174,11 @@ export class ApisixService { }) return res.data } catch (error) { - this.logger.error(error, error.response.data) - return null + if (error?.response?.status === 404) { + return null + } + this.logger.error(error, error.response?.data) + throw error } } diff --git a/server/src/gateway/bucket-domain-task.service.ts b/server/src/gateway/bucket-domain-task.service.ts index ed6b63c354..6be9e5f20e 100644 --- a/server/src/gateway/bucket-domain-task.service.ts +++ b/server/src/gateway/bucket-domain-task.service.ts @@ -4,7 +4,6 @@ import { RegionService } from 'src/region/region.service' import { ApisixService } from './apisix.service' import * as assert from 'node:assert' import { Cron, CronExpression } from '@nestjs/schedule' -import { times } from 'lodash' import { ServerConfig, TASK_LOCK_INIT_TIME } from 'src/constants' import { SystemDatabase } from 'src/database/system-database' @@ -26,22 +25,29 @@ export class BucketDomainTaskService { } // Phase `Creating` -> `Created` - times(this.concurrency, () => this.handleCreatingPhase()) + this.handleCreatingPhase().catch((err) => { + this.logger.error(err) + }) // Phase `Deleting` -> `Deleted` - times(this.concurrency, () => this.handleDeletingPhase()) + this.handleDeletingPhase().catch((err) => { + this.logger.error(err) + }) // Phase `Created` -> `Deleting` - this.handleInactiveState() + this.handleInactiveState().catch((err) => { + this.logger.error(err) + }) // Phase `Deleted` -> `Creating` - this.handleActiveState() + this.handleActiveState().catch((err) => { + this.logger.error(err) + }) // Phase `Deleting` -> `Deleted` - this.handleDeletedState() - - // Clear timeout locks - this.clearTimeoutLocks() + this.handleDeletedState().catch((err) => { + this.logger.error(err) + }) } /** @@ -57,15 +63,9 @@ export class BucketDomainTaskService { .findOneAndUpdate( { phase: DomainPhase.Creating, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) if (!res.value) return @@ -74,31 +74,27 @@ export class BucketDomainTaskService { const region = await this.regionService.findByAppId(doc.appid) assert(region, 'region not found') - // create route first - const route = await this.apisixService.createBucketRoute( - region, - doc.bucketName, - doc.domain, - ) - - this.logger.debug('bucket route created:', route) + // create route if not exists + const id = `bucket-${doc.bucketName}` + const route = await this.apisixService.getRoute(region, id) + if (!route) { + await await this.apisixService.createBucketRoute( + region, + doc.bucketName, + doc.domain, + ) + this.logger.log('bucket route created:' + doc.domain) + } // update phase to `Created` - const updated = await db.collection('BucketDomain').updateOne( - { - _id: doc._id, - phase: DomainPhase.Creating, - }, + await db.collection('BucketDomain').updateOne( + { _id: doc._id, phase: DomainPhase.Creating }, { - $set: { - phase: DomainPhase.Created, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: DomainPhase.Created, lockedAt: TASK_LOCK_INIT_TIME }, }, ) - if (updated.modifiedCount > 0) - this.logger.debug('bucket domain phase updated to Created', doc) + this.logger.log('bucket domain phase updated to Created: ' + doc.domain) } /** @@ -114,15 +110,9 @@ export class BucketDomainTaskService { .findOneAndUpdate( { phase: DomainPhase.Deleting, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) if (!res.value) return @@ -131,25 +121,19 @@ export class BucketDomainTaskService { const region = await this.regionService.findByAppId(doc.appid) assert(region, 'region not found') - // delete route first - const route = await this.apisixService.deleteBucketRoute( - region, - doc.bucketName, - ) - - this.logger.debug('bucket route deleted:', route) + // delete route if exists + const id = `bucket-${doc.bucketName}` + const route = await this.apisixService.getRoute(region, id) + if (route) { + await this.apisixService.deleteBucketRoute(region, doc.bucketName) + this.logger.log('bucket route deleted: ' + doc.bucketName) + } // update phase to `Deleted` const updated = await db.collection('BucketDomain').updateOne( + { _id: doc._id, phase: DomainPhase.Deleting }, { - _id: doc._id, - phase: DomainPhase.Deleting, - }, - { - $set: { - phase: DomainPhase.Deleted, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: DomainPhase.Deleted, lockedAt: TASK_LOCK_INIT_TIME }, }, ) @@ -168,12 +152,10 @@ export class BucketDomainTaskService { { state: DomainState.Active, phase: DomainPhase.Deleted, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, { - $set: { - phase: DomainPhase.Creating, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: DomainPhase.Creating, lockedAt: TASK_LOCK_INIT_TIME }, }, ) } @@ -188,13 +170,11 @@ export class BucketDomainTaskService { await db.collection('BucketDomain').updateMany( { state: DomainState.Inactive, - phase: DomainPhase.Created, + phase: { $in: [DomainPhase.Created, DomainPhase.Creating] }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, { - $set: { - phase: DomainPhase.Deleting, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: DomainPhase.Deleting, lockedAt: TASK_LOCK_INIT_TIME }, }, ) } @@ -211,12 +191,10 @@ export class BucketDomainTaskService { { state: DomainState.Deleted, phase: DomainPhase.Created, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, { - $set: { - phase: DomainPhase.Deleting, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: DomainPhase.Deleting, lockedAt: TASK_LOCK_INIT_TIME }, }, ) @@ -225,24 +203,4 @@ export class BucketDomainTaskService { phase: DomainPhase.Deleted, }) } - - /** - * Clear timeout locks - */ - async clearTimeoutLocks() { - const db = SystemDatabase.db - - await db.collection('BucketDomain').updateMany( - { - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, - ) - } } diff --git a/server/src/gateway/gateway.module.ts b/server/src/gateway/gateway.module.ts index 74d072422d..9bb5d48223 100644 --- a/server/src/gateway/gateway.module.ts +++ b/server/src/gateway/gateway.module.ts @@ -6,6 +6,7 @@ import { BucketDomainService } from './bucket-domain.service' import { WebsiteTaskService } from './website-task.service' import { BucketDomainTaskService } from './bucket-domain-task.service' import { RuntimeDomainTaskService } from './runtime-domain-task.service' +import { ApisixCustomCertService } from './apisix-custom-cert.service' @Module({ imports: [HttpModule], @@ -16,6 +17,7 @@ import { RuntimeDomainTaskService } from './runtime-domain-task.service' WebsiteTaskService, BucketDomainTaskService, RuntimeDomainTaskService, + ApisixCustomCertService, ], exports: [RuntimeDomainService, BucketDomainService], }) diff --git a/server/src/gateway/runtime-domain-task.service.ts b/server/src/gateway/runtime-domain-task.service.ts index 2f2fa4a09f..426b3d04b8 100644 --- a/server/src/gateway/runtime-domain-task.service.ts +++ b/server/src/gateway/runtime-domain-task.service.ts @@ -24,22 +24,29 @@ export class RuntimeDomainTaskService { } // Phase `Creating` -> `Created` - this.handleCreatingPhase() + this.handleCreatingPhase().catch((err) => { + this.logger.error(err) + }) // Phase `Deleting` -> `Deleted` - this.handleDeletingPhase() + this.handleDeletingPhase().catch((err) => { + this.logger.error(err) + }) // Phase `Created` -> `Deleting` - this.handleInactiveState() + this.handleInactiveState().catch((err) => { + this.logger.error(err) + }) // Phase `Deleted` -> `Creating` - this.handleActiveState() + this.handleActiveState().catch((err) => { + this.logger.error(err) + }) // Phase `Deleting` -> `Deleted` - this.handleDeletedState() - - // Clear timeout locks - this.clearTimeoutLocks() + this.handleDeletedState().catch((err) => { + this.logger.error(err) + }) } /** @@ -55,15 +62,9 @@ export class RuntimeDomainTaskService { .findOneAndUpdate( { phase: DomainPhase.Creating, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) if (!res.value) return @@ -75,33 +76,24 @@ export class RuntimeDomainTaskService { const region = await this.regionService.findByAppId(doc.appid) assert(region, 'region not found') - // create route first - const route = await this.apisixService.createAppRoute( - region, - doc.appid, - doc.domain, - ) - - this.logger.debug('app route created:', route) + // create route if not exists + const id = `app-${doc.appid}` + const route = await this.apisixService.getRoute(region, id) + if (!route) { + await this.apisixService.createAppRoute(region, doc.appid, doc.domain) + this.logger.log('app route created: ' + doc.appid) + this.logger.debug(route) + } // update phase to `Created` - const updated = await db - .collection('RuntimeDomain') - .updateOne( - { - _id: doc._id, - phase: DomainPhase.Creating, - }, - { - $set: { - phase: DomainPhase.Created, - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, - ) + await db.collection('RuntimeDomain').updateOne( + { _id: doc._id, phase: DomainPhase.Creating }, + { + $set: { phase: DomainPhase.Created, lockedAt: TASK_LOCK_INIT_TIME }, + }, + ) - if (updated.modifiedCount > 0) - this.logger.debug('app domain phase updated to Created ' + doc.domain) + this.logger.log('app domain phase updated to Created ' + doc.domain) } /** @@ -117,15 +109,9 @@ export class RuntimeDomainTaskService { .findOneAndUpdate( { phase: DomainPhase.Deleting, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) if (!res.value) return @@ -134,28 +120,24 @@ export class RuntimeDomainTaskService { const region = await this.regionService.findByAppId(doc.appid) assert(region, 'region not found') - // delete route first - const route = await this.apisixService.deleteAppRoute(region, doc.appid) - this.logger.debug('app route deleted:', route) + // delete route first if exists + const id = `app-${doc.appid}` + const route = await this.apisixService.getRoute(region, id) + if (route) { + await this.apisixService.deleteAppRoute(region, doc.appid) + this.logger.log('app route deleted: ' + doc.appid) + this.logger.debug(route) + } // update phase to `Deleted` - const updated = await db - .collection('RuntimeDomain') - .updateOne( - { - _id: doc._id, - phase: DomainPhase.Deleting, - }, - { - $set: { - phase: DomainPhase.Deleted, - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, - ) + await db.collection('RuntimeDomain').updateOne( + { _id: doc._id, phase: DomainPhase.Deleting }, + { + $set: { phase: DomainPhase.Deleted, lockedAt: TASK_LOCK_INIT_TIME }, + }, + ) - if (updated.modifiedCount > 0) - this.logger.debug('app domain phase updated to Deleted', doc) + this.logger.log('app domain phase updated to Deleted: ' + doc.appid) } /** @@ -169,12 +151,10 @@ export class RuntimeDomainTaskService { { state: DomainState.Active, phase: DomainPhase.Deleted, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, { - $set: { - phase: DomainPhase.Creating, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: DomainPhase.Creating, lockedAt: TASK_LOCK_INIT_TIME }, }, ) } @@ -189,13 +169,11 @@ export class RuntimeDomainTaskService { await db.collection('RuntimeDomain').updateMany( { state: DomainState.Inactive, - phase: DomainPhase.Created, + phase: { $in: [DomainPhase.Created, DomainPhase.Creating] }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, { - $set: { - phase: DomainPhase.Deleting, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: DomainPhase.Deleting, lockedAt: TASK_LOCK_INIT_TIME }, }, ) } @@ -212,12 +190,10 @@ export class RuntimeDomainTaskService { { state: DomainState.Deleted, phase: DomainPhase.Created, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, { - $set: { - phase: DomainPhase.Deleting, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: DomainPhase.Deleting, lockedAt: TASK_LOCK_INIT_TIME }, }, ) @@ -226,24 +202,4 @@ export class RuntimeDomainTaskService { phase: DomainPhase.Deleted, }) } - - /** - * Clear timeout locks - */ - async clearTimeoutLocks() { - const db = SystemDatabase.db - - await db.collection('RuntimeDomain').updateMany( - { - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, - ) - } } diff --git a/server/src/gateway/website-task.service.ts b/server/src/gateway/website-task.service.ts index b75ec239f9..a8634158a6 100644 --- a/server/src/gateway/website-task.service.ts +++ b/server/src/gateway/website-task.service.ts @@ -6,12 +6,14 @@ import { DomainState, WebsiteHosting, } from '@prisma/client' -import { times } from 'lodash' import { ServerConfig, TASK_LOCK_INIT_TIME } from 'src/constants' import { SystemDatabase } from 'src/database/system-database' import { RegionService } from 'src/region/region.service' import * as assert from 'node:assert' import { ApisixService } from './apisix.service' +import { ApisixCustomCertService } from './apisix-custom-cert.service' +import { ObjectId } from 'mongodb' +import { isConditionTrue } from 'src/utils/getter' @Injectable() export class WebsiteTaskService { @@ -22,6 +24,7 @@ export class WebsiteTaskService { constructor( private readonly regionService: RegionService, private readonly apisixService: ApisixService, + private readonly certService: ApisixCustomCertService, ) {} @Cron(CronExpression.EVERY_SECOND) @@ -31,22 +34,29 @@ export class WebsiteTaskService { } // Phase `Creating` -> `Created` - times(this.concurrency, () => this.handleCreatingPhase()) + this.handleCreatingPhase().catch((err) => { + this.logger.error(err) + }) // Phase `Deleting` -> `Deleted` - times(this.concurrency, () => this.handleDeletingPhase()) + this.handleDeletingPhase().catch((err) => { + this.logger.error(err) + }) // Phase `Created` -> `Deleting` - this.handleInactiveState() + this.handleInactiveState().catch((err) => { + this.logger.error(err) + }) // Phase `Deleted` -> `Creating` - this.handleActiveState() + this.handleActiveState().catch((err) => { + this.logger.error(err) + }) // Phase `Deleting` -> `Deleted` - this.handleDeletedState() - - // Clear timeout locks - this.clearTimeoutLocks() + this.handleDeletedState().catch((err) => { + this.logger.error(err) + }) } /** @@ -62,22 +72,19 @@ export class WebsiteTaskService { .findOneAndUpdate( { phase: DomainPhase.Creating, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) if (!res.value) return this.logger.debug(res.value) // get region by appid - const site = res.value + const site = { + ...res.value, + id: res.value._id.toString(), + } const region = await this.regionService.findByAppId(site.appid) assert(region, 'region not found') @@ -91,33 +98,70 @@ export class WebsiteTaskService { assert(bucketDomain, 'bucket domain not found') - // create website route - const route = await this.apisixService.createWebsiteRoute( - region, - site, - bucketDomain.domain, - ) - this.logger.debug(`create website route: `, route) + // create website route if not exists + const route = await this.apisixService.getRoute(region, site._id.toString()) + if (!route) { + const res = await this.apisixService.createWebsiteRoute( + region, + site, + bucketDomain.domain, + ) + this.logger.log(`create website route: ${site._id}`) + this.logger.debug(res) + } + + // create website custom certificate if custom domain is set + if (site.isCustom) { + const waitingTime = Date.now() - site.updatedAt.getTime() + + // create custom domain certificate + let cert = await this.certService.readWebsiteDomainCert(region, site) + if (!cert) { + cert = await this.certService.createWebsiteDomainCert(region, site) + this.logger.log(`create website cert: ${site._id}`) + // return to wait for cert to be ready + return await this.relock(site._id, waitingTime) + } + + // check if cert status is Ready + const conditions = (cert as any).status?.conditions || [] + if (!isConditionTrue('Ready', conditions)) { + this.logger.log(`website cert is not ready: ${site._id}`) + // return to wait for cert to be ready + return await this.relock(site._id, waitingTime) + } + + // config custom domain certificate to apisix + let apisixTls = await this.certService.readWebsiteApisixTls(region, site) + if (!apisixTls) { + apisixTls = await this.certService.createWebsiteApisixTls(region, site) + this.logger.log(`create website apisix tls: ${site._id}`) + // return to wait for tls config to be ready + return await this.relock(site._id, waitingTime) + } + + // check if apisix tls status is Ready + const apisixTlsConditions = (apisixTls as any).status?.conditions || [] + if (!isConditionTrue('ResourcesAvailable', apisixTlsConditions)) { + this.logger.log(`website apisix tls is not ready: ${site._id}`) + // return to wait for tls config to be ready + return await this.relock(site._id, waitingTime) + } + } // update phase to `Created` - const updated = await db - .collection('WebsiteHosting') - .updateOne( - { - _id: site._id, - phase: DomainPhase.Creating, - }, - { - $set: { - phase: DomainPhase.Created, - lockedAt: TASK_LOCK_INIT_TIME, - }, + await db.collection('WebsiteHosting').updateOne( + { _id: site._id, phase: DomainPhase.Creating }, + { + $set: { + phase: DomainPhase.Created, + lockedAt: TASK_LOCK_INIT_TIME, + updatedAt: new Date(), }, - ) + }, + ) - if (updated.modifiedCount !== 1) { - this.logger.error(`update website hosting phase failed: ${site._id}`) - } + this.logger.log(`update website phase to 'Created': ${site._id}`) } /** @@ -133,48 +177,64 @@ export class WebsiteTaskService { .findOneAndUpdate( { phase: DomainPhase.Deleting, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) if (!res.value) return // get region by appid - const site = res.value + const site = { + ...res.value, + id: res.value._id.toString(), + } const region = await this.regionService.findByAppId(site.appid) assert(region, 'region not found') - // delete website route - const route = await this.apisixService.deleteWebsiteRoute(region, site) - - this.logger.debug(`delete website route: `, route) + // delete website route if exists + const route = await this.apisixService.getRoute(region, site._id.toString()) + if (route) { + const res = await this.apisixService.deleteWebsiteRoute(region, site) + this.logger.log(`delete website route: ${res?.key}`) + this.logger.debug('delete website route', res) + } + // delete website custom certificate if custom domain is set + if (site.isCustom) { + const waitingTime = Date.now() - site.updatedAt.getTime() + + // delete custom domain certificate + const cert = await this.certService.readWebsiteDomainCert(region, site) + if (cert) { + await this.certService.deleteWebsiteDomainCert(region, site) + this.logger.log(`delete website cert: ${site._id}`) + // return to wait for cert to be deleted + return await this.relock(site._id, waitingTime) + } + + // delete custom domain tls config from apisix + const tls = await this.certService.readWebsiteApisixTls(region, site) + if (tls) { + await this.certService.deleteWebsiteApisixTls(region, site) + this.logger.log(`delete website apisix tls: ${site._id}`) + // return to wait for tls config to be deleted + return this.relock(site._id, waitingTime) + } + } // update phase to `Deleted` - const updated = await db - .collection('WebsiteHosting') - .updateOne( - { - _id: site._id, - phase: DomainPhase.Deleting, - }, - { - $set: { - phase: DomainPhase.Deleted, - lockedAt: TASK_LOCK_INIT_TIME, - }, + await db.collection('WebsiteHosting').updateOne( + { _id: site._id, phase: DomainPhase.Deleting }, + { + $set: { + phase: DomainPhase.Deleted, + lockedAt: TASK_LOCK_INIT_TIME, + updatedAt: new Date(), }, - ) + }, + ) - if (updated.modifiedCount > 1) { - this.logger.error(`update website hosting phase failed: ${site._id}`) - } + this.logger.log(`update website phase to 'Deleted': ${site._id}`) } /** @@ -187,12 +247,14 @@ export class WebsiteTaskService { await db.collection('WebsiteHosting').updateMany( { state: DomainState.Inactive, - phase: DomainPhase.Created, + phase: { $in: [DomainPhase.Created, DomainPhase.Creating] }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, { $set: { phase: DomainPhase.Deleting, lockedAt: TASK_LOCK_INIT_TIME, + updatedAt: new Date(), }, }, ) @@ -209,11 +271,13 @@ export class WebsiteTaskService { { state: DomainState.Active, phase: DomainPhase.Deleted, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, { $set: { phase: DomainPhase.Creating, lockedAt: TASK_LOCK_INIT_TIME, + updatedAt: new Date(), }, }, ) @@ -231,11 +295,13 @@ export class WebsiteTaskService { { state: DomainState.Deleted, phase: DomainPhase.Created, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, { $set: { phase: DomainPhase.Deleting, lockedAt: TASK_LOCK_INIT_TIME, + updatedAt: new Date(), }, }, ) @@ -247,21 +313,13 @@ export class WebsiteTaskService { } /** - * Clear timeout locks + * Relock application by appid, lockedTime is in milliseconds */ - async clearTimeoutLocks() { + async relock(id: ObjectId, lockedTime = 0) { const db = SystemDatabase.db - await db.collection('WebsiteHosting').updateMany( - { - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, - ) + const lockedAt = new Date(Date.now() - 1000 * this.lockTimeout + lockedTime) + await db + .collection('WebsiteHosting') + .updateOne({ _id: id }, { $set: { lockedAt } }) } } diff --git a/server/src/initializer/initializer.service.ts b/server/src/initializer/initializer.service.ts index 187e1deb0e..a2547da013 100644 --- a/server/src/initializer/initializer.service.ts +++ b/server/src/initializer/initializer.service.ts @@ -1,4 +1,5 @@ import { Injectable, Logger } from '@nestjs/common' +import { AuthProviderState } from '@prisma/client' import { RegionService } from 'src/region/region.service' import { MinioService } from 'src/storage/minio/minio.service' import { CPU_UNIT, ServerConfig } from '../constants' @@ -34,6 +35,7 @@ export class InitializerService { set: { driver: 'mongodb', connectionUri: ServerConfig.DEFAULT_REGION_DATABASE_URL, + controlConnectionUri: ServerConfig.DEFAULT_REGION_DATABASE_URL, }, }, storageConf: { @@ -46,6 +48,8 @@ export class InitializerService { ServerConfig.DEFAULT_REGION_MINIO_INTERNAL_ENDPOINT, accessKey: ServerConfig.DEFAULT_REGION_MINIO_ROOT_ACCESS_KEY, secretKey: ServerConfig.DEFAULT_REGION_MINIO_ROOT_SECRET_KEY, + controlEndpoint: + ServerConfig.DEFAULT_REGION_MINIO_INTERNAL_ENDPOINT, }, }, gatewayConf: { @@ -77,6 +81,9 @@ export class InitializerService { data: { name: 'standard', displayName: 'Standard', + limitCountPerUser: 10, + priority: 0, + maxRenewalTime: 3600 * 24 * 365 * 10, resource: { limitCPU: 1 * CPU_UNIT, limitMemory: 512, @@ -87,17 +94,39 @@ export class InitializerService { storageCapacity: 1024 * 5, networkTrafficOutbound: 1024 * 5, - limitCountPerUser: 50, limitCountOfCloudFunction: 500, limitCountOfBucket: 10, limitCountOfDatabasePolicy: 10, limitCountOfTrigger: 10, limitCountOfWebsiteHosting: 10, + reservedTimeAfterExpired: 3600 * 24 * 7, limitDatabaseTPS: 100, limitStorageTPS: 1000, }, - priority: 0, + subscriptionOptions: [ + { + name: 'monthly', + displayName: '1 Month', + duration: 31 * 24 * 3600, + price: 0, + specialPrice: 0, + }, + { + name: 'half-yearly', + displayName: '6 Months', + duration: 6 * 31 * 24 * 3600, + price: 0, + specialPrice: 0, + }, + { + name: 'yearly', + displayName: '12 Months', + duration: 12 * 31 * 24 * 3600, + price: 0, + specialPrice: 0, + }, + ], region: { connect: { name: 'default', @@ -134,17 +163,54 @@ export class InitializerService { return res } - async initMinioAlias() { - const regions = await this.regionService.findAll() - - for (const region of regions) { - const res = await this.minioService.setMinioClientTarget(region) - if (res.status === 'success') { - this.logger.verbose('MinioService init - ' + region.name + ' success') - } else { - this.logger.error('MinioService init - ' + region.name + ' failed', res) - throw new Error('set minio client target failed ' + region.name) - } + async createDefaultAuthProvider() { + // check if exists + const existed = await this.prisma.authProvider.count() + if (existed) { + this.logger.debug('default auth provider already exists') + return } + + // create default auth provider - user-password + const resPassword = await this.prisma.authProvider.create({ + data: { + name: 'user-password', + bind: { + password: 'optional', + phone: 'optional', + email: 'optional', + }, + register: true, + default: true, + state: AuthProviderState.Enabled, + config: { usernameField: 'username', passwordField: 'password' }, + }, + }) + + // create auth provider - phone code + const resPhone = await this.prisma.authProvider.create({ + data: { + name: 'phone', + bind: { + password: 'optional', + phone: 'optional', + email: 'optional', + }, + register: true, + default: false, + state: AuthProviderState.Disabled, + config: { + alisms: {}, + }, + }, + }) + + this.logger.verbose( + 'Created default auth providers: ' + + resPassword.name + + ' ' + + resPhone.name, + ) + return resPhone } } diff --git a/server/src/instance/instance-task.service.ts b/server/src/instance/instance-task.service.ts index 18c8b9e702..a76811c1f5 100644 --- a/server/src/instance/instance-task.service.ts +++ b/server/src/instance/instance-task.service.ts @@ -3,20 +3,18 @@ import { Cron, CronExpression } from '@nestjs/schedule' import { Application, ApplicationPhase, ApplicationState } from '@prisma/client' import { isConditionTrue } from '../utils/getter' import { InstanceService } from './instance.service' -import { times } from 'lodash' import { ServerConfig, TASK_LOCK_INIT_TIME } from 'src/constants' import { SystemDatabase } from 'src/database/system-database' -import { ClusterService } from 'src/region/cluster/cluster.service' +import { CronJobService } from 'src/trigger/cron-job.service' @Injectable() export class InstanceTaskService { - readonly lockTimeout = 60 // in second - readonly concurrency = 1 // concurrency count + readonly lockTimeout = 10 // in second private readonly logger = new Logger(InstanceTaskService.name) constructor( - private readonly clusterService: ClusterService, private readonly instanceService: InstanceService, + private readonly cronService: CronJobService, ) {} @Cron(CronExpression.EVERY_SECOND) @@ -26,82 +24,57 @@ export class InstanceTaskService { } // Phase `Created` | `Stopped` -> `Starting` - times(this.concurrency, () => this.handleRunningState()) + this.handleRunningState().catch((err) => { + this.logger.error('handleRunningState error', err) + this.logger.debug(err?.response?.toJSON() || JSON.stringify(err)) + }) // Phase `Starting` -> `Started` - times(this.concurrency, () => this.handleStartingPhase()) + this.handleStartingPhase().catch((err) => { + this.logger.error('handleStartingPhase error', err) + this.logger.debug(err?.response?.toJSON() || JSON.stringify(err)) + }) // Phase `Started` -> `Stopping` - times(this.concurrency, () => this.handleStoppedState()) + this.handleStoppedState().catch((err) => { + this.logger.error('handleStoppedState error', err) + this.logger.debug(err?.response?.toJSON() || JSON.stringify(err)) + }) // Phase `Stopping` -> `Stopped` - times(this.concurrency, () => this.handleStoppingPhase()) - - // Phase `Started` -> `Stopping` - times(this.concurrency, () => this.handleRestartingStateDown()) - - // Phase `Stopped` -> `Starting` - times(this.concurrency, () => this.handleRestartingStateUp()) - - // Clear timeout locks - this.clearTimeoutLocks() + this.handleStoppingPhase().catch((err) => { + this.logger.error('handleStoppingPhase error', err) + this.logger.debug(err?.response?.toJSON() || JSON.stringify(err)) + }) + + // Phase `Started` -> `Starting` + this.handleRestartingState().catch((err) => { + this.logger.error('handleRestartingPhase error', err) + err?.response && this.logger.debug(err?.response?.data || err?.response) + }) } /** * State `Running`: - * - create instance * - move phase `Created` or `Stopped` to `Starting` */ async handleRunningState() { const db = SystemDatabase.db - const res = await db - .collection('Application') - .findOneAndUpdate( - { - state: ApplicationState.Running, - phase: { - $in: [ApplicationPhase.Created, ApplicationPhase.Stopped], - }, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, - }, - ) - - if (!res.value) return - const app = res.value - - try { - // create instance - await this.instanceService.create(app) - - // update phase to `Starting` - const updated = await db.collection('Application').updateOne( - { - appid: app.appid, - phase: { - $in: [ApplicationPhase.Created, ApplicationPhase.Stopped], - }, - }, - { - $set: { - phase: ApplicationPhase.Starting, - lockedAt: TASK_LOCK_INIT_TIME, - }, + await db.collection('Application').updateMany( + { + state: ApplicationState.Running, + phase: { $in: [ApplicationPhase.Created, ApplicationPhase.Stopped] }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, + }, + { + $set: { + phase: ApplicationPhase.Starting, + lockedAt: TASK_LOCK_INIT_TIME, + updatedAt: new Date(), }, - ) - - if (updated.modifiedCount > 0) - this.logger.log(`Application ${app.appid} updated to phase starting`) - } catch (error) { - this.logger.error(error, error.response?.body) - } + }, + ) } /** @@ -117,116 +90,105 @@ export class InstanceTaskService { .findOneAndUpdate( { phase: ApplicationPhase.Starting, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) if (!res.value) return const app = res.value - try { - const appid = app.appid - const instance = await this.instanceService.get(app) - const available = isConditionTrue( - 'Available', - instance.deployment.status?.conditions, - ) - if (!available) { - await this.unlock(appid) - return - } - - if (!instance.service) { - await this.unlock(appid) - return - } - - // if state is `Restarting`, update state to `Running` with phase `Started` - let toState = app.state - if (app.state === ApplicationState.Restarting) { - toState = ApplicationState.Running - } - - // update application state - const updated = await db.collection('Application').updateOne( - { - appid, - phase: ApplicationPhase.Starting, - }, + // create instance + await this.instanceService.create(app) + + // if waiting time is more than 5 minutes, stop the application + const waitingTime = Date.now() - app.updatedAt.getTime() + if (waitingTime > 1000 * 60 * 5) { + await db.collection('Application').updateOne( + { appid: app.appid, phase: ApplicationPhase.Starting }, { $set: { - state: toState, + state: ApplicationState.Stopped, phase: ApplicationPhase.Started, lockedAt: TASK_LOCK_INIT_TIME, + updatedAt: new Date(), }, }, ) - if (updated.modifiedCount > 0) - this.logger.debug(`Application ${app.appid} updated to phase started`) - } catch (error) { - this.logger.error(error) + this.logger.log(`${app.appid} updated to state Stopped due to timeout`) + return } + + const appid = app.appid + const instance = await this.instanceService.get(app) + const unavailable = + instance.deployment?.status?.unavailableReplicas || false + if (unavailable) { + await this.relock(appid, waitingTime) + return + } + + const available = isConditionTrue( + 'Available', + instance.deployment?.status?.conditions || [], + ) + if (!available) { + await this.relock(appid, waitingTime) + return + } + + if (!instance.service) { + await this.relock(appid, waitingTime) + return + } + + // resume cronjobs if any + await this.cronService.resumeAll(app.appid) + + // if state is `Restarting`, update state to `Running` with phase `Started` + let toState = app.state + if (app.state === ApplicationState.Restarting) { + toState = ApplicationState.Running + } + + // update application state + await db.collection('Application').updateOne( + { appid, phase: ApplicationPhase.Starting }, + { + $set: { + state: toState, + phase: ApplicationPhase.Started, + lockedAt: TASK_LOCK_INIT_TIME, + updatedAt: new Date(), + }, + }, + ) + + this.logger.debug(`Application ${app.appid} updated to phase started`) } /** * State `Stopped`: - * - remove instance * - move phase `Started` to `Stopping` */ async handleStoppedState() { const db = SystemDatabase.db - const res = await db - .collection('Application') - .findOneAndUpdate( - { - state: ApplicationState.Stopped, - phase: ApplicationPhase.Started, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, - }, - ) - - if (!res.value) return - const app = res.value - - try { - // remove instance - await this.instanceService.remove(app) - - // update phase to `Stopping` - const updated = await db.collection('Application').updateOne( - { - appid: app.appid, - phase: ApplicationPhase.Started, - }, - { - $set: { - phase: ApplicationPhase.Stopping, - lockedAt: TASK_LOCK_INIT_TIME, - }, + await db.collection('Application').updateMany( + { + state: ApplicationState.Stopped, + phase: ApplicationPhase.Started, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, + }, + { + $set: { + lockedAt: TASK_LOCK_INIT_TIME, + phase: ApplicationPhase.Stopping, + updatedAt: new Date(), }, - ) - - if (updated.modifiedCount > 0) - this.logger.debug(`Application ${app.appid} updated to phase stopping`) - } catch (error) { - this.logger.error(error) - } + }, + ) } /** @@ -242,109 +204,55 @@ export class InstanceTaskService { .findOneAndUpdate( { phase: ApplicationPhase.Stopping, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) if (!res.value) return const app = res.value const appid = app.appid - try { - // check if the instance is removed - const instance = await this.instanceService.get(app) - if (instance.deployment) { - await this.unlock(appid) - return - } + const waitingTime = Date.now() - app.updatedAt.getTime() - // update application phase to `Stopped` - const updated = await db.collection('Application').updateOne( - { - appid, - phase: ApplicationPhase.Stopping, - }, - { - $set: { - phase: ApplicationPhase.Stopped, - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, - ) - - if (updated.modifiedCount > 0) - this.logger.debug(`Application ${app.appid} updated to phase stopped`) - } catch (error) { - this.logger.error(error) + // check if the instance is removed + const instance = await this.instanceService.get(app) + if (instance.deployment) { + await this.instanceService.remove(app) + await this.relock(appid, waitingTime) + return } - } - /** - * State `Restarting`: - * - remove instance - * - move phase `Started` to `Stopping` - */ - async handleRestartingStateDown() { - const db = SystemDatabase.db - - const res = await db - .collection('Application') - .findOneAndUpdate( - { - state: ApplicationState.Restarting, - phase: ApplicationPhase.Started, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, - }, - ) - - if (!res.value) return - const app = res.value - - try { - // remove instance + // check if the service is removed + if (instance.service) { await this.instanceService.remove(app) + await this.relock(appid, waitingTime) + return + } - // update phase to `Stopping` - const updated = await db.collection('Application').updateOne( - { - appid: app.appid, - phase: ApplicationPhase.Started, - }, - { - $set: { - phase: ApplicationPhase.Stopping, - lockedAt: TASK_LOCK_INIT_TIME, - }, + // suspend cronjobs if any + await this.cronService.suspendAll(app.appid) + + // update application phase to `Stopped` + await db.collection('Application').updateOne( + { appid, phase: ApplicationPhase.Stopping }, + { + $set: { + phase: ApplicationPhase.Stopped, + lockedAt: TASK_LOCK_INIT_TIME, + updatedAt: new Date(), }, - ) + }, + ) - if (updated.modifiedCount > 0) - this.logger.debug(`${app.appid} updated to stopping for restarting`) - } catch (error) { - this.logger.error(error) - } + this.logger.log(`Application ${app.appid} updated to phase Stopped`) } /** * State `Restarting`: - * - create instance - * - move phase `Stopped` to `Starting` + * - move phase `Started` to `Starting` */ - async handleRestartingStateUp() { + async handleRestartingState() { const db = SystemDatabase.db const res = await db @@ -352,80 +260,44 @@ export class InstanceTaskService { .findOneAndUpdate( { state: ApplicationState.Restarting, - phase: ApplicationPhase.Stopped, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + phase: ApplicationPhase.Started, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) if (!res.value) return const app = res.value - try { - // create instance - await this.instanceService.create(app) - - // update phase to `Starting` - const updated = await db.collection('Application').updateOne( - { - appid: app.appid, - phase: ApplicationPhase.Stopped, - }, - { - $set: { - phase: ApplicationPhase.Starting, - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, - ) - - if (updated.modifiedCount > 0) - this.logger.debug(`${app.appid} updated starting for restarting`) - } catch (error) { - this.logger.error(error) - } - } + await this.instanceService.restart(app.appid) - /** - * Unlock application by appid - */ - async unlock(appid: string) { - const db = SystemDatabase.db - const updated = await db.collection('Application').updateOne( - { - appid: appid, - }, + // update application phase to `Starting` + await db.collection('Application').updateOne( + { appid: app.appid, phase: ApplicationPhase.Started }, { $set: { + phase: ApplicationPhase.Starting, lockedAt: TASK_LOCK_INIT_TIME, + updatedAt: new Date(), }, }, ) + this.logger.log(`Application ${app.appid} updated to phase Starting`) } /** - * Clear timeout locks + * Relock application by appid, lockedTime is in milliseconds */ - async clearTimeoutLocks() { - const db = SystemDatabase.db + async relock(appid: string, lockedTime = 0) { + // if lockedTime greater than 3 minutes, set it to 3 minutes + if (lockedTime > 3 * 60 * 1000) { + lockedTime = 3 * 60 * 1000 + } - await db.collection('Application').updateMany( - { - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, - ) + const db = SystemDatabase.db + const lockedAt = new Date(Date.now() - 1000 * this.lockTimeout + lockedTime) + await db + .collection('Application') + .updateOne({ appid: appid }, { $set: { lockedAt } }) } } diff --git a/server/src/instance/instance.module.ts b/server/src/instance/instance.module.ts index 893c511755..87287d8741 100644 --- a/server/src/instance/instance.module.ts +++ b/server/src/instance/instance.module.ts @@ -3,9 +3,10 @@ import { InstanceService } from './instance.service' import { InstanceTaskService } from './instance-task.service' import { StorageModule } from '../storage/storage.module' import { DatabaseModule } from '../database/database.module' +import { TriggerModule } from 'src/trigger/trigger.module' @Module({ - imports: [StorageModule, DatabaseModule], + imports: [StorageModule, DatabaseModule, TriggerModule], providers: [InstanceService, InstanceTaskService], }) export class InstanceModule {} diff --git a/server/src/instance/instance.service.ts b/server/src/instance/instance.service.ts index 568bab7ae6..19ed43a70c 100644 --- a/server/src/instance/instance.service.ts +++ b/server/src/instance/instance.service.ts @@ -1,4 +1,4 @@ -import { V1Deployment } from '@kubernetes/client-node' +import { V1Deployment, V1DeploymentSpec } from '@kubernetes/client-node' import { Injectable, Logger } from '@nestjs/common' import { GetApplicationNamespaceByAppId } from '../utils/getter' import { @@ -26,7 +26,7 @@ export class InstanceService { private readonly storageService: StorageService, private readonly databaseService: DatabaseService, private readonly prisma: PrismaService, - ) {} + ) { } async create(app: Application) { const appid = app.appid @@ -34,6 +34,14 @@ export class InstanceService { const region = await this.regionService.findByAppId(appid) const appWithRegion = { ...app, region } as ApplicationWithRegion + // Although a namespace has already been created during application creation, + // we still need to check it again here in order to handle situations where the cluster is rebuilt. + const namespace = await this.clusterService.getAppNamespace(region, appid) + if (!namespace) { + this.logger.debug(`Creating namespace for application ${appid}`) + await this.clusterService.createAppNamespace(region, appid, app.createdBy) + } + const res = await this.get(appWithRegion) if (!res.deployment) { await this.createDeployment(appid, labels) @@ -59,6 +67,127 @@ export class InstanceService { // add bundle label labels[LABEL_KEY_BUNDLE] = app.bundle.name + // create deployment + const data = new V1Deployment() + data.metadata = { name: app.appid, labels } + data.spec = await this.makeDeploymentSpec(app, labels) + + const appsV1Api = this.clusterService.makeAppsV1Api(app.region) + const res = await appsV1Api.createNamespacedDeployment(namespace, data) + + this.logger.log(`create k8s deployment ${res.body?.metadata?.name}`) + + return res.body + } + + async createService(app: ApplicationWithRegion, labels: any) { + const namespace = GetApplicationNamespaceByAppId(app.appid) + const serviceName = app.appid + const coreV1Api = this.clusterService.makeCoreV1Api(app.region) + const res = await coreV1Api.createNamespacedService(namespace, { + metadata: { name: serviceName, labels }, + spec: { + selector: labels, + type: 'ClusterIP', + ports: [{ port: 8000, targetPort: 8000, protocol: 'TCP' }], + }, + }) + this.logger.log(`create k8s service ${res.body?.metadata?.name}`) + return res.body + } + + async remove(app: Application) { + const appid = app.appid + const region = await this.regionService.findByAppId(appid) + const { deployment, service } = await this.get(app) + + const namespace = await this.clusterService.getAppNamespace( + region, + app.appid, + ) + if (!namespace) return + + const appsV1Api = this.clusterService.makeAppsV1Api(region) + const coreV1Api = this.clusterService.makeCoreV1Api(region) + + if (deployment) { + await appsV1Api.deleteNamespacedDeployment(appid, namespace.metadata.name) + } + if (service) { + const name = appid + await coreV1Api.deleteNamespacedService(name, namespace.metadata.name) + } + this.logger.log(`remove k8s deployment ${deployment?.metadata?.name}`) + } + + async get(app: Application) { + const region = await this.regionService.findByAppId(app.appid) + const namespace = await this.clusterService.getAppNamespace( + region, + app.appid, + ) + if (!namespace) { + return { deployment: null, service: null } + } + + const appWithRegion = { ...app, region } + const deployment = await this.getDeployment(appWithRegion) + const service = await this.getService(appWithRegion) + return { deployment, service } + } + + async getDeployment(app: ApplicationWithRegion) { + const appid = app.appid + const appsV1Api = this.clusterService.makeAppsV1Api(app.region) + try { + const namespace = GetApplicationNamespaceByAppId(appid) + const res = await appsV1Api.readNamespacedDeployment(appid, namespace) + return res.body + } catch (error) { + if (error?.response?.body?.reason === 'NotFound') return null + throw error + } + } + + async getService(app: ApplicationWithRegion) { + const appid = app.appid + const coreV1Api = this.clusterService.makeCoreV1Api(app.region) + + try { + const serviceName = appid + const namespace = GetApplicationNamespaceByAppId(appid) + const res = await coreV1Api.readNamespacedService(serviceName, namespace) + return res.body + } catch (error) { + if (error?.response?.body?.reason === 'NotFound') return null + throw error + } + } + + // 修改整个spec + async restart(appid: string) { + const app = await this.prisma.application.findUnique({ + where: { appid }, + include: { + configuration: true, + bundle: true, + runtime: true, + region: true, + }, + }) + const { deployment } = await this.get(app) + deployment.spec = await this.makeDeploymentSpec(app, deployment.spec.template.metadata.labels) + const region = await this.regionService.findByAppId(app.appid) + const appsV1Api = this.clusterService.makeAppsV1Api(region) + const namespace = GetApplicationNamespaceByAppId(app.appid) + const res = await appsV1Api.replaceNamespacedDeployment(app.appid, namespace, deployment) + + this.logger.log(`restart k8s deployment ${res.body?.metadata?.name}`) + + } + + async makeDeploymentSpec(app: any, labels: any): Promise { + // prepare params const limitMemory = app.bundle.resource.limitMemory const limitCpu = app.bundle.resource.limitCPU @@ -70,13 +199,13 @@ export class InstanceService { const dependencies_string = dependencies.join(' ') // db connection uri - const database = await this.databaseService.findOne(appid) - const dbConnectionUri = this.databaseService.getConnectionUri( + const database = await this.databaseService.findOne(app.appid) + const dbConnectionUri = this.databaseService.getInternalConnectionUri( app.region, database, ) - const storage = await this.storageService.findOne(appid) + const storage = await this.storageService.findOne(app.appid) const env = [ { name: 'DB_URI', value: dbConnectionUri }, @@ -97,6 +226,9 @@ export class InstanceService { value: `--max_old_space_size=${max_old_space_size} --max-http-header-size=${max_http_header_size}`, }, { name: 'DEPENDENCIES', value: dependencies_string }, + { + name: 'RESTART_AT', value: new Date().getTime().toString(), + } ] // merge env from app configuration, override if exists @@ -110,10 +242,7 @@ export class InstanceService { } }) - // create deployment - const data = new V1Deployment() - data.metadata = { name: app.appid, labels } - data.spec = { + const spec = { replicas: 1, selector: { matchLabels: labels }, template: { @@ -226,80 +355,6 @@ export class InstanceService { }, // end of spec {} }, // end of template {} } - - const appsV1Api = this.clusterService.makeAppsV1Api(app.region) - const res = await appsV1Api.createNamespacedDeployment(namespace, data) - - this.logger.log(`create k8s deployment ${res.body?.metadata?.name}`) - - return res.body - } - - async createService(app: ApplicationWithRegion, labels: any) { - const namespace = GetApplicationNamespaceByAppId(app.appid) - const serviceName = app.appid - const coreV1Api = this.clusterService.makeCoreV1Api(app.region) - const res = await coreV1Api.createNamespacedService(namespace, { - metadata: { name: serviceName, labels }, - spec: { - selector: labels, - type: 'ClusterIP', - ports: [{ port: 8000, targetPort: 8000, protocol: 'TCP' }], - }, - }) - this.logger.log(`create k8s service ${res.body?.metadata?.name}`) - return res.body - } - - async remove(app: Application) { - const appid = app.appid - const region = await this.regionService.findByAppId(appid) - const { deployment, service } = await this.get(app) - const appsV1Api = this.clusterService.makeAppsV1Api(region) - const coreV1Api = this.clusterService.makeCoreV1Api(region) - - const namespace = GetApplicationNamespaceByAppId(appid) - if (deployment) { - await appsV1Api.deleteNamespacedDeployment(appid, namespace) - } - if (service) { - const name = appid - await coreV1Api.deleteNamespacedService(name, namespace) - } - } - - async get(app: Application) { - const region = await this.regionService.findByAppId(app.appid) - const appWithRegion = { ...app, region } - const deployment = await this.getDeployment(appWithRegion) - const service = await this.getService(appWithRegion) - return { deployment, service } - } - - async getDeployment(app: ApplicationWithRegion) { - const appid = app.appid - const appsV1Api = this.clusterService.makeAppsV1Api(app.region) - try { - const namespace = GetApplicationNamespaceByAppId(appid) - const res = await appsV1Api.readNamespacedDeployment(appid, namespace) - return res.body - } catch (error) { - if (error?.response?.body?.reason === 'NotFound') return null - return null - } - } - - async getService(app: ApplicationWithRegion) { - const appid = app.appid - const coreV1Api = this.clusterService.makeCoreV1Api(app.region) - - try { - const serviceName = appid - const namespace = GetApplicationNamespaceByAppId(appid) - const res = await coreV1Api.readNamespacedService(serviceName, namespace) - return res.body - } catch (error) { - return null - } + return spec } } diff --git a/server/src/main.ts b/server/src/main.ts index 847b715d6a..0271bf2952 100644 --- a/server/src/main.ts +++ b/server/src/main.ts @@ -50,7 +50,7 @@ async function bootstrap() { await initService.createDefaultRegion() await initService.createDefaultBundle() await initService.createDefaultRuntime() - await initService.initMinioAlias() + await initService.createDefaultAuthProvider() } catch (error) { console.error(error) process.exit(1) diff --git a/server/src/region/bundle.service.ts b/server/src/region/bundle.service.ts index c2f1b5ab1f..0616a880a3 100644 --- a/server/src/region/bundle.service.ts +++ b/server/src/region/bundle.service.ts @@ -1,4 +1,5 @@ import { Injectable, Logger } from '@nestjs/common' +import { Bundle } from '@prisma/client' import { PrismaService } from 'src/prisma/prisma.service' @Injectable() @@ -7,9 +8,9 @@ export class BundleService { constructor(private readonly prisma: PrismaService) {} - async findOne(id: string) { - return this.prisma.bundle.findUnique({ - where: { id }, + async findOne(id: string, regionId: string) { + return this.prisma.bundle.findFirst({ + where: { id, regionId }, }) } @@ -35,4 +36,10 @@ export class BundleService { where: { appid }, }) } + + getSubscriptionOption(bundle: Bundle, duration: number) { + const options = bundle.subscriptionOptions + const found = options.find((option) => option.duration === duration) + return found ? found : null + } } diff --git a/server/src/region/cluster/cluster.service.ts b/server/src/region/cluster/cluster.service.ts index 10a945085c..4653e0c8d4 100644 --- a/server/src/region/cluster/cluster.service.ts +++ b/server/src/region/cluster/cluster.service.ts @@ -52,8 +52,8 @@ export class ClusterService { return res.body } catch (err) { this.logger.error(err) - this.logger.debug(err?.response?.body) - return null + this.logger.error(err?.response?.body) + throw err } } @@ -67,8 +67,8 @@ export class ClusterService { } catch (err) { if (err?.response?.body?.reason === 'NotFound') return null this.logger.error(err) - this.logger.debug(err?.response?.body) - return null + this.logger.error(err?.response?.body) + throw err } } @@ -81,8 +81,8 @@ export class ClusterService { return res } catch (err) { this.logger.error(err) - this.logger.debug(err?.response?.body) - return null + this.logger.error(err?.response?.body) + throw err } } diff --git a/server/src/region/region.service.ts b/server/src/region/region.service.ts index fe8e670ae7..e027ff8bb9 100644 --- a/server/src/region/region.service.ts +++ b/server/src/region/region.service.ts @@ -29,9 +29,9 @@ export class RegionService { return regions } - async findOneDesensitized(name: string) { + async findOneDesensitized(id: string) { const region = await this.prisma.region.findUnique({ - where: { name }, + where: { id }, select: { id: true, name: true, @@ -60,15 +60,18 @@ export class RegionService { gatewayConf: false, databaseConf: false, clusterConf: false, + notes: true, bundles: { select: { id: true, name: true, displayName: true, - price: true, priority: true, state: true, resource: true, + limitCountPerUser: true, + subscriptionOptions: true, + notes: true, }, }, }, diff --git a/server/src/runtime-builtin-deps.ts b/server/src/runtime-builtin-deps.ts index 2e1201c472..7707fe74af 100644 --- a/server/src/runtime-builtin-deps.ts +++ b/server/src/runtime-builtin-deps.ts @@ -3,7 +3,7 @@ export const RUNTIME_BUILTIN_DEPENDENCIES = { '@aws-sdk/client-sts': '^3.231.0', '@aws-sdk/s3-request-presigner': '^3.231.0', '@kubernetes/client-node': '^0.18.0', - '@lafjs/cloud': '^0.0.2', + '@lafjs/cloud': '1.0.0-beta.4', 'alipay-sdk': '^3.2.0', axios: '^1.2.1', 'database-proxy': '^0.8.2', diff --git a/server/src/storage/bucket-task.service.ts b/server/src/storage/bucket-task.service.ts index 1dc14d7d78..bf54a56b74 100644 --- a/server/src/storage/bucket-task.service.ts +++ b/server/src/storage/bucket-task.service.ts @@ -1,9 +1,13 @@ import { Injectable, Logger } from '@nestjs/common' -import { DomainPhase, DomainState, StorageBucket } from '@prisma/client' +import { + DomainPhase, + DomainState, + StorageBucket, + WebsiteHosting, +} from '@prisma/client' import { RegionService } from 'src/region/region.service' import * as assert from 'node:assert' import { Cron, CronExpression } from '@nestjs/schedule' -import { times } from 'lodash' import { ServerConfig, TASK_LOCK_INIT_TIME } from 'src/constants' import { SystemDatabase } from 'src/database/system-database' import { MinioService } from './minio/minio.service' @@ -12,7 +16,6 @@ import { BucketDomainService } from 'src/gateway/bucket-domain.service' @Injectable() export class BucketTaskService { readonly lockTimeout = 30 // in second - readonly concurrency = 1 // concurrency count private readonly logger = new Logger(BucketTaskService.name) constructor( @@ -28,22 +31,29 @@ export class BucketTaskService { } // Phase `Creating` -> `Created` - times(this.concurrency, () => this.handleCreatingPhase()) + this.handleCreatingPhase().catch((err) => { + this.logger.error(err) + }) // Phase `Deleting` -> `Deleted` - times(this.concurrency, () => this.handleDeletingPhase()) + this.handleDeletingPhase().catch((err) => { + this.logger.error(err) + }) // Phase `Created` -> `Deleting` - this.handleInactiveState() + this.handleInactiveState().catch((err) => { + this.logger.error(err) + }) // Phase `Deleted` -> `Creating` - this.handleActiveState() + this.handleActiveState().catch((err) => { + this.logger.error(err) + }) // Phase `Deleting` -> `Deleted` - this.handleDeletedState() - - // Clear timeout locks - this.clearTimeoutLocks() + this.handleDeletedState().catch((err) => { + this.logger.error(err) + }) } /** @@ -59,15 +69,9 @@ export class BucketTaskService { .findOneAndUpdate( { phase: DomainPhase.Creating, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) if (!res.value) return @@ -105,16 +109,8 @@ export class BucketTaskService { const updated = await db .collection('StorageBucket') .updateOne( - { - _id: doc._id, - phase: DomainPhase.Creating, - }, - { - $set: { - phase: DomainPhase.Created, - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, + { _id: doc._id, phase: DomainPhase.Creating }, + { $set: { phase: DomainPhase.Created, lockedAt: TASK_LOCK_INIT_TIME } }, ) if (updated.modifiedCount > 0) @@ -134,15 +130,9 @@ export class BucketTaskService { .findOneAndUpdate( { phase: DomainPhase.Deleting, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) if (!res.value) return @@ -170,20 +160,24 @@ export class BucketTaskService { this.logger.debug('bucket domain deleted:', domain) } + // delete bucket website if exists + const websiteRes = await db + .collection('WebsiteHosting') + .updateMany( + { appid: doc.appid, bucketName: doc.name }, + { $set: { state: DomainState.Deleted } }, + ) + + if (websiteRes.modifiedCount > 0) { + this.logger.log('website state set to Deleted for bucket: ' + doc.name) + } + // update phase to `Deleted` const updated = await db .collection('StorageBucket') .updateOne( - { - _id: doc._id, - phase: DomainPhase.Deleting, - }, - { - $set: { - phase: DomainPhase.Deleted, - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, + { _id: doc._id, phase: DomainPhase.Deleting }, + { $set: { phase: DomainPhase.Deleted, lockedAt: TASK_LOCK_INIT_TIME } }, ) if (updated.modifiedCount > 0) @@ -201,12 +195,10 @@ export class BucketTaskService { { state: DomainState.Active, phase: DomainPhase.Deleted, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, { - $set: { - phase: DomainPhase.Creating, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: DomainPhase.Creating, lockedAt: TASK_LOCK_INIT_TIME }, }, ) } @@ -222,12 +214,10 @@ export class BucketTaskService { { state: DomainState.Inactive, phase: DomainPhase.Created, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, { - $set: { - phase: DomainPhase.Deleting, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: DomainPhase.Deleting, lockedAt: TASK_LOCK_INIT_TIME }, }, ) } @@ -243,39 +233,16 @@ export class BucketTaskService { await db.collection('StorageBucket').updateMany( { state: DomainState.Deleted, - phase: DomainPhase.Created, + phase: { $in: [DomainPhase.Created, DomainPhase.Creating] }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, { - $set: { - phase: DomainPhase.Deleting, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: DomainPhase.Deleting, lockedAt: TASK_LOCK_INIT_TIME }, }, ) - await db.collection('StorageBucket').deleteMany({ - state: DomainState.Deleted, - phase: DomainPhase.Deleted, - }) - } - - /** - * Clear timeout locks - */ - async clearTimeoutLocks() { - const db = SystemDatabase.db - - await db.collection('StorageBucket').updateMany( - { - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, - ) + await db + .collection('StorageBucket') + .deleteMany({ state: DomainState.Deleted, phase: DomainPhase.Deleted }) } } diff --git a/server/src/storage/bucket.controller.ts b/server/src/storage/bucket.controller.ts index dbf25c3196..812fb13a6d 100644 --- a/server/src/storage/bucket.controller.ts +++ b/server/src/storage/bucket.controller.ts @@ -156,6 +156,12 @@ export class BucketController { throw new HttpException('bucket not found', HttpStatus.NOT_FOUND) } + if (bucket?.websiteHosting) { + return ResponseUtil.error( + 'bucket has website hosting enabled, please delete it first', + ) + } + const res = await this.bucketService.delete(bucket) if (!res) { return ResponseUtil.error('delete bucket failed') diff --git a/server/src/storage/dto/create-bucket.dto.ts b/server/src/storage/dto/create-bucket.dto.ts index 53034beab3..f3d7404104 100644 --- a/server/src/storage/dto/create-bucket.dto.ts +++ b/server/src/storage/dto/create-bucket.dto.ts @@ -1,13 +1,13 @@ import { ApiProperty } from '@nestjs/swagger' import { BucketPolicy } from '@prisma/client' -import { IsEnum, IsNotEmpty, Length } from 'class-validator' +import { IsEnum, IsNotEmpty, Matches } from 'class-validator' export class CreateBucketDto { @ApiProperty({ description: 'The short name of the bucket which not contain the appid', }) @IsNotEmpty() - @Length(1, 32) + @Matches(/^[a-z0-9][a-z0-9-]{1,30}[a-z0-9]$/) shortName: string @ApiProperty({ diff --git a/server/src/storage/minio/minio.service.ts b/server/src/storage/minio/minio.service.ts index e809c1e8a8..feabc667dd 100644 --- a/server/src/storage/minio/minio.service.ts +++ b/server/src/storage/minio/minio.service.ts @@ -29,7 +29,7 @@ export class MinioService { const conf = region.storageConf return new S3({ - endpoint: conf.externalEndpoint, + endpoint: conf.controlEndpoint, credentials: { accessKeyId: conf.accessKey, secretAccessKey: conf.secretKey, @@ -49,7 +49,7 @@ export class MinioService { const target = region.name const sub_cmd = `admin user add ${target} ${username} ${password}` - return await this.executeMinioClientCmd(sub_cmd) + return await this.executeMinioClientCmd(region, sub_cmd) } /** @@ -60,7 +60,7 @@ export class MinioService { const target = region.name const sub_cmd = `admin user info ${target} ${username}` - const res = await this.executeMinioClientCmd(sub_cmd) + const res = await this.executeMinioClientCmd(region, sub_cmd) if (res.status !== 'success') return null return res } @@ -73,7 +73,7 @@ export class MinioService { const target = region.name const sub_cmd = `admin user remove ${target} ${username}` - return await this.executeMinioClientCmd(sub_cmd) + return await this.executeMinioClientCmd(region, sub_cmd) } /** @@ -84,7 +84,7 @@ export class MinioService { const target = region.name const sub_cmd = `admin group add ${target} ${MINIO_COMMON_USER_GROUP} ${username}` - return await this.executeMinioClientCmd(sub_cmd) + return await this.executeMinioClientCmd(region, sub_cmd) } /** @@ -171,7 +171,7 @@ export class MinioService { const sub_cmd = `du ${region.name}/${bucket}` - const res = await this.executeMinioClientCmd(sub_cmd) + const res = await this.executeMinioClientCmd(region, sub_cmd) return res as GetBucketUsedSizeOutput } @@ -183,7 +183,7 @@ export class MinioService { const target = region.name const sub_cmd = `rb --force ${target}/${bucket}` - return await this.executeMinioClientCmd(sub_cmd) + return await this.executeMinioClientCmd(region, sub_cmd) } /** @@ -217,8 +217,12 @@ export class MinioService { * Execute minio client shell */ private async executeMinioClientCmd( + region: Region, sub_cmd: string, ): Promise { + const res = await this.setMinioClientTarget(region) + assert(res.status === 'success', 'failed to set minio client target') + const mc_path = process.env.MINIO_CLIENT_PATH || 'mc' const cmd = `${mc_path} ${sub_cmd} --json` @@ -242,12 +246,23 @@ export class MinioService { const conf = region.storageConf const access_key = conf.accessKey const access_secret = conf.secretKey - const endpoint = conf.externalEndpoint + const endpoint = conf.controlEndpoint const target = region.name - const cmd = `alias set ${target} ${endpoint} ${access_key} ${access_secret}` + const mc_path = process.env.MINIO_CLIENT_PATH || 'mc' + const cmd = `${mc_path} alias set ${target} ${endpoint} ${access_key} ${access_secret} --json` - return await this.executeMinioClientCmd(cmd) + try { + const { stdout } = await exec(cmd) + const json: MinioCommandExecOutput = JSON.parse(stdout) + return json + } catch (error) { + this.logger.error(`failed to exec command: {${cmd}}`, error) + return { + status: 'error', + error: error, + } + } } /** diff --git a/server/src/storage/storage.module.ts b/server/src/storage/storage.module.ts index 97746c494b..934fd530b1 100644 --- a/server/src/storage/storage.module.ts +++ b/server/src/storage/storage.module.ts @@ -17,6 +17,6 @@ import { BucketTaskService } from './bucket-task.service' BucketService, BucketTaskService, ], - exports: [StorageService, MinioService], + exports: [StorageService, MinioService, BucketService], }) export class StorageModule {} diff --git a/server/src/storage/storage.service.ts b/server/src/storage/storage.service.ts index 058302ca91..43801bb638 100644 --- a/server/src/storage/storage.service.ts +++ b/server/src/storage/storage.service.ts @@ -84,13 +84,9 @@ export class StorageService { await this.prisma.storageBucket.updateMany({ where: { appid, - state: { - not: StorageState.Deleted, - }, - }, - data: { - state: StorageState.Deleted, + state: { not: StorageState.Deleted }, }, + data: { state: StorageState.Deleted }, }) return diff --git a/server/src/application/dto/create-application.dto.ts b/server/src/subscription/dto/create-subscription.dto.ts similarity index 80% rename from server/src/application/dto/create-application.dto.ts rename to server/src/subscription/dto/create-subscription.dto.ts index 7a3eb7277f..082735a3a3 100644 --- a/server/src/application/dto/create-application.dto.ts +++ b/server/src/subscription/dto/create-subscription.dto.ts @@ -1,13 +1,13 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { ApplicationState } from '@prisma/client' -import { IsEnum, IsNotEmpty, IsString, Length } from 'class-validator' +import { IsEnum, IsInt, IsNotEmpty, IsString, Length } from 'class-validator' enum CreateApplicationState { Running = 'Running', Stopped = 'Stopped', } -export class CreateApplicationDto { +export class CreateSubscriptionDto { @ApiProperty({ required: true }) @Length(1, 64) @IsNotEmpty() @@ -36,6 +36,11 @@ export class CreateApplicationDto { @IsString() runtimeId: string + @ApiProperty() + @IsInt() + @IsNotEmpty() + duration: number + validate(): string | null { return null } diff --git a/server/src/subscription/dto/renew-subscription.dto.ts b/server/src/subscription/dto/renew-subscription.dto.ts new file mode 100644 index 0000000000..f43bc305e5 --- /dev/null +++ b/server/src/subscription/dto/renew-subscription.dto.ts @@ -0,0 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger' +import { IsInt, IsNotEmpty } from 'class-validator' + +export class RenewSubscriptionDto { + @ApiProperty() + @IsInt() + @IsNotEmpty() + duration: number +} diff --git a/server/src/subscription/dto/upgrade-subscription.dto.ts b/server/src/subscription/dto/upgrade-subscription.dto.ts new file mode 100644 index 0000000000..4765628cac --- /dev/null +++ b/server/src/subscription/dto/upgrade-subscription.dto.ts @@ -0,0 +1,11 @@ +import { IsBoolean, IsNotEmpty, IsString } from 'class-validator' + +export class UpgradeSubscriptionDto { + @IsString() + @IsNotEmpty() + targetBundleId: string + + @IsBoolean() + @IsNotEmpty() + restart: boolean +} diff --git a/server/src/subscription/renewal-task.service.ts b/server/src/subscription/renewal-task.service.ts new file mode 100644 index 0000000000..da7440c74c --- /dev/null +++ b/server/src/subscription/renewal-task.service.ts @@ -0,0 +1,170 @@ +import { + Account, + SubscriptionRenewal, + SubscriptionRenewalPhase, +} from '.prisma/client' +import { Injectable, Logger } from '@nestjs/common' +import { Cron, CronExpression } from '@nestjs/schedule' +import { ServerConfig, TASK_LOCK_INIT_TIME } from 'src/constants' +import { SystemDatabase } from 'src/database/system-database' +import { ObjectId } from 'mongodb' +import { AccountService } from 'src/account/account.service' +import { Subscription } from '@prisma/client' + +@Injectable() +export class SubscriptionRenewalTaskService { + readonly lockTimeout = 30 // in second + readonly concurrency = 1 // concurrency count + + private readonly logger = new Logger(SubscriptionRenewalTaskService.name) + + constructor(private readonly accountService: AccountService) {} + + @Cron(CronExpression.EVERY_SECOND) + async tick() { + if (ServerConfig.DISABLED_SUBSCRIPTION_TASK) { + return + } + + // Phase `Pending` -> `Paid` + this.handlePendingPhase() + } + + /** + * Phase `Pending`: + * 1. Pay the subscription renewal order from account balance (Transaction) + * 2. Update subscription 'expiredAt' time (Transaction) (lock document) + * 3. Update subscription renewal order phase to ‘Paid’ (Transaction) + */ + async handlePendingPhase() { + const db = SystemDatabase.db + const client = SystemDatabase.client + + const doc = await db + .collection('SubscriptionRenewal') + .findOneAndUpdate( + { + phase: SubscriptionRenewalPhase.Pending, + lockedAt: { $lte: new Date(Date.now() - this.lockTimeout * 1000) }, + }, + { $set: { lockedAt: new Date() } }, + ) + + if (!doc.value) { + return + } + + const renewal = doc.value + + // check account balance + const userid = renewal.createdBy + const session = client.startSession() + await session + .withTransaction(async () => { + const account = await db + .collection('Account') + .findOne({ createdBy: userid }, { session }) + + // if account balance is not enough, delete the subscription & renewal order + if (account?.balance < renewal.amount) { + await db + .collection('SubscriptionRenewal') + .deleteOne({ _id: renewal._id }, { session }) + + await db + .collection('Subscription') + .deleteOne( + { _id: new ObjectId(renewal.subscriptionId) }, + { session }, + ) + return + } + + // Pay the subscription renewal order from account balance + const priceAmount = renewal.amount + if (priceAmount !== 0) { + await db.collection('Account').updateOne( + { + _id: account._id, + balance: { $gte: priceAmount }, + }, + { $inc: { balance: -priceAmount } }, + { session }, + ) + + // Create account transaction + await db.collection('AccountTransaction').insertOne( + { + accountId: account._id, + amount: -priceAmount, + balance: account.balance - priceAmount, + message: `subscription renewal order ${renewal._id}`, + createdAt: new Date(), + updatedAt: new Date(), + }, + { session }, + ) + } + + // Update subscription 'expiredAt' time + await db.collection('Subscription').updateOne( + { _id: new ObjectId(renewal.subscriptionId) }, + [ + { + $set: { + expiredAt: { $add: ['$expiredAt', renewal.duration * 1000] }, + }, + }, + ], + { session }, + ) + + // Update subscription renewal order phase to ‘Paid’ + await db + .collection('SubscriptionRenewal') + .updateOne( + { _id: renewal._id }, + { + $set: { + phase: SubscriptionRenewalPhase.Paid, + lockedAt: TASK_LOCK_INIT_TIME, + }, + }, + { session }, + ) + }) + .catch((err) => { + this.logger.debug(renewal._id, err.toString()) + }) + } + + @Cron(CronExpression.EVERY_MINUTE) + async handlePendingTimeout() { + const timeout = 30 * 60 * 1000 + + const db = SystemDatabase.db + await db.collection('SubscriptionRenewal').updateMany( + { + phase: SubscriptionRenewalPhase.Pending, + lockedAt: { $lte: new Date(Date.now() - this.lockTimeout * 1000) }, + createdAt: { $lte: new Date(Date.now() - timeout) }, + }, + { + $set: { + phase: SubscriptionRenewalPhase.Failed, + message: `Timeout exceeded ${timeout / 1000} seconds`, + }, + }, + ) + } + + /** + * Unlock subscription + */ + async unlock(id: ObjectId) { + const db = SystemDatabase.db + await db + .collection('SubscriptionRenewal') + .updateOne({ _id: id }, { $set: { lockedAt: TASK_LOCK_INIT_TIME } }) + } +} diff --git a/server/src/subscription/subscription-task.service.ts b/server/src/subscription/subscription-task.service.ts new file mode 100644 index 0000000000..5ab5b49bc3 --- /dev/null +++ b/server/src/subscription/subscription-task.service.ts @@ -0,0 +1,287 @@ +import { Application, Subscription, SubscriptionPhase } from '.prisma/client' +import { Injectable, Logger } from '@nestjs/common' +import { Cron, CronExpression } from '@nestjs/schedule' +import { ServerConfig, TASK_LOCK_INIT_TIME } from 'src/constants' +import { SystemDatabase } from 'src/database/system-database' +import * as assert from 'node:assert' +import { ApplicationService } from 'src/application/application.service' +import { ApplicationState, SubscriptionState } from '@prisma/client' +import { ObjectId } from 'mongodb' +import { BundleService } from 'src/region/bundle.service' +import { CreateSubscriptionDto } from './dto/create-subscription.dto' + +@Injectable() +export class SubscriptionTaskService { + readonly lockTimeout = 30 // in second + + private readonly logger = new Logger(SubscriptionTaskService.name) + + constructor( + private readonly bundleService: BundleService, + private readonly applicationService: ApplicationService, + ) {} + + @Cron(CronExpression.EVERY_SECOND) + async tick() { + if (ServerConfig.DISABLED_SUBSCRIPTION_TASK) { + return + } + + // Phase `Pending` -> `Valid` + this.handlePendingPhaseAndNotExpired() + + // Phase `Valid` -> `Expired` + this.handleValidPhaseAndExpired() + + // Phase `Expired` -> `ExpiredAndStopped` + this.handleExpiredPhase() + + // Phase `ExpiredAndStopped` -> `Valid` + this.handleExpiredAndStoppedPhaseAndNotExpired() + + // Phase `ExpiredAndStopped` -> `Deleted` + this.handleExpiredAndStoppedPhase() + + // State `Deleted` + this.handleDeletedState() + } + + /** + * Phase `Pending` and not expired: + * - if appid is null, generate appid + * - if appid exists, but application is not found + * - create application + * - update subscription phase to `Valid` + */ + async handlePendingPhaseAndNotExpired() { + const db = SystemDatabase.db + + const res = await db + .collection('Subscription') + .findOneAndUpdate( + { + phase: SubscriptionPhase.Pending, + expiredAt: { $gt: new Date() }, + lockedAt: { $lt: new Date(Date.now() - this.lockTimeout * 1000) }, + }, + { $set: { lockedAt: new Date() } }, + ) + if (!res.value) return + + // get region by appid + const doc = res.value + + // if application not found, create application + const application = await this.applicationService.findOne(doc.appid) + if (!application) { + const userid = doc.createdBy.toString() + const dto = new CreateSubscriptionDto() + dto.name = doc.input.name + dto.regionId = doc.input.regionId + dto.state = doc.input.state as ApplicationState + dto.runtimeId = doc.input.runtimeId + // doc.bundleId is ObjectId, but prisma typed it as string, so we need to convert it + dto.bundleId = doc.bundleId.toString() + this.logger.debug(dto) + + await this.applicationService.create(userid, doc.appid, dto) + return await this.unlock(doc._id) + } + + // update subscription phase to `Valid` + await db.collection('Subscription').updateOne( + { _id: doc._id }, + { + $set: { phase: SubscriptionPhase.Valid, lockedAt: TASK_LOCK_INIT_TIME }, + }, + ) + } + + /** + * Phase ‘Valid’ with expiredAt < now + * - update subscription phase to ‘Expired’ + */ + async handleValidPhaseAndExpired() { + const db = SystemDatabase.db + + await db.collection('Subscription').updateMany( + { + phase: SubscriptionPhase.Valid, + expiredAt: { $lt: new Date() }, + }, + { $set: { phase: SubscriptionPhase.Expired } }, + ) + } + + /** + * Phase 'Expired': + * - update application state to 'Stopped' + * - update subscription phase to 'ExpiredAndStopped' + */ + async handleExpiredPhase() { + const db = SystemDatabase.db + + const res = await db + .collection('Subscription') + .findOneAndUpdate( + { + phase: SubscriptionPhase.Expired, + lockedAt: { $lt: new Date(Date.now() - this.lockTimeout * 1000) }, + }, + { $set: { lockedAt: new Date() } }, + ) + if (!res.value) return + + const doc = res.value + + // update application state to 'Stopped' + await db + .collection('Application') + .updateOne( + { appid: doc.appid }, + { $set: { state: ApplicationState.Stopped } }, + ) + + // update subscription phase to 'ExpiredAndStopped' + await db.collection('Subscription').updateOne( + { _id: doc._id }, + { + $set: { + phase: SubscriptionPhase.ExpiredAndStopped, + lockedAt: TASK_LOCK_INIT_TIME, + }, + }, + ) + } + + /** + * Phase 'ExpiredAndStopped' but not expired (renewal case): + * - update subscription phase to ‘Valid’ + * (TODO) update application state to ‘Running’ + */ + async handleExpiredAndStoppedPhaseAndNotExpired() { + const db = SystemDatabase.db + + await db.collection('Subscription').updateMany( + { + phase: SubscriptionPhase.ExpiredAndStopped, + expiredAt: { $gt: new Date() }, + }, + { $set: { phase: SubscriptionPhase.Valid } }, + ) + } + + /** + * Phase 'ExpiredAndStopped': + * -if ‘Bundle.reservedTimeAfterExpired’ expired + * 1. Update application state to ‘Deleted’ + * 2. Update subscription phase to ‘ExpiredAndDeleted’ + */ + async handleExpiredAndStoppedPhase() { + const db = SystemDatabase.db + + const specialLockTimeout = 60 * 60 // 1 hour + + const res = await db + .collection('Subscription') + .findOneAndUpdate( + { + phase: SubscriptionPhase.ExpiredAndStopped, + lockedAt: { $lt: new Date(Date.now() - specialLockTimeout * 1000) }, + }, + { $set: { lockedAt: new Date() } }, + ) + if (!res.value) return + + const doc = res.value + + // if ‘Bundle.reservedTimeAfterExpired’ expired + const bundle = await this.bundleService.findApplicationBundle(doc.appid) + assert(bundle, 'bundle not found') + + const reservedTimeAfterExpired = + bundle.resource.reservedTimeAfterExpired * 1000 + const expiredTime = Date.now() - doc.expiredAt.getTime() + if (expiredTime < reservedTimeAfterExpired) { + return // return directly without unlocking it! + } + + // 2. Update subscription state to 'Deleted' + await db.collection('Subscription').updateOne( + { _id: doc._id }, + { + $set: { + state: SubscriptionState.Deleted, + lockedAt: TASK_LOCK_INIT_TIME, + }, + }, + ) + } + + /** + * State `Deleted` + */ + async handleDeletedState() { + const db = SystemDatabase.db + const res = await db + .collection('Subscription') + .findOneAndUpdate( + { + state: SubscriptionState.Deleted, + phase: { $not: { $eq: SubscriptionPhase.Deleted } }, + lockedAt: { $lt: new Date(Date.now() - this.lockTimeout * 1000) }, + }, + { $set: { lockedAt: new Date() } }, + ) + if (!res.value) return + + const doc = res.value + + const app = await this.applicationService.findOne(doc.appid) + if (app && app.state !== ApplicationState.Deleted) { + // delete application, update application state to ‘Deleted’ + await this.applicationService.remove(doc.appid) + this.logger.debug(`deleting application: ${doc.appid}`) + } + + // wait for application to be deleted + if (app) { + this.logger.debug(`waiting for application to be deleted: ${doc.appid}`) + return // return directly without unlocking it + } + + // Update subscription phase to 'Deleted' + await db.collection('Subscription').updateOne( + { _id: doc._id }, + { + $set: { + phase: SubscriptionPhase.Deleted, + lockedAt: TASK_LOCK_INIT_TIME, + }, + }, + ) + this.logger.debug(`subscription phase updated to deleted: ${doc.appid}`) + } + + @Cron(CronExpression.EVERY_MINUTE) + async handlePendingTimeout() { + const timeout = 10 * 60 * 1000 + + const db = SystemDatabase.db + await db.collection('Subscription').deleteMany({ + phase: SubscriptionPhase.Pending, + lockedAt: { $lte: new Date(Date.now() - this.lockTimeout * 1000) }, + createdAt: { $lte: new Date(Date.now() - timeout) }, + }) + } + + /** + * Unlock subscription + */ + async unlock(id: ObjectId) { + const db = SystemDatabase.db + await db + .collection('Subscription') + .updateOne({ _id: id }, { $set: { lockedAt: TASK_LOCK_INIT_TIME } }) + } +} diff --git a/server/src/subscription/subscription.controller.ts b/server/src/subscription/subscription.controller.ts new file mode 100644 index 0000000000..f170b93906 --- /dev/null +++ b/server/src/subscription/subscription.controller.ts @@ -0,0 +1,275 @@ +import { + Controller, + Get, + Post, + Body, + Patch, + Param, + Delete, + Logger, + UseGuards, + Req, +} from '@nestjs/common' +import { SubscriptionService } from './subscription.service' +import { CreateSubscriptionDto } from './dto/create-subscription.dto' +import { UpgradeSubscriptionDto } from './dto/upgrade-subscription.dto' +import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger' +import { JwtAuthGuard } from 'src/auth/jwt.auth.guard' +import { IRequest } from 'src/utils/interface' +import { ResponseUtil } from 'src/utils/response' +import { BundleService } from 'src/region/bundle.service' +import { PrismaService } from 'src/prisma/prisma.service' +import { ApplicationService } from 'src/application/application.service' +import { RegionService } from 'src/region/region.service' +import { ApplicationAuthGuard } from 'src/auth/application.auth.guard' +import { RenewSubscriptionDto } from './dto/renew-subscription.dto' +import * as assert from 'assert' +import { SubscriptionState } from '@prisma/client' +import { AccountService } from 'src/account/account.service' + +@ApiTags('Subscription') +@Controller('subscriptions') +@ApiBearerAuth('Authorization') +export class SubscriptionController { + private readonly logger = new Logger(SubscriptionController.name) + + constructor( + private readonly subscriptService: SubscriptionService, + private readonly applicationService: ApplicationService, + private readonly bundleService: BundleService, + private readonly prisma: PrismaService, + private readonly regionService: RegionService, + private readonly accountService: AccountService, + ) {} + + /** + * Create a new subscription + */ + @ApiOperation({ summary: 'Create a new subscription' }) + @UseGuards(JwtAuthGuard) + @Post() + async create(@Body() dto: CreateSubscriptionDto, @Req() req: IRequest) { + const user = req.user + + // check regionId exists + const region = await this.regionService.findOneDesensitized(dto.regionId) + if (!region) { + return ResponseUtil.error(`region ${dto.regionId} not found`) + } + + // check runtimeId exists + const runtime = await this.prisma.runtime.findUnique({ + where: { id: dto.runtimeId }, + }) + if (!runtime) { + return ResponseUtil.error(`runtime ${dto.runtimeId} not found`) + } + + // check bundleId exists + const bundle = await this.bundleService.findOne(dto.bundleId, region.id) + if (!bundle) { + return ResponseUtil.error(`bundle ${dto.bundleId} not found`) + } + + // check app count limit + const LIMIT_COUNT = bundle.limitCountPerUser || 0 + const count = await this.prisma.subscription.count({ + where: { + createdBy: user.id, + bundleId: dto.bundleId, + state: { not: SubscriptionState.Deleted }, + }, + }) + if (count >= LIMIT_COUNT) { + return ResponseUtil.error( + `application count limit is ${LIMIT_COUNT} for bundle ${bundle.name}`, + ) + } + + // check duration supported + const option = this.bundleService.getSubscriptionOption( + bundle, + dto.duration, + ) + if (!option) { + return ResponseUtil.error(`duration not supported in bundle`) + } + + // check account balance + const account = await this.accountService.findOne(user.id) + const balance = account?.balance || 0 + const priceAmount = option.specialPrice + if (balance < priceAmount) { + return ResponseUtil.error( + `account balance is not enough, need ${priceAmount} but only ${account.balance}`, + ) + } + + // create subscription + const appid = await this.applicationService.tryGenerateUniqueAppid() + const subscription = await this.subscriptService.create( + user.id, + appid, + dto, + option, + ) + return ResponseUtil.ok(subscription) + } + + /** + * Get user's subscriptions + */ + @ApiOperation({ summary: "Get user's subscriptions" }) + @UseGuards(JwtAuthGuard) + @Get() + async findAll(@Req() req: IRequest) { + const user = req.user + const subscriptions = await this.subscriptService.findAll(user.id) + return ResponseUtil.ok(subscriptions) + } + + /** + * Get subscription by appid + */ + @ApiOperation({ summary: 'Get subscription by appid' }) + @UseGuards(JwtAuthGuard, ApplicationAuthGuard) + @Get(':appid') + async findOne(@Param('appid') appid: string) { + const subscription = await this.subscriptService.findOneByAppid(appid) + if (!subscription) { + return ResponseUtil.error(`subscription ${appid} not found`) + } + + return ResponseUtil.ok(subscription) + } + + /** + * Renew a subscription + */ + @ApiOperation({ summary: 'Renew a subscription' }) + @UseGuards(JwtAuthGuard) + @Post(':id/renewal') + async renew( + @Param('id') id: string, + @Body() dto: RenewSubscriptionDto, + @Req() req: IRequest, + ) { + const { duration } = dto + + // get subscription + const user = req.user + const subscription = await this.subscriptService.findOne(user.id, id) + if (!subscription) { + return ResponseUtil.error(`subscription ${id} not found`) + } + + const app = subscription.application + const bundle = await this.bundleService.findOne( + subscription.bundleId, + app.regionId, + ) + assert(bundle, `bundle ${subscription.bundleId} not found`) + + const option = this.bundleService.getSubscriptionOption(bundle, duration) + if (!option) { + return ResponseUtil.error(`duration not supported in bundle`) + } + const priceAmount = option.specialPrice + + // check max renewal time + const MAX_RENEWAL_AT = Date.now() + bundle.maxRenewalTime * 1000 + const newExpiredAt = subscription.expiredAt.getTime() + duration * 1000 + if (newExpiredAt > MAX_RENEWAL_AT) { + const dateStr = new Date(MAX_RENEWAL_AT).toLocaleString() + return ResponseUtil.error( + `max renewal time is ${dateStr} for bundle ${bundle.name}`, + ) + } + + // check account balance + const account = await this.accountService.findOne(user.id) + const balance = account?.balance || 0 + if (balance < priceAmount) { + return ResponseUtil.error( + `account balance is not enough, need ${priceAmount} but only ${account.balance}`, + ) + } + + // renew subscription + const res = await this.subscriptService.renew(subscription, option) + return ResponseUtil.ok(res) + } + + /** + * TODO: Upgrade a subscription + */ + @ApiOperation({ summary: 'Upgrade a subscription - TODO' }) + @UseGuards(JwtAuthGuard) + @Patch(':id/upgrade') + async upgrade( + @Param('id') id: string, + @Body() dto: UpgradeSubscriptionDto, + @Req() req: IRequest, + ) { + const { targetBundleId, restart } = dto + + // get subscription + const user = req.user + const subscription = await this.subscriptService.findOne(user.id, id) + if (!subscription) { + return ResponseUtil.error(`subscription ${id} not found`) + } + + // get target bundle + const app = subscription.application + const targetBundle = await this.bundleService.findOne( + targetBundleId, + app.regionId, + ) + if (!targetBundle) { + return ResponseUtil.error(`bundle ${targetBundleId} not found`) + } + + // check bundle is upgradeable + const bundle = await this.bundleService.findOne( + subscription.bundleId, + app.regionId, + ) + assert(bundle, `bundle ${subscription.bundleId} not found`) + + if (bundle.id === targetBundle.id) { + return ResponseUtil.error(`bundle is the same`) + } + + // check if target bundle limit count is reached + const LIMIT_COUNT = targetBundle.limitCountPerUser || 0 + const count = await this.prisma.subscription.count({ + where: { + createdBy: user.id, + bundleId: targetBundle.id, + state: { not: SubscriptionState.Deleted }, + }, + }) + if (count >= LIMIT_COUNT) { + return ResponseUtil.error( + `application count limit is ${LIMIT_COUNT} for bundle ${targetBundle.name}`, + ) + } + + return ResponseUtil.error(`not implemented`) + } + + /** + * Delete a subscription + * @param id + * @returns + */ + @ApiOperation({ summary: 'Delete a subscription' }) + @UseGuards(JwtAuthGuard) + @Delete(':id') + async remove(@Param('id') id: string, @Req() req: IRequest) { + const userid = req.user.id + const res = await this.subscriptService.remove(userid, id) + return ResponseUtil.ok(res) + } +} diff --git a/server/src/subscription/subscription.module.ts b/server/src/subscription/subscription.module.ts new file mode 100644 index 0000000000..e5a1f6301a --- /dev/null +++ b/server/src/subscription/subscription.module.ts @@ -0,0 +1,19 @@ +import { Module } from '@nestjs/common' +import { SubscriptionService } from './subscription.service' +import { SubscriptionController } from './subscription.controller' +import { SubscriptionTaskService } from './subscription-task.service' +import { ApplicationService } from 'src/application/application.service' +import { SubscriptionRenewalTaskService } from './renewal-task.service' +import { AccountModule } from 'src/account/account.module' + +@Module({ + imports: [AccountModule], + controllers: [SubscriptionController], + providers: [ + SubscriptionService, + SubscriptionTaskService, + ApplicationService, + SubscriptionRenewalTaskService, + ], +}) +export class SubscriptionModule {} diff --git a/server/src/subscription/subscription.service.ts b/server/src/subscription/subscription.service.ts new file mode 100644 index 0000000000..729efa6622 --- /dev/null +++ b/server/src/subscription/subscription.service.ts @@ -0,0 +1,124 @@ +import { Injectable, Logger } from '@nestjs/common' +import { + BundleSubscriptionOption, + Subscription, + SubscriptionPhase, + SubscriptionRenewalPhase, + SubscriptionRenewalPlan, + SubscriptionState, +} from '@prisma/client' +import { TASK_LOCK_INIT_TIME } from 'src/constants' +import { PrismaService } from 'src/prisma/prisma.service' +import { BundleService } from 'src/region/bundle.service' +import { CreateSubscriptionDto } from './dto/create-subscription.dto' + +@Injectable() +export class SubscriptionService { + private readonly logger = new Logger(SubscriptionService.name) + + constructor( + private readonly prisma: PrismaService, + private readonly bundleService: BundleService, + ) {} + + async create( + userid: string, + appid: string, + dto: CreateSubscriptionDto, + option: BundleSubscriptionOption, + ) { + // start transaction + const res = await this.prisma.$transaction(async (tx) => { + // create subscription + const subscription = await tx.subscription.create({ + data: { + input: { + name: dto.name, + state: dto.state, + regionId: dto.regionId, + runtimeId: dto.runtimeId, + }, + appid: appid, + bundleId: dto.bundleId, + phase: SubscriptionPhase.Pending, + renewalPlan: SubscriptionRenewalPlan.Manual, + expiredAt: new Date(), + lockedAt: TASK_LOCK_INIT_TIME, + createdBy: userid, + }, + }) + + // create subscription renewal + await tx.subscriptionRenewal.create({ + data: { + subscriptionId: subscription.id, + duration: option.duration, + amount: option.specialPrice, + phase: SubscriptionRenewalPhase.Pending, + lockedAt: TASK_LOCK_INIT_TIME, + createdBy: userid, + }, + }) + + return subscription + }) + + return res + } + + async findAll(userid: string) { + const res = await this.prisma.subscription.findMany({ + where: { createdBy: userid }, + include: { application: true }, + }) + + return res + } + + async findOne(userid: string, id: string) { + const res = await this.prisma.subscription.findUnique({ + where: { id }, + include: { application: true }, + }) + + return res + } + + async findOneByAppid(appid: string) { + const res = await this.prisma.subscription.findUnique({ + where: { + appid, + }, + }) + + return res + } + + async remove(userid: string, id: string) { + const res = await this.prisma.subscription.updateMany({ + where: { id, createdBy: userid, state: SubscriptionState.Created }, + data: { state: SubscriptionState.Deleted }, + }) + + return res + } + + /** + * Renew a subscription by creating a subscription renewal + */ + async renew(subscription: Subscription, option: BundleSubscriptionOption) { + // create subscription renewal + const res = await this.prisma.subscriptionRenewal.create({ + data: { + subscriptionId: subscription.id, + duration: option.duration, + amount: option.specialPrice, + phase: SubscriptionRenewalPhase.Pending, + lockedAt: TASK_LOCK_INIT_TIME, + createdBy: subscription.createdBy, + }, + }) + + return res + } +} diff --git a/server/src/trigger/cron-job.service.ts b/server/src/trigger/cron-job.service.ts index 93502f1f70..2d56082dca 100644 --- a/server/src/trigger/cron-job.service.ts +++ b/server/src/trigger/cron-job.service.ts @@ -1,11 +1,13 @@ import { Injectable, Logger } from '@nestjs/common' -import { CronTrigger } from '@prisma/client' +import { CronTrigger, TriggerPhase } from '@prisma/client' import { ClusterService } from 'src/region/cluster/cluster.service' import * as assert from 'node:assert' import { RegionService } from 'src/region/region.service' import { GetApplicationNamespaceByAppId } from 'src/utils/getter' import { FunctionService } from 'src/function/function.service' import { FOREVER_IN_SECONDS, X_LAF_TRIGGER_TOKEN_KEY } from 'src/constants' +import { TriggerService } from './trigger.service' +import * as k8s from '@kubernetes/client-node' @Injectable() export class CronJobService { @@ -15,6 +17,7 @@ export class CronJobService { private readonly clusterService: ClusterService, private readonly regionService: RegionService, private readonly funcService: FunctionService, + private readonly triggerService: TriggerService, ) {} async create(trigger: CronTrigger) { @@ -30,47 +33,43 @@ export class CronJobService { const batchApi = this.clusterService.makeBatchV1Api(region) const name = `cron-${trigger.id}` const command = await this.getTriggerCommand(trigger) - const res = await batchApi - .createNamespacedCronJob(ns, { - metadata: { - name, - labels: { - appid, - id: trigger.id, - }, + const res = await batchApi.createNamespacedCronJob(ns, { + metadata: { + name, + labels: { + appid, + id: trigger.id, }, - spec: { - schedule: trigger.cron, - successfulJobsHistoryLimit: 1, - failedJobsHistoryLimit: 1, - concurrencyPolicy: 'Allow', - startingDeadlineSeconds: 60, - jobTemplate: { - spec: { - activeDeadlineSeconds: 60, - template: { - spec: { - restartPolicy: 'Never', - terminationGracePeriodSeconds: 30, - automountServiceAccountToken: false, - containers: [ - { - name: name, - image: 'curlimages/curl:7.87.0', - command: ['sh', '-c', command], - imagePullPolicy: 'IfNotPresent', - }, - ], - }, + }, + spec: { + schedule: trigger.cron, + successfulJobsHistoryLimit: 1, + failedJobsHistoryLimit: 1, + suspend: false, + concurrencyPolicy: 'Allow', + startingDeadlineSeconds: 60, + jobTemplate: { + spec: { + activeDeadlineSeconds: 60, + template: { + spec: { + restartPolicy: 'Never', + terminationGracePeriodSeconds: 30, + automountServiceAccountToken: false, + containers: [ + { + name: name, + image: 'curlimages/curl:7.87.0', + command: ['sh', '-c', command], + imagePullPolicy: 'IfNotPresent', + }, + ], }, }, }, }, - }) - .catch((err) => { - this.logger.error(`create cronjob ${name} failed:`, err) - return null - }) + }, + }) this.logger.debug(`create cronjob ${name} success`) return res.body @@ -80,13 +79,43 @@ export class CronJobService { const appid = trigger.appid const ns = GetApplicationNamespaceByAppId(appid) const region = await this.regionService.findByAppId(appid) - const batchApi = this.clusterService.makeBatchV1Api(region) - const name = `cron-${trigger.id}` - const res = await batchApi.readNamespacedCronJob(name, ns).catch((err) => { - this.logger.error(`read cronjob ${name} failed:`, err) - return null - }) - return res.body + try { + const batchApi = this.clusterService.makeBatchV1Api(region) + const name = `cron-${trigger.id}` + const res = await batchApi.readNamespacedCronJob(name, ns) + return res.body + } catch (err) { + if (err?.response?.body?.reason === 'NotFound') return null + this.logger.error(err) + this.logger.error(err?.response?.body) + throw err + } + } + + async suspend(trigger: CronTrigger) { + return await this.patchSuspend(trigger, true) + } + + async resume(trigger: CronTrigger) { + return await this.patchSuspend(trigger, false) + } + + async suspendAll(appid: string) { + const triggers = await this.triggerService.findAll(appid) + for (const trigger of triggers) { + if (trigger.phase !== TriggerPhase.Created) continue + await this.suspend(trigger) + this.logger.log(`suspend cronjob ${trigger.id} success of ${appid}`) + } + } + + async resumeAll(appid: string) { + const triggers = await this.triggerService.findAll(appid) + for (const trigger of triggers) { + if (trigger.phase !== TriggerPhase.Created) continue + await this.resume(trigger) + this.logger.log(`resume cronjob ${trigger.id} success of ${appid}`) + } } async delete(trigger: CronTrigger) { @@ -95,12 +124,7 @@ export class CronJobService { const region = await this.regionService.findByAppId(appid) const batchApi = this.clusterService.makeBatchV1Api(region) const name = `cron-${trigger.id}` - const res = await batchApi - .deleteNamespacedCronJob(name, ns) - .catch((err) => { - this.logger.error(`delete cronjob ${name} failed:`, err) - return null - }) + const res = await batchApi.deleteNamespacedCronJob(name, ns) return res.body } @@ -120,4 +144,32 @@ export class CronJobService { const command = `curl -X POST -H "${X_LAF_TRIGGER_TOKEN_KEY}: ${token}" ${invokeUrl}` return command } + + private async patchSuspend(trigger: CronTrigger, suspend: boolean) { + const appid = trigger.appid + const ns = GetApplicationNamespaceByAppId(appid) + const region = await this.regionService.findByAppId(appid) + const batchApi = this.clusterService.makeBatchV1Api(region) + const name = `cron-${trigger.id}` + const body = [{ op: 'replace', path: '/spec/suspend', value: suspend }] + try { + const res = await batchApi.patchNamespacedCronJob( + name, + ns, + body, + undefined, + undefined, + undefined, + undefined, + undefined, + { + headers: { 'Content-Type': k8s.PatchUtils.PATCH_FORMAT_JSON_PATCH }, + }, + ) + return res.body + } catch (err) { + if (err?.response?.body?.reason === 'NotFound') return null + throw err + } + } } diff --git a/server/src/trigger/trigger-task.service.ts b/server/src/trigger/trigger-task.service.ts index be7ee1879b..5222b896f4 100644 --- a/server/src/trigger/trigger-task.service.ts +++ b/server/src/trigger/trigger-task.service.ts @@ -1,11 +1,9 @@ import { Injectable, Logger } from '@nestjs/common' import { Cron, CronExpression } from '@nestjs/schedule' -import { times } from 'lodash' import { TASK_LOCK_INIT_TIME } from 'src/constants' import { SystemDatabase } from 'src/database/system-database' import { CronJobService } from './cron-job.service' import { CronTrigger, TriggerPhase, TriggerState } from '@prisma/client' -import * as assert from 'node:assert' @Injectable() export class TriggerTaskService { @@ -18,22 +16,29 @@ export class TriggerTaskService { @Cron(CronExpression.EVERY_SECOND) async tick() { // Phase `Creating` -> `Created` - times(this.concurrency, () => this.handleCreatingPhase()) + this.handleCreatingPhase().catch((err) => { + this.logger.error('handleCreatingPhase error: ' + err) + }) // Phase `Deleting` -> `Deleted` - times(this.concurrency, () => this.handleDeletingPhase()) + this.handleDeletingPhase().catch((err) => { + this.logger.error('handleDeletingPhase error: ' + err) + }) // Phase `Created` -> `Deleting` - this.handleInactiveState() + this.handleInactiveState().catch((err) => { + this.logger.error('handleInactiveState error: ' + err) + }) // Phase `Deleted` -> `Creating` - this.handleActiveState() + this.handleActiveState().catch((err) => { + this.logger.error('handleActiveState error: ' + err) + }) // Phase `Deleting` -> `Deleted` - this.handleDeletedState() - - // Clear timeout locks - this.clearTimeoutLocks() + this.handleDeletedState().catch((err) => { + this.logger.error('handleDeletedState error: ' + err) + }) } /** @@ -49,15 +54,9 @@ export class TriggerTaskService { .findOneAndUpdate( { phase: TriggerPhase.Creating, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) if (!res.value) return @@ -67,28 +66,22 @@ export class TriggerTaskService { id: res.value._id.toString(), } - // create cron job - const job = await this.cronService.create(doc) - if (!job) return - - this.logger.debug('cron job created: ' + doc._id) + // create cron job if not exists + const job = await this.cronService.findOne(doc) + if (!job) { + await this.cronService.create(doc) + this.logger.log('cron job created: ' + doc._id) + } // update phase to `Created` - const updated = await db.collection('CronTrigger').updateOne( + await db.collection('CronTrigger').updateOne( + { _id: doc._id, phase: TriggerPhase.Creating }, { - _id: doc._id, - phase: TriggerPhase.Creating, - }, - { - $set: { - phase: TriggerPhase.Created, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: TriggerPhase.Created, lockedAt: TASK_LOCK_INIT_TIME }, }, ) - if (updated.modifiedCount > 0) - this.logger.debug('trigger phase updated to Created ', doc._id) + this.logger.log('trigger phase updated to Created: ' + doc._id) } /** @@ -104,15 +97,9 @@ export class TriggerTaskService { .findOneAndUpdate( { phase: TriggerPhase.Deleting, - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: new Date(), - }, + lockedAt: { $lt: new Date(Date.now() - 1000 * this.lockTimeout) }, }, + { $set: { lockedAt: new Date() } }, ) if (!res.value) return @@ -122,28 +109,22 @@ export class TriggerTaskService { id: res.value._id.toString(), } - // delete cron job - const ret = await this.cronService.delete(doc) - if (ret?.status !== 'Success') return - - this.logger.debug('cron job deleted:', doc._id) + // delete cron job if exists + const job = await this.cronService.findOne(doc) + if (job) { + await this.cronService.delete(doc) + this.logger.log('cron job deleted: ' + doc._id) + } // update phase to `Deleted` - const updated = await db.collection('CronTrigger').updateOne( + await db.collection('CronTrigger').updateOne( + { _id: doc._id, phase: TriggerPhase.Deleting }, { - _id: doc._id, - phase: TriggerPhase.Deleting, - }, - { - $set: { - phase: TriggerPhase.Deleted, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: TriggerPhase.Deleted, lockedAt: TASK_LOCK_INIT_TIME }, }, ) - if (updated.modifiedCount > 0) - this.logger.debug('cron trigger phase updated to Deleted ' + doc._id) + this.logger.debug('cron trigger phase updated to Deleted: ' + doc._id) } /** @@ -154,15 +135,9 @@ export class TriggerTaskService { const db = SystemDatabase.db await db.collection('CronTrigger').updateMany( + { state: TriggerState.Active, phase: TriggerPhase.Deleted }, { - state: TriggerState.Active, - phase: TriggerPhase.Deleted, - }, - { - $set: { - phase: TriggerPhase.Creating, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: TriggerPhase.Creating, lockedAt: TASK_LOCK_INIT_TIME }, }, ) } @@ -177,13 +152,10 @@ export class TriggerTaskService { await db.collection('CronTrigger').updateMany( { state: TriggerState.Inactive, - phase: TriggerPhase.Created, + phase: { $in: [TriggerPhase.Created, TriggerPhase.Creating] }, }, { - $set: { - phase: TriggerPhase.Deleting, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: TriggerPhase.Deleting, lockedAt: TASK_LOCK_INIT_TIME }, }, ) } @@ -197,41 +169,14 @@ export class TriggerTaskService { const db = SystemDatabase.db await db.collection('CronTrigger').updateMany( + { state: TriggerState.Deleted, phase: TriggerPhase.Created }, { - state: TriggerState.Deleted, - phase: TriggerPhase.Created, - }, - { - $set: { - phase: TriggerPhase.Deleting, - lockedAt: TASK_LOCK_INIT_TIME, - }, + $set: { phase: TriggerPhase.Deleting, lockedAt: TASK_LOCK_INIT_TIME }, }, ) - await db.collection('CronTrigger').deleteMany({ - state: TriggerState.Deleted, - phase: TriggerPhase.Deleted, - }) - } - - /** - * Clear timeout locks - */ - async clearTimeoutLocks() { - const db = SystemDatabase.db - - await db.collection('CronTrigger').updateMany( - { - lockedAt: { - $lt: new Date(Date.now() - 1000 * this.lockTimeout), - }, - }, - { - $set: { - lockedAt: TASK_LOCK_INIT_TIME, - }, - }, - ) + await db + .collection('CronTrigger') + .deleteMany({ state: TriggerState.Deleted, phase: TriggerPhase.Deleted }) } } diff --git a/server/src/trigger/trigger.controller.ts b/server/src/trigger/trigger.controller.ts index ca82928c8a..3c3781dc16 100644 --- a/server/src/trigger/trigger.controller.ts +++ b/server/src/trigger/trigger.controller.ts @@ -85,8 +85,14 @@ export class TriggerController { @ApiResponse({ type: ResponseUtil }) @UseGuards(JwtAuthGuard, ApplicationAuthGuard) @Delete(':id') - async remove(@Param('id') id: string) { - const res = await this.triggerService.remove(id) + async remove(@Param('id') id: string, @Param('appid') appid: string) { + // check if trigger exists + const trigger = await this.triggerService.findOne(appid, id) + if (!trigger) { + return ResponseUtil.error('Trigger not found') + } + + const res = await this.triggerService.remove(appid, id) return ResponseUtil.ok(res) } } diff --git a/server/src/trigger/trigger.module.ts b/server/src/trigger/trigger.module.ts index a92cd87626..cc76d01d05 100644 --- a/server/src/trigger/trigger.module.ts +++ b/server/src/trigger/trigger.module.ts @@ -24,5 +24,6 @@ import { MongoService } from 'src/database/mongo.service' DatabaseService, MongoService, ], + exports: [TriggerService, CronJobService], }) export class TriggerModule {} diff --git a/server/src/trigger/trigger.service.ts b/server/src/trigger/trigger.service.ts index 8299ac136b..6060ed394d 100644 --- a/server/src/trigger/trigger.service.ts +++ b/server/src/trigger/trigger.service.ts @@ -42,17 +42,25 @@ export class TriggerService { return res } + async findOne(appid: string, id: string) { + const res = await this.prisma.cronTrigger.findFirst({ + where: { id, appid }, + }) + + return res + } + async findAll(appid: string) { const res = await this.prisma.cronTrigger.findMany({ - where: { appid }, + where: { appid, state: TriggerState.Active }, }) return res } - async remove(id: string) { - const res = await this.prisma.cronTrigger.update({ - where: { id }, + async remove(appid: string, id: string) { + const res = await this.prisma.cronTrigger.updateMany({ + where: { id, appid }, data: { state: TriggerState.Deleted, }, diff --git a/server/src/user/dto/user.response.ts b/server/src/user/dto/user.response.ts index 49e2cf4da7..8c5e465269 100644 --- a/server/src/user/dto/user.response.ts +++ b/server/src/user/dto/user.response.ts @@ -18,6 +18,9 @@ export class UserProfileDto implements UserProfile { from: string + @ApiProperty() + openData: any + @ApiProperty() createdAt: Date diff --git a/server/src/user/user.service.ts b/server/src/user/user.service.ts index cb945e98e4..7bd7a3715b 100644 --- a/server/src/user/user.service.ts +++ b/server/src/user/user.service.ts @@ -80,4 +80,23 @@ export class UserService { where, }) } + + // find user by username | phone | email + async find(username: string) { + // match either username or phone or email + return await this.prisma.user.findFirst({ + where: { + OR: [{ username }, { phone: username }, { email: username }], + }, + }) + } + + // find user by phone + async findByPhone(phone: string) { + return await this.prisma.user.findFirst({ + where: { + phone, + }, + }) + } } diff --git a/server/src/utils/crypto.ts b/server/src/utils/crypto.ts new file mode 100644 index 0000000000..5ed262ec09 --- /dev/null +++ b/server/src/utils/crypto.ts @@ -0,0 +1,8 @@ +import * as crypto from 'crypto' + +// use sha256 to hash the password +export function hashPassword(password: string): string { + const hash = crypto.createHash('sha256') + hash.update(password) + return hash.digest('hex') +} diff --git a/server/src/utils/number.ts b/server/src/utils/number.ts new file mode 100644 index 0000000000..ecdca79275 --- /dev/null +++ b/server/src/utils/number.ts @@ -0,0 +1,39 @@ +/** + * PriceRound() + * - keep two decimals + * - 1.234 => 1.23 + * - 1.235 => 1.24 + * + * Special case: + * - capitalize the first letter of this function name to make it like a constructor + * @param price + * @returns + */ +export function PriceRound(price: number | string) { + const priceNum = Number(price) + return Math.round(priceNum * 100) / 100 +} + +export function PriceAdd(price1: number | string, price2: number | string) { + const price1Num = Number(price1) + const price2Num = Number(price2) + return PriceRound(price1Num + price2Num) +} + +export function PriceSub(price1: number | string, price2: number | string) { + const price1Num = Number(price1) + const price2Num = Number(price2) + return PriceRound(price1Num - price2Num) +} + +export function PriceMul(price1: number | string, price2: number | string) { + const price1Num = Number(price1) + const price2Num = Number(price2) + return PriceRound(price1Num * price2Num) +} + +export function PriceDiv(price1: number | string, price2: number | string) { + const price1Num = Number(price1) + const price2Num = Number(price2) + return PriceRound(price1Num / price2Num) +} diff --git a/server/src/utils/random.ts b/server/src/utils/random.ts index 28bfb5f84f..69baf08ca3 100644 --- a/server/src/utils/random.ts +++ b/server/src/utils/random.ts @@ -1,4 +1,5 @@ import * as nanoid from 'nanoid' +import * as dayjs from 'dayjs' export function GenerateAlphaNumericPassword(length: number) { const nano = nanoid.customAlphabet( @@ -7,3 +8,18 @@ export function GenerateAlphaNumericPassword(length: number) { ) return nano() } + +export function GenerateRandomString(length: number) { + return GenerateAlphaNumericPassword(length) +} + +export function GenerateRandomNumericString(length: number) { + const nano = nanoid.customAlphabet('0123456789', length || 16) + return nano() +} + +export function GenerateOrderNumber() { + const dateStr = dayjs().format('YYYYMMDDHHMMSS') + const randomStr = GenerateRandomNumericString(6) + return `${dateStr}${randomStr}` +} diff --git a/server/src/website/website.controller.ts b/server/src/website/website.controller.ts index aa105939ae..27acba0b13 100644 --- a/server/src/website/website.controller.ts +++ b/server/src/website/website.controller.ts @@ -20,12 +20,19 @@ import { import { JwtAuthGuard } from 'src/auth/jwt.auth.guard' import { ApplicationAuthGuard } from 'src/auth/application.auth.guard' import { ResponseUtil } from 'src/utils/response' +import { BundleService } from 'src/region/bundle.service' +import { BucketService } from 'src/storage/bucket.service' +import { DomainState } from '@prisma/client' @ApiTags('WebsiteHosting') @ApiBearerAuth('Authorization') @Controller('apps/:appid/websites') export class WebsiteController { - constructor(private readonly websiteService: WebsiteService) {} + constructor( + private readonly websiteService: WebsiteService, + private readonly bundleService: BundleService, + private readonly bucketService: BucketService, + ) {} /** * Create a new website @@ -39,8 +46,33 @@ export class WebsiteController { @UseGuards(JwtAuthGuard, ApplicationAuthGuard) @Post() async create(@Param('appid') appid: string, @Body() dto: CreateWebsiteDto) { - const site = await this.websiteService.create(appid, dto) + // check if website hosting limit reached + const bundle = await this.bundleService.findApplicationBundle(appid) + const LIMIT_COUNT = bundle?.resource?.limitCountOfWebsiteHosting || 0 + const count = await this.websiteService.count(appid) + if (count >= LIMIT_COUNT) { + return ResponseUtil.error( + `website hosting limit (${LIMIT_COUNT}) reached`, + ) + } + // check if bucket already binded as website hosting + const bucket = await this.bucketService.findOne(appid, dto.bucketName) + if (!bucket) { + return ResponseUtil.error('bucket not found') + } + + if (bucket.websiteHosting?.state === DomainState.Deleted) { + return ResponseUtil.error( + 'The previous website is deleting, please try again later.', + ) + } + + if (bucket.websiteHosting) { + return ResponseUtil.error('bucket already binded as website hosting') + } + + const site = await this.websiteService.create(appid, dto) if (!site) { return ResponseUtil.error('failed to create website') } diff --git a/server/src/website/website.module.ts b/server/src/website/website.module.ts index c904ca72ae..cfa5aae2e4 100644 --- a/server/src/website/website.module.ts +++ b/server/src/website/website.module.ts @@ -2,9 +2,10 @@ import { Module } from '@nestjs/common' import { WebsiteService } from './website.service' import { WebsiteController } from './website.controller' import { ApplicationService } from 'src/application/application.service' +import { StorageModule } from 'src/storage/storage.module' @Module({ - imports: [], + imports: [StorageModule], controllers: [WebsiteController], providers: [WebsiteService, ApplicationService], }) diff --git a/web/.env b/web/.env index caf8c56d5f..9a5dde27c7 100644 --- a/web/.env +++ b/web/.env @@ -3,4 +3,4 @@ VITE_SERVER_BASE_URL= # this only used for dev environment, change it to your local api server url if needed # don't change it directly, you should create a .env.local file and set it there -VITE_DEV_SERVER_URL=http://api.dev.laf.run \ No newline at end of file +VITE_DEV_SERVER_URL=http://api.laf.run diff --git a/web/index.html b/web/index.html index ec0583ebc9..527e016598 100644 --- a/web/index.html +++ b/web/index.html @@ -10,7 +10,7 @@
- + diff --git a/web/package-lock.json b/web/package-lock.json index f8ce18f99e..eb564ac6ad 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,62 +1,67 @@ { "name": "web", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "web", - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "dependencies": { - "@chakra-ui/icons": "^2.0.17", - "@chakra-ui/react": "^2.5.1", + "@chakra-ui/anatomy": "^2.1.1", + "@chakra-ui/icons": "^2.0.18", + "@chakra-ui/react": "^2.5.5", "@emotion/react": "^11.10.6", "@emotion/styled": "^11.10.6", - "@tanstack/react-query": "^4.24.6", - "axios": "^1.3.3", + "@tanstack/react-query": "^4.28.0", + "axios": "^1.3.4", "clsx": "^1.2.1", "dayjs": "^1.11.7", - "framer-motion": "^9.0.4", - "i18next": "^22.4.9", + "dotenv": "^16.0.3", + "framer-motion": "^10.10.0", + "i18next": "^22.4.13", "i18next-browser-languagedetector": "7.0.1", - "i18next-http-backend": "2.1.1", - "immer": "^9.0.16", - "laf-client-sdk": "^1.0.0-beta.2", + "i18next-http-backend": "2.2.0", + "immer": "^9.0.21", + "laf-client-sdk": "^1.0.0-beta.7", "lodash": "^4.17.21", "make-plural": "^7.2.0", - "monaco-editor": "^0.35.0", + "monaco-editor": "^0.36.1", "qrcode.react": "^3.1.0", "react": "18.2.0", - "react-datepicker": "^4.10.0", + "react-datepicker": "^4.11.0", "react-dom": "18.2.0", - "react-hook-form": "^7.43.1", - "react-i18next": "^12.1.5", - "react-icons": "^4.7.1", - "react-router-dom": "^6.8.1", + "react-hook-form": "^7.43.9", + "react-i18next": "^12.2.0", + "react-icons": "^4.8.0", + "react-router-dom": "^6.10.0", "react-syntax-highlighter": "^15.5.0", - "sass": "^1.58.2", - "zustand": "^4.3.3" + "sass": "^1.60.0", + "zustand": "^4.3.6" }, "devDependencies": { - "@types/lodash": "^4.14.191", - "@types/node": "18.13.0", - "@types/react": "^18.0.28", - "@types/react-datepicker": "^4.8.0", + "@types/lodash": "^4.14.192", + "@types/node": "18.15.11", + "@types/react": "^18.0.31", + "@types/react-datepicker": "^4.10.0", "@types/react-dom": "^18.0.11", "@types/react-syntax-highlighter": "^15.5.6", - "@vitejs/plugin-react-swc": "^3.1.0", - "autoprefixer": "^10.4.13", + "@vitejs/plugin-react-swc": "^3.2.0", + "autoprefixer": "^10.4.14", "click-to-react-component": "^1.0.8", - "eslint": "^8.34.0", + "eslint": "^8.37.0", "eslint-config-react-app": "^7.0.1", "eslint-plugin-simple-import-sort": "^10.0.0", "husky": "^8.0.3", - "lint-staged": "^13.1.2", + "install": "^0.13.0", + "lint-staged": "^13.2.0", "postcss": "^8.4.21", - "prettier": "^2.8.4", - "tailwindcss": "^3.2.7", - "typescript": "4.9.5", - "vite": "^4.1.1" + "prettier": "^2.8.7", + "prettier-plugin-tailwindcss": "^0.2.6", + "tailwindcss": "^3.3.1", + "typescript": "5.0.3", + "vite": "^4.2.1", + "vite-plugin-rewrite-all": "^1.0.1" } }, "node_modules/@ampproject/remapping": { @@ -1926,17 +1931,17 @@ } }, "node_modules/@chakra-ui/accordion": { - "version": "2.1.9", - "resolved": "https://registry.npmmirror.com/@chakra-ui/accordion/-/accordion-2.1.9.tgz", - "integrity": "sha512-a9CKIAUHezc0f5FR/SQ4GVxnWuIb2HbDTxTEKTp58w/J9pecIbJaNrJ5TUZ0MVbDU9jkgO9RsZ29jkja8PomAw==", + "version": "2.1.11", + "resolved": "https://registry.npmmirror.com/@chakra-ui/accordion/-/accordion-2.1.11.tgz", + "integrity": "sha512-mfVPmqETp9pyRDHJ33AdF19oHv/LyxVzQJtlxUByuvs8Cj9QQZ2LQLg5kejm+b3mj03A7A6yfbuo3RNaI4Bhsg==", "dependencies": { - "@chakra-ui/descendant": "3.0.13", + "@chakra-ui/descendant": "3.0.14", "@chakra-ui/icon": "3.0.16", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-controllable-state": "2.0.8", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/transition": "2.0.15" + "@chakra-ui/transition": "2.0.16" }, "peerDependencies": { "@chakra-ui/system": ">=2.0.0", @@ -1945,12 +1950,12 @@ } }, "node_modules/@chakra-ui/alert": { - "version": "2.0.17", - "resolved": "https://registry.npmmirror.com/@chakra-ui/alert/-/alert-2.0.17.tgz", - "integrity": "sha512-0Y5vw+HkeXpwbL1roVpSSNM6luMRmUbwduUSHEA4OnX1ismvsDb1ZBfpi4Vxp6w8euJ2Uj6df3krbd5tbCP6tg==", + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/@chakra-ui/alert/-/alert-2.1.0.tgz", + "integrity": "sha512-OcfHwoXI5VrmM+tHJTHT62Bx6TfyfCxSa0PWUOueJzSyhlUOKBND5we6UtrOB7D0jwX45qKKEDJOLG5yCG21jQ==", "dependencies": { "@chakra-ui/icon": "3.0.16", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5", "@chakra-ui/spinner": "2.0.13" }, @@ -1965,13 +1970,13 @@ "integrity": "sha512-pKfOS/mztc4sUXHNc8ypJ1gPWSolWT770jrgVRfolVbYlki8y5Y+As996zMF6k5lewTu6j9DQequ7Cc9a69IVQ==" }, "node_modules/@chakra-ui/avatar": { - "version": "2.2.5", - "resolved": "https://registry.npmmirror.com/@chakra-ui/avatar/-/avatar-2.2.5.tgz", - "integrity": "sha512-TEHXuGE79+fEn61qJ7J/A0Ec+WjyNwobrDTATcLg9Zx2/WEMmZNfrWIAlI5ANQAwVbdSWeGVbyoLAK5mbcrE0A==", + "version": "2.2.8", + "resolved": "https://registry.npmmirror.com/@chakra-ui/avatar/-/avatar-2.2.8.tgz", + "integrity": "sha512-uBs9PMrqyK111tPIYIKnOM4n3mwgKqGpvYmtwBnnbQLTNLg4gtiWWVbpTuNMpyu1av0xQYomjUt8Doed8w6p8g==", "dependencies": { "@chakra-ui/image": "2.0.15", "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5" }, "peerDependencies": { @@ -1980,12 +1985,12 @@ } }, "node_modules/@chakra-ui/breadcrumb": { - "version": "2.1.4", - "resolved": "https://registry.npmmirror.com/@chakra-ui/breadcrumb/-/breadcrumb-2.1.4.tgz", - "integrity": "sha512-vyBx5TAxPnHhb0b8nyRGfqyjleD//9mySFhk96c9GL+T6YDO4swHw5y/kvDv3Ngc/iRwJ9hdI49PZKwPxLqsEg==", + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/@chakra-ui/breadcrumb/-/breadcrumb-2.1.5.tgz", + "integrity": "sha512-p3eQQrHQBkRB69xOmNyBJqEdfCrMt+e0eOH+Pm/DjFWfIVIbnIaFbmDCeWClqlLa21Ypc6h1hR9jEmvg8kmOog==", "dependencies": { "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5" }, "peerDependencies": { @@ -2002,11 +2007,11 @@ } }, "node_modules/@chakra-ui/button": { - "version": "2.0.16", - "resolved": "https://registry.npmmirror.com/@chakra-ui/button/-/button-2.0.16.tgz", - "integrity": "sha512-NjuTKa7gNhnGSUutKuTc8HoAOe9WWIigpciBG7yj3ok67kg8bXtSzPyQFZlgTY6XGdAckWTT+Do4tvhwa5LA+g==", + "version": "2.0.18", + "resolved": "https://registry.npmmirror.com/@chakra-ui/button/-/button-2.0.18.tgz", + "integrity": "sha512-E3c99+lOm6ou4nQVOTLkG+IdOPMjsQK+Qe7VyP8A/xeAMFONuibrWPRPpprr4ZkB4kEoLMfNuyH2+aEza3ScUA==", "dependencies": { - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", "@chakra-ui/spinner": "2.0.13" @@ -2029,12 +2034,12 @@ } }, "node_modules/@chakra-ui/checkbox": { - "version": "2.2.10", - "resolved": "https://registry.npmmirror.com/@chakra-ui/checkbox/-/checkbox-2.2.10.tgz", - "integrity": "sha512-vzxEjw99qj7loxAdP1WuHNt4EAvj/t6cc8oxyOB2mEvkAzhxI34rLR+3zWDuHWsmhyUO+XEDh4FiWdR+DK5Siw==", + "version": "2.2.14", + "resolved": "https://registry.npmmirror.com/@chakra-ui/checkbox/-/checkbox-2.2.14.tgz", + "integrity": "sha512-uqo6lFWLqYBujPglrvRhTAErtuIXpmdpc5w0W4bjK7kyvLhxOpUh1hlDb2WoqlNpfRn/OaNeF6VinPnf9BJL8w==", "dependencies": { - "@chakra-ui/form-control": "2.0.17", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/form-control": "2.0.18", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-callback-ref": "2.0.7", "@chakra-ui/react-use-controllable-state": "2.0.8", @@ -2043,7 +2048,7 @@ "@chakra-ui/react-use-update-effect": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", "@chakra-ui/visually-hidden": "2.0.15", - "@zag-js/focus-visible": "0.2.1" + "@zag-js/focus-visible": "0.2.2" }, "peerDependencies": { "@chakra-ui/system": ">=2.0.0", @@ -2108,20 +2113,20 @@ } }, "node_modules/@chakra-ui/css-reset": { - "version": "2.0.12", - "resolved": "https://registry.npmmirror.com/@chakra-ui/css-reset/-/css-reset-2.0.12.tgz", - "integrity": "sha512-Q5OYIMvqTl2vZ947kIYxcS5DhQXeStB84BzzBd6C10wOx1gFUu9pL+jLpOnHR3hhpWRMdX5o7eT+gMJWIYUZ0Q==", + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/@chakra-ui/css-reset/-/css-reset-2.1.1.tgz", + "integrity": "sha512-jwEOfIAWmQsnChHQTW/eRE+dfE4MjmhvSvoUug5nkV1pI7veC/20noFlIZxzi82EbiQI8Fs0+Jnusgxr2yaOHA==", "peerDependencies": { "@emotion/react": ">=10.0.35", "react": ">=18" } }, "node_modules/@chakra-ui/descendant": { - "version": "3.0.13", - "resolved": "https://registry.npmmirror.com/@chakra-ui/descendant/-/descendant-3.0.13.tgz", - "integrity": "sha512-9nzxZVxUSMc4xPL5fSaRkEOQjDQWUGjGvrZI7VzWk9eq63cojOtIxtWMSW383G9148PzWJjJYt30Eud5tdZzlg==", + "version": "3.0.14", + "resolved": "https://registry.npmmirror.com/@chakra-ui/descendant/-/descendant-3.0.14.tgz", + "integrity": "sha512-+Ahvp9H4HMpfScIv9w1vaecGz7qWAaK1YFHHolz/SIsGLaLGlbdp+5UNabQC7L6TUnzzJDQDxzwif78rTD7ang==", "dependencies": { - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-merge-refs": "2.0.7" }, "peerDependencies": { @@ -2134,11 +2139,11 @@ "integrity": "sha512-PVtDkPrDD5b8aoL6Atg7SLjkwhWb7BwMcLOF1L449L3nZN+DAO3nyAh6iUhZVJyunELj9d0r65CDlnMREyJZmA==" }, "node_modules/@chakra-ui/editable": { - "version": "2.0.19", - "resolved": "https://registry.npmmirror.com/@chakra-ui/editable/-/editable-2.0.19.tgz", - "integrity": "sha512-YxRJsJ2JQd42zfPBgTKzIhg1HugT+gfQz1ZosmUN+IZT9YZXL2yodHTUz6Lee04Vc/CdEqgBFLuREXEUNBfGtA==", + "version": "2.0.21", + "resolved": "https://registry.npmmirror.com/@chakra-ui/editable/-/editable-2.0.21.tgz", + "integrity": "sha512-oYuXbHnggxSYJN7P9Pn0Scs9tPC91no4z1y58Oe+ILoJKZ+bFAEHtL7FEISDNJxw++MEukeFu7GU1hVqmdLsKQ==", "dependencies": { - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-callback-ref": "2.0.7", "@chakra-ui/react-use-controllable-state": "2.0.8", @@ -2171,12 +2176,12 @@ } }, "node_modules/@chakra-ui/form-control": { - "version": "2.0.17", - "resolved": "https://registry.npmmirror.com/@chakra-ui/form-control/-/form-control-2.0.17.tgz", - "integrity": "sha512-34ptCaJ2LNvQNOlB6MAKsmH1AkT1xo7E+3Vw10Urr81yTOjDTM/iU6vG3JKPfRDMyXeowPjXmutlnuk72SSjRg==", + "version": "2.0.18", + "resolved": "https://registry.npmmirror.com/@chakra-ui/form-control/-/form-control-2.0.18.tgz", + "integrity": "sha512-I0a0jG01IAtRPccOXSNugyRdUAe8Dy40ctqedZvznMweOXzbMCF1m+sHPLdWeWC/VI13VoAispdPY0/zHOdjsQ==", "dependencies": { "@chakra-ui/icon": "3.0.16", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/shared-utils": "2.0.5" @@ -2213,9 +2218,9 @@ } }, "node_modules/@chakra-ui/icons": { - "version": "2.0.17", - "resolved": "https://registry.npmmirror.com/@chakra-ui/icons/-/icons-2.0.17.tgz", - "integrity": "sha512-HMJP0WrJgAmFR9+Xh/CBH0nVnGMsJ4ZC8MK6tMgxPKd9/muvn0I4hsicHqdPlLpmB0TlxlhkBAKaVMtOdz6F0w==", + "version": "2.0.18", + "resolved": "https://registry.npmmirror.com/@chakra-ui/icons/-/icons-2.0.18.tgz", + "integrity": "sha512-E/+DF/jw7kdN4/XxCZRnr4FdMXhkl50Q34MVwN9rADWMwPK9uSZPGyC7HOx6rilo7q4bFjYDH3yRj9g+VfbVkg==", "dependencies": { "@chakra-ui/icon": "3.0.16" }, @@ -2238,14 +2243,14 @@ } }, "node_modules/@chakra-ui/input": { - "version": "2.0.20", - "resolved": "https://registry.npmmirror.com/@chakra-ui/input/-/input-2.0.20.tgz", - "integrity": "sha512-ypmsy4n4uNBVgn6Gd24Zrpi+qRf/T9WEzWkysuYC9Qfxo+i7yuf3snp7XmBy8KSGVSiXE11eO8ZN5oCg6Xg0jg==", + "version": "2.0.21", + "resolved": "https://registry.npmmirror.com/@chakra-ui/input/-/input-2.0.21.tgz", + "integrity": "sha512-AIWjjg6MgcOtlvKmVoZfPPfgF+sBSWL3Zq2HSCAMvS6h7jfxz/Xv0UTFGPk5F4Wt0YHT7qMySg0Jsm0b78HZJg==", "dependencies": { - "@chakra-ui/form-control": "2.0.17", + "@chakra-ui/form-control": "2.0.18", "@chakra-ui/object-utils": "2.0.8", "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5" }, "peerDependencies": { @@ -2254,15 +2259,15 @@ } }, "node_modules/@chakra-ui/layout": { - "version": "2.1.16", - "resolved": "https://registry.npmmirror.com/@chakra-ui/layout/-/layout-2.1.16.tgz", - "integrity": "sha512-QFS3feozIGsvB0H74lUocev55aRF26eNrdmhfJifwikZAiq+zzZAMdBdNU9UJhHClnMOU8/iGZ0MF7ti4zQS1A==", + "version": "2.1.18", + "resolved": "https://registry.npmmirror.com/@chakra-ui/layout/-/layout-2.1.18.tgz", + "integrity": "sha512-F4Gh2e+DGdaWdWT5NZduIFD9NM7Bnuh8sXARFHWPvIu7yvAwZ3ddqC9GK4F3qUngdmkJxDLWQqRSwSh96Lxbhw==", "dependencies": { "@chakra-ui/breakpoint-utils": "2.0.8", "@chakra-ui/icon": "3.0.16", "@chakra-ui/object-utils": "2.0.8", "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5" }, "peerDependencies": { @@ -2298,16 +2303,16 @@ } }, "node_modules/@chakra-ui/menu": { - "version": "2.1.9", - "resolved": "https://registry.npmmirror.com/@chakra-ui/menu/-/menu-2.1.9.tgz", - "integrity": "sha512-ue5nD4QJcl3H3UwN0zZNJmH89XUebnvEdW6THAUL41hDjJ0J/Fjpg9Sgzwug2aBbBXBNbVMsUuhcCj6x91d+IQ==", + "version": "2.1.12", + "resolved": "https://registry.npmmirror.com/@chakra-ui/menu/-/menu-2.1.12.tgz", + "integrity": "sha512-ylNK1VJlr/3/EGg9dLPZ87cBJJjeiYXeU/gOAphsKXMnByrXWhbp4YVnyyyha2KZ0zEw0aPU4nCZ+A69aT9wrg==", "dependencies": { "@chakra-ui/clickable": "2.0.14", - "@chakra-ui/descendant": "3.0.13", + "@chakra-ui/descendant": "3.0.14", "@chakra-ui/lazy-utils": "2.0.5", "@chakra-ui/popper": "3.0.13", "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-animation-state": "2.0.8", "@chakra-ui/react-use-controllable-state": "2.0.8", "@chakra-ui/react-use-disclosure": "2.0.8", @@ -2316,7 +2321,7 @@ "@chakra-ui/react-use-outside-click": "2.0.7", "@chakra-ui/react-use-update-effect": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/transition": "2.0.15" + "@chakra-ui/transition": "2.0.16" }, "peerDependencies": { "@chakra-ui/system": ">=2.0.0", @@ -2325,18 +2330,18 @@ } }, "node_modules/@chakra-ui/modal": { - "version": "2.2.9", - "resolved": "https://registry.npmmirror.com/@chakra-ui/modal/-/modal-2.2.9.tgz", - "integrity": "sha512-nTfNp7XsVwn5+xJOtstoFA8j0kq/9sJj7KesyYzjEDaMKvCZvIOntRYowoydho43jb4+YC7ebKhp0KOIINS0gg==", + "version": "2.2.11", + "resolved": "https://registry.npmmirror.com/@chakra-ui/modal/-/modal-2.2.11.tgz", + "integrity": "sha512-2J0ZUV5tEzkPiawdkgPz6bmex7NXAde1VXooMwdvK+vuT8PV3U61yorTJOZVLdw7TjjI1Yo94mzsp6UwBud43Q==", "dependencies": { "@chakra-ui/close-button": "2.0.17", "@chakra-ui/focus-lock": "2.0.16", - "@chakra-ui/portal": "2.0.15", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/portal": "2.0.16", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/transition": "2.0.15", + "@chakra-ui/transition": "2.0.16", "aria-hidden": "^1.2.2", "react-remove-scroll": "^2.5.5" }, @@ -2348,14 +2353,14 @@ } }, "node_modules/@chakra-ui/number-input": { - "version": "2.0.18", - "resolved": "https://registry.npmmirror.com/@chakra-ui/number-input/-/number-input-2.0.18.tgz", - "integrity": "sha512-cPkyAFFHHzeFBselrT1BtjlzMkJ6TKrTDUnHFlzqXy6aqeXuhrjFhMfXucjedSpOqedsP9ZbKFTdIAhu9DdL/A==", + "version": "2.0.19", + "resolved": "https://registry.npmmirror.com/@chakra-ui/number-input/-/number-input-2.0.19.tgz", + "integrity": "sha512-HDaITvtMEqOauOrCPsARDxKD9PSHmhWywpcyCSOX0lMe4xx2aaGhU0QQFhsJsykj8Er6pytMv6t0KZksdDv3YA==", "dependencies": { "@chakra-ui/counter": "2.0.14", - "@chakra-ui/form-control": "2.0.17", + "@chakra-ui/form-control": "2.0.18", "@chakra-ui/icon": "3.0.16", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-callback-ref": "2.0.7", "@chakra-ui/react-use-event-listener": "2.0.7", @@ -2381,13 +2386,13 @@ "integrity": "sha512-2upjT2JgRuiupdrtBWklKBS6tqeGMA77Nh6Q0JaoQuH/8yq+15CGckqn3IUWkWoGI0Fg3bK9LDlbbD+9DLw95Q==" }, "node_modules/@chakra-ui/pin-input": { - "version": "2.0.19", - "resolved": "https://registry.npmmirror.com/@chakra-ui/pin-input/-/pin-input-2.0.19.tgz", - "integrity": "sha512-6O7s4vWz4cqQ6zvMov9sYj6ZqWAsTxR/MNGe3DNgu1zWQg8veNCYtj1rNGhNS3eZNUMAa8uM2dXIphGTP53Xow==", + "version": "2.0.20", + "resolved": "https://registry.npmmirror.com/@chakra-ui/pin-input/-/pin-input-2.0.20.tgz", + "integrity": "sha512-IHVmerrtHN8F+jRB3W1HnMir1S1TUCWhI7qDInxqPtoRffHt6mzZgLZ0izx8p1fD4HkW4c1d4/ZLEz9uH9bBRg==", "dependencies": { - "@chakra-ui/descendant": "3.0.13", + "@chakra-ui/descendant": "3.0.14", "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-controllable-state": "2.0.8", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/shared-utils": "2.0.5" @@ -2398,14 +2403,14 @@ } }, "node_modules/@chakra-ui/popover": { - "version": "2.1.8", - "resolved": "https://registry.npmmirror.com/@chakra-ui/popover/-/popover-2.1.8.tgz", - "integrity": "sha512-ob7fAz+WWmXIq7iGHVB3wDKzZTj+T+noYBT/U1Q+jIf+jMr2WOpJLTfb0HTZcfhvn4EBFlfBg7Wk5qbXNaOn7g==", + "version": "2.1.9", + "resolved": "https://registry.npmmirror.com/@chakra-ui/popover/-/popover-2.1.9.tgz", + "integrity": "sha512-OMJ12VVs9N32tFaZSOqikkKPtwAVwXYsES/D1pff/amBrE3ngCrpxJSIp4uvTdORfIYDojJqrR52ZplDKS9hRQ==", "dependencies": { "@chakra-ui/close-button": "2.0.17", "@chakra-ui/lazy-utils": "2.0.5", "@chakra-ui/popper": "3.0.13", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-animation-state": "2.0.8", "@chakra-ui/react-use-disclosure": "2.0.8", @@ -2434,11 +2439,11 @@ } }, "node_modules/@chakra-ui/portal": { - "version": "2.0.15", - "resolved": "https://registry.npmmirror.com/@chakra-ui/portal/-/portal-2.0.15.tgz", - "integrity": "sha512-z8v7K3j1/nMuBzp2+wRIIw7s/eipVtnXLdjK5yqbMxMRa44E8Mu5VNJLz3aQFLHXEUST+ifqrjImQeli9do6LQ==", + "version": "2.0.16", + "resolved": "https://registry.npmmirror.com/@chakra-ui/portal/-/portal-2.0.16.tgz", + "integrity": "sha512-bVID0qbQ0l4xq38LdqAN4EKD4/uFkDnXzFwOlviC9sl0dNhzICDb1ltuH/Adl1d2HTMqyN60O3GO58eHy7plnQ==", "dependencies": { - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-safe-layout-effect": "2.0.5" }, "peerDependencies": { @@ -2447,11 +2452,11 @@ } }, "node_modules/@chakra-ui/progress": { - "version": "2.1.5", - "resolved": "https://registry.npmmirror.com/@chakra-ui/progress/-/progress-2.1.5.tgz", - "integrity": "sha512-jj5Vp4lxUchuwp4RPCepM0yAyKi344bgsOd3Apd+ldxclDcewPc82fbwDu7g/Xv27LqJkT+7E/SlQy04wGrk0g==", + "version": "2.1.6", + "resolved": "https://registry.npmmirror.com/@chakra-ui/progress/-/progress-2.1.6.tgz", + "integrity": "sha512-hHh5Ysv4z6bK+j2GJbi/FT9CVyto2PtNUNwBmr3oNMVsoOUMoRjczfXvvYqp0EHr9PCpxqrq7sRwgQXUzhbDSw==", "dependencies": { - "@chakra-ui/react-context": "2.0.7" + "@chakra-ui/react-context": "2.0.8" }, "peerDependencies": { "@chakra-ui/system": ">=2.0.0", @@ -2459,14 +2464,14 @@ } }, "node_modules/@chakra-ui/provider": { - "version": "2.1.2", - "resolved": "https://registry.npmmirror.com/@chakra-ui/provider/-/provider-2.1.2.tgz", - "integrity": "sha512-4lLlz8QuJv00BhfyKzWpzfoti9MDOdJ/MqXixJV/EZ02RMBOdE9qy9bSz/WckPC2MVhtRUuwMkxH+0QY21PXuw==", + "version": "2.2.2", + "resolved": "https://registry.npmmirror.com/@chakra-ui/provider/-/provider-2.2.2.tgz", + "integrity": "sha512-UVwnIDnAWq1aKroN5AF+OpNpUqLVeIUk7tKvX3z4CY9FsPFFi6LTEhRHdhpwaU1Tau3Tf9agEu5URegpY7S8BA==", "dependencies": { - "@chakra-ui/css-reset": "2.0.12", - "@chakra-ui/portal": "2.0.15", + "@chakra-ui/css-reset": "2.1.1", + "@chakra-ui/portal": "2.0.16", "@chakra-ui/react-env": "3.0.0", - "@chakra-ui/system": "2.5.1", + "@chakra-ui/system": "2.5.5", "@chakra-ui/utils": "2.0.15" }, "peerDependencies": { @@ -2477,16 +2482,16 @@ } }, "node_modules/@chakra-ui/radio": { - "version": "2.0.19", - "resolved": "https://registry.npmmirror.com/@chakra-ui/radio/-/radio-2.0.19.tgz", - "integrity": "sha512-PlJiV59eGSmeKP4v/4+ccQUWGRd0cjPKkj/p3L+UbOf8pl9dWm8y9kIeL5TYbghQSDv0nzkrH4+yMnnDTZjdMQ==", + "version": "2.0.22", + "resolved": "https://registry.npmmirror.com/@chakra-ui/radio/-/radio-2.0.22.tgz", + "integrity": "sha512-GsQ5WAnLwivWl6gPk8P1x+tCcpVakCt5R5T0HumF7DGPXKdJbjS+RaFySrbETmyTJsKY4QrfXn+g8CWVrMjPjw==", "dependencies": { - "@chakra-ui/form-control": "2.0.17", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/form-control": "2.0.18", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", - "@zag-js/focus-visible": "0.2.1" + "@zag-js/focus-visible": "0.2.2" }, "peerDependencies": { "@chakra-ui/system": ">=2.0.0", @@ -2494,59 +2499,59 @@ } }, "node_modules/@chakra-ui/react": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@chakra-ui/react/-/react-2.5.1.tgz", - "integrity": "sha512-ugkaqfcNMb9L4TkalWiF3rnqfr0TlUUD46JZaDIZiORVisaSwXTZTQrVfG40VghhaJT28rnC5WtiE8kd567ZBQ==", - "dependencies": { - "@chakra-ui/accordion": "2.1.9", - "@chakra-ui/alert": "2.0.17", - "@chakra-ui/avatar": "2.2.5", - "@chakra-ui/breadcrumb": "2.1.4", - "@chakra-ui/button": "2.0.16", + "version": "2.5.5", + "resolved": "https://registry.npmmirror.com/@chakra-ui/react/-/react-2.5.5.tgz", + "integrity": "sha512-aBVMUtdWv2MrptD/tKSqICPsuJ+I+jvauegffO1qPUDlK3RrXIDeOHkLGWohgXNcjY5bGVWguFEzJm97//0ooQ==", + "dependencies": { + "@chakra-ui/accordion": "2.1.11", + "@chakra-ui/alert": "2.1.0", + "@chakra-ui/avatar": "2.2.8", + "@chakra-ui/breadcrumb": "2.1.5", + "@chakra-ui/button": "2.0.18", "@chakra-ui/card": "2.1.6", - "@chakra-ui/checkbox": "2.2.10", + "@chakra-ui/checkbox": "2.2.14", "@chakra-ui/close-button": "2.0.17", "@chakra-ui/control-box": "2.0.13", "@chakra-ui/counter": "2.0.14", - "@chakra-ui/css-reset": "2.0.12", - "@chakra-ui/editable": "2.0.19", + "@chakra-ui/css-reset": "2.1.1", + "@chakra-ui/editable": "2.0.21", "@chakra-ui/focus-lock": "2.0.16", - "@chakra-ui/form-control": "2.0.17", + "@chakra-ui/form-control": "2.0.18", "@chakra-ui/hooks": "2.1.6", "@chakra-ui/icon": "3.0.16", "@chakra-ui/image": "2.0.15", - "@chakra-ui/input": "2.0.20", - "@chakra-ui/layout": "2.1.16", + "@chakra-ui/input": "2.0.21", + "@chakra-ui/layout": "2.1.18", "@chakra-ui/live-region": "2.0.13", "@chakra-ui/media-query": "3.2.12", - "@chakra-ui/menu": "2.1.9", - "@chakra-ui/modal": "2.2.9", - "@chakra-ui/number-input": "2.0.18", - "@chakra-ui/pin-input": "2.0.19", - "@chakra-ui/popover": "2.1.8", + "@chakra-ui/menu": "2.1.12", + "@chakra-ui/modal": "2.2.11", + "@chakra-ui/number-input": "2.0.19", + "@chakra-ui/pin-input": "2.0.20", + "@chakra-ui/popover": "2.1.9", "@chakra-ui/popper": "3.0.13", - "@chakra-ui/portal": "2.0.15", - "@chakra-ui/progress": "2.1.5", - "@chakra-ui/provider": "2.1.2", - "@chakra-ui/radio": "2.0.19", + "@chakra-ui/portal": "2.0.16", + "@chakra-ui/progress": "2.1.6", + "@chakra-ui/provider": "2.2.2", + "@chakra-ui/radio": "2.0.22", "@chakra-ui/react-env": "3.0.0", - "@chakra-ui/select": "2.0.18", + "@chakra-ui/select": "2.0.19", "@chakra-ui/skeleton": "2.0.24", - "@chakra-ui/slider": "2.0.21", + "@chakra-ui/slider": "2.0.23", "@chakra-ui/spinner": "2.0.13", - "@chakra-ui/stat": "2.0.17", - "@chakra-ui/styled-system": "2.6.1", - "@chakra-ui/switch": "2.0.22", - "@chakra-ui/system": "2.5.1", - "@chakra-ui/table": "2.0.16", - "@chakra-ui/tabs": "2.1.8", - "@chakra-ui/tag": "2.0.17", - "@chakra-ui/textarea": "2.0.18", - "@chakra-ui/theme": "2.2.5", - "@chakra-ui/theme-utils": "2.0.11", - "@chakra-ui/toast": "6.0.1", - "@chakra-ui/tooltip": "2.2.6", - "@chakra-ui/transition": "2.0.15", + "@chakra-ui/stat": "2.0.18", + "@chakra-ui/styled-system": "2.8.0", + "@chakra-ui/switch": "2.0.26", + "@chakra-ui/system": "2.5.5", + "@chakra-ui/table": "2.0.17", + "@chakra-ui/tabs": "2.1.9", + "@chakra-ui/tag": "3.0.0", + "@chakra-ui/textarea": "2.0.19", + "@chakra-ui/theme": "3.0.1", + "@chakra-ui/theme-utils": "2.0.15", + "@chakra-ui/toast": "6.1.1", + "@chakra-ui/tooltip": "2.2.7", + "@chakra-ui/transition": "2.0.16", "@chakra-ui/utils": "2.0.15", "@chakra-ui/visually-hidden": "2.0.15" }, @@ -2567,9 +2572,9 @@ } }, "node_modules/@chakra-ui/react-context": { - "version": "2.0.7", - "resolved": "https://registry.npmmirror.com/@chakra-ui/react-context/-/react-context-2.0.7.tgz", - "integrity": "sha512-i7EGmSU+h2GB30cwrKB4t1R5BMHyGoJM5L2Zz7b+ZUX4aAqyPcfe97wPiQB6Rgr1ImGXrUeov4CDVrRZ2FPgLQ==", + "version": "2.0.8", + "resolved": "https://registry.npmmirror.com/@chakra-ui/react-context/-/react-context-2.0.8.tgz", + "integrity": "sha512-tRTKdn6lCTXM6WPjSokAAKCw2ioih7Eg8cNgaYRSwKBck8nkz9YqxgIIEj3dJD7MGtpl24S/SNI98iRWkRwR/A==", "peerDependencies": { "react": ">=18" } @@ -2739,11 +2744,11 @@ } }, "node_modules/@chakra-ui/react-use-size": { - "version": "2.0.9", - "resolved": "https://registry.npmmirror.com/@chakra-ui/react-use-size/-/react-use-size-2.0.9.tgz", - "integrity": "sha512-Jce7QmO1jlQZq+Y77VKckWzroRnajChzUQ8xhLQZO6VbYvrpg3cu+X2QCz3G+MZzB+1/hnvvAqmZ+uJLd8rEJg==", + "version": "2.0.10", + "resolved": "https://registry.npmmirror.com/@chakra-ui/react-use-size/-/react-use-size-2.0.10.tgz", + "integrity": "sha512-fdIkH14GDnKQrtQfxX8N3gxbXRPXEl67Y3zeD9z4bKKcQUAYIMqs0MsPZY+FMpGQw8QqafM44nXfL038aIrC5w==", "dependencies": { - "@zag-js/element-size": "0.3.1" + "@zag-js/element-size": "0.3.2" }, "peerDependencies": { "react": ">=18" @@ -2780,11 +2785,11 @@ } }, "node_modules/@chakra-ui/select": { - "version": "2.0.18", - "resolved": "https://registry.npmmirror.com/@chakra-ui/select/-/select-2.0.18.tgz", - "integrity": "sha512-1d2lUT5LM6oOs5x4lzBh4GFDuXX62+lr+sgV7099g951/5UNbb0CS2hSZHsO7yZThLNbr7QTWZvAOAayVcGzdw==", + "version": "2.0.19", + "resolved": "https://registry.npmmirror.com/@chakra-ui/select/-/select-2.0.19.tgz", + "integrity": "sha512-eAlFh+JhwtJ17OrB6fO6gEAGOMH18ERNrXLqWbYLrs674Le7xuREgtuAYDoxUzvYXYYTTdOJtVbcHGriI3o6rA==", "dependencies": { - "@chakra-ui/form-control": "2.0.17", + "@chakra-ui/form-control": "2.0.18", "@chakra-ui/shared-utils": "2.0.5" }, "peerDependencies": { @@ -2812,19 +2817,19 @@ } }, "node_modules/@chakra-ui/slider": { - "version": "2.0.21", - "resolved": "https://registry.npmmirror.com/@chakra-ui/slider/-/slider-2.0.21.tgz", - "integrity": "sha512-Mm76yJxEqJl21+3waEcKg3tM8Y4elJ7mcViN6Brj35PTfzUJfSJxeBGo1nLPJ+X5jLj7o/L4kfBmUk3lY4QYEQ==", + "version": "2.0.23", + "resolved": "https://registry.npmmirror.com/@chakra-ui/slider/-/slider-2.0.23.tgz", + "integrity": "sha512-/eyRUXLla+ZdBUPXpakE3SAS2JS8mIJR6qcUYiPVKSpRAi6tMyYeQijAXn2QC1AUVd2JrG8Pz+1Jy7Po3uA7cA==", "dependencies": { "@chakra-ui/number-utils": "2.0.7", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-callback-ref": "2.0.7", "@chakra-ui/react-use-controllable-state": "2.0.8", "@chakra-ui/react-use-latest-ref": "2.0.5", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/react-use-pan-event": "2.0.9", - "@chakra-ui/react-use-size": "2.0.9", + "@chakra-ui/react-use-size": "2.0.10", "@chakra-ui/react-use-update-effect": "2.0.7" }, "peerDependencies": { @@ -2845,12 +2850,12 @@ } }, "node_modules/@chakra-ui/stat": { - "version": "2.0.17", - "resolved": "https://registry.npmmirror.com/@chakra-ui/stat/-/stat-2.0.17.tgz", - "integrity": "sha512-PhD+5oVLWjQmGLfeZSmexp3AtLcaggWBwoMZ4z8QMZIQzf/fJJWMk0bMqxlpTv8ORDkfY/4ImuFB/RJHvcqlcA==", + "version": "2.0.18", + "resolved": "https://registry.npmmirror.com/@chakra-ui/stat/-/stat-2.0.18.tgz", + "integrity": "sha512-wKyfBqhVlIs9bkSerUc6F9KJMw0yTIEKArW7dejWwzToCLPr47u+CtYO6jlJHV6lRvkhi4K4Qc6pyvtJxZ3VpA==", "dependencies": { "@chakra-ui/icon": "3.0.16", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5" }, "peerDependencies": { @@ -2859,9 +2864,9 @@ } }, "node_modules/@chakra-ui/styled-system": { - "version": "2.6.1", - "resolved": "https://registry.npmmirror.com/@chakra-ui/styled-system/-/styled-system-2.6.1.tgz", - "integrity": "sha512-jy/1dVi1LxjoRCm+Eo5mqBgvPy5SCWMlIcz6GbIZBDpkGeKZwtqrZLjekxxLBCy8ORY+kJlUB0FT6AzVR/1tjw==", + "version": "2.8.0", + "resolved": "https://registry.npmmirror.com/@chakra-ui/styled-system/-/styled-system-2.8.0.tgz", + "integrity": "sha512-bmRv/8ACJGGKGx84U1npiUddwdNifJ+/ETklGwooS5APM0ymwUtBYZpFxjYNJrqvVYpg3mVY6HhMyBVptLS7iA==", "dependencies": { "@chakra-ui/shared-utils": "2.0.5", "csstype": "^3.0.11", @@ -2869,11 +2874,11 @@ } }, "node_modules/@chakra-ui/switch": { - "version": "2.0.22", - "resolved": "https://registry.npmmirror.com/@chakra-ui/switch/-/switch-2.0.22.tgz", - "integrity": "sha512-+/Yy6y7VFD91uSPruF8ZvePi3tl5D8UNVATtWEQ+QBI92DLSM+PtgJ2F0Y9GMZ9NzMxpZ80DqwY7/kqcPCfLvw==", + "version": "2.0.26", + "resolved": "https://registry.npmmirror.com/@chakra-ui/switch/-/switch-2.0.26.tgz", + "integrity": "sha512-x62lF6VazSZJQuVxosChVR6+0lIJe8Pxgkl/C9vxjhp2yVYb3mew5tcX/sDOu0dYZy8ro/9hMfGkdN4r9xEU8A==", "dependencies": { - "@chakra-ui/checkbox": "2.2.10", + "@chakra-ui/checkbox": "2.2.14", "@chakra-ui/shared-utils": "2.0.5" }, "peerDependencies": { @@ -2883,17 +2888,17 @@ } }, "node_modules/@chakra-ui/system": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@chakra-ui/system/-/system-2.5.1.tgz", - "integrity": "sha512-4+86OrcSoq7lGkm5fh+sJ3IWXSTzjz+HOllRbCW2Rtnmcg7ritiXVNV2VygEg2DrCcx5+tNqRHDM764zW+AEug==", + "version": "2.5.5", + "resolved": "https://registry.npmmirror.com/@chakra-ui/system/-/system-2.5.5.tgz", + "integrity": "sha512-52BIp/Zyvefgxn5RTByfkTeG4J+y81LWEjWm8jCaRFsLVm8IFgqIrngtcq4I7gD5n/UKbneHlb4eLHo4uc5yDQ==", "dependencies": { "@chakra-ui/color-mode": "2.1.12", "@chakra-ui/object-utils": "2.0.8", "@chakra-ui/react-utils": "2.0.12", - "@chakra-ui/styled-system": "2.6.1", - "@chakra-ui/theme-utils": "2.0.11", + "@chakra-ui/styled-system": "2.8.0", + "@chakra-ui/theme-utils": "2.0.15", "@chakra-ui/utils": "2.0.15", - "react-fast-compare": "3.2.0" + "react-fast-compare": "3.2.1" }, "peerDependencies": { "@emotion/react": "^11.0.0", @@ -2902,11 +2907,11 @@ } }, "node_modules/@chakra-ui/table": { - "version": "2.0.16", - "resolved": "https://registry.npmmirror.com/@chakra-ui/table/-/table-2.0.16.tgz", - "integrity": "sha512-vWDXZ6Ad3Aj66curp1tZBHvCfQHX2FJ4ijLiqGgQszWFIchfhJ5vMgEBJaFMZ+BN1draAjuRTZqaQefOApzvRg==", + "version": "2.0.17", + "resolved": "https://registry.npmmirror.com/@chakra-ui/table/-/table-2.0.17.tgz", + "integrity": "sha512-OScheTEp1LOYvTki2NFwnAYvac8siAhW9BI5RKm5f5ORL2gVJo4I72RUqE0aKe1oboxgm7CYt5afT5PS5cG61A==", "dependencies": { - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5" }, "peerDependencies": { @@ -2915,15 +2920,15 @@ } }, "node_modules/@chakra-ui/tabs": { - "version": "2.1.8", - "resolved": "https://registry.npmmirror.com/@chakra-ui/tabs/-/tabs-2.1.8.tgz", - "integrity": "sha512-B7LeFN04Ny2jsSy5TFOQxnbZ6ITxGxLxsB2PE0vvQjMSblBrUryOxdjw80HZhfiw6od0ikK9CeKQOIt9QCguSw==", + "version": "2.1.9", + "resolved": "https://registry.npmmirror.com/@chakra-ui/tabs/-/tabs-2.1.9.tgz", + "integrity": "sha512-Yf8e0kRvaGM6jfkJum0aInQ0U3ZlCafmrYYni2lqjcTtThqu+Yosmo3iYlnullXxCw5MVznfrkb9ySvgQowuYg==", "dependencies": { "@chakra-ui/clickable": "2.0.14", - "@chakra-ui/descendant": "3.0.13", + "@chakra-ui/descendant": "3.0.14", "@chakra-ui/lazy-utils": "2.0.5", "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-controllable-state": "2.0.8", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/react-use-safe-layout-effect": "2.0.5", @@ -2935,12 +2940,12 @@ } }, "node_modules/@chakra-ui/tag": { - "version": "2.0.17", - "resolved": "https://registry.npmmirror.com/@chakra-ui/tag/-/tag-2.0.17.tgz", - "integrity": "sha512-A47zE9Ft9qxOJ+5r1cUseKRCoEdqCRzFm0pOtZgRcckqavglk75Xjgz8HbBpUO2zqqd49MlqdOwR8o87fXS1vg==", + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/@chakra-ui/tag/-/tag-3.0.0.tgz", + "integrity": "sha512-YWdMmw/1OWRwNkG9pX+wVtZio+B89odaPj6XeMn5nfNN8+jyhIEpouWv34+CO9G0m1lupJTxPSfgLAd7cqXZMA==", "dependencies": { "@chakra-ui/icon": "3.0.16", - "@chakra-ui/react-context": "2.0.7" + "@chakra-ui/react-context": "2.0.8" }, "peerDependencies": { "@chakra-ui/system": ">=2.0.0", @@ -2948,11 +2953,11 @@ } }, "node_modules/@chakra-ui/textarea": { - "version": "2.0.18", - "resolved": "https://registry.npmmirror.com/@chakra-ui/textarea/-/textarea-2.0.18.tgz", - "integrity": "sha512-aGHHb29vVifO0OtcK/k8cMykzjOKo/coDTU0NJqz7OOLAWIMNV2eGenvmO1n9tTZbmbqHiX+Sa1nPRX+pd14lg==", + "version": "2.0.19", + "resolved": "https://registry.npmmirror.com/@chakra-ui/textarea/-/textarea-2.0.19.tgz", + "integrity": "sha512-adJk+qVGsFeJDvfn56CcJKKse8k7oMGlODrmpnpTdF+xvlsiTM+1GfaJvgNSpHHuQFdz/A0z1uJtfGefk0G2ZA==", "dependencies": { - "@chakra-ui/form-control": "2.0.17", + "@chakra-ui/form-control": "2.0.18", "@chakra-ui/shared-utils": "2.0.5" }, "peerDependencies": { @@ -2961,9 +2966,9 @@ } }, "node_modules/@chakra-ui/theme": { - "version": "2.2.5", - "resolved": "https://registry.npmmirror.com/@chakra-ui/theme/-/theme-2.2.5.tgz", - "integrity": "sha512-hYASZMwu0NqEv6PPydu+F3I+kMNd44yR4TwjR/lXBz/LEh64L6UPY6kQjebCfgdVtsGdl3HKg+eLlfa7SvfRgw==", + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/@chakra-ui/theme/-/theme-3.0.1.tgz", + "integrity": "sha512-92kDm/Ux/51uJqhRKevQo/O/rdwucDYcpHg2QuwzdAxISCeYvgtl2TtgOOl5EnqEP0j3IEAvZHZUlv8TTbawaw==", "dependencies": { "@chakra-ui/anatomy": "2.1.2", "@chakra-ui/shared-utils": "2.0.5", @@ -2987,45 +2992,45 @@ } }, "node_modules/@chakra-ui/theme-utils": { - "version": "2.0.11", - "resolved": "https://registry.npmmirror.com/@chakra-ui/theme-utils/-/theme-utils-2.0.11.tgz", - "integrity": "sha512-lBAay6Sq3/fl7exd3mFxWAbzgdQowytor0fnlHrpNStn1HgFjXukwsf6356XQOie2Vd8qaMM7qZtMh4AiC0dcg==", + "version": "2.0.15", + "resolved": "https://registry.npmmirror.com/@chakra-ui/theme-utils/-/theme-utils-2.0.15.tgz", + "integrity": "sha512-UuxtEgE7gwMTGDXtUpTOI7F5X0iHB9ekEOG5PWPn2wWBL7rlk2JtPI7UP5Um5Yg6vvBfXYGK1ySahxqsgf+87g==", "dependencies": { "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/styled-system": "2.6.1", - "@chakra-ui/theme": "2.2.5", + "@chakra-ui/styled-system": "2.8.0", + "@chakra-ui/theme": "3.0.1", "lodash.mergewith": "4.6.2" } }, "node_modules/@chakra-ui/toast": { - "version": "6.0.1", - "resolved": "https://registry.npmmirror.com/@chakra-ui/toast/-/toast-6.0.1.tgz", - "integrity": "sha512-ej2kJXvu/d2h6qnXU5D8XTyw0qpsfmbiU7hUffo/sPxkz89AUOQ08RUuUmB1ssW/FZcQvNMJ5WgzCTKHGBxtxw==", + "version": "6.1.1", + "resolved": "https://registry.npmmirror.com/@chakra-ui/toast/-/toast-6.1.1.tgz", + "integrity": "sha512-JtjIKkPVjEu8okGGCipCxNVgK/15h5AicTATZ6RbG2MsHmr4GfKG3fUCvpbuZseArqmLqGLQZQJjVE9vJzaSkQ==", "dependencies": { - "@chakra-ui/alert": "2.0.17", + "@chakra-ui/alert": "2.1.0", "@chakra-ui/close-button": "2.0.17", - "@chakra-ui/portal": "2.0.15", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/portal": "2.0.16", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-timeout": "2.0.5", "@chakra-ui/react-use-update-effect": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/styled-system": "2.6.1", - "@chakra-ui/theme": "2.2.5" + "@chakra-ui/styled-system": "2.8.0", + "@chakra-ui/theme": "3.0.1" }, "peerDependencies": { - "@chakra-ui/system": "2.5.1", + "@chakra-ui/system": "2.5.5", "framer-motion": ">=4.0.0", "react": ">=18", "react-dom": ">=18" } }, "node_modules/@chakra-ui/tooltip": { - "version": "2.2.6", - "resolved": "https://registry.npmmirror.com/@chakra-ui/tooltip/-/tooltip-2.2.6.tgz", - "integrity": "sha512-4cbneidZ5+HCWge3OZzewRQieIvhDjSsl+scrl4Scx7E0z3OmqlTIESU5nGIZDBLYqKn/UirEZhqaQ33FOS2fw==", + "version": "2.2.7", + "resolved": "https://registry.npmmirror.com/@chakra-ui/tooltip/-/tooltip-2.2.7.tgz", + "integrity": "sha512-ImUJ6NnVqARaYqpgtO+kzucDRmxo8AF3jMjARw0bx2LxUkKwgRCOEaaRK5p5dHc0Kr6t5/XqjDeUNa19/sLauA==", "dependencies": { "@chakra-ui/popper": "3.0.13", - "@chakra-ui/portal": "2.0.15", + "@chakra-ui/portal": "2.0.16", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-disclosure": "2.0.8", "@chakra-ui/react-use-event-listener": "2.0.7", @@ -3040,9 +3045,9 @@ } }, "node_modules/@chakra-ui/transition": { - "version": "2.0.15", - "resolved": "https://registry.npmmirror.com/@chakra-ui/transition/-/transition-2.0.15.tgz", - "integrity": "sha512-o9LBK/llQfUDHF/Ty3cQ6nShpekKTqHUoJlUOzNKhoTsNpoRerr9v0jwojrX1YI02KtVjfhFU6PiqXlDfREoNw==", + "version": "2.0.16", + "resolved": "https://registry.npmmirror.com/@chakra-ui/transition/-/transition-2.0.16.tgz", + "integrity": "sha512-E+RkwlPc3H7P1crEXmXwDXMB2lqY2LLia2P5siQ4IEnRWIgZXlIw+8Em+NtHNgusel2N+9yuB0wT9SeZZeZ3CQ==", "dependencies": { "@chakra-ui/shared-utils": "2.0.5" }, @@ -3205,9 +3210,9 @@ "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" }, "node_modules/@esbuild/android-arm": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.16.17.tgz", - "integrity": "sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.17.12.tgz", + "integrity": "sha512-E/sgkvwoIfj4aMAPL2e35VnUJspzVYl7+M1B2cqeubdBhADV4uPon0KCc8p2G+LqSJ6i8ocYPCqY3A4GGq0zkQ==", "cpu": [ "arm" ], @@ -3221,9 +3226,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz", - "integrity": "sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.17.12.tgz", + "integrity": "sha512-WQ9p5oiXXYJ33F2EkE3r0FRDFVpEdcDiwNX3u7Xaibxfx6vQE0Sb8ytrfQsA5WO6kDn6mDfKLh6KrPBjvkk7xA==", "cpu": [ "arm64" ], @@ -3237,9 +3242,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.16.17.tgz", - "integrity": "sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.17.12.tgz", + "integrity": "sha512-m4OsaCr5gT+se25rFPHKQXARMyAehHTQAz4XX1Vk3d27VtqiX0ALMBPoXZsGaB6JYryCLfgGwUslMqTfqeLU0w==", "cpu": [ "x64" ], @@ -3253,9 +3258,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz", - "integrity": "sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.12.tgz", + "integrity": "sha512-O3GCZghRIx+RAN0NDPhyyhRgwa19MoKlzGonIb5hgTj78krqp9XZbYCvFr9N1eUxg0ZQEpiiZ4QvsOQwBpP+lg==", "cpu": [ "arm64" ], @@ -3269,9 +3274,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz", - "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.17.12.tgz", + "integrity": "sha512-5D48jM3tW27h1qjaD9UNRuN+4v0zvksqZSPZqeSWggfMlsVdAhH3pwSfQIFJwcs9QJ9BRibPS4ViZgs3d2wsCA==", "cpu": [ "x64" ], @@ -3285,9 +3290,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz", - "integrity": "sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.12.tgz", + "integrity": "sha512-OWvHzmLNTdF1erSvrfoEBGlN94IE6vCEaGEkEH29uo/VoONqPnoDFfShi41Ew+yKimx4vrmmAJEGNoyyP+OgOQ==", "cpu": [ "arm64" ], @@ -3301,9 +3306,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz", - "integrity": "sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.12.tgz", + "integrity": "sha512-A0Xg5CZv8MU9xh4a+7NUpi5VHBKh1RaGJKqjxe4KG87X+mTjDE6ZvlJqpWoeJxgfXHT7IMP9tDFu7IZ03OtJAw==", "cpu": [ "x64" ], @@ -3317,9 +3322,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz", - "integrity": "sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.17.12.tgz", + "integrity": "sha512-WsHyJ7b7vzHdJ1fv67Yf++2dz3D726oO3QCu8iNYik4fb5YuuReOI9OtA+n7Mk0xyQivNTPbl181s+5oZ38gyA==", "cpu": [ "arm" ], @@ -3333,9 +3338,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz", - "integrity": "sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.17.12.tgz", + "integrity": "sha512-cK3AjkEc+8v8YG02hYLQIQlOznW+v9N+OI9BAFuyqkfQFR+DnDLhEM5N8QRxAUz99cJTo1rLNXqRrvY15gbQUg==", "cpu": [ "arm64" ], @@ -3349,9 +3354,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz", - "integrity": "sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.17.12.tgz", + "integrity": "sha512-jdOBXJqcgHlah/nYHnj3Hrnl9l63RjtQ4vn9+bohjQPI2QafASB5MtHAoEv0JQHVb/xYQTFOeuHnNYE1zF7tYw==", "cpu": [ "ia32" ], @@ -3365,9 +3370,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz", - "integrity": "sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.17.12.tgz", + "integrity": "sha512-GTOEtj8h9qPKXCyiBBnHconSCV9LwFyx/gv3Phw0pa25qPYjVuuGZ4Dk14bGCfGX3qKF0+ceeQvwmtI+aYBbVA==", "cpu": [ "loong64" ], @@ -3381,9 +3386,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz", - "integrity": "sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.12.tgz", + "integrity": "sha512-o8CIhfBwKcxmEENOH9RwmUejs5jFiNoDw7YgS0EJTF6kgPgcqLFjgoc5kDey5cMHRVCIWc6kK2ShUePOcc7RbA==", "cpu": [ "mips64el" ], @@ -3397,9 +3402,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz", - "integrity": "sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.12.tgz", + "integrity": "sha512-biMLH6NR/GR4z+ap0oJYb877LdBpGac8KfZoEnDiBKd7MD/xt8eaw1SFfYRUeMVx519kVkAOL2GExdFmYnZx3A==", "cpu": [ "ppc64" ], @@ -3413,9 +3418,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz", - "integrity": "sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.12.tgz", + "integrity": "sha512-jkphYUiO38wZGeWlfIBMB72auOllNA2sLfiZPGDtOBb1ELN8lmqBrlMiucgL8awBw1zBXN69PmZM6g4yTX84TA==", "cpu": [ "riscv64" ], @@ -3429,9 +3434,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz", - "integrity": "sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.17.12.tgz", + "integrity": "sha512-j3ucLdeY9HBcvODhCY4b+Ds3hWGO8t+SAidtmWu/ukfLLG/oYDMaA+dnugTVAg5fnUOGNbIYL9TOjhWgQB8W5g==", "cpu": [ "s390x" ], @@ -3445,9 +3450,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz", - "integrity": "sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.17.12.tgz", + "integrity": "sha512-uo5JL3cgaEGotaqSaJdRfFNSCUJOIliKLnDGWaVCgIKkHxwhYMm95pfMbWZ9l7GeW9kDg0tSxcy9NYdEtjwwmA==", "cpu": [ "x64" ], @@ -3461,9 +3466,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz", - "integrity": "sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.12.tgz", + "integrity": "sha512-DNdoRg8JX+gGsbqt2gPgkgb00mqOgOO27KnrWZtdABl6yWTST30aibGJ6geBq3WM2TIeW6COs5AScnC7GwtGPg==", "cpu": [ "x64" ], @@ -3477,9 +3482,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz", - "integrity": "sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.12.tgz", + "integrity": "sha512-aVsENlr7B64w8I1lhHShND5o8cW6sB9n9MUtLumFlPhG3elhNWtE7M1TFpj3m7lT3sKQUMkGFjTQBrvDDO1YWA==", "cpu": [ "x64" ], @@ -3493,9 +3498,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz", - "integrity": "sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.17.12.tgz", + "integrity": "sha512-qbHGVQdKSwi0JQJuZznS4SyY27tYXYF0mrgthbxXrZI3AHKuRvU+Eqbg/F0rmLDpW/jkIZBlCO1XfHUBMNJ1pg==", "cpu": [ "x64" ], @@ -3509,9 +3514,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz", - "integrity": "sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.17.12.tgz", + "integrity": "sha512-zsCp8Ql+96xXTVTmm6ffvoTSZSV2B/LzzkUXAY33F/76EajNw1m+jZ9zPfNJlJ3Rh4EzOszNDHsmG/fZOhtqDg==", "cpu": [ "arm64" ], @@ -3525,9 +3530,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz", - "integrity": "sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.17.12.tgz", + "integrity": "sha512-FfrFjR4id7wcFYOdqbDfDET3tjxCozUgbqdkOABsSFzoZGFC92UK7mg4JKRc/B3NNEf1s2WHxJ7VfTdVDPN3ng==", "cpu": [ "ia32" ], @@ -3541,9 +3546,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz", - "integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.17.12.tgz", + "integrity": "sha512-JOOxw49BVZx2/5tW3FqkdjSD/5gXYeVGPDcB0lvap0gLQshkh1Nyel1QazC+wNxus3xPlsYAgqU1BUmrmCvWtw==", "cpu": [ "x64" ], @@ -3556,15 +3561,39 @@ "node": ">=12" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz", + "integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==", + "dev": true, + "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.4.0", + "resolved": "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", + "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", + "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.5.1", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -3597,6 +3626,15 @@ "node": ">=10" } }, + "node_modules/@eslint/js": { + "version": "8.37.0", + "resolved": "https://registry.npmmirror.com/@eslint/js/-/js-8.37.0.tgz", + "integrity": "sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@floating-ui/core": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.6.2.tgz", @@ -3719,64 +3757,6 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, - "node_modules/@motionone/animation": { - "version": "10.15.1", - "resolved": "https://registry.npmmirror.com/@motionone/animation/-/animation-10.15.1.tgz", - "integrity": "sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==", - "dependencies": { - "@motionone/easing": "^10.15.1", - "@motionone/types": "^10.15.1", - "@motionone/utils": "^10.15.1", - "tslib": "^2.3.1" - } - }, - "node_modules/@motionone/dom": { - "version": "10.15.5", - "resolved": "https://registry.npmmirror.com/@motionone/dom/-/dom-10.15.5.tgz", - "integrity": "sha512-Xc5avlgyh3xukU9tydh9+8mB8+2zAq+WlLsC3eEIp7Ax7DnXgY7Bj/iv0a4X2R9z9ZFZiaXK3BO0xMYHKbAAdA==", - "dependencies": { - "@motionone/animation": "^10.15.1", - "@motionone/generators": "^10.15.1", - "@motionone/types": "^10.15.1", - "@motionone/utils": "^10.15.1", - "hey-listen": "^1.0.8", - "tslib": "^2.3.1" - } - }, - "node_modules/@motionone/easing": { - "version": "10.15.1", - "resolved": "https://registry.npmmirror.com/@motionone/easing/-/easing-10.15.1.tgz", - "integrity": "sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw==", - "dependencies": { - "@motionone/utils": "^10.15.1", - "tslib": "^2.3.1" - } - }, - "node_modules/@motionone/generators": { - "version": "10.15.1", - "resolved": "https://registry.npmmirror.com/@motionone/generators/-/generators-10.15.1.tgz", - "integrity": "sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ==", - "dependencies": { - "@motionone/types": "^10.15.1", - "@motionone/utils": "^10.15.1", - "tslib": "^2.3.1" - } - }, - "node_modules/@motionone/types": { - "version": "10.15.1", - "resolved": "https://registry.npmmirror.com/@motionone/types/-/types-10.15.1.tgz", - "integrity": "sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA==" - }, - "node_modules/@motionone/utils": { - "version": "10.15.1", - "resolved": "https://registry.npmmirror.com/@motionone/utils/-/utils-10.15.1.tgz", - "integrity": "sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw==", - "dependencies": { - "@motionone/types": "^10.15.1", - "hey-listen": "^1.0.8", - "tslib": "^2.3.1" - } - }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -3853,9 +3833,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.3.2", - "resolved": "https://registry.npmmirror.com/@remix-run/router/-/router-1.3.2.tgz", - "integrity": "sha512-t54ONhl/h75X94SWsHGQ4G/ZrCEguKSRQr7DrjTciJXW0YU1QhlwYeycvK5JgkzlxmvrK7wq1NB/PLtHxoiDcA==", + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/@remix-run/router/-/router-1.5.0.tgz", + "integrity": "sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==", "engines": { "node": ">=14" } @@ -4049,16 +4029,16 @@ } }, "node_modules/@tanstack/query-core": { - "version": "4.24.9", - "resolved": "https://registry.npmmirror.com/@tanstack/query-core/-/query-core-4.24.9.tgz", - "integrity": "sha512-pZQ2NpdaHzx8gPPkAPh06d6zRkjfonUzILSYBXrdHDapP2eaBbGsx5L4/dMF+fyAglFzQZdDDzZgAykbM20QVw==" + "version": "4.27.0", + "resolved": "https://registry.npmmirror.com/@tanstack/query-core/-/query-core-4.27.0.tgz", + "integrity": "sha512-sm+QncWaPmM73IPwFlmWSKPqjdTXZeFf/7aEmWh00z7yl2FjqophPt0dE1EHW9P1giMC5rMviv7OUbSDmWzXXA==" }, "node_modules/@tanstack/react-query": { - "version": "4.24.9", - "resolved": "https://registry.npmmirror.com/@tanstack/react-query/-/react-query-4.24.9.tgz", - "integrity": "sha512-6WLwUT9mrngIinRtcZjrWOUENOuLbWvQpKmU6DZCo2iPQVA+qvv3Ji90Amme4AkUyWQ8ZSSRTnAFq8V2tj2ACg==", + "version": "4.28.0", + "resolved": "https://registry.npmmirror.com/@tanstack/react-query/-/react-query-4.28.0.tgz", + "integrity": "sha512-8cGBV5300RHlvYdS4ea+G1JcZIt5CIuprXYFnsWggkmGoC0b5JaqG0fIX3qwDL9PTNkKvG76NGThIWbpXivMrQ==", "dependencies": { - "@tanstack/query-core": "4.24.9", + "@tanstack/query-core": "4.27.0", "use-sync-external-store": "^1.2.0" }, "peerDependencies": { @@ -4096,9 +4076,9 @@ "dev": true }, "node_modules/@types/lodash": { - "version": "4.14.191", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", - "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==" + "version": "4.14.192", + "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.192.tgz", + "integrity": "sha512-km+Vyn3BYm5ytMO13k9KTp27O75rbQ0NFw+U//g+PX7VZyjCioXaRFisqSIJRECljcTv73G3i6BpglNGHgUQ5A==" }, "node_modules/@types/lodash.mergewith": { "version": "4.6.7", @@ -4109,9 +4089,9 @@ } }, "node_modules/@types/node": { - "version": "18.13.0", - "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.13.0.tgz", - "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==", + "version": "18.15.11", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.15.11.tgz", + "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", "dev": true }, "node_modules/@types/parse-json": { @@ -4126,9 +4106,9 @@ "devOptional": true }, "node_modules/@types/react": { - "version": "18.0.28", - "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.0.28.tgz", - "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==", + "version": "18.0.31", + "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.0.31.tgz", + "integrity": "sha512-EEG67of7DsvRDU6BLLI0p+k1GojDLz9+lZsnCpCRTa/lOokvyPBvp8S5x+A24hME3yyQuIipcP70KJ6H7Qupww==", "devOptional": true, "dependencies": { "@types/prop-types": "*", @@ -4137,11 +4117,10 @@ } }, "node_modules/@types/react-datepicker": { - "version": "4.8.0", - "resolved": "https://mirrors.tencent.com/npm/@types%2freact-datepicker/-/react-datepicker-4.8.0.tgz", - "integrity": "sha512-20uzZsIf4moPAjjHDfPvH8UaOHZBxrkiQZoLS3wgKq8Xhp+95gdercLEdoA7/I8nR9R5Jz2qQkdMIM+Lq4AS1A==", + "version": "4.10.0", + "resolved": "https://registry.npmmirror.com/@types/react-datepicker/-/react-datepicker-4.10.0.tgz", + "integrity": "sha512-Cq+ks20vBIU6XN67TbkCHu8M7V46Y6vJrKE2n+8q/GfueJyWWTIKeC3Z7cz/d+qxGDq/VCrqA929R0U4lNuztg==", "dev": true, - "license": "MIT", "dependencies": { "@popperjs/core": "^2.9.2", "@types/react": "*", @@ -4524,14 +4503,14 @@ } }, "node_modules/@zag-js/element-size": { - "version": "0.3.1", - "resolved": "https://registry.npmmirror.com/@zag-js/element-size/-/element-size-0.3.1.tgz", - "integrity": "sha512-jR5j4G//bRzcxwAACWi9EfITnwjNmn10LxF4NmALrdZU7/PNWP3uUCdhCxd/0SCyeiJXUl0yvD57rWAbKPs1nw==" + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/@zag-js/element-size/-/element-size-0.3.2.tgz", + "integrity": "sha512-bVvvigUGvAuj7PCkE5AbzvTJDTw5f3bg9nQdv+ErhVN8SfPPppLJEmmWdxqsRzrHXgx8ypJt/+Ty0kjtISVDsQ==" }, "node_modules/@zag-js/focus-visible": { - "version": "0.2.1", - "resolved": "https://registry.npmmirror.com/@zag-js/focus-visible/-/focus-visible-0.2.1.tgz", - "integrity": "sha512-19uTjoZGP4/Ax7kSNhhay9JA83BirKzpqLkeEAilrpdI1hE5xuq6q+tzJOsrMOOqJrm7LkmZp5lbsTQzvK2pYg==" + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/@zag-js/focus-visible/-/focus-visible-0.2.2.tgz", + "integrity": "sha512-0j2gZq8HiZ51z4zNnSkF1iSkqlwRDvdH+son3wHdoz+7IUdMN/5Exd4TxMJ+gq2Of1DiXReYLL9qqh2PdQ4wgA==" }, "node_modules/acorn": { "version": "8.8.2", @@ -4554,41 +4533,9 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-node": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", - "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", - "dev": true, - "dependencies": { - "acorn": "^7.0.0", - "acorn-walk": "^7.0.0", - "xtend": "^4.0.2" - } - }, - "node_modules/acorn-node/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/aggregate-error": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "resolved": "https://registry.npmmirror.com/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "dependencies": { @@ -4613,7 +4560,7 @@ }, "node_modules/ansi-escapes": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "resolved": "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "dependencies": { @@ -4621,9 +4568,6 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ansi-regex": { @@ -4646,6 +4590,12 @@ "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==", + "dev": true + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -4788,7 +4738,7 @@ }, "node_modules/astral-regex": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "resolved": "https://registry.npmmirror.com/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, "engines": { @@ -4801,23 +4751,13 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/autoprefixer": { - "version": "10.4.13", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", - "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", + "version": "10.4.14", + "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - } - ], "dependencies": { - "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001426", + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -4843,9 +4783,9 @@ } }, "node_modules/axios": { - "version": "1.3.3", - "resolved": "https://registry.npmmirror.com/axios/-/axios-1.3.3.tgz", - "integrity": "sha512-eYq77dYIFS77AQlhzEL937yUBSepBfPIe8FcgEDN35vMNZKMrs81pgnyrQpwfy4NF4b4XWX1Zgx7yX+25w8QJA==", + "version": "1.3.4", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.3.4.tgz", + "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==", "dependencies": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -4996,25 +4936,15 @@ } }, "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.21.5", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" }, "bin": { "browserslist": "cli.js" @@ -5088,20 +5018,10 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001441", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz", - "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] + "version": "1.0.30001469", + "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001469.tgz", + "integrity": "sha512-Rcp7221ScNqQPP3W+lVOYDyjdR6dC+neEQCttoNr5bAyz54AboB4iwpnWgyi8P4YUsPybVzT4LgWiBbI3drL4g==", + "dev": true }, "node_modules/chalk": { "version": "2.4.2", @@ -5196,7 +5116,7 @@ }, "node_modules/clean-stack": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "resolved": "https://registry.npmmirror.com/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, "engines": { @@ -5205,7 +5125,7 @@ }, "node_modules/cli-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "resolved": "https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "dependencies": { @@ -5273,7 +5193,7 @@ }, "node_modules/colorette": { "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "resolved": "https://registry.npmmirror.com/colorette/-/colorette-2.0.19.tgz", "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", "dev": true }, @@ -5298,12 +5218,12 @@ } }, "node_modules/commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "version": "10.0.0", + "resolved": "https://registry.npmmirror.com/commander/-/commander-10.0.0.tgz", + "integrity": "sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==", "dev": true, "engines": { - "node": "^12.20.0 || >=14" + "node": ">=14" } }, "node_modules/compute-scroll-into-view": { @@ -5323,6 +5243,15 @@ "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", "dev": true }, + "node_modules/connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", @@ -5496,15 +5425,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/defined": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", - "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -5518,23 +5438,6 @@ "resolved": "https://registry.npmmirror.com/detect-node-es/-/detect-node-es-1.1.0.tgz", "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, - "node_modules/detective": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", - "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", - "dev": true, - "dependencies": { - "acorn-node": "^1.8.2", - "defined": "^1.0.0", - "minimist": "^1.2.6" - }, - "bin": { - "detective": "bin/detective.js" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -5571,6 +5474,14 @@ "node": ">=6.0.0" } }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "engines": { + "node": ">=12" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -5663,9 +5574,9 @@ } }, "node_modules/esbuild": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.16.17.tgz", - "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.17.12.tgz", + "integrity": "sha512-bX/zHl7Gn2CpQwcMtRogTTBf9l1nl+H6R8nUbjk+RuKqAE3+8FDulLA+pHvX7aA7Xe07Iwa+CWvy9I8Y2qqPKQ==", "dev": true, "hasInstallScript": true, "bin": { @@ -5675,28 +5586,28 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.16.17", - "@esbuild/android-arm64": "0.16.17", - "@esbuild/android-x64": "0.16.17", - "@esbuild/darwin-arm64": "0.16.17", - "@esbuild/darwin-x64": "0.16.17", - "@esbuild/freebsd-arm64": "0.16.17", - "@esbuild/freebsd-x64": "0.16.17", - "@esbuild/linux-arm": "0.16.17", - "@esbuild/linux-arm64": "0.16.17", - "@esbuild/linux-ia32": "0.16.17", - "@esbuild/linux-loong64": "0.16.17", - "@esbuild/linux-mips64el": "0.16.17", - "@esbuild/linux-ppc64": "0.16.17", - "@esbuild/linux-riscv64": "0.16.17", - "@esbuild/linux-s390x": "0.16.17", - "@esbuild/linux-x64": "0.16.17", - "@esbuild/netbsd-x64": "0.16.17", - "@esbuild/openbsd-x64": "0.16.17", - "@esbuild/sunos-x64": "0.16.17", - "@esbuild/win32-arm64": "0.16.17", - "@esbuild/win32-ia32": "0.16.17", - "@esbuild/win32-x64": "0.16.17" + "@esbuild/android-arm": "0.17.12", + "@esbuild/android-arm64": "0.17.12", + "@esbuild/android-x64": "0.17.12", + "@esbuild/darwin-arm64": "0.17.12", + "@esbuild/darwin-x64": "0.17.12", + "@esbuild/freebsd-arm64": "0.17.12", + "@esbuild/freebsd-x64": "0.17.12", + "@esbuild/linux-arm": "0.17.12", + "@esbuild/linux-arm64": "0.17.12", + "@esbuild/linux-ia32": "0.17.12", + "@esbuild/linux-loong64": "0.17.12", + "@esbuild/linux-mips64el": "0.17.12", + "@esbuild/linux-ppc64": "0.17.12", + "@esbuild/linux-riscv64": "0.17.12", + "@esbuild/linux-s390x": "0.17.12", + "@esbuild/linux-x64": "0.17.12", + "@esbuild/netbsd-x64": "0.17.12", + "@esbuild/openbsd-x64": "0.17.12", + "@esbuild/sunos-x64": "0.17.12", + "@esbuild/win32-arm64": "0.17.12", + "@esbuild/win32-ia32": "0.17.12", + "@esbuild/win32-x64": "0.17.12" } }, "node_modules/escalade": { @@ -5720,12 +5631,15 @@ } }, "node_modules/eslint": { - "version": "8.34.0", - "resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.34.0.tgz", - "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==", + "version": "8.37.0", + "resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.37.0.tgz", + "integrity": "sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.4.1", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.2", + "@eslint/js": "8.37.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -5736,10 +5650,9 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-visitor-keys": "^3.4.0", + "espree": "^9.5.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", @@ -5760,7 +5673,6 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -6104,9 +6016,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.0", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -6210,23 +6122,23 @@ } }, "node_modules/espree": { - "version": "9.4.1", - "resolved": "https://registry.npmmirror.com/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.5.1", + "resolved": "https://registry.npmmirror.com/espree/-/espree-9.5.1.tgz", + "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", "dev": true, "dependencies": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -6266,14 +6178,14 @@ } }, "node_modules/execa": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz", - "integrity": "sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==", + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/execa/-/execa-7.1.1.tgz", + "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", "dev": true, "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.1", - "human-signals": "^3.0.1", + "human-signals": "^4.3.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", @@ -6282,10 +6194,7 @@ "strip-final-newline": "^3.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" } }, "node_modules/fast-deep-equal": { @@ -6483,12 +6392,10 @@ } }, "node_modules/framer-motion": { - "version": "9.0.4", - "resolved": "https://registry.npmmirror.com/framer-motion/-/framer-motion-9.0.4.tgz", - "integrity": "sha512-lZ1+2/WBn8iYRYmeEFpu/X2fI1GNwJL+X21EpnWwKP3vkJsnWBXZF5kHF29wIPk9sBU2xDIpDm9SAVo206bp9A==", + "version": "10.10.0", + "resolved": "https://registry.npmmirror.com/framer-motion/-/framer-motion-10.10.0.tgz", + "integrity": "sha512-eCsyOcJimIRbx9KOzBTO3j9u1rF/H8/o/ybizYqdrzHkEeHx9L2NcEfGWfV0OHTc1JV17ECVzuZpomupEJ4+dw==", "dependencies": { - "@motionone/dom": "^10.15.3", - "hey-listen": "^1.0.8", "tslib": "^2.4.0" }, "optionalDependencies": { @@ -6497,6 +6404,14 @@ "peerDependencies": { "react": "^18.0.0", "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } } }, "node_modules/framer-motion/node_modules/@emotion/is-prop-valid": { @@ -6611,14 +6526,11 @@ }, "node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/get-symbol-description": { @@ -6808,11 +6720,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hey-listen": { - "version": "1.0.8", - "resolved": "https://registry.npmmirror.com/hey-listen/-/hey-listen-1.0.8.tgz", - "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==" - }, "node_modules/highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -6844,12 +6751,12 @@ } }, "node_modules/human-signals": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz", - "integrity": "sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==", + "version": "4.3.1", + "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", "dev": true, "engines": { - "node": ">=12.20.0" + "node": ">=14.18.0" } }, "node_modules/husky": { @@ -6865,9 +6772,9 @@ } }, "node_modules/i18next": { - "version": "22.4.10", - "resolved": "https://registry.npmmirror.com/i18next/-/i18next-22.4.10.tgz", - "integrity": "sha512-3EqgGK6fAJRjnGgfkNSStl4mYLCjUoJID338yVyLMj5APT67HUtWoqSayZewiiC5elzMUB1VEUwcmSCoeQcNEA==", + "version": "22.4.13", + "resolved": "https://registry.npmmirror.com/i18next/-/i18next-22.4.13.tgz", + "integrity": "sha512-GX7flMHRRqQA0I1yGLmaZ4Hwt1JfLqagk8QPDPZsqekbKtXsuIngSVWM/s3SLgNkrEXjA+0sMGNuOEkkmyqmWg==", "dependencies": { "@babel/runtime": "^7.20.6" } @@ -6881,9 +6788,9 @@ } }, "node_modules/i18next-http-backend": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.1.1.tgz", - "integrity": "sha512-jByfUCDVgQ8+/Wens7queQhYYvMcGTW/lR4IJJNEDDXnmqjLrwi8ubXKpmp76/JIWEZHffNdWqnxFJcTVGeaOw==", + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/i18next-http-backend/-/i18next-http-backend-2.2.0.tgz", + "integrity": "sha512-Z4sM7R6tzdLknSPER9GisEBxKPg5FkI07UrQniuroZmS15PHQrcCPLyuGKj8SS68tf+O2aEDYSUnmy1TZqZSbw==", "dependencies": { "cross-fetch": "3.1.5" } @@ -6917,9 +6824,9 @@ } }, "node_modules/immer": { - "version": "9.0.19", - "resolved": "https://registry.npmmirror.com/immer/-/immer-9.0.19.tgz", - "integrity": "sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ==" + "version": "9.0.21", + "resolved": "https://registry.npmmirror.com/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==" }, "node_modules/immutable": { "version": "4.2.1", @@ -6952,7 +6859,7 @@ }, "node_modules/indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "resolved": "https://registry.npmmirror.com/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, "engines": { @@ -6975,6 +6882,15 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/install": { + "version": "0.13.0", + "resolved": "https://registry.npmmirror.com/install/-/install-0.13.0.tgz", + "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/internal-slot": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", @@ -7224,14 +7140,11 @@ }, "node_modules/is-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-3.0.0.tgz", "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-string": { @@ -7282,6 +7195,15 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/jiti": { + "version": "1.18.2", + "resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.18.2.tgz", + "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/js-sdsl": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", @@ -7364,9 +7286,9 @@ } }, "node_modules/laf-client-sdk": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/laf-client-sdk/-/laf-client-sdk-1.0.0-beta.2.tgz", - "integrity": "sha512-0Jbctghkw0D4/k+locZEBpkvHoFRHQ2ZQ60mBUKoz9fLxheK4ddTI71RFckB1aBKhFgSqfH6Hsdhxnl/MGEJWw==", + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/laf-client-sdk/-/laf-client-sdk-1.0.0-beta.7.tgz", + "integrity": "sha512-qe5KRt5PT6tFllklXDP+/r8Gglu9udyrHG8VInITxgWpGfQEScnprU3wGl+EBtDaTKnA+nRbsXXIS2aMuuWzpg==", "dependencies": { "axios": "^0.21.1", "database-ql": "^1.0.0-beta.2" @@ -7409,9 +7331,9 @@ } }, "node_modules/lilconfig": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", - "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", "dev": true, "engines": { "node": ">=10" @@ -7423,24 +7345,24 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/lint-staged": { - "version": "13.1.2", - "resolved": "https://registry.npmmirror.com/lint-staged/-/lint-staged-13.1.2.tgz", - "integrity": "sha512-K9b4FPbWkpnupvK3WXZLbgu9pchUJ6N7TtVZjbaPsoizkqFUDkUReUL25xdrCljJs7uLUF3tZ7nVPeo/6lp+6w==", + "version": "13.2.0", + "resolved": "https://registry.npmmirror.com/lint-staged/-/lint-staged-13.2.0.tgz", + "integrity": "sha512-GbyK5iWinax5Dfw5obm2g2ccUiZXNGtAS4mCbJ0Lv4rq6iEtfBSjOYdcbOtAIFtM114t0vdpViDDetjVTSd8Vw==", "dev": true, "dependencies": { + "chalk": "5.2.0", "cli-truncate": "^3.1.0", - "colorette": "^2.0.19", - "commander": "^9.4.1", + "commander": "^10.0.0", "debug": "^4.3.4", - "execa": "^6.1.0", - "lilconfig": "2.0.6", - "listr2": "^5.0.5", + "execa": "^7.0.0", + "lilconfig": "2.1.0", + "listr2": "^5.0.7", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", - "object-inspect": "^1.12.2", + "object-inspect": "^1.12.3", "pidtree": "^0.6.0", "string-argv": "^0.3.1", - "yaml": "^2.1.3" + "yaml": "^2.2.1" }, "bin": { "lint-staged": "bin/lint-staged.js" @@ -7449,19 +7371,28 @@ "node": "^14.13.1 || >=16.0.0" } }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + } + }, "node_modules/lint-staged/node_modules/yaml": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.0.tgz", - "integrity": "sha512-auf7Gi6QwO7HW//GA9seGvTXVGWl1CM/ADWh1+RxtXr6XOxnT65ovDl9fTi4e0monEyJxCHqDpF6QnFDXmJE4g==", + "version": "2.2.1", + "resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.2.1.tgz", + "integrity": "sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==", "dev": true, "engines": { "node": ">= 14" } }, "node_modules/listr2": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.6.tgz", - "integrity": "sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag==", + "version": "5.0.8", + "resolved": "https://registry.npmmirror.com/listr2/-/listr2-5.0.8.tgz", + "integrity": "sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==", "dev": true, "dependencies": { "cli-truncate": "^2.1.0", @@ -7469,7 +7400,7 @@ "log-update": "^4.0.0", "p-map": "^4.0.0", "rfdc": "^1.3.0", - "rxjs": "^7.5.7", + "rxjs": "^7.8.0", "through": "^2.3.8", "wrap-ansi": "^7.0.0" }, @@ -7487,7 +7418,7 @@ }, "node_modules/listr2/node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { @@ -7495,14 +7426,11 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/listr2/node_modules/cli-truncate": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "resolved": "https://registry.npmmirror.com/cli-truncate/-/cli-truncate-2.1.0.tgz", "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, "dependencies": { @@ -7511,14 +7439,11 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/listr2/node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { @@ -7530,19 +7455,19 @@ }, "node_modules/listr2/node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/listr2/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "node_modules/listr2/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { @@ -7551,7 +7476,7 @@ }, "node_modules/listr2/node_modules/slice-ansi": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "resolved": "https://registry.npmmirror.com/slice-ansi/-/slice-ansi-3.0.0.tgz", "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, "dependencies": { @@ -7565,7 +7490,7 @@ }, "node_modules/listr2/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { @@ -7631,7 +7556,7 @@ }, "node_modules/log-update": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "resolved": "https://registry.npmmirror.com/log-update/-/log-update-4.0.0.tgz", "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", "dev": true, "dependencies": { @@ -7642,14 +7567,11 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update/node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { @@ -7657,14 +7579,11 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/log-update/node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { @@ -7676,19 +7595,19 @@ }, "node_modules/log-update/node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/log-update/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "node_modules/log-update/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { @@ -7697,7 +7616,7 @@ }, "node_modules/log-update/node_modules/slice-ansi": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "resolved": "https://registry.npmmirror.com/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "dependencies": { @@ -7707,14 +7626,11 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/log-update/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { @@ -7728,7 +7644,7 @@ }, "node_modules/log-update/node_modules/wrap-ansi": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "dependencies": { @@ -7780,7 +7696,7 @@ }, "node_modules/merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, @@ -7827,14 +7743,11 @@ }, "node_modules/mimic-fn": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz", "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, "engines": { "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/minimatch": { @@ -7859,9 +7772,9 @@ } }, "node_modules/monaco-editor": { - "version": "0.35.0", - "resolved": "https://registry.npmmirror.com/monaco-editor/-/monaco-editor-0.35.0.tgz", - "integrity": "sha512-BJfkAZ0EJ7JgrgWzqjfBNP9hPSS8NlfECEDMEIIiozV2UaPq22yeuOjgbd3TwMh3anH0krWZirXZfn8KUSxiOA==" + "version": "0.36.1", + "resolved": "https://registry.npmmirror.com/monaco-editor/-/monaco-editor-0.36.1.tgz", + "integrity": "sha512-/CaclMHKQ3A6rnzBzOADfwdSJ25BFoFT0Emxsc4zYVyav5SkK9iA6lEtIeuN/oRYbwPgviJT+t3l+sjFa28jYg==" }, "node_modules/ms": { "version": "2.1.2", @@ -7869,6 +7782,17 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -7937,7 +7861,7 @@ }, "node_modules/npm-run-path": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-5.1.0.tgz", "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", "dev": true, "dependencies": { @@ -7945,21 +7869,15 @@ }, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/npm-run-path/node_modules/path-key": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "resolved": "https://registry.npmmirror.com/path-key/-/path-key-4.0.0.tgz", "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, "engines": { "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/object-assign": { @@ -7980,13 +7898,10 @@ } }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "version": "1.12.3", + "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true }, "node_modules/object-keys": { "version": "1.1.1", @@ -8087,7 +8002,7 @@ }, "node_modules/onetime": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "resolved": "https://registry.npmmirror.com/onetime/-/onetime-6.0.0.tgz", "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "dependencies": { @@ -8095,9 +8010,6 @@ }, "engines": { "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/optionator": { @@ -8149,7 +8061,7 @@ }, "node_modules/p-map": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "resolved": "https://registry.npmmirror.com/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, "dependencies": { @@ -8157,9 +8069,6 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/parent-module": { @@ -8285,6 +8194,15 @@ "node": ">=0.10.0" } }, + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/point-in-polygon": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/point-in-polygon/-/point-in-polygon-1.1.0.tgz", @@ -8418,9 +8336,9 @@ } }, "node_modules/prettier": { - "version": "2.8.4", - "resolved": "https://registry.npmmirror.com/prettier/-/prettier-2.8.4.tgz", - "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", + "version": "2.8.7", + "resolved": "https://registry.npmmirror.com/prettier/-/prettier-2.8.7.tgz", + "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -8429,6 +8347,80 @@ "node": ">=10.13.0" } }, + "node_modules/prettier-plugin-tailwindcss": { + "version": "0.2.6", + "resolved": "https://registry.npmmirror.com/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.2.6.tgz", + "integrity": "sha512-F+7XCl9RLF/LPrGdUMHWpsT6TM31JraonAUyE6eBmpqymFvDwyl0ETHsKFHP1NG+sEfv8bmKqnTxEbWQbHPlBA==", + "dev": true, + "engines": { + "node": ">=12.17.0" + }, + "peerDependencies": { + "@ianvs/prettier-plugin-sort-imports": "*", + "@prettier/plugin-php": "*", + "@prettier/plugin-pug": "*", + "@shopify/prettier-plugin-liquid": "*", + "@shufo/prettier-plugin-blade": "*", + "@trivago/prettier-plugin-sort-imports": "*", + "prettier": ">=2.2.0", + "prettier-plugin-astro": "*", + "prettier-plugin-css-order": "*", + "prettier-plugin-import-sort": "*", + "prettier-plugin-jsdoc": "*", + "prettier-plugin-organize-attributes": "*", + "prettier-plugin-organize-imports": "*", + "prettier-plugin-style-order": "*", + "prettier-plugin-svelte": "*", + "prettier-plugin-twig-melody": "*" + }, + "peerDependenciesMeta": { + "@ianvs/prettier-plugin-sort-imports": { + "optional": true + }, + "@prettier/plugin-php": { + "optional": true + }, + "@prettier/plugin-pug": { + "optional": true + }, + "@shopify/prettier-plugin-liquid": { + "optional": true + }, + "@shufo/prettier-plugin-blade": { + "optional": true + }, + "@trivago/prettier-plugin-sort-imports": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + }, + "prettier-plugin-css-order": { + "optional": true + }, + "prettier-plugin-import-sort": { + "optional": true + }, + "prettier-plugin-jsdoc": { + "optional": true + }, + "prettier-plugin-organize-attributes": { + "optional": true + }, + "prettier-plugin-organize-imports": { + "optional": true + }, + "prettier-plugin-style-order": { + "optional": true + }, + "prettier-plugin-svelte": { + "optional": true + }, + "prettier-plugin-twig-melody": { + "optional": true + } + } + }, "node_modules/prismjs": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", @@ -8536,9 +8528,9 @@ } }, "node_modules/react-datepicker": { - "version": "4.10.0", - "resolved": "https://registry.npmmirror.com/react-datepicker/-/react-datepicker-4.10.0.tgz", - "integrity": "sha512-6IfBCZyWj54ZZGLmEZJ9c4Yph0s9MVfEGDC2evOvf9AmVz+RRcfP2Czqad88Ff9wREbcbqa4dk7IFYeXF1d3Ag==", + "version": "4.11.0", + "resolved": "https://registry.npmmirror.com/react-datepicker/-/react-datepicker-4.11.0.tgz", + "integrity": "sha512-50n93o7mQwBEhg05tbopjFKgs8qgi8VBCAOMC4VqrKut72eAjESc/wXS/k5hRtnP0oe2FCGw7MJuIwh37wuXOw==", "dependencies": { "@popperjs/core": "^2.9.2", "classnames": "^2.2.6", @@ -8565,9 +8557,9 @@ } }, "node_modules/react-fast-compare": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", - "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/react-fast-compare/-/react-fast-compare-3.2.1.tgz", + "integrity": "sha512-xTYf9zFim2pEif/Fw16dBiXpe0hoy5PxcD8+OwBnTtNLfIm3g6WxhKNurY+6OmdH1u6Ta/W/Vl6vjbYP1MFnDg==" }, "node_modules/react-focus-lock": { "version": "2.9.4", @@ -8592,9 +8584,9 @@ } }, "node_modules/react-hook-form": { - "version": "7.43.1", - "resolved": "https://registry.npmmirror.com/react-hook-form/-/react-hook-form-7.43.1.tgz", - "integrity": "sha512-+s3+s8LLytRMriwwuSqeLStVjRXFGxgjjx2jED7Z+wz1J/88vpxieRQGvJVvzrzVxshZ0BRuocFERb779m2kNg==", + "version": "7.43.9", + "resolved": "https://registry.npmmirror.com/react-hook-form/-/react-hook-form-7.43.9.tgz", + "integrity": "sha512-AUDN3Pz2NSeoxQ7Hs6OhQhDr6gtF9YRuutGDwPQqhSUAHJSgGl2VeY3qN19MG0SucpjgDiuMJ4iC5T5uB+eaNQ==", "engines": { "node": ">=12.22.0" }, @@ -8603,9 +8595,9 @@ } }, "node_modules/react-i18next": { - "version": "12.1.5", - "resolved": "https://registry.npmmirror.com/react-i18next/-/react-i18next-12.1.5.tgz", - "integrity": "sha512-7PQAv6DA0TcStG96fle+8RfTwxVbHVlZZJPoEszwUNvDuWpGldJmNWa3ZPesEsZQZGF6GkzwvEh6p57qpFD2gQ==", + "version": "12.2.0", + "resolved": "https://registry.npmmirror.com/react-i18next/-/react-i18next-12.2.0.tgz", + "integrity": "sha512-5XeVgSygaGfyFmDd2WcXvINRw2WEC1XviW1LXY/xLOEMzsCFRwKqfnHN+hUjla8ZipbVJR27GCMSuTr0BhBBBQ==", "dependencies": { "@babel/runtime": "^7.20.6", "html-parse-stringify": "^3.0.1" @@ -8624,9 +8616,9 @@ } }, "node_modules/react-icons": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.7.1.tgz", - "integrity": "sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==", + "version": "4.8.0", + "resolved": "https://registry.npmmirror.com/react-icons/-/react-icons-4.8.0.tgz", + "integrity": "sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==", "peerDependencies": { "react": "*" } @@ -8721,11 +8713,11 @@ } }, "node_modules/react-router": { - "version": "6.8.1", - "resolved": "https://registry.npmmirror.com/react-router/-/react-router-6.8.1.tgz", - "integrity": "sha512-Jgi8BzAJQ8MkPt8ipXnR73rnD7EmZ0HFFb7jdQU24TynGW1Ooqin2KVDN9voSC+7xhqbbCd2cjGUepb6RObnyg==", + "version": "6.10.0", + "resolved": "https://registry.npmmirror.com/react-router/-/react-router-6.10.0.tgz", + "integrity": "sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==", "dependencies": { - "@remix-run/router": "1.3.2" + "@remix-run/router": "1.5.0" }, "engines": { "node": ">=14" @@ -8735,12 +8727,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.8.1", - "resolved": "https://registry.npmmirror.com/react-router-dom/-/react-router-dom-6.8.1.tgz", - "integrity": "sha512-67EXNfkQgf34P7+PSb6VlBuaacGhkKn3kpE51+P6zYSG2kiRoumXEL6e27zTa9+PGF2MNXbgIUHTVlleLbIcHQ==", + "version": "6.10.0", + "resolved": "https://registry.npmmirror.com/react-router-dom/-/react-router-dom-6.10.0.tgz", + "integrity": "sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==", "dependencies": { - "@remix-run/router": "1.3.2", - "react-router": "6.8.1" + "@remix-run/router": "1.5.0", + "react-router": "6.10.0" }, "engines": { "node": ">=14" @@ -8960,7 +8952,7 @@ }, "node_modules/restore-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "resolved": "https://registry.npmmirror.com/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "dependencies": { @@ -8973,7 +8965,7 @@ }, "node_modules/restore-cursor/node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, "engines": { @@ -8982,7 +8974,7 @@ }, "node_modules/restore-cursor/node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "resolved": "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "dependencies": { @@ -8990,9 +8982,6 @@ }, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/reusify": { @@ -9007,7 +8996,7 @@ }, "node_modules/rfdc": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz", "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", "dev": true }, @@ -9027,9 +9016,9 @@ } }, "node_modules/rollup": { - "version": "3.17.1", - "resolved": "https://registry.npmmirror.com/rollup/-/rollup-3.17.1.tgz", - "integrity": "sha512-8RnSms6rNqHmZK+wiqgnPCqen+rRnUHXkciGDirh7B00g1rX1vpKbPDhuxCvAG2bburoI+W4Q9/PlUB/zYkiYA==", + "version": "3.20.0", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-3.20.0.tgz", + "integrity": "sha512-YsIfrk80NqUDrxrjWPXUa7PWvAfegZEXHuPsEZg58fGCdjL1I9C1i/NaG+L+27kxxwkrG/QEDEQc8s/ynXWWGQ==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -9067,7 +9056,7 @@ }, "node_modules/rxjs": { "version": "7.8.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", + "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.0.tgz", "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", "dev": true, "dependencies": { @@ -9089,9 +9078,9 @@ } }, "node_modules/sass": { - "version": "1.58.3", - "resolved": "https://registry.npmmirror.com/sass/-/sass-1.58.3.tgz", - "integrity": "sha512-Q7RaEtYf6BflYrQ+buPudKR26/lH+10EmO9bBqbmPh/KeLqv8bjpTNqxe71ocONqXq+jYiCbpPUmQMS+JJPk4A==", + "version": "1.60.0", + "resolved": "https://registry.npmmirror.com/sass/-/sass-1.60.0.tgz", + "integrity": "sha512-updbwW6fNb5gGm8qMXzVO7V4sWf7LMXnMly/JEyfbfERbVH46Fn6q02BX7/eHTdKpE7d+oTkMMQpFWNUMfFbgQ==", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -9158,7 +9147,7 @@ }, "node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, @@ -9353,30 +9342,74 @@ }, "node_modules/strip-final-newline": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "resolved": "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz", "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylis": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", + "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" + }, + "node_modules/sucrase": { + "version": "3.31.0", + "resolved": "https://registry.npmmirror.com/sucrase/-/sucrase-3.31.0.tgz", + "integrity": "sha512-6QsHnkqyVEzYcaiHsOKkzOtOgdJcb8i54x6AV2hDwyZcY9ZyykGZVw6L/YN98xC0evwTP6utsWWrKRaa8QlfEQ==", + "dev": true, + "dependencies": { + "commander": "^4.0.0", + "glob": "7.1.6", + "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": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 6" } }, - "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==", + "node_modules/sucrase/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmmirror.com/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/stylis": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", - "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" - }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -9400,20 +9433,20 @@ } }, "node_modules/tailwindcss": { - "version": "3.2.7", - "resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.2.7.tgz", - "integrity": "sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==", + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.3.1.tgz", + "integrity": "sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==", "dev": true, "dependencies": { "arg": "^5.0.2", "chokidar": "^3.5.3", "color-name": "^1.1.4", - "detective": "^5.2.1", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.2.12", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", + "jiti": "^1.17.2", "lilconfig": "^2.0.6", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", @@ -9427,7 +9460,8 @@ "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0", "quick-lru": "^5.1.1", - "resolve": "^1.22.1" + "resolve": "^1.22.1", + "sucrase": "^3.29.0" }, "bin": { "tailwind": "lib/cli.js", @@ -9452,9 +9486,30 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "https://registry.npmmirror.com/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, @@ -9492,6 +9547,12 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "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==", + "dev": true + }, "node_modules/tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -9556,27 +9617,24 @@ }, "node_modules/type-fest": { "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.3", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.0.3.tgz", + "integrity": "sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=12.20" } }, "node_modules/unbox-primitive": { @@ -9739,15 +9797,15 @@ "dev": true }, "node_modules/vite": { - "version": "4.1.2", - "resolved": "https://registry.npmmirror.com/vite/-/vite-4.1.2.tgz", - "integrity": "sha512-MWDb9Rfy3DI8omDQySbMK93nQqStwbsQWejXRY2EBzEWKmLAXWb1mkI9Yw2IJrc+oCvPCI1Os5xSSIBYY6DEAw==", + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/vite/-/vite-4.2.1.tgz", + "integrity": "sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==", "dev": true, "dependencies": { - "esbuild": "^0.16.14", + "esbuild": "^0.17.5", "postcss": "^8.4.21", "resolve": "^1.22.1", - "rollup": "^3.10.0" + "rollup": "^3.18.0" }, "bin": { "vite": "bin/vite.js" @@ -9787,6 +9845,21 @@ } } }, + "node_modules/vite-plugin-rewrite-all": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/vite-plugin-rewrite-all/-/vite-plugin-rewrite-all-1.0.1.tgz", + "integrity": "sha512-W0DAchC8ynuQH0lYLIu5/5+JGfYlUTRD8GGNtHFXRJX4FzzB9MajtqHBp26zq/ly9sDt5BqrfdT08rv3RbB0LQ==", + "dev": true, + "dependencies": { + "connect-history-api-fallback": "^1.6.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "vite": "^2.0.0 || ^3.0.0 || ^4.0.0" + } + }, "node_modules/void-elements": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", @@ -9860,7 +9933,7 @@ }, "node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { @@ -9870,14 +9943,11 @@ }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { @@ -9885,14 +9955,11 @@ }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { @@ -9904,19 +9971,19 @@ }, "node_modules/wrap-ansi/node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/wrap-ansi/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { @@ -9925,7 +9992,7 @@ }, "node_modules/wrap-ansi/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { @@ -9978,9 +10045,9 @@ } }, "node_modules/zustand": { - "version": "4.3.3", - "resolved": "https://registry.npmmirror.com/zustand/-/zustand-4.3.3.tgz", - "integrity": "sha512-x2jXq8S0kfLGNwGh87nhRfEc2eZy37tSatpSoSIN+O6HIaBhgQHSONV/F9VNrNcBcKQu/E80K1DeHDYQC/zCrQ==", + "version": "4.3.6", + "resolved": "https://registry.npmmirror.com/zustand/-/zustand-4.3.6.tgz", + "integrity": "sha512-6J5zDxjxLE+yukC2XZWf/IyWVKnXT9b9HUv09VJ/bwGCpKNcaTqp7Ws28Xr8jnbvnZcdRaidztAPsXFBIqufiw==", "dependencies": { "use-sync-external-store": "1.2.0" }, @@ -11286,26 +11353,26 @@ } }, "@chakra-ui/accordion": { - "version": "2.1.9", - "resolved": "https://registry.npmmirror.com/@chakra-ui/accordion/-/accordion-2.1.9.tgz", - "integrity": "sha512-a9CKIAUHezc0f5FR/SQ4GVxnWuIb2HbDTxTEKTp58w/J9pecIbJaNrJ5TUZ0MVbDU9jkgO9RsZ29jkja8PomAw==", + "version": "2.1.11", + "resolved": "https://registry.npmmirror.com/@chakra-ui/accordion/-/accordion-2.1.11.tgz", + "integrity": "sha512-mfVPmqETp9pyRDHJ33AdF19oHv/LyxVzQJtlxUByuvs8Cj9QQZ2LQLg5kejm+b3mj03A7A6yfbuo3RNaI4Bhsg==", "requires": { - "@chakra-ui/descendant": "3.0.13", + "@chakra-ui/descendant": "3.0.14", "@chakra-ui/icon": "3.0.16", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-controllable-state": "2.0.8", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/transition": "2.0.15" + "@chakra-ui/transition": "2.0.16" } }, "@chakra-ui/alert": { - "version": "2.0.17", - "resolved": "https://registry.npmmirror.com/@chakra-ui/alert/-/alert-2.0.17.tgz", - "integrity": "sha512-0Y5vw+HkeXpwbL1roVpSSNM6luMRmUbwduUSHEA4OnX1ismvsDb1ZBfpi4Vxp6w8euJ2Uj6df3krbd5tbCP6tg==", + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/@chakra-ui/alert/-/alert-2.1.0.tgz", + "integrity": "sha512-OcfHwoXI5VrmM+tHJTHT62Bx6TfyfCxSa0PWUOueJzSyhlUOKBND5we6UtrOB7D0jwX45qKKEDJOLG5yCG21jQ==", "requires": { "@chakra-ui/icon": "3.0.16", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5", "@chakra-ui/spinner": "2.0.13" } @@ -11316,23 +11383,23 @@ "integrity": "sha512-pKfOS/mztc4sUXHNc8ypJ1gPWSolWT770jrgVRfolVbYlki8y5Y+As996zMF6k5lewTu6j9DQequ7Cc9a69IVQ==" }, "@chakra-ui/avatar": { - "version": "2.2.5", - "resolved": "https://registry.npmmirror.com/@chakra-ui/avatar/-/avatar-2.2.5.tgz", - "integrity": "sha512-TEHXuGE79+fEn61qJ7J/A0Ec+WjyNwobrDTATcLg9Zx2/WEMmZNfrWIAlI5ANQAwVbdSWeGVbyoLAK5mbcrE0A==", + "version": "2.2.8", + "resolved": "https://registry.npmmirror.com/@chakra-ui/avatar/-/avatar-2.2.8.tgz", + "integrity": "sha512-uBs9PMrqyK111tPIYIKnOM4n3mwgKqGpvYmtwBnnbQLTNLg4gtiWWVbpTuNMpyu1av0xQYomjUt8Doed8w6p8g==", "requires": { "@chakra-ui/image": "2.0.15", "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5" } }, "@chakra-ui/breadcrumb": { - "version": "2.1.4", - "resolved": "https://registry.npmmirror.com/@chakra-ui/breadcrumb/-/breadcrumb-2.1.4.tgz", - "integrity": "sha512-vyBx5TAxPnHhb0b8nyRGfqyjleD//9mySFhk96c9GL+T6YDO4swHw5y/kvDv3Ngc/iRwJ9hdI49PZKwPxLqsEg==", + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/@chakra-ui/breadcrumb/-/breadcrumb-2.1.5.tgz", + "integrity": "sha512-p3eQQrHQBkRB69xOmNyBJqEdfCrMt+e0eOH+Pm/DjFWfIVIbnIaFbmDCeWClqlLa21Ypc6h1hR9jEmvg8kmOog==", "requires": { "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5" } }, @@ -11345,11 +11412,11 @@ } }, "@chakra-ui/button": { - "version": "2.0.16", - "resolved": "https://registry.npmmirror.com/@chakra-ui/button/-/button-2.0.16.tgz", - "integrity": "sha512-NjuTKa7gNhnGSUutKuTc8HoAOe9WWIigpciBG7yj3ok67kg8bXtSzPyQFZlgTY6XGdAckWTT+Do4tvhwa5LA+g==", + "version": "2.0.18", + "resolved": "https://registry.npmmirror.com/@chakra-ui/button/-/button-2.0.18.tgz", + "integrity": "sha512-E3c99+lOm6ou4nQVOTLkG+IdOPMjsQK+Qe7VyP8A/xeAMFONuibrWPRPpprr4ZkB4kEoLMfNuyH2+aEza3ScUA==", "requires": { - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", "@chakra-ui/spinner": "2.0.13" @@ -11364,12 +11431,12 @@ } }, "@chakra-ui/checkbox": { - "version": "2.2.10", - "resolved": "https://registry.npmmirror.com/@chakra-ui/checkbox/-/checkbox-2.2.10.tgz", - "integrity": "sha512-vzxEjw99qj7loxAdP1WuHNt4EAvj/t6cc8oxyOB2mEvkAzhxI34rLR+3zWDuHWsmhyUO+XEDh4FiWdR+DK5Siw==", + "version": "2.2.14", + "resolved": "https://registry.npmmirror.com/@chakra-ui/checkbox/-/checkbox-2.2.14.tgz", + "integrity": "sha512-uqo6lFWLqYBujPglrvRhTAErtuIXpmdpc5w0W4bjK7kyvLhxOpUh1hlDb2WoqlNpfRn/OaNeF6VinPnf9BJL8w==", "requires": { - "@chakra-ui/form-control": "2.0.17", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/form-control": "2.0.18", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-callback-ref": "2.0.7", "@chakra-ui/react-use-controllable-state": "2.0.8", @@ -11378,7 +11445,7 @@ "@chakra-ui/react-use-update-effect": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", "@chakra-ui/visually-hidden": "2.0.15", - "@zag-js/focus-visible": "0.2.1" + "@zag-js/focus-visible": "0.2.2" } }, "@chakra-ui/clickable": { @@ -11423,17 +11490,17 @@ } }, "@chakra-ui/css-reset": { - "version": "2.0.12", - "resolved": "https://registry.npmmirror.com/@chakra-ui/css-reset/-/css-reset-2.0.12.tgz", - "integrity": "sha512-Q5OYIMvqTl2vZ947kIYxcS5DhQXeStB84BzzBd6C10wOx1gFUu9pL+jLpOnHR3hhpWRMdX5o7eT+gMJWIYUZ0Q==", + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/@chakra-ui/css-reset/-/css-reset-2.1.1.tgz", + "integrity": "sha512-jwEOfIAWmQsnChHQTW/eRE+dfE4MjmhvSvoUug5nkV1pI7veC/20noFlIZxzi82EbiQI8Fs0+Jnusgxr2yaOHA==", "requires": {} }, "@chakra-ui/descendant": { - "version": "3.0.13", - "resolved": "https://registry.npmmirror.com/@chakra-ui/descendant/-/descendant-3.0.13.tgz", - "integrity": "sha512-9nzxZVxUSMc4xPL5fSaRkEOQjDQWUGjGvrZI7VzWk9eq63cojOtIxtWMSW383G9148PzWJjJYt30Eud5tdZzlg==", + "version": "3.0.14", + "resolved": "https://registry.npmmirror.com/@chakra-ui/descendant/-/descendant-3.0.14.tgz", + "integrity": "sha512-+Ahvp9H4HMpfScIv9w1vaecGz7qWAaK1YFHHolz/SIsGLaLGlbdp+5UNabQC7L6TUnzzJDQDxzwif78rTD7ang==", "requires": { - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-merge-refs": "2.0.7" } }, @@ -11443,11 +11510,11 @@ "integrity": "sha512-PVtDkPrDD5b8aoL6Atg7SLjkwhWb7BwMcLOF1L449L3nZN+DAO3nyAh6iUhZVJyunELj9d0r65CDlnMREyJZmA==" }, "@chakra-ui/editable": { - "version": "2.0.19", - "resolved": "https://registry.npmmirror.com/@chakra-ui/editable/-/editable-2.0.19.tgz", - "integrity": "sha512-YxRJsJ2JQd42zfPBgTKzIhg1HugT+gfQz1ZosmUN+IZT9YZXL2yodHTUz6Lee04Vc/CdEqgBFLuREXEUNBfGtA==", + "version": "2.0.21", + "resolved": "https://registry.npmmirror.com/@chakra-ui/editable/-/editable-2.0.21.tgz", + "integrity": "sha512-oYuXbHnggxSYJN7P9Pn0Scs9tPC91no4z1y58Oe+ILoJKZ+bFAEHtL7FEISDNJxw++MEukeFu7GU1hVqmdLsKQ==", "requires": { - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-callback-ref": "2.0.7", "@chakra-ui/react-use-controllable-state": "2.0.8", @@ -11473,12 +11540,12 @@ } }, "@chakra-ui/form-control": { - "version": "2.0.17", - "resolved": "https://registry.npmmirror.com/@chakra-ui/form-control/-/form-control-2.0.17.tgz", - "integrity": "sha512-34ptCaJ2LNvQNOlB6MAKsmH1AkT1xo7E+3Vw10Urr81yTOjDTM/iU6vG3JKPfRDMyXeowPjXmutlnuk72SSjRg==", + "version": "2.0.18", + "resolved": "https://registry.npmmirror.com/@chakra-ui/form-control/-/form-control-2.0.18.tgz", + "integrity": "sha512-I0a0jG01IAtRPccOXSNugyRdUAe8Dy40ctqedZvznMweOXzbMCF1m+sHPLdWeWC/VI13VoAispdPY0/zHOdjsQ==", "requires": { "@chakra-ui/icon": "3.0.16", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/shared-utils": "2.0.5" @@ -11504,9 +11571,9 @@ } }, "@chakra-ui/icons": { - "version": "2.0.17", - "resolved": "https://registry.npmmirror.com/@chakra-ui/icons/-/icons-2.0.17.tgz", - "integrity": "sha512-HMJP0WrJgAmFR9+Xh/CBH0nVnGMsJ4ZC8MK6tMgxPKd9/muvn0I4hsicHqdPlLpmB0TlxlhkBAKaVMtOdz6F0w==", + "version": "2.0.18", + "resolved": "https://registry.npmmirror.com/@chakra-ui/icons/-/icons-2.0.18.tgz", + "integrity": "sha512-E/+DF/jw7kdN4/XxCZRnr4FdMXhkl50Q34MVwN9rADWMwPK9uSZPGyC7HOx6rilo7q4bFjYDH3yRj9g+VfbVkg==", "requires": { "@chakra-ui/icon": "3.0.16" } @@ -11521,27 +11588,27 @@ } }, "@chakra-ui/input": { - "version": "2.0.20", - "resolved": "https://registry.npmmirror.com/@chakra-ui/input/-/input-2.0.20.tgz", - "integrity": "sha512-ypmsy4n4uNBVgn6Gd24Zrpi+qRf/T9WEzWkysuYC9Qfxo+i7yuf3snp7XmBy8KSGVSiXE11eO8ZN5oCg6Xg0jg==", + "version": "2.0.21", + "resolved": "https://registry.npmmirror.com/@chakra-ui/input/-/input-2.0.21.tgz", + "integrity": "sha512-AIWjjg6MgcOtlvKmVoZfPPfgF+sBSWL3Zq2HSCAMvS6h7jfxz/Xv0UTFGPk5F4Wt0YHT7qMySg0Jsm0b78HZJg==", "requires": { - "@chakra-ui/form-control": "2.0.17", + "@chakra-ui/form-control": "2.0.18", "@chakra-ui/object-utils": "2.0.8", "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5" } }, "@chakra-ui/layout": { - "version": "2.1.16", - "resolved": "https://registry.npmmirror.com/@chakra-ui/layout/-/layout-2.1.16.tgz", - "integrity": "sha512-QFS3feozIGsvB0H74lUocev55aRF26eNrdmhfJifwikZAiq+zzZAMdBdNU9UJhHClnMOU8/iGZ0MF7ti4zQS1A==", + "version": "2.1.18", + "resolved": "https://registry.npmmirror.com/@chakra-ui/layout/-/layout-2.1.18.tgz", + "integrity": "sha512-F4Gh2e+DGdaWdWT5NZduIFD9NM7Bnuh8sXARFHWPvIu7yvAwZ3ddqC9GK4F3qUngdmkJxDLWQqRSwSh96Lxbhw==", "requires": { "@chakra-ui/breakpoint-utils": "2.0.8", "@chakra-ui/icon": "3.0.16", "@chakra-ui/object-utils": "2.0.8", "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5" } }, @@ -11567,16 +11634,16 @@ } }, "@chakra-ui/menu": { - "version": "2.1.9", - "resolved": "https://registry.npmmirror.com/@chakra-ui/menu/-/menu-2.1.9.tgz", - "integrity": "sha512-ue5nD4QJcl3H3UwN0zZNJmH89XUebnvEdW6THAUL41hDjJ0J/Fjpg9Sgzwug2aBbBXBNbVMsUuhcCj6x91d+IQ==", + "version": "2.1.12", + "resolved": "https://registry.npmmirror.com/@chakra-ui/menu/-/menu-2.1.12.tgz", + "integrity": "sha512-ylNK1VJlr/3/EGg9dLPZ87cBJJjeiYXeU/gOAphsKXMnByrXWhbp4YVnyyyha2KZ0zEw0aPU4nCZ+A69aT9wrg==", "requires": { "@chakra-ui/clickable": "2.0.14", - "@chakra-ui/descendant": "3.0.13", + "@chakra-ui/descendant": "3.0.14", "@chakra-ui/lazy-utils": "2.0.5", "@chakra-ui/popper": "3.0.13", "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-animation-state": "2.0.8", "@chakra-ui/react-use-controllable-state": "2.0.8", "@chakra-ui/react-use-disclosure": "2.0.8", @@ -11585,35 +11652,35 @@ "@chakra-ui/react-use-outside-click": "2.0.7", "@chakra-ui/react-use-update-effect": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/transition": "2.0.15" + "@chakra-ui/transition": "2.0.16" } }, "@chakra-ui/modal": { - "version": "2.2.9", - "resolved": "https://registry.npmmirror.com/@chakra-ui/modal/-/modal-2.2.9.tgz", - "integrity": "sha512-nTfNp7XsVwn5+xJOtstoFA8j0kq/9sJj7KesyYzjEDaMKvCZvIOntRYowoydho43jb4+YC7ebKhp0KOIINS0gg==", + "version": "2.2.11", + "resolved": "https://registry.npmmirror.com/@chakra-ui/modal/-/modal-2.2.11.tgz", + "integrity": "sha512-2J0ZUV5tEzkPiawdkgPz6bmex7NXAde1VXooMwdvK+vuT8PV3U61yorTJOZVLdw7TjjI1Yo94mzsp6UwBud43Q==", "requires": { "@chakra-ui/close-button": "2.0.17", "@chakra-ui/focus-lock": "2.0.16", - "@chakra-ui/portal": "2.0.15", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/portal": "2.0.16", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/transition": "2.0.15", + "@chakra-ui/transition": "2.0.16", "aria-hidden": "^1.2.2", "react-remove-scroll": "^2.5.5" } }, "@chakra-ui/number-input": { - "version": "2.0.18", - "resolved": "https://registry.npmmirror.com/@chakra-ui/number-input/-/number-input-2.0.18.tgz", - "integrity": "sha512-cPkyAFFHHzeFBselrT1BtjlzMkJ6TKrTDUnHFlzqXy6aqeXuhrjFhMfXucjedSpOqedsP9ZbKFTdIAhu9DdL/A==", + "version": "2.0.19", + "resolved": "https://registry.npmmirror.com/@chakra-ui/number-input/-/number-input-2.0.19.tgz", + "integrity": "sha512-HDaITvtMEqOauOrCPsARDxKD9PSHmhWywpcyCSOX0lMe4xx2aaGhU0QQFhsJsykj8Er6pytMv6t0KZksdDv3YA==", "requires": { "@chakra-ui/counter": "2.0.14", - "@chakra-ui/form-control": "2.0.17", + "@chakra-ui/form-control": "2.0.18", "@chakra-ui/icon": "3.0.16", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-callback-ref": "2.0.7", "@chakra-ui/react-use-event-listener": "2.0.7", @@ -11635,27 +11702,27 @@ "integrity": "sha512-2upjT2JgRuiupdrtBWklKBS6tqeGMA77Nh6Q0JaoQuH/8yq+15CGckqn3IUWkWoGI0Fg3bK9LDlbbD+9DLw95Q==" }, "@chakra-ui/pin-input": { - "version": "2.0.19", - "resolved": "https://registry.npmmirror.com/@chakra-ui/pin-input/-/pin-input-2.0.19.tgz", - "integrity": "sha512-6O7s4vWz4cqQ6zvMov9sYj6ZqWAsTxR/MNGe3DNgu1zWQg8veNCYtj1rNGhNS3eZNUMAa8uM2dXIphGTP53Xow==", + "version": "2.0.20", + "resolved": "https://registry.npmmirror.com/@chakra-ui/pin-input/-/pin-input-2.0.20.tgz", + "integrity": "sha512-IHVmerrtHN8F+jRB3W1HnMir1S1TUCWhI7qDInxqPtoRffHt6mzZgLZ0izx8p1fD4HkW4c1d4/ZLEz9uH9bBRg==", "requires": { - "@chakra-ui/descendant": "3.0.13", + "@chakra-ui/descendant": "3.0.14", "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-controllable-state": "2.0.8", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/shared-utils": "2.0.5" } }, "@chakra-ui/popover": { - "version": "2.1.8", - "resolved": "https://registry.npmmirror.com/@chakra-ui/popover/-/popover-2.1.8.tgz", - "integrity": "sha512-ob7fAz+WWmXIq7iGHVB3wDKzZTj+T+noYBT/U1Q+jIf+jMr2WOpJLTfb0HTZcfhvn4EBFlfBg7Wk5qbXNaOn7g==", + "version": "2.1.9", + "resolved": "https://registry.npmmirror.com/@chakra-ui/popover/-/popover-2.1.9.tgz", + "integrity": "sha512-OMJ12VVs9N32tFaZSOqikkKPtwAVwXYsES/D1pff/amBrE3ngCrpxJSIp4uvTdORfIYDojJqrR52ZplDKS9hRQ==", "requires": { "@chakra-ui/close-button": "2.0.17", "@chakra-ui/lazy-utils": "2.0.5", "@chakra-ui/popper": "3.0.13", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-animation-state": "2.0.8", "@chakra-ui/react-use-disclosure": "2.0.8", @@ -11676,101 +11743,101 @@ } }, "@chakra-ui/portal": { - "version": "2.0.15", - "resolved": "https://registry.npmmirror.com/@chakra-ui/portal/-/portal-2.0.15.tgz", - "integrity": "sha512-z8v7K3j1/nMuBzp2+wRIIw7s/eipVtnXLdjK5yqbMxMRa44E8Mu5VNJLz3aQFLHXEUST+ifqrjImQeli9do6LQ==", + "version": "2.0.16", + "resolved": "https://registry.npmmirror.com/@chakra-ui/portal/-/portal-2.0.16.tgz", + "integrity": "sha512-bVID0qbQ0l4xq38LdqAN4EKD4/uFkDnXzFwOlviC9sl0dNhzICDb1ltuH/Adl1d2HTMqyN60O3GO58eHy7plnQ==", "requires": { - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-safe-layout-effect": "2.0.5" } }, "@chakra-ui/progress": { - "version": "2.1.5", - "resolved": "https://registry.npmmirror.com/@chakra-ui/progress/-/progress-2.1.5.tgz", - "integrity": "sha512-jj5Vp4lxUchuwp4RPCepM0yAyKi344bgsOd3Apd+ldxclDcewPc82fbwDu7g/Xv27LqJkT+7E/SlQy04wGrk0g==", + "version": "2.1.6", + "resolved": "https://registry.npmmirror.com/@chakra-ui/progress/-/progress-2.1.6.tgz", + "integrity": "sha512-hHh5Ysv4z6bK+j2GJbi/FT9CVyto2PtNUNwBmr3oNMVsoOUMoRjczfXvvYqp0EHr9PCpxqrq7sRwgQXUzhbDSw==", "requires": { - "@chakra-ui/react-context": "2.0.7" + "@chakra-ui/react-context": "2.0.8" } }, "@chakra-ui/provider": { - "version": "2.1.2", - "resolved": "https://registry.npmmirror.com/@chakra-ui/provider/-/provider-2.1.2.tgz", - "integrity": "sha512-4lLlz8QuJv00BhfyKzWpzfoti9MDOdJ/MqXixJV/EZ02RMBOdE9qy9bSz/WckPC2MVhtRUuwMkxH+0QY21PXuw==", + "version": "2.2.2", + "resolved": "https://registry.npmmirror.com/@chakra-ui/provider/-/provider-2.2.2.tgz", + "integrity": "sha512-UVwnIDnAWq1aKroN5AF+OpNpUqLVeIUk7tKvX3z4CY9FsPFFi6LTEhRHdhpwaU1Tau3Tf9agEu5URegpY7S8BA==", "requires": { - "@chakra-ui/css-reset": "2.0.12", - "@chakra-ui/portal": "2.0.15", + "@chakra-ui/css-reset": "2.1.1", + "@chakra-ui/portal": "2.0.16", "@chakra-ui/react-env": "3.0.0", - "@chakra-ui/system": "2.5.1", + "@chakra-ui/system": "2.5.5", "@chakra-ui/utils": "2.0.15" } }, "@chakra-ui/radio": { - "version": "2.0.19", - "resolved": "https://registry.npmmirror.com/@chakra-ui/radio/-/radio-2.0.19.tgz", - "integrity": "sha512-PlJiV59eGSmeKP4v/4+ccQUWGRd0cjPKkj/p3L+UbOf8pl9dWm8y9kIeL5TYbghQSDv0nzkrH4+yMnnDTZjdMQ==", + "version": "2.0.22", + "resolved": "https://registry.npmmirror.com/@chakra-ui/radio/-/radio-2.0.22.tgz", + "integrity": "sha512-GsQ5WAnLwivWl6gPk8P1x+tCcpVakCt5R5T0HumF7DGPXKdJbjS+RaFySrbETmyTJsKY4QrfXn+g8CWVrMjPjw==", "requires": { - "@chakra-ui/form-control": "2.0.17", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/form-control": "2.0.18", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", - "@zag-js/focus-visible": "0.2.1" + "@zag-js/focus-visible": "0.2.2" } }, "@chakra-ui/react": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@chakra-ui/react/-/react-2.5.1.tgz", - "integrity": "sha512-ugkaqfcNMb9L4TkalWiF3rnqfr0TlUUD46JZaDIZiORVisaSwXTZTQrVfG40VghhaJT28rnC5WtiE8kd567ZBQ==", - "requires": { - "@chakra-ui/accordion": "2.1.9", - "@chakra-ui/alert": "2.0.17", - "@chakra-ui/avatar": "2.2.5", - "@chakra-ui/breadcrumb": "2.1.4", - "@chakra-ui/button": "2.0.16", + "version": "2.5.5", + "resolved": "https://registry.npmmirror.com/@chakra-ui/react/-/react-2.5.5.tgz", + "integrity": "sha512-aBVMUtdWv2MrptD/tKSqICPsuJ+I+jvauegffO1qPUDlK3RrXIDeOHkLGWohgXNcjY5bGVWguFEzJm97//0ooQ==", + "requires": { + "@chakra-ui/accordion": "2.1.11", + "@chakra-ui/alert": "2.1.0", + "@chakra-ui/avatar": "2.2.8", + "@chakra-ui/breadcrumb": "2.1.5", + "@chakra-ui/button": "2.0.18", "@chakra-ui/card": "2.1.6", - "@chakra-ui/checkbox": "2.2.10", + "@chakra-ui/checkbox": "2.2.14", "@chakra-ui/close-button": "2.0.17", "@chakra-ui/control-box": "2.0.13", "@chakra-ui/counter": "2.0.14", - "@chakra-ui/css-reset": "2.0.12", - "@chakra-ui/editable": "2.0.19", + "@chakra-ui/css-reset": "2.1.1", + "@chakra-ui/editable": "2.0.21", "@chakra-ui/focus-lock": "2.0.16", - "@chakra-ui/form-control": "2.0.17", + "@chakra-ui/form-control": "2.0.18", "@chakra-ui/hooks": "2.1.6", "@chakra-ui/icon": "3.0.16", "@chakra-ui/image": "2.0.15", - "@chakra-ui/input": "2.0.20", - "@chakra-ui/layout": "2.1.16", + "@chakra-ui/input": "2.0.21", + "@chakra-ui/layout": "2.1.18", "@chakra-ui/live-region": "2.0.13", "@chakra-ui/media-query": "3.2.12", - "@chakra-ui/menu": "2.1.9", - "@chakra-ui/modal": "2.2.9", - "@chakra-ui/number-input": "2.0.18", - "@chakra-ui/pin-input": "2.0.19", - "@chakra-ui/popover": "2.1.8", + "@chakra-ui/menu": "2.1.12", + "@chakra-ui/modal": "2.2.11", + "@chakra-ui/number-input": "2.0.19", + "@chakra-ui/pin-input": "2.0.20", + "@chakra-ui/popover": "2.1.9", "@chakra-ui/popper": "3.0.13", - "@chakra-ui/portal": "2.0.15", - "@chakra-ui/progress": "2.1.5", - "@chakra-ui/provider": "2.1.2", - "@chakra-ui/radio": "2.0.19", + "@chakra-ui/portal": "2.0.16", + "@chakra-ui/progress": "2.1.6", + "@chakra-ui/provider": "2.2.2", + "@chakra-ui/radio": "2.0.22", "@chakra-ui/react-env": "3.0.0", - "@chakra-ui/select": "2.0.18", + "@chakra-ui/select": "2.0.19", "@chakra-ui/skeleton": "2.0.24", - "@chakra-ui/slider": "2.0.21", + "@chakra-ui/slider": "2.0.23", "@chakra-ui/spinner": "2.0.13", - "@chakra-ui/stat": "2.0.17", - "@chakra-ui/styled-system": "2.6.1", - "@chakra-ui/switch": "2.0.22", - "@chakra-ui/system": "2.5.1", - "@chakra-ui/table": "2.0.16", - "@chakra-ui/tabs": "2.1.8", - "@chakra-ui/tag": "2.0.17", - "@chakra-ui/textarea": "2.0.18", - "@chakra-ui/theme": "2.2.5", - "@chakra-ui/theme-utils": "2.0.11", - "@chakra-ui/toast": "6.0.1", - "@chakra-ui/tooltip": "2.2.6", - "@chakra-ui/transition": "2.0.15", + "@chakra-ui/stat": "2.0.18", + "@chakra-ui/styled-system": "2.8.0", + "@chakra-ui/switch": "2.0.26", + "@chakra-ui/system": "2.5.5", + "@chakra-ui/table": "2.0.17", + "@chakra-ui/tabs": "2.1.9", + "@chakra-ui/tag": "3.0.0", + "@chakra-ui/textarea": "2.0.19", + "@chakra-ui/theme": "3.0.1", + "@chakra-ui/theme-utils": "2.0.15", + "@chakra-ui/toast": "6.1.1", + "@chakra-ui/tooltip": "2.2.7", + "@chakra-ui/transition": "2.0.16", "@chakra-ui/utils": "2.0.15", "@chakra-ui/visually-hidden": "2.0.15" } @@ -11782,9 +11849,9 @@ "requires": {} }, "@chakra-ui/react-context": { - "version": "2.0.7", - "resolved": "https://registry.npmmirror.com/@chakra-ui/react-context/-/react-context-2.0.7.tgz", - "integrity": "sha512-i7EGmSU+h2GB30cwrKB4t1R5BMHyGoJM5L2Zz7b+ZUX4aAqyPcfe97wPiQB6Rgr1ImGXrUeov4CDVrRZ2FPgLQ==", + "version": "2.0.8", + "resolved": "https://registry.npmmirror.com/@chakra-ui/react-context/-/react-context-2.0.8.tgz", + "integrity": "sha512-tRTKdn6lCTXM6WPjSokAAKCw2ioih7Eg8cNgaYRSwKBck8nkz9YqxgIIEj3dJD7MGtpl24S/SNI98iRWkRwR/A==", "requires": {} }, "@chakra-ui/react-env": { @@ -11910,11 +11977,11 @@ "requires": {} }, "@chakra-ui/react-use-size": { - "version": "2.0.9", - "resolved": "https://registry.npmmirror.com/@chakra-ui/react-use-size/-/react-use-size-2.0.9.tgz", - "integrity": "sha512-Jce7QmO1jlQZq+Y77VKckWzroRnajChzUQ8xhLQZO6VbYvrpg3cu+X2QCz3G+MZzB+1/hnvvAqmZ+uJLd8rEJg==", + "version": "2.0.10", + "resolved": "https://registry.npmmirror.com/@chakra-ui/react-use-size/-/react-use-size-2.0.10.tgz", + "integrity": "sha512-fdIkH14GDnKQrtQfxX8N3gxbXRPXEl67Y3zeD9z4bKKcQUAYIMqs0MsPZY+FMpGQw8QqafM44nXfL038aIrC5w==", "requires": { - "@zag-js/element-size": "0.3.1" + "@zag-js/element-size": "0.3.2" } }, "@chakra-ui/react-use-timeout": { @@ -11940,11 +12007,11 @@ } }, "@chakra-ui/select": { - "version": "2.0.18", - "resolved": "https://registry.npmmirror.com/@chakra-ui/select/-/select-2.0.18.tgz", - "integrity": "sha512-1d2lUT5LM6oOs5x4lzBh4GFDuXX62+lr+sgV7099g951/5UNbb0CS2hSZHsO7yZThLNbr7QTWZvAOAayVcGzdw==", + "version": "2.0.19", + "resolved": "https://registry.npmmirror.com/@chakra-ui/select/-/select-2.0.19.tgz", + "integrity": "sha512-eAlFh+JhwtJ17OrB6fO6gEAGOMH18ERNrXLqWbYLrs674Le7xuREgtuAYDoxUzvYXYYTTdOJtVbcHGriI3o6rA==", "requires": { - "@chakra-ui/form-control": "2.0.17", + "@chakra-ui/form-control": "2.0.18", "@chakra-ui/shared-utils": "2.0.5" } }, @@ -11964,19 +12031,19 @@ } }, "@chakra-ui/slider": { - "version": "2.0.21", - "resolved": "https://registry.npmmirror.com/@chakra-ui/slider/-/slider-2.0.21.tgz", - "integrity": "sha512-Mm76yJxEqJl21+3waEcKg3tM8Y4elJ7mcViN6Brj35PTfzUJfSJxeBGo1nLPJ+X5jLj7o/L4kfBmUk3lY4QYEQ==", + "version": "2.0.23", + "resolved": "https://registry.npmmirror.com/@chakra-ui/slider/-/slider-2.0.23.tgz", + "integrity": "sha512-/eyRUXLla+ZdBUPXpakE3SAS2JS8mIJR6qcUYiPVKSpRAi6tMyYeQijAXn2QC1AUVd2JrG8Pz+1Jy7Po3uA7cA==", "requires": { "@chakra-ui/number-utils": "2.0.7", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-callback-ref": "2.0.7", "@chakra-ui/react-use-controllable-state": "2.0.8", "@chakra-ui/react-use-latest-ref": "2.0.5", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/react-use-pan-event": "2.0.9", - "@chakra-ui/react-use-size": "2.0.9", + "@chakra-ui/react-use-size": "2.0.10", "@chakra-ui/react-use-update-effect": "2.0.7" } }, @@ -11989,19 +12056,19 @@ } }, "@chakra-ui/stat": { - "version": "2.0.17", - "resolved": "https://registry.npmmirror.com/@chakra-ui/stat/-/stat-2.0.17.tgz", - "integrity": "sha512-PhD+5oVLWjQmGLfeZSmexp3AtLcaggWBwoMZ4z8QMZIQzf/fJJWMk0bMqxlpTv8ORDkfY/4ImuFB/RJHvcqlcA==", + "version": "2.0.18", + "resolved": "https://registry.npmmirror.com/@chakra-ui/stat/-/stat-2.0.18.tgz", + "integrity": "sha512-wKyfBqhVlIs9bkSerUc6F9KJMw0yTIEKArW7dejWwzToCLPr47u+CtYO6jlJHV6lRvkhi4K4Qc6pyvtJxZ3VpA==", "requires": { "@chakra-ui/icon": "3.0.16", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5" } }, "@chakra-ui/styled-system": { - "version": "2.6.1", - "resolved": "https://registry.npmmirror.com/@chakra-ui/styled-system/-/styled-system-2.6.1.tgz", - "integrity": "sha512-jy/1dVi1LxjoRCm+Eo5mqBgvPy5SCWMlIcz6GbIZBDpkGeKZwtqrZLjekxxLBCy8ORY+kJlUB0FT6AzVR/1tjw==", + "version": "2.8.0", + "resolved": "https://registry.npmmirror.com/@chakra-ui/styled-system/-/styled-system-2.8.0.tgz", + "integrity": "sha512-bmRv/8ACJGGKGx84U1npiUddwdNifJ+/ETklGwooS5APM0ymwUtBYZpFxjYNJrqvVYpg3mVY6HhMyBVptLS7iA==", "requires": { "@chakra-ui/shared-utils": "2.0.5", "csstype": "^3.0.11", @@ -12009,47 +12076,47 @@ } }, "@chakra-ui/switch": { - "version": "2.0.22", - "resolved": "https://registry.npmmirror.com/@chakra-ui/switch/-/switch-2.0.22.tgz", - "integrity": "sha512-+/Yy6y7VFD91uSPruF8ZvePi3tl5D8UNVATtWEQ+QBI92DLSM+PtgJ2F0Y9GMZ9NzMxpZ80DqwY7/kqcPCfLvw==", + "version": "2.0.26", + "resolved": "https://registry.npmmirror.com/@chakra-ui/switch/-/switch-2.0.26.tgz", + "integrity": "sha512-x62lF6VazSZJQuVxosChVR6+0lIJe8Pxgkl/C9vxjhp2yVYb3mew5tcX/sDOu0dYZy8ro/9hMfGkdN4r9xEU8A==", "requires": { - "@chakra-ui/checkbox": "2.2.10", + "@chakra-ui/checkbox": "2.2.14", "@chakra-ui/shared-utils": "2.0.5" } }, "@chakra-ui/system": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@chakra-ui/system/-/system-2.5.1.tgz", - "integrity": "sha512-4+86OrcSoq7lGkm5fh+sJ3IWXSTzjz+HOllRbCW2Rtnmcg7ritiXVNV2VygEg2DrCcx5+tNqRHDM764zW+AEug==", + "version": "2.5.5", + "resolved": "https://registry.npmmirror.com/@chakra-ui/system/-/system-2.5.5.tgz", + "integrity": "sha512-52BIp/Zyvefgxn5RTByfkTeG4J+y81LWEjWm8jCaRFsLVm8IFgqIrngtcq4I7gD5n/UKbneHlb4eLHo4uc5yDQ==", "requires": { "@chakra-ui/color-mode": "2.1.12", "@chakra-ui/object-utils": "2.0.8", "@chakra-ui/react-utils": "2.0.12", - "@chakra-ui/styled-system": "2.6.1", - "@chakra-ui/theme-utils": "2.0.11", + "@chakra-ui/styled-system": "2.8.0", + "@chakra-ui/theme-utils": "2.0.15", "@chakra-ui/utils": "2.0.15", - "react-fast-compare": "3.2.0" + "react-fast-compare": "3.2.1" } }, "@chakra-ui/table": { - "version": "2.0.16", - "resolved": "https://registry.npmmirror.com/@chakra-ui/table/-/table-2.0.16.tgz", - "integrity": "sha512-vWDXZ6Ad3Aj66curp1tZBHvCfQHX2FJ4ijLiqGgQszWFIchfhJ5vMgEBJaFMZ+BN1draAjuRTZqaQefOApzvRg==", + "version": "2.0.17", + "resolved": "https://registry.npmmirror.com/@chakra-ui/table/-/table-2.0.17.tgz", + "integrity": "sha512-OScheTEp1LOYvTki2NFwnAYvac8siAhW9BI5RKm5f5ORL2gVJo4I72RUqE0aKe1oboxgm7CYt5afT5PS5cG61A==", "requires": { - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/shared-utils": "2.0.5" } }, "@chakra-ui/tabs": { - "version": "2.1.8", - "resolved": "https://registry.npmmirror.com/@chakra-ui/tabs/-/tabs-2.1.8.tgz", - "integrity": "sha512-B7LeFN04Ny2jsSy5TFOQxnbZ6ITxGxLxsB2PE0vvQjMSblBrUryOxdjw80HZhfiw6od0ikK9CeKQOIt9QCguSw==", + "version": "2.1.9", + "resolved": "https://registry.npmmirror.com/@chakra-ui/tabs/-/tabs-2.1.9.tgz", + "integrity": "sha512-Yf8e0kRvaGM6jfkJum0aInQ0U3ZlCafmrYYni2lqjcTtThqu+Yosmo3iYlnullXxCw5MVznfrkb9ySvgQowuYg==", "requires": { "@chakra-ui/clickable": "2.0.14", - "@chakra-ui/descendant": "3.0.13", + "@chakra-ui/descendant": "3.0.14", "@chakra-ui/lazy-utils": "2.0.5", "@chakra-ui/react-children-utils": "2.0.6", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-controllable-state": "2.0.8", "@chakra-ui/react-use-merge-refs": "2.0.7", "@chakra-ui/react-use-safe-layout-effect": "2.0.5", @@ -12057,27 +12124,27 @@ } }, "@chakra-ui/tag": { - "version": "2.0.17", - "resolved": "https://registry.npmmirror.com/@chakra-ui/tag/-/tag-2.0.17.tgz", - "integrity": "sha512-A47zE9Ft9qxOJ+5r1cUseKRCoEdqCRzFm0pOtZgRcckqavglk75Xjgz8HbBpUO2zqqd49MlqdOwR8o87fXS1vg==", + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/@chakra-ui/tag/-/tag-3.0.0.tgz", + "integrity": "sha512-YWdMmw/1OWRwNkG9pX+wVtZio+B89odaPj6XeMn5nfNN8+jyhIEpouWv34+CO9G0m1lupJTxPSfgLAd7cqXZMA==", "requires": { "@chakra-ui/icon": "3.0.16", - "@chakra-ui/react-context": "2.0.7" + "@chakra-ui/react-context": "2.0.8" } }, "@chakra-ui/textarea": { - "version": "2.0.18", - "resolved": "https://registry.npmmirror.com/@chakra-ui/textarea/-/textarea-2.0.18.tgz", - "integrity": "sha512-aGHHb29vVifO0OtcK/k8cMykzjOKo/coDTU0NJqz7OOLAWIMNV2eGenvmO1n9tTZbmbqHiX+Sa1nPRX+pd14lg==", + "version": "2.0.19", + "resolved": "https://registry.npmmirror.com/@chakra-ui/textarea/-/textarea-2.0.19.tgz", + "integrity": "sha512-adJk+qVGsFeJDvfn56CcJKKse8k7oMGlODrmpnpTdF+xvlsiTM+1GfaJvgNSpHHuQFdz/A0z1uJtfGefk0G2ZA==", "requires": { - "@chakra-ui/form-control": "2.0.17", + "@chakra-ui/form-control": "2.0.18", "@chakra-ui/shared-utils": "2.0.5" } }, "@chakra-ui/theme": { - "version": "2.2.5", - "resolved": "https://registry.npmmirror.com/@chakra-ui/theme/-/theme-2.2.5.tgz", - "integrity": "sha512-hYASZMwu0NqEv6PPydu+F3I+kMNd44yR4TwjR/lXBz/LEh64L6UPY6kQjebCfgdVtsGdl3HKg+eLlfa7SvfRgw==", + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/@chakra-ui/theme/-/theme-3.0.1.tgz", + "integrity": "sha512-92kDm/Ux/51uJqhRKevQo/O/rdwucDYcpHg2QuwzdAxISCeYvgtl2TtgOOl5EnqEP0j3IEAvZHZUlv8TTbawaw==", "requires": { "@chakra-ui/anatomy": "2.1.2", "@chakra-ui/shared-utils": "2.0.5", @@ -12095,39 +12162,39 @@ } }, "@chakra-ui/theme-utils": { - "version": "2.0.11", - "resolved": "https://registry.npmmirror.com/@chakra-ui/theme-utils/-/theme-utils-2.0.11.tgz", - "integrity": "sha512-lBAay6Sq3/fl7exd3mFxWAbzgdQowytor0fnlHrpNStn1HgFjXukwsf6356XQOie2Vd8qaMM7qZtMh4AiC0dcg==", + "version": "2.0.15", + "resolved": "https://registry.npmmirror.com/@chakra-ui/theme-utils/-/theme-utils-2.0.15.tgz", + "integrity": "sha512-UuxtEgE7gwMTGDXtUpTOI7F5X0iHB9ekEOG5PWPn2wWBL7rlk2JtPI7UP5Um5Yg6vvBfXYGK1ySahxqsgf+87g==", "requires": { "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/styled-system": "2.6.1", - "@chakra-ui/theme": "2.2.5", + "@chakra-ui/styled-system": "2.8.0", + "@chakra-ui/theme": "3.0.1", "lodash.mergewith": "4.6.2" } }, "@chakra-ui/toast": { - "version": "6.0.1", - "resolved": "https://registry.npmmirror.com/@chakra-ui/toast/-/toast-6.0.1.tgz", - "integrity": "sha512-ej2kJXvu/d2h6qnXU5D8XTyw0qpsfmbiU7hUffo/sPxkz89AUOQ08RUuUmB1ssW/FZcQvNMJ5WgzCTKHGBxtxw==", + "version": "6.1.1", + "resolved": "https://registry.npmmirror.com/@chakra-ui/toast/-/toast-6.1.1.tgz", + "integrity": "sha512-JtjIKkPVjEu8okGGCipCxNVgK/15h5AicTATZ6RbG2MsHmr4GfKG3fUCvpbuZseArqmLqGLQZQJjVE9vJzaSkQ==", "requires": { - "@chakra-ui/alert": "2.0.17", + "@chakra-ui/alert": "2.1.0", "@chakra-ui/close-button": "2.0.17", - "@chakra-ui/portal": "2.0.15", - "@chakra-ui/react-context": "2.0.7", + "@chakra-ui/portal": "2.0.16", + "@chakra-ui/react-context": "2.0.8", "@chakra-ui/react-use-timeout": "2.0.5", "@chakra-ui/react-use-update-effect": "2.0.7", "@chakra-ui/shared-utils": "2.0.5", - "@chakra-ui/styled-system": "2.6.1", - "@chakra-ui/theme": "2.2.5" + "@chakra-ui/styled-system": "2.8.0", + "@chakra-ui/theme": "3.0.1" } }, "@chakra-ui/tooltip": { - "version": "2.2.6", - "resolved": "https://registry.npmmirror.com/@chakra-ui/tooltip/-/tooltip-2.2.6.tgz", - "integrity": "sha512-4cbneidZ5+HCWge3OZzewRQieIvhDjSsl+scrl4Scx7E0z3OmqlTIESU5nGIZDBLYqKn/UirEZhqaQ33FOS2fw==", + "version": "2.2.7", + "resolved": "https://registry.npmmirror.com/@chakra-ui/tooltip/-/tooltip-2.2.7.tgz", + "integrity": "sha512-ImUJ6NnVqARaYqpgtO+kzucDRmxo8AF3jMjARw0bx2LxUkKwgRCOEaaRK5p5dHc0Kr6t5/XqjDeUNa19/sLauA==", "requires": { "@chakra-ui/popper": "3.0.13", - "@chakra-ui/portal": "2.0.15", + "@chakra-ui/portal": "2.0.16", "@chakra-ui/react-types": "2.0.7", "@chakra-ui/react-use-disclosure": "2.0.8", "@chakra-ui/react-use-event-listener": "2.0.7", @@ -12136,9 +12203,9 @@ } }, "@chakra-ui/transition": { - "version": "2.0.15", - "resolved": "https://registry.npmmirror.com/@chakra-ui/transition/-/transition-2.0.15.tgz", - "integrity": "sha512-o9LBK/llQfUDHF/Ty3cQ6nShpekKTqHUoJlUOzNKhoTsNpoRerr9v0jwojrX1YI02KtVjfhFU6PiqXlDfREoNw==", + "version": "2.0.16", + "resolved": "https://registry.npmmirror.com/@chakra-ui/transition/-/transition-2.0.16.tgz", + "integrity": "sha512-E+RkwlPc3H7P1crEXmXwDXMB2lqY2LLia2P5siQ4IEnRWIgZXlIw+8Em+NtHNgusel2N+9yuB0wT9SeZZeZ3CQ==", "requires": { "@chakra-ui/shared-utils": "2.0.5" } @@ -12275,168 +12342,183 @@ "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" }, "@esbuild/android-arm": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.16.17.tgz", - "integrity": "sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.17.12.tgz", + "integrity": "sha512-E/sgkvwoIfj4aMAPL2e35VnUJspzVYl7+M1B2cqeubdBhADV4uPon0KCc8p2G+LqSJ6i8ocYPCqY3A4GGq0zkQ==", "dev": true, "optional": true }, "@esbuild/android-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz", - "integrity": "sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.17.12.tgz", + "integrity": "sha512-WQ9p5oiXXYJ33F2EkE3r0FRDFVpEdcDiwNX3u7Xaibxfx6vQE0Sb8ytrfQsA5WO6kDn6mDfKLh6KrPBjvkk7xA==", "dev": true, "optional": true }, "@esbuild/android-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.16.17.tgz", - "integrity": "sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.17.12.tgz", + "integrity": "sha512-m4OsaCr5gT+se25rFPHKQXARMyAehHTQAz4XX1Vk3d27VtqiX0ALMBPoXZsGaB6JYryCLfgGwUslMqTfqeLU0w==", "dev": true, "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz", - "integrity": "sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.12.tgz", + "integrity": "sha512-O3GCZghRIx+RAN0NDPhyyhRgwa19MoKlzGonIb5hgTj78krqp9XZbYCvFr9N1eUxg0ZQEpiiZ4QvsOQwBpP+lg==", "dev": true, "optional": true }, "@esbuild/darwin-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz", - "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.17.12.tgz", + "integrity": "sha512-5D48jM3tW27h1qjaD9UNRuN+4v0zvksqZSPZqeSWggfMlsVdAhH3pwSfQIFJwcs9QJ9BRibPS4ViZgs3d2wsCA==", "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz", - "integrity": "sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.12.tgz", + "integrity": "sha512-OWvHzmLNTdF1erSvrfoEBGlN94IE6vCEaGEkEH29uo/VoONqPnoDFfShi41Ew+yKimx4vrmmAJEGNoyyP+OgOQ==", "dev": true, "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz", - "integrity": "sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.12.tgz", + "integrity": "sha512-A0Xg5CZv8MU9xh4a+7NUpi5VHBKh1RaGJKqjxe4KG87X+mTjDE6ZvlJqpWoeJxgfXHT7IMP9tDFu7IZ03OtJAw==", "dev": true, "optional": true }, "@esbuild/linux-arm": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz", - "integrity": "sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.17.12.tgz", + "integrity": "sha512-WsHyJ7b7vzHdJ1fv67Yf++2dz3D726oO3QCu8iNYik4fb5YuuReOI9OtA+n7Mk0xyQivNTPbl181s+5oZ38gyA==", "dev": true, "optional": true }, "@esbuild/linux-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz", - "integrity": "sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.17.12.tgz", + "integrity": "sha512-cK3AjkEc+8v8YG02hYLQIQlOznW+v9N+OI9BAFuyqkfQFR+DnDLhEM5N8QRxAUz99cJTo1rLNXqRrvY15gbQUg==", "dev": true, "optional": true }, "@esbuild/linux-ia32": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz", - "integrity": "sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.17.12.tgz", + "integrity": "sha512-jdOBXJqcgHlah/nYHnj3Hrnl9l63RjtQ4vn9+bohjQPI2QafASB5MtHAoEv0JQHVb/xYQTFOeuHnNYE1zF7tYw==", "dev": true, "optional": true }, "@esbuild/linux-loong64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz", - "integrity": "sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.17.12.tgz", + "integrity": "sha512-GTOEtj8h9qPKXCyiBBnHconSCV9LwFyx/gv3Phw0pa25qPYjVuuGZ4Dk14bGCfGX3qKF0+ceeQvwmtI+aYBbVA==", "dev": true, "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz", - "integrity": "sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.12.tgz", + "integrity": "sha512-o8CIhfBwKcxmEENOH9RwmUejs5jFiNoDw7YgS0EJTF6kgPgcqLFjgoc5kDey5cMHRVCIWc6kK2ShUePOcc7RbA==", "dev": true, "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz", - "integrity": "sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.12.tgz", + "integrity": "sha512-biMLH6NR/GR4z+ap0oJYb877LdBpGac8KfZoEnDiBKd7MD/xt8eaw1SFfYRUeMVx519kVkAOL2GExdFmYnZx3A==", "dev": true, "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz", - "integrity": "sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.12.tgz", + "integrity": "sha512-jkphYUiO38wZGeWlfIBMB72auOllNA2sLfiZPGDtOBb1ELN8lmqBrlMiucgL8awBw1zBXN69PmZM6g4yTX84TA==", "dev": true, "optional": true }, "@esbuild/linux-s390x": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz", - "integrity": "sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.17.12.tgz", + "integrity": "sha512-j3ucLdeY9HBcvODhCY4b+Ds3hWGO8t+SAidtmWu/ukfLLG/oYDMaA+dnugTVAg5fnUOGNbIYL9TOjhWgQB8W5g==", "dev": true, "optional": true }, "@esbuild/linux-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz", - "integrity": "sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.17.12.tgz", + "integrity": "sha512-uo5JL3cgaEGotaqSaJdRfFNSCUJOIliKLnDGWaVCgIKkHxwhYMm95pfMbWZ9l7GeW9kDg0tSxcy9NYdEtjwwmA==", "dev": true, "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz", - "integrity": "sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.12.tgz", + "integrity": "sha512-DNdoRg8JX+gGsbqt2gPgkgb00mqOgOO27KnrWZtdABl6yWTST30aibGJ6geBq3WM2TIeW6COs5AScnC7GwtGPg==", "dev": true, "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz", - "integrity": "sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.12.tgz", + "integrity": "sha512-aVsENlr7B64w8I1lhHShND5o8cW6sB9n9MUtLumFlPhG3elhNWtE7M1TFpj3m7lT3sKQUMkGFjTQBrvDDO1YWA==", "dev": true, "optional": true }, "@esbuild/sunos-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz", - "integrity": "sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.17.12.tgz", + "integrity": "sha512-qbHGVQdKSwi0JQJuZznS4SyY27tYXYF0mrgthbxXrZI3AHKuRvU+Eqbg/F0rmLDpW/jkIZBlCO1XfHUBMNJ1pg==", "dev": true, "optional": true }, "@esbuild/win32-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz", - "integrity": "sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.17.12.tgz", + "integrity": "sha512-zsCp8Ql+96xXTVTmm6ffvoTSZSV2B/LzzkUXAY33F/76EajNw1m+jZ9zPfNJlJ3Rh4EzOszNDHsmG/fZOhtqDg==", "dev": true, "optional": true }, "@esbuild/win32-ia32": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz", - "integrity": "sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.17.12.tgz", + "integrity": "sha512-FfrFjR4id7wcFYOdqbDfDET3tjxCozUgbqdkOABsSFzoZGFC92UK7mg4JKRc/B3NNEf1s2WHxJ7VfTdVDPN3ng==", "dev": true, "optional": true }, "@esbuild/win32-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz", - "integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==", + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.17.12.tgz", + "integrity": "sha512-JOOxw49BVZx2/5tW3FqkdjSD/5gXYeVGPDcB0lvap0gLQshkh1Nyel1QazC+wNxus3xPlsYAgqU1BUmrmCvWtw==", "dev": true, "optional": true }, + "@eslint-community/eslint-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz", + "integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.4.0", + "resolved": "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", + "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", + "dev": true + }, "@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", + "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.5.1", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -12462,6 +12544,12 @@ } } }, + "@eslint/js": { + "version": "8.37.0", + "resolved": "https://registry.npmmirror.com/@eslint/js/-/js-8.37.0.tgz", + "integrity": "sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==", + "dev": true + }, "@floating-ui/core": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-0.6.2.tgz", @@ -12560,64 +12648,6 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, - "@motionone/animation": { - "version": "10.15.1", - "resolved": "https://registry.npmmirror.com/@motionone/animation/-/animation-10.15.1.tgz", - "integrity": "sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==", - "requires": { - "@motionone/easing": "^10.15.1", - "@motionone/types": "^10.15.1", - "@motionone/utils": "^10.15.1", - "tslib": "^2.3.1" - } - }, - "@motionone/dom": { - "version": "10.15.5", - "resolved": "https://registry.npmmirror.com/@motionone/dom/-/dom-10.15.5.tgz", - "integrity": "sha512-Xc5avlgyh3xukU9tydh9+8mB8+2zAq+WlLsC3eEIp7Ax7DnXgY7Bj/iv0a4X2R9z9ZFZiaXK3BO0xMYHKbAAdA==", - "requires": { - "@motionone/animation": "^10.15.1", - "@motionone/generators": "^10.15.1", - "@motionone/types": "^10.15.1", - "@motionone/utils": "^10.15.1", - "hey-listen": "^1.0.8", - "tslib": "^2.3.1" - } - }, - "@motionone/easing": { - "version": "10.15.1", - "resolved": "https://registry.npmmirror.com/@motionone/easing/-/easing-10.15.1.tgz", - "integrity": "sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw==", - "requires": { - "@motionone/utils": "^10.15.1", - "tslib": "^2.3.1" - } - }, - "@motionone/generators": { - "version": "10.15.1", - "resolved": "https://registry.npmmirror.com/@motionone/generators/-/generators-10.15.1.tgz", - "integrity": "sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ==", - "requires": { - "@motionone/types": "^10.15.1", - "@motionone/utils": "^10.15.1", - "tslib": "^2.3.1" - } - }, - "@motionone/types": { - "version": "10.15.1", - "resolved": "https://registry.npmmirror.com/@motionone/types/-/types-10.15.1.tgz", - "integrity": "sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA==" - }, - "@motionone/utils": { - "version": "10.15.1", - "resolved": "https://registry.npmmirror.com/@motionone/utils/-/utils-10.15.1.tgz", - "integrity": "sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw==", - "requires": { - "@motionone/types": "^10.15.1", - "hey-listen": "^1.0.8", - "tslib": "^2.3.1" - } - }, "@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -12677,9 +12707,9 @@ "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" }, "@remix-run/router": { - "version": "1.3.2", - "resolved": "https://registry.npmmirror.com/@remix-run/router/-/router-1.3.2.tgz", - "integrity": "sha512-t54ONhl/h75X94SWsHGQ4G/ZrCEguKSRQr7DrjTciJXW0YU1QhlwYeycvK5JgkzlxmvrK7wq1NB/PLtHxoiDcA==" + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/@remix-run/router/-/router-1.5.0.tgz", + "integrity": "sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==" }, "@rushstack/eslint-patch": { "version": "1.2.0", @@ -12776,16 +12806,16 @@ "optional": true }, "@tanstack/query-core": { - "version": "4.24.9", - "resolved": "https://registry.npmmirror.com/@tanstack/query-core/-/query-core-4.24.9.tgz", - "integrity": "sha512-pZQ2NpdaHzx8gPPkAPh06d6zRkjfonUzILSYBXrdHDapP2eaBbGsx5L4/dMF+fyAglFzQZdDDzZgAykbM20QVw==" + "version": "4.27.0", + "resolved": "https://registry.npmmirror.com/@tanstack/query-core/-/query-core-4.27.0.tgz", + "integrity": "sha512-sm+QncWaPmM73IPwFlmWSKPqjdTXZeFf/7aEmWh00z7yl2FjqophPt0dE1EHW9P1giMC5rMviv7OUbSDmWzXXA==" }, "@tanstack/react-query": { - "version": "4.24.9", - "resolved": "https://registry.npmmirror.com/@tanstack/react-query/-/react-query-4.24.9.tgz", - "integrity": "sha512-6WLwUT9mrngIinRtcZjrWOUENOuLbWvQpKmU6DZCo2iPQVA+qvv3Ji90Amme4AkUyWQ8ZSSRTnAFq8V2tj2ACg==", + "version": "4.28.0", + "resolved": "https://registry.npmmirror.com/@tanstack/react-query/-/react-query-4.28.0.tgz", + "integrity": "sha512-8cGBV5300RHlvYdS4ea+G1JcZIt5CIuprXYFnsWggkmGoC0b5JaqG0fIX3qwDL9PTNkKvG76NGThIWbpXivMrQ==", "requires": { - "@tanstack/query-core": "4.24.9", + "@tanstack/query-core": "4.27.0", "use-sync-external-store": "^1.2.0" } }, @@ -12810,9 +12840,9 @@ "dev": true }, "@types/lodash": { - "version": "4.14.191", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", - "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==" + "version": "4.14.192", + "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.192.tgz", + "integrity": "sha512-km+Vyn3BYm5ytMO13k9KTp27O75rbQ0NFw+U//g+PX7VZyjCioXaRFisqSIJRECljcTv73G3i6BpglNGHgUQ5A==" }, "@types/lodash.mergewith": { "version": "4.6.7", @@ -12823,9 +12853,9 @@ } }, "@types/node": { - "version": "18.13.0", - "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.13.0.tgz", - "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==", + "version": "18.15.11", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.15.11.tgz", + "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", "dev": true }, "@types/parse-json": { @@ -12840,9 +12870,9 @@ "devOptional": true }, "@types/react": { - "version": "18.0.28", - "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.0.28.tgz", - "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==", + "version": "18.0.31", + "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.0.31.tgz", + "integrity": "sha512-EEG67of7DsvRDU6BLLI0p+k1GojDLz9+lZsnCpCRTa/lOokvyPBvp8S5x+A24hME3yyQuIipcP70KJ6H7Qupww==", "devOptional": true, "requires": { "@types/prop-types": "*", @@ -12851,9 +12881,9 @@ } }, "@types/react-datepicker": { - "version": "4.8.0", - "resolved": "https://mirrors.tencent.com/npm/@types%2freact-datepicker/-/react-datepicker-4.8.0.tgz", - "integrity": "sha512-20uzZsIf4moPAjjHDfPvH8UaOHZBxrkiQZoLS3wgKq8Xhp+95gdercLEdoA7/I8nR9R5Jz2qQkdMIM+Lq4AS1A==", + "version": "4.10.0", + "resolved": "https://registry.npmmirror.com/@types/react-datepicker/-/react-datepicker-4.10.0.tgz", + "integrity": "sha512-Cq+ks20vBIU6XN67TbkCHu8M7V46Y6vJrKE2n+8q/GfueJyWWTIKeC3Z7cz/d+qxGDq/VCrqA929R0U4lNuztg==", "dev": true, "requires": { "@popperjs/core": "^2.9.2", @@ -13108,14 +13138,14 @@ } }, "@zag-js/element-size": { - "version": "0.3.1", - "resolved": "https://registry.npmmirror.com/@zag-js/element-size/-/element-size-0.3.1.tgz", - "integrity": "sha512-jR5j4G//bRzcxwAACWi9EfITnwjNmn10LxF4NmALrdZU7/PNWP3uUCdhCxd/0SCyeiJXUl0yvD57rWAbKPs1nw==" + "version": "0.3.2", + "resolved": "https://registry.npmmirror.com/@zag-js/element-size/-/element-size-0.3.2.tgz", + "integrity": "sha512-bVvvigUGvAuj7PCkE5AbzvTJDTw5f3bg9nQdv+ErhVN8SfPPppLJEmmWdxqsRzrHXgx8ypJt/+Ty0kjtISVDsQ==" }, "@zag-js/focus-visible": { - "version": "0.2.1", - "resolved": "https://registry.npmmirror.com/@zag-js/focus-visible/-/focus-visible-0.2.1.tgz", - "integrity": "sha512-19uTjoZGP4/Ax7kSNhhay9JA83BirKzpqLkeEAilrpdI1hE5xuq6q+tzJOsrMOOqJrm7LkmZp5lbsTQzvK2pYg==" + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/@zag-js/focus-visible/-/focus-visible-0.2.2.tgz", + "integrity": "sha512-0j2gZq8HiZ51z4zNnSkF1iSkqlwRDvdH+son3wHdoz+7IUdMN/5Exd4TxMJ+gq2Of1DiXReYLL9qqh2PdQ4wgA==" }, "acorn": { "version": "8.8.2", @@ -13130,34 +13160,9 @@ "dev": true, "requires": {} }, - "acorn-node": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", - "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", - "dev": true, - "requires": { - "acorn": "^7.0.0", - "acorn-walk": "^7.0.0", - "xtend": "^4.0.2" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - } - } - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true - }, "aggregate-error": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "resolved": "https://registry.npmmirror.com/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "requires": { @@ -13179,7 +13184,7 @@ }, "ansi-escapes": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "resolved": "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "requires": { @@ -13200,6 +13205,12 @@ "color-convert": "^1.9.0" } }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, "anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -13303,7 +13314,7 @@ }, "astral-regex": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "resolved": "https://registry.npmmirror.com/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, @@ -13313,13 +13324,13 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "autoprefixer": { - "version": "10.4.13", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", - "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", + "version": "10.4.14", + "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", "dev": true, "requires": { - "browserslist": "^4.21.4", - "caniuse-lite": "^1.0.30001426", + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -13333,9 +13344,9 @@ "dev": true }, "axios": { - "version": "1.3.3", - "resolved": "https://registry.npmmirror.com/axios/-/axios-1.3.3.tgz", - "integrity": "sha512-eYq77dYIFS77AQlhzEL937yUBSepBfPIe8FcgEDN35vMNZKMrs81pgnyrQpwfy4NF4b4XWX1Zgx7yX+25w8QJA==", + "version": "1.3.4", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.3.4.tgz", + "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==", "requires": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -13453,15 +13464,15 @@ } }, "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.21.5", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" } }, "bson": { @@ -13503,9 +13514,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001441", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz", - "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==", + "version": "1.0.30001469", + "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001469.tgz", + "integrity": "sha512-Rcp7221ScNqQPP3W+lVOYDyjdR6dC+neEQCttoNr5bAyz54AboB4iwpnWgyi8P4YUsPybVzT4LgWiBbI3drL4g==", "dev": true }, "chalk": { @@ -13572,13 +13583,13 @@ }, "clean-stack": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "resolved": "https://registry.npmmirror.com/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, "cli-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "resolved": "https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "requires": { @@ -13631,7 +13642,7 @@ }, "colorette": { "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "resolved": "https://registry.npmmirror.com/colorette/-/colorette-2.0.19.tgz", "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", "dev": true }, @@ -13649,9 +13660,9 @@ "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==" }, "commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "version": "10.0.0", + "resolved": "https://registry.npmmirror.com/commander/-/commander-10.0.0.tgz", + "integrity": "sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==", "dev": true }, "compute-scroll-into-view": { @@ -13671,6 +13682,12 @@ "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", "dev": true }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true + }, "convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", @@ -13801,12 +13818,6 @@ "object-keys": "^1.1.1" } }, - "defined": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", - "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", - "dev": true - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -13817,17 +13828,6 @@ "resolved": "https://registry.npmmirror.com/detect-node-es/-/detect-node-es-1.1.0.tgz", "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, - "detective": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", - "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", - "dev": true, - "requires": { - "acorn-node": "^1.8.2", - "defined": "^1.0.0", - "minimist": "^1.2.6" - } - }, "didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -13858,6 +13858,11 @@ "esutils": "^2.0.2" } }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, "eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -13938,33 +13943,33 @@ } }, "esbuild": { - "version": "0.16.17", - "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.16.17.tgz", - "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==", - "dev": true, - "requires": { - "@esbuild/android-arm": "0.16.17", - "@esbuild/android-arm64": "0.16.17", - "@esbuild/android-x64": "0.16.17", - "@esbuild/darwin-arm64": "0.16.17", - "@esbuild/darwin-x64": "0.16.17", - "@esbuild/freebsd-arm64": "0.16.17", - "@esbuild/freebsd-x64": "0.16.17", - "@esbuild/linux-arm": "0.16.17", - "@esbuild/linux-arm64": "0.16.17", - "@esbuild/linux-ia32": "0.16.17", - "@esbuild/linux-loong64": "0.16.17", - "@esbuild/linux-mips64el": "0.16.17", - "@esbuild/linux-ppc64": "0.16.17", - "@esbuild/linux-riscv64": "0.16.17", - "@esbuild/linux-s390x": "0.16.17", - "@esbuild/linux-x64": "0.16.17", - "@esbuild/netbsd-x64": "0.16.17", - "@esbuild/openbsd-x64": "0.16.17", - "@esbuild/sunos-x64": "0.16.17", - "@esbuild/win32-arm64": "0.16.17", - "@esbuild/win32-ia32": "0.16.17", - "@esbuild/win32-x64": "0.16.17" + "version": "0.17.12", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.17.12.tgz", + "integrity": "sha512-bX/zHl7Gn2CpQwcMtRogTTBf9l1nl+H6R8nUbjk+RuKqAE3+8FDulLA+pHvX7aA7Xe07Iwa+CWvy9I8Y2qqPKQ==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.17.12", + "@esbuild/android-arm64": "0.17.12", + "@esbuild/android-x64": "0.17.12", + "@esbuild/darwin-arm64": "0.17.12", + "@esbuild/darwin-x64": "0.17.12", + "@esbuild/freebsd-arm64": "0.17.12", + "@esbuild/freebsd-x64": "0.17.12", + "@esbuild/linux-arm": "0.17.12", + "@esbuild/linux-arm64": "0.17.12", + "@esbuild/linux-ia32": "0.17.12", + "@esbuild/linux-loong64": "0.17.12", + "@esbuild/linux-mips64el": "0.17.12", + "@esbuild/linux-ppc64": "0.17.12", + "@esbuild/linux-riscv64": "0.17.12", + "@esbuild/linux-s390x": "0.17.12", + "@esbuild/linux-x64": "0.17.12", + "@esbuild/netbsd-x64": "0.17.12", + "@esbuild/openbsd-x64": "0.17.12", + "@esbuild/sunos-x64": "0.17.12", + "@esbuild/win32-arm64": "0.17.12", + "@esbuild/win32-ia32": "0.17.12", + "@esbuild/win32-x64": "0.17.12" } }, "escalade": { @@ -13979,12 +13984,15 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "eslint": { - "version": "8.34.0", - "resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.34.0.tgz", - "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==", + "version": "8.37.0", + "resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.37.0.tgz", + "integrity": "sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.4.1", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.2", + "@eslint/js": "8.37.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -13995,10 +14003,9 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-visitor-keys": "^3.4.0", + "espree": "^9.5.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", @@ -14019,7 +14026,6 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -14337,26 +14343,26 @@ } }, "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.0", + "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", + "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", "dev": true }, "espree": { - "version": "9.4.1", - "resolved": "https://registry.npmmirror.com/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.5.1", + "resolved": "https://registry.npmmirror.com/espree/-/espree-9.5.1.tgz", + "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", "dev": true, "requires": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.0" } }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -14384,14 +14390,14 @@ "dev": true }, "execa": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz", - "integrity": "sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==", + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/execa/-/execa-7.1.1.tgz", + "integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==", "dev": true, "requires": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.1", - "human-signals": "^3.0.1", + "human-signals": "^4.3.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", @@ -14542,13 +14548,11 @@ "dev": true }, "framer-motion": { - "version": "9.0.4", - "resolved": "https://registry.npmmirror.com/framer-motion/-/framer-motion-9.0.4.tgz", - "integrity": "sha512-lZ1+2/WBn8iYRYmeEFpu/X2fI1GNwJL+X21EpnWwKP3vkJsnWBXZF5kHF29wIPk9sBU2xDIpDm9SAVo206bp9A==", + "version": "10.10.0", + "resolved": "https://registry.npmmirror.com/framer-motion/-/framer-motion-10.10.0.tgz", + "integrity": "sha512-eCsyOcJimIRbx9KOzBTO3j9u1rF/H8/o/ybizYqdrzHkEeHx9L2NcEfGWfV0OHTc1JV17ECVzuZpomupEJ4+dw==", "requires": { "@emotion/is-prop-valid": "^0.8.2", - "@motionone/dom": "^10.15.3", - "hey-listen": "^1.0.8", "tslib": "^2.4.0" }, "dependencies": { @@ -14643,7 +14647,7 @@ }, "get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, @@ -14775,11 +14779,6 @@ "space-separated-tokens": "^1.0.0" } }, - "hey-listen": { - "version": "1.0.8", - "resolved": "https://registry.npmmirror.com/hey-listen/-/hey-listen-1.0.8.tgz", - "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==" - }, "highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -14808,9 +14807,9 @@ } }, "human-signals": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-3.0.1.tgz", - "integrity": "sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==", + "version": "4.3.1", + "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", "dev": true }, "husky": { @@ -14820,9 +14819,9 @@ "dev": true }, "i18next": { - "version": "22.4.10", - "resolved": "https://registry.npmmirror.com/i18next/-/i18next-22.4.10.tgz", - "integrity": "sha512-3EqgGK6fAJRjnGgfkNSStl4mYLCjUoJID338yVyLMj5APT67HUtWoqSayZewiiC5elzMUB1VEUwcmSCoeQcNEA==", + "version": "22.4.13", + "resolved": "https://registry.npmmirror.com/i18next/-/i18next-22.4.13.tgz", + "integrity": "sha512-GX7flMHRRqQA0I1yGLmaZ4Hwt1JfLqagk8QPDPZsqekbKtXsuIngSVWM/s3SLgNkrEXjA+0sMGNuOEkkmyqmWg==", "requires": { "@babel/runtime": "^7.20.6" } @@ -14836,9 +14835,9 @@ } }, "i18next-http-backend": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.1.1.tgz", - "integrity": "sha512-jByfUCDVgQ8+/Wens7queQhYYvMcGTW/lR4IJJNEDDXnmqjLrwi8ubXKpmp76/JIWEZHffNdWqnxFJcTVGeaOw==", + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/i18next-http-backend/-/i18next-http-backend-2.2.0.tgz", + "integrity": "sha512-Z4sM7R6tzdLknSPER9GisEBxKPg5FkI07UrQniuroZmS15PHQrcCPLyuGKj8SS68tf+O2aEDYSUnmy1TZqZSbw==", "requires": { "cross-fetch": "3.1.5" } @@ -14855,9 +14854,9 @@ "dev": true }, "immer": { - "version": "9.0.19", - "resolved": "https://registry.npmmirror.com/immer/-/immer-9.0.19.tgz", - "integrity": "sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ==" + "version": "9.0.21", + "resolved": "https://registry.npmmirror.com/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==" }, "immutable": { "version": "4.2.1", @@ -14881,7 +14880,7 @@ }, "indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "resolved": "https://registry.npmmirror.com/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, @@ -14901,6 +14900,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "install": { + "version": "0.13.0", + "resolved": "https://registry.npmmirror.com/install/-/install-0.13.0.tgz", + "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", + "dev": true + }, "internal-slot": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", @@ -15065,7 +15070,7 @@ }, "is-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-3.0.0.tgz", "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true }, @@ -15102,6 +15107,12 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "jiti": { + "version": "1.18.2", + "resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.18.2.tgz", + "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==", + "dev": true + }, "js-sdsl": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", @@ -15162,9 +15173,9 @@ } }, "laf-client-sdk": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/laf-client-sdk/-/laf-client-sdk-1.0.0-beta.2.tgz", - "integrity": "sha512-0Jbctghkw0D4/k+locZEBpkvHoFRHQ2ZQ60mBUKoz9fLxheK4ddTI71RFckB1aBKhFgSqfH6Hsdhxnl/MGEJWw==", + "version": "1.0.0-beta.7", + "resolved": "https://registry.npmjs.org/laf-client-sdk/-/laf-client-sdk-1.0.0-beta.7.tgz", + "integrity": "sha512-qe5KRt5PT6tFllklXDP+/r8Gglu9udyrHG8VInITxgWpGfQEScnprU3wGl+EBtDaTKnA+nRbsXXIS2aMuuWzpg==", "requires": { "axios": "^0.21.1", "database-ql": "^1.0.0-beta.2" @@ -15206,9 +15217,9 @@ } }, "lilconfig": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", - "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", "dev": true }, "lines-and-columns": { @@ -15217,38 +15228,44 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "lint-staged": { - "version": "13.1.2", - "resolved": "https://registry.npmmirror.com/lint-staged/-/lint-staged-13.1.2.tgz", - "integrity": "sha512-K9b4FPbWkpnupvK3WXZLbgu9pchUJ6N7TtVZjbaPsoizkqFUDkUReUL25xdrCljJs7uLUF3tZ7nVPeo/6lp+6w==", + "version": "13.2.0", + "resolved": "https://registry.npmmirror.com/lint-staged/-/lint-staged-13.2.0.tgz", + "integrity": "sha512-GbyK5iWinax5Dfw5obm2g2ccUiZXNGtAS4mCbJ0Lv4rq6iEtfBSjOYdcbOtAIFtM114t0vdpViDDetjVTSd8Vw==", "dev": true, "requires": { + "chalk": "5.2.0", "cli-truncate": "^3.1.0", - "colorette": "^2.0.19", - "commander": "^9.4.1", + "commander": "^10.0.0", "debug": "^4.3.4", - "execa": "^6.1.0", - "lilconfig": "2.0.6", - "listr2": "^5.0.5", + "execa": "^7.0.0", + "lilconfig": "2.1.0", + "listr2": "^5.0.7", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", - "object-inspect": "^1.12.2", + "object-inspect": "^1.12.3", "pidtree": "^0.6.0", "string-argv": "^0.3.1", - "yaml": "^2.1.3" + "yaml": "^2.2.1" }, "dependencies": { + "chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "dev": true + }, "yaml": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.0.tgz", - "integrity": "sha512-auf7Gi6QwO7HW//GA9seGvTXVGWl1CM/ADWh1+RxtXr6XOxnT65ovDl9fTi4e0monEyJxCHqDpF6QnFDXmJE4g==", + "version": "2.2.1", + "resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.2.1.tgz", + "integrity": "sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==", "dev": true } } }, "listr2": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-5.0.6.tgz", - "integrity": "sha512-u60KxKBy1BR2uLJNTWNptzWQ1ob/gjMzIJPZffAENzpZqbMZ/5PrXXOomDcevIS/+IB7s1mmCEtSlT2qHWMqag==", + "version": "5.0.8", + "resolved": "https://registry.npmmirror.com/listr2/-/listr2-5.0.8.tgz", + "integrity": "sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==", "dev": true, "requires": { "cli-truncate": "^2.1.0", @@ -15256,14 +15273,14 @@ "log-update": "^4.0.0", "p-map": "^4.0.0", "rfdc": "^1.3.0", - "rxjs": "^7.5.7", + "rxjs": "^7.8.0", "through": "^2.3.8", "wrap-ansi": "^7.0.0" }, "dependencies": { "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { @@ -15272,7 +15289,7 @@ }, "cli-truncate": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "resolved": "https://registry.npmmirror.com/cli-truncate/-/cli-truncate-2.1.0.tgz", "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, "requires": { @@ -15282,7 +15299,7 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { @@ -15291,25 +15308,25 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "slice-ansi": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "resolved": "https://registry.npmmirror.com/slice-ansi/-/slice-ansi-3.0.0.tgz", "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, "requires": { @@ -15320,7 +15337,7 @@ }, "string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { @@ -15379,7 +15396,7 @@ }, "log-update": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "resolved": "https://registry.npmmirror.com/log-update/-/log-update-4.0.0.tgz", "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", "dev": true, "requires": { @@ -15391,7 +15408,7 @@ "dependencies": { "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { @@ -15400,7 +15417,7 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { @@ -15409,25 +15426,25 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "slice-ansi": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "resolved": "https://registry.npmmirror.com/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { @@ -15438,7 +15455,7 @@ }, "string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { @@ -15449,7 +15466,7 @@ }, "wrap-ansi": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "requires": { @@ -15493,7 +15510,7 @@ }, "merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, @@ -15528,7 +15545,7 @@ }, "mimic-fn": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-4.0.0.tgz", "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true }, @@ -15548,9 +15565,9 @@ "dev": true }, "monaco-editor": { - "version": "0.35.0", - "resolved": "https://registry.npmmirror.com/monaco-editor/-/monaco-editor-0.35.0.tgz", - "integrity": "sha512-BJfkAZ0EJ7JgrgWzqjfBNP9hPSS8NlfECEDMEIIiozV2UaPq22yeuOjgbd3TwMh3anH0krWZirXZfn8KUSxiOA==" + "version": "0.36.1", + "resolved": "https://registry.npmmirror.com/monaco-editor/-/monaco-editor-0.36.1.tgz", + "integrity": "sha512-/CaclMHKQ3A6rnzBzOADfwdSJ25BFoFT0Emxsc4zYVyav5SkK9iA6lEtIeuN/oRYbwPgviJT+t3l+sjFa28jYg==" }, "ms": { "version": "2.1.2", @@ -15558,6 +15575,17 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "nanoid": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", @@ -15603,7 +15631,7 @@ }, "npm-run-path": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-5.1.0.tgz", "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", "dev": true, "requires": { @@ -15612,7 +15640,7 @@ "dependencies": { "path-key": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "resolved": "https://registry.npmmirror.com/path-key/-/path-key-4.0.0.tgz", "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true } @@ -15630,9 +15658,9 @@ "dev": true }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.12.3", + "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true }, "object-keys": { @@ -15707,7 +15735,7 @@ }, "onetime": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "resolved": "https://registry.npmmirror.com/onetime/-/onetime-6.0.0.tgz", "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "requires": { @@ -15748,7 +15776,7 @@ }, "p-map": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "resolved": "https://registry.npmmirror.com/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, "requires": { @@ -15838,6 +15866,12 @@ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true }, + "pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmmirror.com/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true + }, "point-in-polygon": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/point-in-polygon/-/point-in-polygon-1.1.0.tgz", @@ -15917,11 +15951,18 @@ "dev": true }, "prettier": { - "version": "2.8.4", - "resolved": "https://registry.npmmirror.com/prettier/-/prettier-2.8.4.tgz", - "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", + "version": "2.8.7", + "resolved": "https://registry.npmmirror.com/prettier/-/prettier-2.8.7.tgz", + "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", "dev": true }, + "prettier-plugin-tailwindcss": { + "version": "0.2.6", + "resolved": "https://registry.npmmirror.com/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.2.6.tgz", + "integrity": "sha512-F+7XCl9RLF/LPrGdUMHWpsT6TM31JraonAUyE6eBmpqymFvDwyl0ETHsKFHP1NG+sEfv8bmKqnTxEbWQbHPlBA==", + "dev": true, + "requires": {} + }, "prismjs": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", @@ -15991,9 +16032,9 @@ } }, "react-datepicker": { - "version": "4.10.0", - "resolved": "https://registry.npmmirror.com/react-datepicker/-/react-datepicker-4.10.0.tgz", - "integrity": "sha512-6IfBCZyWj54ZZGLmEZJ9c4Yph0s9MVfEGDC2evOvf9AmVz+RRcfP2Czqad88Ff9wREbcbqa4dk7IFYeXF1d3Ag==", + "version": "4.11.0", + "resolved": "https://registry.npmmirror.com/react-datepicker/-/react-datepicker-4.11.0.tgz", + "integrity": "sha512-50n93o7mQwBEhg05tbopjFKgs8qgi8VBCAOMC4VqrKut72eAjESc/wXS/k5hRtnP0oe2FCGw7MJuIwh37wuXOw==", "requires": { "@popperjs/core": "^2.9.2", "classnames": "^2.2.6", @@ -16013,9 +16054,9 @@ } }, "react-fast-compare": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", - "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + "version": "3.2.1", + "resolved": "https://registry.npmmirror.com/react-fast-compare/-/react-fast-compare-3.2.1.tgz", + "integrity": "sha512-xTYf9zFim2pEif/Fw16dBiXpe0hoy5PxcD8+OwBnTtNLfIm3g6WxhKNurY+6OmdH1u6Ta/W/Vl6vjbYP1MFnDg==" }, "react-focus-lock": { "version": "2.9.4", @@ -16031,24 +16072,24 @@ } }, "react-hook-form": { - "version": "7.43.1", - "resolved": "https://registry.npmmirror.com/react-hook-form/-/react-hook-form-7.43.1.tgz", - "integrity": "sha512-+s3+s8LLytRMriwwuSqeLStVjRXFGxgjjx2jED7Z+wz1J/88vpxieRQGvJVvzrzVxshZ0BRuocFERb779m2kNg==", + "version": "7.43.9", + "resolved": "https://registry.npmmirror.com/react-hook-form/-/react-hook-form-7.43.9.tgz", + "integrity": "sha512-AUDN3Pz2NSeoxQ7Hs6OhQhDr6gtF9YRuutGDwPQqhSUAHJSgGl2VeY3qN19MG0SucpjgDiuMJ4iC5T5uB+eaNQ==", "requires": {} }, "react-i18next": { - "version": "12.1.5", - "resolved": "https://registry.npmmirror.com/react-i18next/-/react-i18next-12.1.5.tgz", - "integrity": "sha512-7PQAv6DA0TcStG96fle+8RfTwxVbHVlZZJPoEszwUNvDuWpGldJmNWa3ZPesEsZQZGF6GkzwvEh6p57qpFD2gQ==", + "version": "12.2.0", + "resolved": "https://registry.npmmirror.com/react-i18next/-/react-i18next-12.2.0.tgz", + "integrity": "sha512-5XeVgSygaGfyFmDd2WcXvINRw2WEC1XviW1LXY/xLOEMzsCFRwKqfnHN+hUjla8ZipbVJR27GCMSuTr0BhBBBQ==", "requires": { "@babel/runtime": "^7.20.6", "html-parse-stringify": "^3.0.1" } }, "react-icons": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.7.1.tgz", - "integrity": "sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==", + "version": "4.8.0", + "resolved": "https://registry.npmmirror.com/react-icons/-/react-icons-4.8.0.tgz", + "integrity": "sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==", "requires": {} }, "react-is": { @@ -16099,20 +16140,20 @@ } }, "react-router": { - "version": "6.8.1", - "resolved": "https://registry.npmmirror.com/react-router/-/react-router-6.8.1.tgz", - "integrity": "sha512-Jgi8BzAJQ8MkPt8ipXnR73rnD7EmZ0HFFb7jdQU24TynGW1Ooqin2KVDN9voSC+7xhqbbCd2cjGUepb6RObnyg==", + "version": "6.10.0", + "resolved": "https://registry.npmmirror.com/react-router/-/react-router-6.10.0.tgz", + "integrity": "sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==", "requires": { - "@remix-run/router": "1.3.2" + "@remix-run/router": "1.5.0" } }, "react-router-dom": { - "version": "6.8.1", - "resolved": "https://registry.npmmirror.com/react-router-dom/-/react-router-dom-6.8.1.tgz", - "integrity": "sha512-67EXNfkQgf34P7+PSb6VlBuaacGhkKn3kpE51+P6zYSG2kiRoumXEL6e27zTa9+PGF2MNXbgIUHTVlleLbIcHQ==", + "version": "6.10.0", + "resolved": "https://registry.npmmirror.com/react-router-dom/-/react-router-dom-6.10.0.tgz", + "integrity": "sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==", "requires": { - "@remix-run/router": "1.3.2", - "react-router": "6.8.1" + "@remix-run/router": "1.5.0", + "react-router": "6.10.0" } }, "react-style-singleton": { @@ -16271,7 +16312,7 @@ }, "restore-cursor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "resolved": "https://registry.npmmirror.com/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "requires": { @@ -16281,13 +16322,13 @@ "dependencies": { "mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, "onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "resolved": "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { @@ -16304,7 +16345,7 @@ }, "rfdc": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz", "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", "dev": true }, @@ -16318,9 +16359,9 @@ } }, "rollup": { - "version": "3.17.1", - "resolved": "https://registry.npmmirror.com/rollup/-/rollup-3.17.1.tgz", - "integrity": "sha512-8RnSms6rNqHmZK+wiqgnPCqen+rRnUHXkciGDirh7B00g1rX1vpKbPDhuxCvAG2bburoI+W4Q9/PlUB/zYkiYA==", + "version": "3.20.0", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-3.20.0.tgz", + "integrity": "sha512-YsIfrk80NqUDrxrjWPXUa7PWvAfegZEXHuPsEZg58fGCdjL1I9C1i/NaG+L+27kxxwkrG/QEDEQc8s/ynXWWGQ==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -16337,7 +16378,7 @@ }, "rxjs": { "version": "7.8.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", + "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.0.tgz", "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", "dev": true, "requires": { @@ -16356,9 +16397,9 @@ } }, "sass": { - "version": "1.58.3", - "resolved": "https://registry.npmmirror.com/sass/-/sass-1.58.3.tgz", - "integrity": "sha512-Q7RaEtYf6BflYrQ+buPudKR26/lH+10EmO9bBqbmPh/KeLqv8bjpTNqxe71ocONqXq+jYiCbpPUmQMS+JJPk4A==", + "version": "1.60.0", + "resolved": "https://registry.npmmirror.com/sass/-/sass-1.60.0.tgz", + "integrity": "sha512-updbwW6fNb5gGm8qMXzVO7V4sWf7LMXnMly/JEyfbfERbVH46Fn6q02BX7/eHTdKpE7d+oTkMMQpFWNUMfFbgQ==", "requires": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -16407,7 +16448,7 @@ }, "signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, @@ -16545,7 +16586,7 @@ }, "strip-final-newline": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "resolved": "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz", "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true }, @@ -16560,6 +16601,42 @@ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" }, + "sucrase": { + "version": "3.31.0", + "resolved": "https://registry.npmmirror.com/sucrase/-/sucrase-3.31.0.tgz", + "integrity": "sha512-6QsHnkqyVEzYcaiHsOKkzOtOgdJcb8i54x6AV2hDwyZcY9ZyykGZVw6L/YN98xC0evwTP6utsWWrKRaa8QlfEQ==", + "dev": true, + "requires": { + "commander": "^4.0.0", + "glob": "7.1.6", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "dependencies": { + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmmirror.com/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -16574,20 +16651,20 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, "tailwindcss": { - "version": "3.2.7", - "resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.2.7.tgz", - "integrity": "sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==", + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.3.1.tgz", + "integrity": "sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==", "dev": true, "requires": { "arg": "^5.0.2", "chokidar": "^3.5.3", "color-name": "^1.1.4", - "detective": "^5.2.1", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.2.12", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", + "jiti": "^1.17.2", "lilconfig": "^2.0.6", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", @@ -16601,7 +16678,8 @@ "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0", "quick-lru": "^5.1.1", - "resolve": "^1.22.1" + "resolve": "^1.22.1", + "sucrase": "^3.29.0" }, "dependencies": { "color-name": { @@ -16618,9 +16696,27 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "requires": { + "any-promise": "^1.0.0" + } + }, + "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==", + "dev": true, + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, "through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "https://registry.npmmirror.com/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, @@ -16652,6 +16748,12 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "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==", + "dev": true + }, "tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -16708,14 +16810,14 @@ }, "type-fest": { "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true }, "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.3", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.0.3.tgz", + "integrity": "sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==", "dev": true }, "unbox-primitive": { @@ -16814,16 +16916,25 @@ "dev": true }, "vite": { - "version": "4.1.2", - "resolved": "https://registry.npmmirror.com/vite/-/vite-4.1.2.tgz", - "integrity": "sha512-MWDb9Rfy3DI8omDQySbMK93nQqStwbsQWejXRY2EBzEWKmLAXWb1mkI9Yw2IJrc+oCvPCI1Os5xSSIBYY6DEAw==", + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/vite/-/vite-4.2.1.tgz", + "integrity": "sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==", "dev": true, "requires": { - "esbuild": "^0.16.14", + "esbuild": "^0.17.5", "fsevents": "~2.3.2", "postcss": "^8.4.21", "resolve": "^1.22.1", - "rollup": "^3.10.0" + "rollup": "^3.18.0" + } + }, + "vite-plugin-rewrite-all": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/vite-plugin-rewrite-all/-/vite-plugin-rewrite-all-1.0.1.tgz", + "integrity": "sha512-W0DAchC8ynuQH0lYLIu5/5+JGfYlUTRD8GGNtHFXRJX4FzzB9MajtqHBp26zq/ly9sDt5BqrfdT08rv3RbB0LQ==", + "dev": true, + "requires": { + "connect-history-api-fallback": "^1.6.0" } }, "void-elements": { @@ -16883,7 +16994,7 @@ }, "wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { @@ -16894,7 +17005,7 @@ "dependencies": { "ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { @@ -16903,7 +17014,7 @@ }, "color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { @@ -16912,25 +17023,25 @@ }, "color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { @@ -16970,9 +17081,9 @@ "dev": true }, "zustand": { - "version": "4.3.3", - "resolved": "https://registry.npmmirror.com/zustand/-/zustand-4.3.3.tgz", - "integrity": "sha512-x2jXq8S0kfLGNwGh87nhRfEc2eZy37tSatpSoSIN+O6HIaBhgQHSONV/F9VNrNcBcKQu/E80K1DeHDYQC/zCrQ==", + "version": "4.3.6", + "resolved": "https://registry.npmmirror.com/zustand/-/zustand-4.3.6.tgz", + "integrity": "sha512-6J5zDxjxLE+yukC2XZWf/IyWVKnXT9b9HUv09VJ/bwGCpKNcaTqp7Ws28Xr8jnbvnZcdRaidztAPsXFBIqufiw==", "requires": { "use-sync-external-store": "1.2.0" } diff --git a/web/package.json b/web/package.json index b33c0f69dc..558ecc93af 100644 --- a/web/package.json +++ b/web/package.json @@ -1,7 +1,7 @@ { "name": "web", "private": true, - "version": "1.0.0-beta.4", + "version": "1.0.0-beta.7", "scripts": { "dev": "vite", "build": "tsc && vite build", @@ -13,55 +13,60 @@ "lint-staged": "lint-staged" }, "dependencies": { - "@chakra-ui/icons": "^2.0.17", - "@chakra-ui/react": "^2.5.1", + "@chakra-ui/anatomy": "^2.1.1", + "@chakra-ui/icons": "^2.0.18", + "@chakra-ui/react": "^2.5.5", "@emotion/react": "^11.10.6", "@emotion/styled": "^11.10.6", - "@tanstack/react-query": "^4.24.6", - "axios": "^1.3.3", + "@tanstack/react-query": "^4.28.0", + "axios": "^1.3.4", "clsx": "^1.2.1", "dayjs": "^1.11.7", - "framer-motion": "^9.0.4", - "i18next": "^22.4.9", + "dotenv": "^16.0.3", + "framer-motion": "^10.10.0", + "i18next": "^22.4.13", "i18next-browser-languagedetector": "7.0.1", - "i18next-http-backend": "2.1.1", - "immer": "^9.0.16", - "laf-client-sdk": "^1.0.0-beta.2", + "i18next-http-backend": "2.2.0", + "immer": "^9.0.21", + "laf-client-sdk": "^1.0.0-beta.7", "lodash": "^4.17.21", "make-plural": "^7.2.0", - "monaco-editor": "^0.35.0", + "monaco-editor": "^0.36.1", "qrcode.react": "^3.1.0", "react": "18.2.0", - "react-datepicker": "^4.10.0", + "react-datepicker": "^4.11.0", "react-dom": "18.2.0", - "react-hook-form": "^7.43.1", - "react-i18next": "^12.1.5", - "react-icons": "^4.7.1", - "react-router-dom": "^6.8.1", + "react-hook-form": "^7.43.9", + "react-i18next": "^12.2.0", + "react-icons": "^4.8.0", + "react-router-dom": "^6.10.0", "react-syntax-highlighter": "^15.5.0", - "sass": "^1.58.2", - "zustand": "^4.3.3" + "sass": "^1.60.0", + "zustand": "^4.3.6" }, "devDependencies": { - "@types/lodash": "^4.14.191", - "@types/node": "18.13.0", - "@types/react": "^18.0.28", - "@types/react-datepicker": "^4.8.0", + "@types/lodash": "^4.14.192", + "@types/node": "18.15.11", + "@types/react": "^18.0.31", + "@types/react-datepicker": "^4.10.0", "@types/react-dom": "^18.0.11", "@types/react-syntax-highlighter": "^15.5.6", - "@vitejs/plugin-react-swc": "^3.1.0", - "autoprefixer": "^10.4.13", + "@vitejs/plugin-react-swc": "^3.2.0", + "autoprefixer": "^10.4.14", "click-to-react-component": "^1.0.8", - "eslint": "^8.34.0", + "eslint": "^8.37.0", "eslint-config-react-app": "^7.0.1", "eslint-plugin-simple-import-sort": "^10.0.0", "husky": "^8.0.3", - "lint-staged": "^13.1.2", + "install": "^0.13.0", + "lint-staged": "^13.2.0", "postcss": "^8.4.21", - "prettier": "^2.8.4", - "tailwindcss": "^3.2.7", - "typescript": "4.9.5", - "vite": "^4.1.1" + "prettier": "^2.8.7", + "prettier-plugin-tailwindcss": "^0.2.6", + "tailwindcss": "^3.3.1", + "typescript": "5.0.3", + "vite": "^4.2.1", + "vite-plugin-rewrite-all": "^1.0.1" }, "lint-staged": { "*.{ts,tsx}": [ diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml new file mode 100644 index 0000000000..62696b6660 --- /dev/null +++ b/web/pnpm-lock.yaml @@ -0,0 +1,6801 @@ +lockfileVersion: 5.4 + +specifiers: + '@chakra-ui/anatomy': ^2.1.1 + '@chakra-ui/icons': ^2.0.18 + '@chakra-ui/react': ^2.5.5 + '@emotion/react': ^11.10.6 + '@emotion/styled': ^11.10.6 + '@tanstack/react-query': ^4.28.0 + '@types/lodash': ^4.14.192 + '@types/node': 18.15.11 + '@types/react': ^18.0.31 + '@types/react-datepicker': ^4.10.0 + '@types/react-dom': ^18.0.11 + '@types/react-syntax-highlighter': ^15.5.6 + '@vitejs/plugin-react-swc': ^3.2.0 + autoprefixer: ^10.4.14 + axios: ^1.3.4 + click-to-react-component: ^1.0.8 + clsx: ^1.2.1 + dayjs: ^1.11.7 + eslint: ^8.37.0 + eslint-config-react-app: ^7.0.1 + eslint-plugin-simple-import-sort: ^10.0.0 + framer-motion: ^10.10.0 + husky: ^8.0.3 + i18next: ^22.4.13 + i18next-browser-languagedetector: 7.0.1 + i18next-http-backend: 2.2.0 + immer: ^9.0.21 + install: ^0.13.0 + laf-client-sdk: ^1.0.0-beta.2 + lint-staged: ^13.2.0 + lodash: ^4.17.21 + make-plural: ^7.2.0 + monaco-editor: ^0.36.1 + postcss: ^8.4.21 + prettier: ^2.8.7 + prettier-plugin-tailwindcss: ^0.2.6 + qrcode.react: ^3.1.0 + react: 18.2.0 + react-datepicker: ^4.11.0 + react-dom: 18.2.0 + react-hook-form: ^7.43.9 + react-i18next: ^12.2.0 + react-icons: ^4.8.0 + react-router-dom: ^6.10.0 + react-syntax-highlighter: ^15.5.0 + sass: ^1.60.0 + tailwindcss: ^3.3.1 + typescript: 5.0.3 + vite: ^4.2.1 + zustand: ^4.3.6 + +dependencies: + '@chakra-ui/anatomy': 2.1.1 + '@chakra-ui/icons': 2.0.18_react@18.2.0 + '@chakra-ui/react': 2.5.5_um4lldyvuaveppcjvfvkxhb3s4 + '@emotion/react': 11.10.6_o2wclmlv6kymw75psj4clbbe6a + '@emotion/styled': 11.10.6_y3jktkphxddpitstssvkgnnxe4 + '@tanstack/react-query': 4.28.0_biqbaboplfbrettd7655fr4n2y + axios: 1.3.4 + clsx: 1.2.1 + dayjs: 1.11.7 + framer-motion: 10.10.0_biqbaboplfbrettd7655fr4n2y + i18next: 22.4.13 + i18next-browser-languagedetector: 7.0.1 + i18next-http-backend: 2.2.0 + immer: 9.0.21 + laf-client-sdk: 1.0.0-beta.2 + lodash: 4.17.21 + make-plural: 7.2.0 + monaco-editor: 0.36.1 + qrcode.react: 3.1.0_react@18.2.0 + react: 18.2.0 + react-datepicker: 4.11.0_biqbaboplfbrettd7655fr4n2y + react-dom: 18.2.0_react@18.2.0 + react-hook-form: 7.43.9_react@18.2.0 + react-i18next: 12.2.0_2rh65uwnd6kial3dj4kteywnti + react-icons: 4.8.0_react@18.2.0 + react-router-dom: 6.10.0_biqbaboplfbrettd7655fr4n2y + react-syntax-highlighter: 15.5.0_react@18.2.0 + sass: 1.60.0 + zustand: 4.3.6_immer@9.0.21+react@18.2.0 + +devDependencies: + '@types/lodash': 4.14.192 + '@types/node': 18.15.11 + '@types/react': 18.0.31 + '@types/react-datepicker': 4.10.0_biqbaboplfbrettd7655fr4n2y + '@types/react-dom': 18.0.11 + '@types/react-syntax-highlighter': 15.5.6 + '@vitejs/plugin-react-swc': 3.2.0_vite@4.2.1 + autoprefixer: 10.4.14_postcss@8.4.21 + click-to-react-component: 1.0.8_6ayuu6vm2uqggsikytom4xssc4 + eslint: 8.37.0 + eslint-config-react-app: 7.0.1_vwh6htx42aidho2qgfca5u5rwm + eslint-plugin-simple-import-sort: 10.0.0_eslint@8.37.0 + husky: 8.0.3 + install: 0.13.0 + lint-staged: 13.2.0 + postcss: 8.4.21 + prettier: 2.8.7 + prettier-plugin-tailwindcss: 0.2.6_prettier@2.8.7 + tailwindcss: 3.3.1_postcss@8.4.21 + typescript: 5.0.3 + vite: 4.2.1_hghbulspu73jfdazs4i6yiqype + +packages: + + /@ampproject/remapping/2.2.0: + resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.1.1 + '@jridgewell/trace-mapping': 0.3.17 + dev: true + + /@babel/code-frame/7.18.6: + resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.18.6 + + /@babel/compat-data/7.20.5: + resolution: {integrity: sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core/7.20.5: + resolution: {integrity: sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.0 + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helpers': 7.20.6 + '@babel/parser': 7.20.5 + '@babel/template': 7.18.10 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 + convert-source-map: 1.9.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.2 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/eslint-parser/7.19.1_nlidl7rzdmevvywe7nf3sd6qkm: + resolution: {integrity: sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==} + engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} + peerDependencies: + '@babel/core': '>=7.11.0' + eslint: ^7.5.0 || ^8.0.0 + dependencies: + '@babel/core': 7.20.5 + '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 + eslint: 8.37.0 + eslint-visitor-keys: 2.1.0 + semver: 6.3.0 + dev: true + + /@babel/generator/7.20.5: + resolution: {integrity: sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + '@jridgewell/gen-mapping': 0.3.2 + jsesc: 2.5.2 + dev: true + + /@babel/helper-annotate-as-pure/7.18.6: + resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@babel/helper-builder-binary-assignment-operator-visitor/7.18.9: + resolution: {integrity: sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-explode-assignable-expression': 7.18.6 + '@babel/types': 7.20.5 + dev: true + + /@babel/helper-compilation-targets/7.20.0_@babel+core@7.20.5: + resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 + '@babel/helper-validator-option': 7.18.6 + browserslist: 4.21.4 + semver: 6.3.0 + dev: true + + /@babel/helper-create-class-features-plugin/7.20.5_@babel+core@7.20.5: + resolution: {integrity: sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-member-expression-to-functions': 7.18.9 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-split-export-declaration': 7.18.6 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-create-regexp-features-plugin/7.20.5_@babel+core@7.20.5: + resolution: {integrity: sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-annotate-as-pure': 7.18.6 + regexpu-core: 5.2.2 + dev: true + + /@babel/helper-define-polyfill-provider/0.3.3_@babel+core@7.20.5: + resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} + peerDependencies: + '@babel/core': ^7.4.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + debug: 4.3.4 + lodash.debounce: 4.0.8 + resolve: 1.22.1 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-environment-visitor/7.18.9: + resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-explode-assignable-expression/7.18.6: + resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@babel/helper-function-name/7.19.0: + resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.18.10 + '@babel/types': 7.20.5 + dev: true + + /@babel/helper-hoist-variables/7.18.6: + resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@babel/helper-member-expression-to-functions/7.18.9: + resolution: {integrity: sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@babel/helper-module-imports/7.18.6: + resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + + /@babel/helper-module-transforms/7.20.2: + resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-simple-access': 7.20.2 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-validator-identifier': 7.19.1 + '@babel/template': 7.18.10 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-optimise-call-expression/7.18.6: + resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@babel/helper-plugin-utils/7.20.2: + resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-remap-async-to-generator/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-wrap-function': 7.20.5 + '@babel/types': 7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-replace-supers/7.19.1: + resolution: {integrity: sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-member-expression-to-functions': 7.18.9 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-simple-access/7.20.2: + resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@babel/helper-skip-transparent-expression-wrappers/7.20.0: + resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@babel/helper-split-export-declaration/7.18.6: + resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@babel/helper-string-parser/7.19.4: + resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-identifier/7.19.1: + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-option/7.18.6: + resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-wrap-function/7.20.5: + resolution: {integrity: sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.19.0 + '@babel/template': 7.18.10 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helpers/7.20.6: + resolution: {integrity: sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.18.10 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/highlight/7.18.6: + resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.19.1 + chalk: 2.4.2 + js-tokens: 4.0.0 + + /@babel/parser/7.20.5: + resolution: {integrity: sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-async-generator-functions/7.20.1_@babel+core@7.20.5: + resolution: {integrity: sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-class-properties/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-class-static-block/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-decorators/7.20.5_@babel+core@7.20.5: + resolution: {integrity: sha512-Lac7PpRJXcC3s9cKsBfl+uc+DYXU5FD06BrTFunQO6QIQT+DwyzDPURAowI3bcvD1dZF/ank1Z5rstUJn3Hn4Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/plugin-syntax-decorators': 7.19.0_@babel+core@7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-dynamic-import/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-export-namespace-from/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-json-strings/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-logical-assignment-operators/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-nullish-coalescing-operator/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-numeric-separator/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-object-rest-spread/7.20.2_@babel+core@7.20.5: + resolution: {integrity: sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-transform-parameters': 7.20.5_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-optional-catch-binding/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-optional-chaining/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-private-methods/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-private-property-in-object/7.20.5_@babel+core@7.20.5: + resolution: {integrity: sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-create-class-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-unicode-property-regex/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} + engines: {node: '>=4'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.20.5: + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.20.5: + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.20.5: + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-decorators/7.19.0_@babel+core@7.20.5: + resolution: {integrity: sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-flow/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-import-assertions/7.20.0_@babel+core@7.20.5: + resolution: {integrity: sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.20.5: + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.20.5: + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.20.5: + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.20.5: + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-typescript/7.20.0_@babel+core@7.20.5: + resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-arrow-functions/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-async-to-generator/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-block-scoped-functions/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-block-scoping/7.20.5_@babel+core@7.20.5: + resolution: {integrity: sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-classes/7.20.2_@babel+core@7.20.5: + resolution: {integrity: sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-replace-supers': 7.19.1 + '@babel/helper-split-export-declaration': 7.18.6 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-computed-properties/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-destructuring/7.20.2_@babel+core@7.20.5: + resolution: {integrity: sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-dotall-regex/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-duplicate-keys/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-exponentiation-operator/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-flow-strip-types/7.19.0_@babel+core@7.20.5: + resolution: {integrity: sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-flow': 7.18.6_@babel+core@7.20.5 + dev: true + + /@babel/plugin-transform-for-of/7.18.8_@babel+core@7.20.5: + resolution: {integrity: sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-function-name/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-literals/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-member-expression-literals/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-modules-amd/7.19.6_@babel+core@7.20.5: + resolution: {integrity: sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-plugin-utils': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-commonjs/7.19.6_@babel+core@7.20.5: + resolution: {integrity: sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-simple-access': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-systemjs/7.19.6_@babel+core@7.20.5: + resolution: {integrity: sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-validator-identifier': 7.19.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-umd/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-plugin-utils': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-named-capturing-groups-regex/7.20.5_@babel+core@7.20.5: + resolution: {integrity: sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-new-target/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-object-super/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-replace-supers': 7.19.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-parameters/7.20.5_@babel+core@7.20.5: + resolution: {integrity: sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-property-literals/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-react-display-name/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.5 + dev: true + + /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.20.5: + resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.5 + '@babel/types': 7.20.5 + dev: true + + /@babel/plugin-transform-react-pure-annotations/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-regenerator/7.20.5_@babel+core@7.20.5: + resolution: {integrity: sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + regenerator-transform: 0.15.1 + dev: true + + /@babel/plugin-transform-reserved-words/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-runtime/7.19.6_@babel+core@7.20.5: + resolution: {integrity: sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.20.5 + babel-plugin-polyfill-corejs3: 0.6.0_@babel+core@7.20.5 + babel-plugin-polyfill-regenerator: 0.4.1_@babel+core@7.20.5 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-shorthand-properties/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-spread/7.19.0_@babel+core@7.20.5: + resolution: {integrity: sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + dev: true + + /@babel/plugin-transform-sticky-regex/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-template-literals/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-typeof-symbol/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-typescript/7.20.2_@babel+core@7.20.5: + resolution: {integrity: sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-typescript': 7.20.0_@babel+core@7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-unicode-escapes/7.18.10_@babel+core@7.20.5: + resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-unicode-regex/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/preset-env/7.20.2_@babel+core@7.20.5: + resolution: {integrity: sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-validator-option': 7.18.6 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-proposal-async-generator-functions': 7.20.1_@babel+core@7.20.5 + '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-class-static-block': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-dynamic-import': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-export-namespace-from': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-logical-assignment-operators': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-object-rest-spread': 7.20.2_@babel+core@7.20.5 + '@babel/plugin-proposal-optional-catch-binding': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-private-property-in-object': 7.20.5_@babel+core@7.20.5 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.5 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.20.5 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-import-assertions': 7.20.0_@babel+core@7.20.5 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.5 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.20.5 + '@babel/plugin-transform-arrow-functions': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-async-to-generator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-block-scoped-functions': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-block-scoping': 7.20.5_@babel+core@7.20.5 + '@babel/plugin-transform-classes': 7.20.2_@babel+core@7.20.5 + '@babel/plugin-transform-computed-properties': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-destructuring': 7.20.2_@babel+core@7.20.5 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-duplicate-keys': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-exponentiation-operator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-for-of': 7.18.8_@babel+core@7.20.5 + '@babel/plugin-transform-function-name': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-literals': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-member-expression-literals': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-modules-amd': 7.19.6_@babel+core@7.20.5 + '@babel/plugin-transform-modules-commonjs': 7.19.6_@babel+core@7.20.5 + '@babel/plugin-transform-modules-systemjs': 7.19.6_@babel+core@7.20.5 + '@babel/plugin-transform-modules-umd': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-named-capturing-groups-regex': 7.20.5_@babel+core@7.20.5 + '@babel/plugin-transform-new-target': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-object-super': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-parameters': 7.20.5_@babel+core@7.20.5 + '@babel/plugin-transform-property-literals': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-regenerator': 7.20.5_@babel+core@7.20.5 + '@babel/plugin-transform-reserved-words': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-shorthand-properties': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-spread': 7.19.0_@babel+core@7.20.5 + '@babel/plugin-transform-sticky-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-template-literals': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-typeof-symbol': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-unicode-escapes': 7.18.10_@babel+core@7.20.5 + '@babel/plugin-transform-unicode-regex': 7.18.6_@babel+core@7.20.5 + '@babel/preset-modules': 0.1.5_@babel+core@7.20.5 + '@babel/types': 7.20.5 + babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.20.5 + babel-plugin-polyfill-corejs3: 0.6.0_@babel+core@7.20.5 + babel-plugin-polyfill-regenerator: 0.4.1_@babel+core@7.20.5 + core-js-compat: 3.26.1 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/preset-modules/0.1.5_@babel+core@7.20.5: + resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.5 + '@babel/types': 7.20.5 + esutils: 2.0.3 + dev: true + + /@babel/preset-react/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-validator-option': 7.18.6 + '@babel/plugin-transform-react-display-name': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.5 + '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-react-pure-annotations': 7.18.6_@babel+core@7.20.5 + dev: true + + /@babel/preset-typescript/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-validator-option': 7.18.6 + '@babel/plugin-transform-typescript': 7.20.2_@babel+core@7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/runtime-corejs3/7.20.6: + resolution: {integrity: sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ==} + engines: {node: '>=6.9.0'} + dependencies: + core-js-pure: 3.26.1 + regenerator-runtime: 0.13.11 + dev: true + + /@babel/runtime/7.20.6: + resolution: {integrity: sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.11 + + /@babel/template/7.18.10: + resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 + dev: true + + /@babel/traverse/7.20.5: + resolution: {integrity: sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.20.5 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types/7.20.5: + resolution: {integrity: sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.19.4 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 + + /@chakra-ui/accordion/2.1.11_ilj7yjzppgy652mi4bmrwbxlhe: + resolution: {integrity: sha512-mfVPmqETp9pyRDHJ33AdF19oHv/LyxVzQJtlxUByuvs8Cj9QQZ2LQLg5kejm+b3mj03A7A6yfbuo3RNaI4Bhsg==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + framer-motion: '>=4.0.0' + react: '>=18' + dependencies: + '@chakra-ui/descendant': 3.0.14_react@18.2.0 + '@chakra-ui/icon': 3.0.16_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-controllable-state': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + '@chakra-ui/transition': 2.0.16_sma346mxzutnq53sdybs2rokta + framer-motion: 10.10.0_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + dev: false + + /@chakra-ui/alert/2.1.0_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-OcfHwoXI5VrmM+tHJTHT62Bx6TfyfCxSa0PWUOueJzSyhlUOKBND5we6UtrOB7D0jwX45qKKEDJOLG5yCG21jQ==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/icon': 3.0.16_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/spinner': 2.0.13_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/anatomy/2.1.1: + resolution: {integrity: sha512-LUHAoqJAgxAqmyckG5bUpBrfEo1FleEyY+1A8hkWciy58gZ+h3GoY9oBpHcdo7XdHPpy3G+3hieK/7i9NLwxAw==} + dev: false + + /@chakra-ui/anatomy/2.1.2: + resolution: {integrity: sha512-pKfOS/mztc4sUXHNc8ypJ1gPWSolWT770jrgVRfolVbYlki8y5Y+As996zMF6k5lewTu6j9DQequ7Cc9a69IVQ==} + dev: false + + /@chakra-ui/avatar/2.2.8_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-uBs9PMrqyK111tPIYIKnOM4n3mwgKqGpvYmtwBnnbQLTNLg4gtiWWVbpTuNMpyu1av0xQYomjUt8Doed8w6p8g==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/image': 2.0.15_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/react-children-utils': 2.0.6_react@18.2.0 + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/breadcrumb/2.1.5_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-p3eQQrHQBkRB69xOmNyBJqEdfCrMt+e0eOH+Pm/DjFWfIVIbnIaFbmDCeWClqlLa21Ypc6h1hR9jEmvg8kmOog==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/react-children-utils': 2.0.6_react@18.2.0 + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/breakpoint-utils/2.0.8: + resolution: {integrity: sha512-Pq32MlEX9fwb5j5xx8s18zJMARNHlQZH2VH1RZgfgRDpp7DcEgtRW5AInfN5CfqdHLO1dGxA7I3MqEuL5JnIsA==} + dependencies: + '@chakra-ui/shared-utils': 2.0.5 + dev: false + + /@chakra-ui/button/2.0.18_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-E3c99+lOm6ou4nQVOTLkG+IdOPMjsQK+Qe7VyP8A/xeAMFONuibrWPRPpprr4ZkB4kEoLMfNuyH2+aEza3ScUA==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/spinner': 2.0.13_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/card/2.1.6_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-fFd/WAdRNVY/WOSQv4skpy0WeVhhI0f7dTY1Sm0jVl0KLmuP/GnpsWtKtqWjNcV00K963EXDyhlk6+9oxbP4gw==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/checkbox/2.2.14_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-uqo6lFWLqYBujPglrvRhTAErtuIXpmdpc5w0W4bjK7kyvLhxOpUh1hlDb2WoqlNpfRn/OaNeF6VinPnf9BJL8w==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/form-control': 2.0.18_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-types': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-callback-ref': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-controllable-state': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-safe-layout-effect': 2.0.5_react@18.2.0 + '@chakra-ui/react-use-update-effect': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + '@chakra-ui/visually-hidden': 2.0.15_lze4h7kxffpjhokvtqbtrlfkmq + '@zag-js/focus-visible': 0.2.2 + react: 18.2.0 + dev: false + + /@chakra-ui/clickable/2.0.14_react@18.2.0: + resolution: {integrity: sha512-jfsM1qaD74ZykLHmvmsKRhDyokLUxEfL8Il1VoZMNX5RBI0xW/56vKpLTFF/v/+vLPLS+Te2cZdD4+2O+G6ulA==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + react: 18.2.0 + dev: false + + /@chakra-ui/close-button/2.0.17_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-05YPXk456t1Xa3KpqTrvm+7smx+95dmaPiwjiBN3p7LHUQVHJd8ZXSDB0V+WKi419k3cVQeJUdU/azDO2f40sw==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/icon': 3.0.16_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/color-mode/2.1.12_react@18.2.0: + resolution: {integrity: sha512-sYyfJGDoJSLYO+V2hxV9r033qhte5Nw/wAn5yRGGZnEEN1dKPEdWQ3XZvglWSDTNd0w9zkoH2w6vP4FBBYb/iw==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/react-use-safe-layout-effect': 2.0.5_react@18.2.0 + react: 18.2.0 + dev: false + + /@chakra-ui/control-box/2.0.13_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-FEyrU4crxati80KUF/+1Z1CU3eZK6Sa0Yv7Z/ydtz9/tvGblXW9NFanoomXAOvcIFLbaLQPPATm9Gmpr7VG05A==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/counter/2.0.14_react@18.2.0: + resolution: {integrity: sha512-KxcSRfUbb94dP77xTip2myoE7P2HQQN4V5fRJmNAGbzcyLciJ+aDylUU/UxgNcEjawUp6Q242NbWb1TSbKoqog==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/number-utils': 2.0.7 + '@chakra-ui/react-use-callback-ref': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + react: 18.2.0 + dev: false + + /@chakra-ui/css-reset/2.1.1_3og6jmu6wvzuytygvdoxepq3x4: + resolution: {integrity: sha512-jwEOfIAWmQsnChHQTW/eRE+dfE4MjmhvSvoUug5nkV1pI7veC/20noFlIZxzi82EbiQI8Fs0+Jnusgxr2yaOHA==} + peerDependencies: + '@emotion/react': '>=10.0.35' + react: '>=18' + dependencies: + '@emotion/react': 11.10.6_o2wclmlv6kymw75psj4clbbe6a + react: 18.2.0 + dev: false + + /@chakra-ui/descendant/3.0.14_react@18.2.0: + resolution: {integrity: sha512-+Ahvp9H4HMpfScIv9w1vaecGz7qWAaK1YFHHolz/SIsGLaLGlbdp+5UNabQC7L6TUnzzJDQDxzwif78rTD7ang==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + react: 18.2.0 + dev: false + + /@chakra-ui/dom-utils/2.0.6: + resolution: {integrity: sha512-PVtDkPrDD5b8aoL6Atg7SLjkwhWb7BwMcLOF1L449L3nZN+DAO3nyAh6iUhZVJyunELj9d0r65CDlnMREyJZmA==} + dev: false + + /@chakra-ui/editable/2.0.21_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-oYuXbHnggxSYJN7P9Pn0Scs9tPC91no4z1y58Oe+ILoJKZ+bFAEHtL7FEISDNJxw++MEukeFu7GU1hVqmdLsKQ==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-types': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-callback-ref': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-controllable-state': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-focus-on-pointer-down': 2.0.6_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-safe-layout-effect': 2.0.5_react@18.2.0 + '@chakra-ui/react-use-update-effect': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/event-utils/2.0.8: + resolution: {integrity: sha512-IGM/yGUHS+8TOQrZGpAKOJl/xGBrmRYJrmbHfUE7zrG3PpQyXvbLDP1M+RggkCFVgHlJi2wpYIf0QtQlU0XZfw==} + dev: false + + /@chakra-ui/focus-lock/2.0.16_o2wclmlv6kymw75psj4clbbe6a: + resolution: {integrity: sha512-UuAdGCPVrCa1lecoAvpOQD7JFT7a9RdmhKWhFt5ioIcekSLJcerdLHuuL3w0qz//8kd1/SOt7oP0aJqdAJQrCw==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/dom-utils': 2.0.6 + react: 18.2.0 + react-focus-lock: 2.9.2_o2wclmlv6kymw75psj4clbbe6a + transitivePeerDependencies: + - '@types/react' + dev: false + + /@chakra-ui/form-control/2.0.18_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-I0a0jG01IAtRPccOXSNugyRdUAe8Dy40ctqedZvznMweOXzbMCF1m+sHPLdWeWC/VI13VoAispdPY0/zHOdjsQ==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/icon': 3.0.16_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-types': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/hooks/2.1.6_react@18.2.0: + resolution: {integrity: sha512-oMSOeoOF6/UpwTVlDFHSROAA4hPY8WgJ0erdHs1ZkuwAwHv7UzjDkvrb6xYzAAH9qHoFzc5RIBm6jVoh3LCc+Q==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/react-utils': 2.0.12_react@18.2.0 + '@chakra-ui/utils': 2.0.15 + compute-scroll-into-view: 1.0.20 + copy-to-clipboard: 3.3.3 + react: 18.2.0 + dev: false + + /@chakra-ui/icon/3.0.16_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-RpA1X5Ptz8Mt39HSyEIW1wxAz2AXyf9H0JJ5HVx/dBdMZaGMDJ0HyyPBVci0m4RCoJuyG1HHG/DXJaVfUTVAeg==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/icon/3.0.16_react@18.2.0: + resolution: {integrity: sha512-RpA1X5Ptz8Mt39HSyEIW1wxAz2AXyf9H0JJ5HVx/dBdMZaGMDJ0HyyPBVci0m4RCoJuyG1HHG/DXJaVfUTVAeg==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/shared-utils': 2.0.5 + react: 18.2.0 + dev: false + + /@chakra-ui/icons/2.0.18_react@18.2.0: + resolution: {integrity: sha512-E/+DF/jw7kdN4/XxCZRnr4FdMXhkl50Q34MVwN9rADWMwPK9uSZPGyC7HOx6rilo7q4bFjYDH3yRj9g+VfbVkg==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/icon': 3.0.16_react@18.2.0 + react: 18.2.0 + dev: false + + /@chakra-ui/image/2.0.15_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-w2rElXtI3FHXuGpMCsSklus+pO1Pl2LWDwsCGdpBQUvGFbnHfl7MftQgTlaGHeD5OS95Pxva39hKrA2VklKHiQ==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/react-use-safe-layout-effect': 2.0.5_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/input/2.0.21_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-AIWjjg6MgcOtlvKmVoZfPPfgF+sBSWL3Zq2HSCAMvS6h7jfxz/Xv0UTFGPk5F4Wt0YHT7qMySg0Jsm0b78HZJg==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/form-control': 2.0.18_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/object-utils': 2.0.8 + '@chakra-ui/react-children-utils': 2.0.6_react@18.2.0 + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/layout/2.1.18_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-F4Gh2e+DGdaWdWT5NZduIFD9NM7Bnuh8sXARFHWPvIu7yvAwZ3ddqC9GK4F3qUngdmkJxDLWQqRSwSh96Lxbhw==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/breakpoint-utils': 2.0.8 + '@chakra-ui/icon': 3.0.16_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/object-utils': 2.0.8 + '@chakra-ui/react-children-utils': 2.0.6_react@18.2.0 + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/lazy-utils/2.0.5: + resolution: {integrity: sha512-UULqw7FBvcckQk2n3iPO56TMJvDsNv0FKZI6PlUNJVaGsPbsYxK/8IQ60vZgaTVPtVcjY6BE+y6zg8u9HOqpyg==} + dev: false + + /@chakra-ui/live-region/2.0.13_react@18.2.0: + resolution: {integrity: sha512-Ja+Slk6ZkxSA5oJzU2VuGU7TpZpbMb/4P4OUhIf2D30ctmIeXkxTWw1Bs1nGJAVtAPcGS5sKA+zb89i8g+0cTQ==} + peerDependencies: + react: '>=18' + dependencies: + react: 18.2.0 + dev: false + + /@chakra-ui/media-query/3.2.12_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-8pSLDf3oxxhFrhd40rs7vSeIBfvOmIKHA7DJlGUC/y+9irD24ZwgmCtFnn+y3gI47hTJsopbSX+wb8nr7XPswA==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/breakpoint-utils': 2.0.8 + '@chakra-ui/react-env': 3.0.0_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/menu/2.1.12_ilj7yjzppgy652mi4bmrwbxlhe: + resolution: {integrity: sha512-ylNK1VJlr/3/EGg9dLPZ87cBJJjeiYXeU/gOAphsKXMnByrXWhbp4YVnyyyha2KZ0zEw0aPU4nCZ+A69aT9wrg==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + framer-motion: '>=4.0.0' + react: '>=18' + dependencies: + '@chakra-ui/clickable': 2.0.14_react@18.2.0 + '@chakra-ui/descendant': 3.0.14_react@18.2.0 + '@chakra-ui/lazy-utils': 2.0.5 + '@chakra-ui/popper': 3.0.13_react@18.2.0 + '@chakra-ui/react-children-utils': 2.0.6_react@18.2.0 + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-animation-state': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-controllable-state': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-disclosure': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-focus-effect': 2.0.9_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-outside-click': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-update-effect': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + '@chakra-ui/transition': 2.0.16_sma346mxzutnq53sdybs2rokta + framer-motion: 10.10.0_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + dev: false + + /@chakra-ui/modal/2.2.11_52ucbt34utwkx5z3z2xe3fqqm4: + resolution: {integrity: sha512-2J0ZUV5tEzkPiawdkgPz6bmex7NXAde1VXooMwdvK+vuT8PV3U61yorTJOZVLdw7TjjI1Yo94mzsp6UwBud43Q==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + framer-motion: '>=4.0.0' + react: '>=18' + react-dom: '>=18' + dependencies: + '@chakra-ui/close-button': 2.0.17_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/focus-lock': 2.0.16_o2wclmlv6kymw75psj4clbbe6a + '@chakra-ui/portal': 2.0.16_biqbaboplfbrettd7655fr4n2y + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-types': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + '@chakra-ui/transition': 2.0.16_sma346mxzutnq53sdybs2rokta + aria-hidden: 1.2.2_o2wclmlv6kymw75psj4clbbe6a + framer-motion: 10.10.0_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + react-remove-scroll: 2.5.5_o2wclmlv6kymw75psj4clbbe6a + transitivePeerDependencies: + - '@types/react' + dev: false + + /@chakra-ui/number-input/2.0.19_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-HDaITvtMEqOauOrCPsARDxKD9PSHmhWywpcyCSOX0lMe4xx2aaGhU0QQFhsJsykj8Er6pytMv6t0KZksdDv3YA==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/counter': 2.0.14_react@18.2.0 + '@chakra-ui/form-control': 2.0.18_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/icon': 3.0.16_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-types': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-callback-ref': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-event-listener': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-interval': 2.0.5_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-safe-layout-effect': 2.0.5_react@18.2.0 + '@chakra-ui/react-use-update-effect': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/number-utils/2.0.7: + resolution: {integrity: sha512-yOGxBjXNvLTBvQyhMDqGU0Oj26s91mbAlqKHiuw737AXHt0aPllOthVUqQMeaYLwLCjGMg0jtI7JReRzyi94Dg==} + dev: false + + /@chakra-ui/object-utils/2.0.8: + resolution: {integrity: sha512-2upjT2JgRuiupdrtBWklKBS6tqeGMA77Nh6Q0JaoQuH/8yq+15CGckqn3IUWkWoGI0Fg3bK9LDlbbD+9DLw95Q==} + dev: false + + /@chakra-ui/pin-input/2.0.20_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-IHVmerrtHN8F+jRB3W1HnMir1S1TUCWhI7qDInxqPtoRffHt6mzZgLZ0izx8p1fD4HkW4c1d4/ZLEz9uH9bBRg==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/descendant': 3.0.14_react@18.2.0 + '@chakra-ui/react-children-utils': 2.0.6_react@18.2.0 + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-controllable-state': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/popover/2.1.9_ilj7yjzppgy652mi4bmrwbxlhe: + resolution: {integrity: sha512-OMJ12VVs9N32tFaZSOqikkKPtwAVwXYsES/D1pff/amBrE3ngCrpxJSIp4uvTdORfIYDojJqrR52ZplDKS9hRQ==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + framer-motion: '>=4.0.0' + react: '>=18' + dependencies: + '@chakra-ui/close-button': 2.0.17_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/lazy-utils': 2.0.5 + '@chakra-ui/popper': 3.0.13_react@18.2.0 + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-types': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-animation-state': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-disclosure': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-focus-effect': 2.0.9_react@18.2.0 + '@chakra-ui/react-use-focus-on-pointer-down': 2.0.6_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + framer-motion: 10.10.0_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + dev: false + + /@chakra-ui/popper/3.0.13_react@18.2.0: + resolution: {integrity: sha512-FwtmYz80Ju8oK3Z1HQfisUE7JIMmDsCQsRBu6XuJ3TFQnBHit73yjZmxKjuRJ4JgyT4WBnZoTF3ATbRKSagBeg==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/react-types': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@popperjs/core': 2.11.6 + react: 18.2.0 + dev: false + + /@chakra-ui/portal/2.0.16_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-bVID0qbQ0l4xq38LdqAN4EKD4/uFkDnXzFwOlviC9sl0dNhzICDb1ltuH/Adl1d2HTMqyN60O3GO58eHy7plnQ==} + peerDependencies: + react: '>=18' + react-dom: '>=18' + dependencies: + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-safe-layout-effect': 2.0.5_react@18.2.0 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /@chakra-ui/progress/2.1.6_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-hHh5Ysv4z6bK+j2GJbi/FT9CVyto2PtNUNwBmr3oNMVsoOUMoRjczfXvvYqp0EHr9PCpxqrq7sRwgQXUzhbDSw==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/provider/2.2.2_fbxtuirhogpez7m7qjkm3itwca: + resolution: {integrity: sha512-UVwnIDnAWq1aKroN5AF+OpNpUqLVeIUk7tKvX3z4CY9FsPFFi6LTEhRHdhpwaU1Tau3Tf9agEu5URegpY7S8BA==} + peerDependencies: + '@emotion/react': ^11.0.0 + '@emotion/styled': ^11.0.0 + react: '>=18' + react-dom: '>=18' + dependencies: + '@chakra-ui/css-reset': 2.1.1_3og6jmu6wvzuytygvdoxepq3x4 + '@chakra-ui/portal': 2.0.16_biqbaboplfbrettd7655fr4n2y + '@chakra-ui/react-env': 3.0.0_react@18.2.0 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + '@chakra-ui/utils': 2.0.15 + '@emotion/react': 11.10.6_o2wclmlv6kymw75psj4clbbe6a + '@emotion/styled': 11.10.6_y3jktkphxddpitstssvkgnnxe4 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /@chakra-ui/radio/2.0.22_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-GsQ5WAnLwivWl6gPk8P1x+tCcpVakCt5R5T0HumF7DGPXKdJbjS+RaFySrbETmyTJsKY4QrfXn+g8CWVrMjPjw==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/form-control': 2.0.18_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-types': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + '@zag-js/focus-visible': 0.2.2 + react: 18.2.0 + dev: false + + /@chakra-ui/react-children-utils/2.0.6_react@18.2.0: + resolution: {integrity: sha512-QVR2RC7QsOsbWwEnq9YduhpqSFnZGvjjGREV8ygKi8ADhXh93C8azLECCUVgRJF2Wc+So1fgxmjLcbZfY2VmBA==} + peerDependencies: + react: '>=18' + dependencies: + react: 18.2.0 + dev: false + + /@chakra-ui/react-context/2.0.8_react@18.2.0: + resolution: {integrity: sha512-tRTKdn6lCTXM6WPjSokAAKCw2ioih7Eg8cNgaYRSwKBck8nkz9YqxgIIEj3dJD7MGtpl24S/SNI98iRWkRwR/A==} + peerDependencies: + react: '>=18' + dependencies: + react: 18.2.0 + dev: false + + /@chakra-ui/react-env/3.0.0_react@18.2.0: + resolution: {integrity: sha512-tfMRO2v508HQWAqSADFrwZgR9oU10qC97oV6zGbjHh9ALP0/IcFR+Bi71KRTveDTm85fMeAzZYGj57P3Dsipkw==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/react-use-safe-layout-effect': 2.0.5_react@18.2.0 + react: 18.2.0 + dev: false + + /@chakra-ui/react-types/2.0.7_react@18.2.0: + resolution: {integrity: sha512-12zv2qIZ8EHwiytggtGvo4iLT0APris7T0qaAWqzpUGS0cdUtR8W+V1BJ5Ocq+7tA6dzQ/7+w5hmXih61TuhWQ==} + peerDependencies: + react: '>=18' + dependencies: + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-animation-state/2.0.8_react@18.2.0: + resolution: {integrity: sha512-xv9zSF2Rd1mHWQ+m5DLBWeh4atF8qrNvsOs3MNrvxKYBS3f79N3pqcQGrWAEvirXWXfiCeje2VAkEggqFRIo+Q==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/dom-utils': 2.0.6 + '@chakra-ui/react-use-event-listener': 2.0.7_react@18.2.0 + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-callback-ref/2.0.7_react@18.2.0: + resolution: {integrity: sha512-YjT76nTpfHAK5NxplAlZsQwNju5KmQExnqsWNPFeOR6vvbC34+iPSTr+r91i1Hdy7gBSbevsOsd5Wm6RN3GuMw==} + peerDependencies: + react: '>=18' + dependencies: + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-controllable-state/2.0.8_react@18.2.0: + resolution: {integrity: sha512-F7rdCbLEmRjwwODqWZ3y+mKgSSHPcLQxeUygwk1BkZPXbKkJJKymOIjIynil2cbH7ku3hcSIWRvuhpCcfQWJ7Q==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/react-use-callback-ref': 2.0.7_react@18.2.0 + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-disclosure/2.0.8_react@18.2.0: + resolution: {integrity: sha512-2ir/mHe1YND40e+FyLHnDsnDsBQPwzKDLzfe9GZri7y31oU83JSbHdlAXAhp3bpjohslwavtRCp+S/zRxfO9aQ==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/react-use-callback-ref': 2.0.7_react@18.2.0 + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-event-listener/2.0.7_react@18.2.0: + resolution: {integrity: sha512-4wvpx4yudIO3B31pOrXuTHDErawmwiXnvAN7gLEOVREi16+YGNcFnRJ5X5nRrmB7j2MDUtsEDpRBFfw5Z9xQ5g==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/react-use-callback-ref': 2.0.7_react@18.2.0 + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-focus-effect/2.0.9_react@18.2.0: + resolution: {integrity: sha512-20nfNkpbVwyb41q9wxp8c4jmVp6TUGAPE3uFTDpiGcIOyPW5aecQtPmTXPMJH+2aa8Nu1wyoT1btxO+UYiQM3g==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/dom-utils': 2.0.6 + '@chakra-ui/react-use-event-listener': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-safe-layout-effect': 2.0.5_react@18.2.0 + '@chakra-ui/react-use-update-effect': 2.0.7_react@18.2.0 + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-focus-on-pointer-down/2.0.6_react@18.2.0: + resolution: {integrity: sha512-OigXiLRVySn3tyVqJ/rn57WGuukW8TQe8fJYiLwXbcNyAMuYYounvRxvCy2b53sQ7QIZamza0N0jhirbH5FNoQ==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/react-use-event-listener': 2.0.7_react@18.2.0 + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-interval/2.0.5_react@18.2.0: + resolution: {integrity: sha512-1nbdwMi2K87V6p5f5AseOKif2CkldLaJlq1TOqaPRwb7v3aU9rltBtYdf+fIyuHSToNJUV6wd9budCFdLCl3Fg==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/react-use-callback-ref': 2.0.7_react@18.2.0 + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-latest-ref/2.0.5_react@18.2.0: + resolution: {integrity: sha512-3mIuFzMyIo3Ok/D8uhV9voVg7KkrYVO/pwVvNPJOHsDQqCA6DpYE4WDsrIx+fVcwad3Ta7SupexR5PoI+kq6QQ==} + peerDependencies: + react: '>=18' + dependencies: + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-merge-refs/2.0.7_react@18.2.0: + resolution: {integrity: sha512-zds4Uhsc+AMzdH8JDDkLVet9baUBgtOjPbhC5r3A0ZXjZvGhCztFAVE3aExYiVoMPoHLKbLcqvCWE6ioFKz1lw==} + peerDependencies: + react: '>=18' + dependencies: + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-outside-click/2.0.7_react@18.2.0: + resolution: {integrity: sha512-MsAuGLkwYNxNJ5rb8lYNvXApXxYMnJ3MzqBpQj1kh5qP/+JSla9XMjE/P94ub4fSEttmNSqs43SmPPrmPuihsQ==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/react-use-callback-ref': 2.0.7_react@18.2.0 + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-pan-event/2.0.9_react@18.2.0: + resolution: {integrity: sha512-xu35QXkiyrgsHUOnctl+SwNcwf9Rl62uYE5y8soKOZdBm8E+FvZIt2hxUzK1EoekbJCMzEZ0Yv1ZQCssVkSLaQ==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/event-utils': 2.0.8 + '@chakra-ui/react-use-latest-ref': 2.0.5_react@18.2.0 + framesync: 6.1.2 + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-previous/2.0.5_react@18.2.0: + resolution: {integrity: sha512-BIZgjycPE4Xr+MkhKe0h67uHXzQQkBX/u5rYPd65iMGdX1bCkbE0oorZNfOHLKdTmnEb4oVsNvfN6Rfr+Mnbxw==} + peerDependencies: + react: '>=18' + dependencies: + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-safe-layout-effect/2.0.5_react@18.2.0: + resolution: {integrity: sha512-MwAQBz3VxoeFLaesaSEN87reVNVbjcQBDex2WGexAg6hUB6n4gc1OWYH/iXp4tzp4kuggBNhEHkk9BMYXWfhJQ==} + peerDependencies: + react: '>=18' + dependencies: + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-size/2.0.10_react@18.2.0: + resolution: {integrity: sha512-fdIkH14GDnKQrtQfxX8N3gxbXRPXEl67Y3zeD9z4bKKcQUAYIMqs0MsPZY+FMpGQw8QqafM44nXfL038aIrC5w==} + peerDependencies: + react: '>=18' + dependencies: + '@zag-js/element-size': 0.3.2 + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-timeout/2.0.5_react@18.2.0: + resolution: {integrity: sha512-QqmB+jVphh3h/CS60PieorpY7UqSPkrQCB7f7F+i9vwwIjtP8fxVHMmkb64K7VlzQiMPzv12nlID5dqkzlv0mw==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/react-use-callback-ref': 2.0.7_react@18.2.0 + react: 18.2.0 + dev: false + + /@chakra-ui/react-use-update-effect/2.0.7_react@18.2.0: + resolution: {integrity: sha512-vBM2bmmM83ZdDtasWv3PXPznpTUd+FvqBC8J8rxoRmvdMEfrxTiQRBJhiGHLpS9BPLLPQlosN6KdFU97csB6zg==} + peerDependencies: + react: '>=18' + dependencies: + react: 18.2.0 + dev: false + + /@chakra-ui/react-utils/2.0.12_react@18.2.0: + resolution: {integrity: sha512-GbSfVb283+YA3kA8w8xWmzbjNWk14uhNpntnipHCftBibl0lxtQ9YqMFQLwuFOO0U2gYVocszqqDWX+XNKq9hw==} + peerDependencies: + react: '>=18' + dependencies: + '@chakra-ui/utils': 2.0.15 + react: 18.2.0 + dev: false + + /@chakra-ui/react/2.5.5_um4lldyvuaveppcjvfvkxhb3s4: + resolution: {integrity: sha512-aBVMUtdWv2MrptD/tKSqICPsuJ+I+jvauegffO1qPUDlK3RrXIDeOHkLGWohgXNcjY5bGVWguFEzJm97//0ooQ==} + peerDependencies: + '@emotion/react': ^11.0.0 + '@emotion/styled': ^11.0.0 + framer-motion: '>=4.0.0' + react: '>=18' + react-dom: '>=18' + dependencies: + '@chakra-ui/accordion': 2.1.11_ilj7yjzppgy652mi4bmrwbxlhe + '@chakra-ui/alert': 2.1.0_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/avatar': 2.2.8_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/breadcrumb': 2.1.5_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/button': 2.0.18_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/card': 2.1.6_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/checkbox': 2.2.14_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/close-button': 2.0.17_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/control-box': 2.0.13_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/counter': 2.0.14_react@18.2.0 + '@chakra-ui/css-reset': 2.1.1_3og6jmu6wvzuytygvdoxepq3x4 + '@chakra-ui/editable': 2.0.21_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/focus-lock': 2.0.16_o2wclmlv6kymw75psj4clbbe6a + '@chakra-ui/form-control': 2.0.18_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/hooks': 2.1.6_react@18.2.0 + '@chakra-ui/icon': 3.0.16_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/image': 2.0.15_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/input': 2.0.21_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/layout': 2.1.18_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/live-region': 2.0.13_react@18.2.0 + '@chakra-ui/media-query': 3.2.12_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/menu': 2.1.12_ilj7yjzppgy652mi4bmrwbxlhe + '@chakra-ui/modal': 2.2.11_52ucbt34utwkx5z3z2xe3fqqm4 + '@chakra-ui/number-input': 2.0.19_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/pin-input': 2.0.20_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/popover': 2.1.9_ilj7yjzppgy652mi4bmrwbxlhe + '@chakra-ui/popper': 3.0.13_react@18.2.0 + '@chakra-ui/portal': 2.0.16_biqbaboplfbrettd7655fr4n2y + '@chakra-ui/progress': 2.1.6_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/provider': 2.2.2_fbxtuirhogpez7m7qjkm3itwca + '@chakra-ui/radio': 2.0.22_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/react-env': 3.0.0_react@18.2.0 + '@chakra-ui/select': 2.0.19_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/skeleton': 2.0.24_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/slider': 2.0.23_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/spinner': 2.0.13_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/stat': 2.0.18_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/styled-system': 2.8.0 + '@chakra-ui/switch': 2.0.26_ilj7yjzppgy652mi4bmrwbxlhe + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + '@chakra-ui/table': 2.0.17_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/tabs': 2.1.9_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/tag': 3.0.0_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/textarea': 2.0.19_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/theme': 3.0.1_wv7sq5bj4kx5i3evdevscgumbi + '@chakra-ui/theme-utils': 2.0.15 + '@chakra-ui/toast': 6.1.1_xt3wqam72hls6n5f3kcoh4zcy4 + '@chakra-ui/tooltip': 2.2.7_xt3wqam72hls6n5f3kcoh4zcy4 + '@chakra-ui/transition': 2.0.16_sma346mxzutnq53sdybs2rokta + '@chakra-ui/utils': 2.0.15 + '@chakra-ui/visually-hidden': 2.0.15_lze4h7kxffpjhokvtqbtrlfkmq + '@emotion/react': 11.10.6_o2wclmlv6kymw75psj4clbbe6a + '@emotion/styled': 11.10.6_y3jktkphxddpitstssvkgnnxe4 + framer-motion: 10.10.0_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + transitivePeerDependencies: + - '@types/react' + dev: false + + /@chakra-ui/select/2.0.19_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-eAlFh+JhwtJ17OrB6fO6gEAGOMH18ERNrXLqWbYLrs674Le7xuREgtuAYDoxUzvYXYYTTdOJtVbcHGriI3o6rA==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/form-control': 2.0.18_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/shared-utils/2.0.5: + resolution: {integrity: sha512-4/Wur0FqDov7Y0nCXl7HbHzCg4aq86h+SXdoUeuCMD3dSj7dpsVnStLYhng1vxvlbUnLpdF4oz5Myt3i/a7N3Q==} + dev: false + + /@chakra-ui/skeleton/2.0.24_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-1jXtVKcl/jpbrJlc/TyMsFyI651GTXY5ma30kWyTXoby2E+cxbV6OR8GB/NMZdGxbQBax8/VdtYVjI0n+OBqWA==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/media-query': 3.2.12_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/react-use-previous': 2.0.5_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/slider/2.0.23_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-/eyRUXLla+ZdBUPXpakE3SAS2JS8mIJR6qcUYiPVKSpRAi6tMyYeQijAXn2QC1AUVd2JrG8Pz+1Jy7Po3uA7cA==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/number-utils': 2.0.7 + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-types': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-callback-ref': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-controllable-state': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-latest-ref': 2.0.5_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-pan-event': 2.0.9_react@18.2.0 + '@chakra-ui/react-use-size': 2.0.10_react@18.2.0 + '@chakra-ui/react-use-update-effect': 2.0.7_react@18.2.0 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/spinner/2.0.13_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-T1/aSkVpUIuiYyrjfn1+LsQEG7Onbi1UE9ccS/evgf61Dzy4GgTXQUnDuWFSgpV58owqirqOu6jn/9eCwDlzlg==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/stat/2.0.18_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-wKyfBqhVlIs9bkSerUc6F9KJMw0yTIEKArW7dejWwzToCLPr47u+CtYO6jlJHV6lRvkhi4K4Qc6pyvtJxZ3VpA==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/icon': 3.0.16_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/styled-system/2.8.0: + resolution: {integrity: sha512-bmRv/8ACJGGKGx84U1npiUddwdNifJ+/ETklGwooS5APM0ymwUtBYZpFxjYNJrqvVYpg3mVY6HhMyBVptLS7iA==} + dependencies: + '@chakra-ui/shared-utils': 2.0.5 + csstype: 3.1.1 + lodash.mergewith: 4.6.2 + dev: false + + /@chakra-ui/switch/2.0.26_ilj7yjzppgy652mi4bmrwbxlhe: + resolution: {integrity: sha512-x62lF6VazSZJQuVxosChVR6+0lIJe8Pxgkl/C9vxjhp2yVYb3mew5tcX/sDOu0dYZy8ro/9hMfGkdN4r9xEU8A==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + framer-motion: '>=4.0.0' + react: '>=18' + dependencies: + '@chakra-ui/checkbox': 2.2.14_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + framer-motion: 10.10.0_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + dev: false + + /@chakra-ui/system/2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba: + resolution: {integrity: sha512-52BIp/Zyvefgxn5RTByfkTeG4J+y81LWEjWm8jCaRFsLVm8IFgqIrngtcq4I7gD5n/UKbneHlb4eLHo4uc5yDQ==} + peerDependencies: + '@emotion/react': ^11.0.0 + '@emotion/styled': ^11.0.0 + react: '>=18' + dependencies: + '@chakra-ui/color-mode': 2.1.12_react@18.2.0 + '@chakra-ui/object-utils': 2.0.8 + '@chakra-ui/react-utils': 2.0.12_react@18.2.0 + '@chakra-ui/styled-system': 2.8.0 + '@chakra-ui/theme-utils': 2.0.15 + '@chakra-ui/utils': 2.0.15 + '@emotion/react': 11.10.6_o2wclmlv6kymw75psj4clbbe6a + '@emotion/styled': 11.10.6_y3jktkphxddpitstssvkgnnxe4 + react: 18.2.0 + react-fast-compare: 3.2.1 + dev: false + + /@chakra-ui/table/2.0.17_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-OScheTEp1LOYvTki2NFwnAYvac8siAhW9BI5RKm5f5ORL2gVJo4I72RUqE0aKe1oboxgm7CYt5afT5PS5cG61A==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/tabs/2.1.9_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-Yf8e0kRvaGM6jfkJum0aInQ0U3ZlCafmrYYni2lqjcTtThqu+Yosmo3iYlnullXxCw5MVznfrkb9ySvgQowuYg==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/clickable': 2.0.14_react@18.2.0 + '@chakra-ui/descendant': 3.0.14_react@18.2.0 + '@chakra-ui/lazy-utils': 2.0.5 + '@chakra-ui/react-children-utils': 2.0.6_react@18.2.0 + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-controllable-state': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-safe-layout-effect': 2.0.5_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/tag/3.0.0_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-YWdMmw/1OWRwNkG9pX+wVtZio+B89odaPj6XeMn5nfNN8+jyhIEpouWv34+CO9G0m1lupJTxPSfgLAd7cqXZMA==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/icon': 3.0.16_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/textarea/2.0.19_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-adJk+qVGsFeJDvfn56CcJKKse8k7oMGlODrmpnpTdF+xvlsiTM+1GfaJvgNSpHHuQFdz/A0z1uJtfGefk0G2ZA==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/form-control': 2.0.18_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@chakra-ui/theme-tools/2.0.17_wv7sq5bj4kx5i3evdevscgumbi: + resolution: {integrity: sha512-Auu38hnihlJZQcPok6itRDBbwof3TpXGYtDPnOvrq4Xp7jnab36HLt7KEXSDPXbtOk3ZqU99pvI1en5LbDrdjg==} + peerDependencies: + '@chakra-ui/styled-system': '>=2.0.0' + dependencies: + '@chakra-ui/anatomy': 2.1.2 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/styled-system': 2.8.0 + color2k: 2.0.0 + dev: false + + /@chakra-ui/theme-utils/2.0.15: + resolution: {integrity: sha512-UuxtEgE7gwMTGDXtUpTOI7F5X0iHB9ekEOG5PWPn2wWBL7rlk2JtPI7UP5Um5Yg6vvBfXYGK1ySahxqsgf+87g==} + dependencies: + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/styled-system': 2.8.0 + '@chakra-ui/theme': 3.0.1_wv7sq5bj4kx5i3evdevscgumbi + lodash.mergewith: 4.6.2 + dev: false + + /@chakra-ui/theme/3.0.1_wv7sq5bj4kx5i3evdevscgumbi: + resolution: {integrity: sha512-92kDm/Ux/51uJqhRKevQo/O/rdwucDYcpHg2QuwzdAxISCeYvgtl2TtgOOl5EnqEP0j3IEAvZHZUlv8TTbawaw==} + peerDependencies: + '@chakra-ui/styled-system': '>=2.0.0' + dependencies: + '@chakra-ui/anatomy': 2.1.2 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/styled-system': 2.8.0 + '@chakra-ui/theme-tools': 2.0.17_wv7sq5bj4kx5i3evdevscgumbi + dev: false + + /@chakra-ui/toast/6.1.1_xt3wqam72hls6n5f3kcoh4zcy4: + resolution: {integrity: sha512-JtjIKkPVjEu8okGGCipCxNVgK/15h5AicTATZ6RbG2MsHmr4GfKG3fUCvpbuZseArqmLqGLQZQJjVE9vJzaSkQ==} + peerDependencies: + '@chakra-ui/system': 2.5.5 + framer-motion: '>=4.0.0' + react: '>=18' + react-dom: '>=18' + dependencies: + '@chakra-ui/alert': 2.1.0_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/close-button': 2.0.17_lze4h7kxffpjhokvtqbtrlfkmq + '@chakra-ui/portal': 2.0.16_biqbaboplfbrettd7655fr4n2y + '@chakra-ui/react-context': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-timeout': 2.0.5_react@18.2.0 + '@chakra-ui/react-use-update-effect': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/styled-system': 2.8.0 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + '@chakra-ui/theme': 3.0.1_wv7sq5bj4kx5i3evdevscgumbi + framer-motion: 10.10.0_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /@chakra-ui/tooltip/2.2.7_xt3wqam72hls6n5f3kcoh4zcy4: + resolution: {integrity: sha512-ImUJ6NnVqARaYqpgtO+kzucDRmxo8AF3jMjARw0bx2LxUkKwgRCOEaaRK5p5dHc0Kr6t5/XqjDeUNa19/sLauA==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + framer-motion: '>=4.0.0' + react: '>=18' + react-dom: '>=18' + dependencies: + '@chakra-ui/popper': 3.0.13_react@18.2.0 + '@chakra-ui/portal': 2.0.16_biqbaboplfbrettd7655fr4n2y + '@chakra-ui/react-types': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-disclosure': 2.0.8_react@18.2.0 + '@chakra-ui/react-use-event-listener': 2.0.7_react@18.2.0 + '@chakra-ui/react-use-merge-refs': 2.0.7_react@18.2.0 + '@chakra-ui/shared-utils': 2.0.5 + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + framer-motion: 10.10.0_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /@chakra-ui/transition/2.0.16_sma346mxzutnq53sdybs2rokta: + resolution: {integrity: sha512-E+RkwlPc3H7P1crEXmXwDXMB2lqY2LLia2P5siQ4IEnRWIgZXlIw+8Em+NtHNgusel2N+9yuB0wT9SeZZeZ3CQ==} + peerDependencies: + framer-motion: '>=4.0.0' + react: '>=18' + dependencies: + '@chakra-ui/shared-utils': 2.0.5 + framer-motion: 10.10.0_biqbaboplfbrettd7655fr4n2y + react: 18.2.0 + dev: false + + /@chakra-ui/utils/2.0.15: + resolution: {integrity: sha512-El4+jL0WSaYYs+rJbuYFDbjmfCcfGDmRY95GO4xwzit6YAPZBLcR65rOEwLps+XWluZTy1xdMrusg/hW0c1aAA==} + dependencies: + '@types/lodash.mergewith': 4.6.7 + css-box-model: 1.2.1 + framesync: 6.1.2 + lodash.mergewith: 4.6.2 + dev: false + + /@chakra-ui/visually-hidden/2.0.15_lze4h7kxffpjhokvtqbtrlfkmq: + resolution: {integrity: sha512-WWULIiucYRBIewHKFA7BssQ2ABLHLVd9lrUo3N3SZgR0u4ZRDDVEUNOy+r+9ruDze8+36dGbN9wsN1IdELtdOw==} + peerDependencies: + '@chakra-ui/system': '>=2.0.0' + react: '>=18' + dependencies: + '@chakra-ui/system': 2.5.5_xqp3pgpqjlfxxa3zxu4zoc4fba + react: 18.2.0 + dev: false + + /@emotion/babel-plugin/11.10.6: + resolution: {integrity: sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ==} + dependencies: + '@babel/helper-module-imports': 7.18.6 + '@babel/runtime': 7.20.6 + '@emotion/hash': 0.9.0 + '@emotion/memoize': 0.8.0 + '@emotion/serialize': 1.1.1 + babel-plugin-macros: 3.1.0 + convert-source-map: 1.9.0 + escape-string-regexp: 4.0.0 + find-root: 1.1.0 + source-map: 0.5.7 + stylis: 4.1.3 + dev: false + + /@emotion/cache/11.10.5: + resolution: {integrity: sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==} + dependencies: + '@emotion/memoize': 0.8.0 + '@emotion/sheet': 1.2.1 + '@emotion/utils': 1.2.0 + '@emotion/weak-memoize': 0.3.0 + stylis: 4.1.3 + dev: false + + /@emotion/hash/0.9.0: + resolution: {integrity: sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==} + dev: false + + /@emotion/is-prop-valid/0.8.8: + resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==} + requiresBuild: true + dependencies: + '@emotion/memoize': 0.7.4 + dev: false + optional: true + + /@emotion/is-prop-valid/1.2.0: + resolution: {integrity: sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==} + dependencies: + '@emotion/memoize': 0.8.0 + dev: false + + /@emotion/memoize/0.7.4: + resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==} + dev: false + optional: true + + /@emotion/memoize/0.8.0: + resolution: {integrity: sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==} + dev: false + + /@emotion/react/11.10.6_o2wclmlv6kymw75psj4clbbe6a: + resolution: {integrity: sha512-6HT8jBmcSkfzO7mc+N1L9uwvOnlcGoix8Zn7srt+9ga0MjREo6lRpuVX0kzo6Jp6oTqDhREOFsygN6Ew4fEQbw==} + peerDependencies: + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.20.6 + '@emotion/babel-plugin': 11.10.6 + '@emotion/cache': 11.10.5 + '@emotion/serialize': 1.1.1 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.0_react@18.2.0 + '@emotion/utils': 1.2.0 + '@emotion/weak-memoize': 0.3.0 + '@types/react': 18.0.31 + hoist-non-react-statics: 3.3.2 + react: 18.2.0 + dev: false + + /@emotion/serialize/1.1.1: + resolution: {integrity: sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==} + dependencies: + '@emotion/hash': 0.9.0 + '@emotion/memoize': 0.8.0 + '@emotion/unitless': 0.8.0 + '@emotion/utils': 1.2.0 + csstype: 3.1.1 + dev: false + + /@emotion/sheet/1.2.1: + resolution: {integrity: sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==} + dev: false + + /@emotion/styled/11.10.6_y3jktkphxddpitstssvkgnnxe4: + resolution: {integrity: sha512-OXtBzOmDSJo5Q0AFemHCfl+bUueT8BIcPSxu0EGTpGk6DmI5dnhSzQANm1e1ze0YZL7TDyAyy6s/b/zmGOS3Og==} + peerDependencies: + '@emotion/react': ^11.0.0-rc.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.20.6 + '@emotion/babel-plugin': 11.10.6 + '@emotion/is-prop-valid': 1.2.0 + '@emotion/react': 11.10.6_o2wclmlv6kymw75psj4clbbe6a + '@emotion/serialize': 1.1.1 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.0_react@18.2.0 + '@emotion/utils': 1.2.0 + '@types/react': 18.0.31 + react: 18.2.0 + dev: false + + /@emotion/unitless/0.8.0: + resolution: {integrity: sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==} + dev: false + + /@emotion/use-insertion-effect-with-fallbacks/1.0.0_react@18.2.0: + resolution: {integrity: sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 18.2.0 + dev: false + + /@emotion/utils/1.2.0: + resolution: {integrity: sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==} + dev: false + + /@emotion/weak-memoize/0.3.0: + resolution: {integrity: sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==} + dev: false + + /@esbuild/android-arm/0.17.14: + resolution: {integrity: sha512-0CnlwnjDU8cks0yJLXfkaU/uoLyRf9VZJs4p1PskBr2AlAHeEsFEwJEo0of/Z3g+ilw5mpyDwThlxzNEIxOE4g==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64/0.17.14: + resolution: {integrity: sha512-eLOpPO1RvtsP71afiFTvS7tVFShJBCT0txiv/xjFBo5a7R7Gjw7X0IgIaFoLKhqXYAXhahoXm7qAmRXhY4guJg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64/0.17.14: + resolution: {integrity: sha512-nrfQYWBfLGfSGLvRVlt6xi63B5IbfHm3tZCdu/82zuFPQ7zez4XjmRtF/wIRYbJQ/DsZrxJdEvYFE67avYXyng==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64/0.17.14: + resolution: {integrity: sha512-eoSjEuDsU1ROwgBH/c+fZzuSyJUVXQTOIN9xuLs9dE/9HbV/A5IqdXHU1p2OfIMwBwOYJ9SFVGGldxeRCUJFyw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64/0.17.14: + resolution: {integrity: sha512-zN0U8RWfrDttdFNkHqFYZtOH8hdi22z0pFm0aIJPsNC4QQZv7je8DWCX5iA4Zx6tRhS0CCc0XC2m7wKsbWEo5g==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64/0.17.14: + resolution: {integrity: sha512-z0VcD4ibeZWVQCW1O7szaLxGsx54gcCnajEJMdYoYjLiq4g1jrP2lMq6pk71dbS5+7op/L2Aod+erw+EUr28/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64/0.17.14: + resolution: {integrity: sha512-hd9mPcxfTgJlolrPlcXkQk9BMwNBvNBsVaUe5eNUqXut6weDQH8whcNaKNF2RO8NbpT6GY8rHOK2A9y++s+ehw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm/0.17.14: + resolution: {integrity: sha512-BNTl+wSJ1omsH8s3TkQmIIIQHwvwJrU9u1ggb9XU2KTVM4TmthRIVyxSp2qxROJHhZuW/r8fht46/QE8hU8Qvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64/0.17.14: + resolution: {integrity: sha512-FhAMNYOq3Iblcj9i+K0l1Fp/MHt+zBeRu/Qkf0LtrcFu3T45jcwB6A1iMsemQ42vR3GBhjNZJZTaCe3VFPbn9g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32/0.17.14: + resolution: {integrity: sha512-91OK/lQ5y2v7AsmnFT+0EyxdPTNhov3y2CWMdizyMfxSxRqHazXdzgBKtlmkU2KYIc+9ZK3Vwp2KyXogEATYxQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64/0.17.14: + resolution: {integrity: sha512-vp15H+5NR6hubNgMluqqKza85HcGJgq7t6rMH7O3Y6ApiOWPkvW2AJfNojUQimfTp6OUrACUXfR4hmpcENXoMQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el/0.17.14: + resolution: {integrity: sha512-90TOdFV7N+fgi6c2+GO9ochEkmm9kBAKnuD5e08GQMgMINOdOFHuYLPQ91RYVrnWwQ5683sJKuLi9l4SsbJ7Hg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64/0.17.14: + resolution: {integrity: sha512-NnBGeoqKkTugpBOBZZoktQQ1Yqb7aHKmHxsw43NddPB2YWLAlpb7THZIzsRsTr0Xw3nqiPxbA1H31ZMOG+VVPQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64/0.17.14: + resolution: {integrity: sha512-0qdlKScLXA8MGVy21JUKvMzCYWovctuP8KKqhtE5A6IVPq4onxXhSuhwDd2g5sRCzNDlDjitc5sX31BzDoL5Fw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x/0.17.14: + resolution: {integrity: sha512-Hdm2Jo1yaaOro4v3+6/zJk6ygCqIZuSDJHdHaf8nVH/tfOuoEX5Riv03Ka15LmQBYJObUTNS1UdyoMk0WUn9Ww==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64/0.17.14: + resolution: {integrity: sha512-8KHF17OstlK4DuzeF/KmSgzrTWQrkWj5boluiiq7kvJCiQVzUrmSkaBvcLB2UgHpKENO2i6BthPkmUhNDaJsVw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64/0.17.14: + resolution: {integrity: sha512-nVwpqvb3yyXztxIT2+VsxJhB5GCgzPdk1n0HHSnchRAcxqKO6ghXwHhJnr0j/B+5FSyEqSxF4q03rbA2fKXtUQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64/0.17.14: + resolution: {integrity: sha512-1RZ7uQQ9zcy/GSAJL1xPdN7NDdOOtNEGiJalg/MOzeakZeTrgH/DoCkbq7TaPDiPhWqnDF+4bnydxRqQD7il6g==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64/0.17.14: + resolution: {integrity: sha512-nqMjDsFwv7vp7msrwWRysnM38Sd44PKmW8EzV01YzDBTcTWUpczQg6mGao9VLicXSgW/iookNK6AxeogNVNDZA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64/0.17.14: + resolution: {integrity: sha512-xrD0mccTKRBBIotrITV7WVQAwNJ5+1va6L0H9zN92v2yEdjfAN7864cUaZwJS7JPEs53bDTzKFbfqVlG2HhyKQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32/0.17.14: + resolution: {integrity: sha512-nXpkz9bbJrLLyUTYtRotSS3t5b+FOuljg8LgLdINWFs3FfqZMtbnBCZFUmBzQPyxqU87F8Av+3Nco/M3hEcu1w==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64/0.17.14: + resolution: {integrity: sha512-gPQmsi2DKTaEgG14hc3CHXHp62k8g6qr0Pas+I4lUxRMugGSATh/Bi8Dgusoz9IQ0IfdrvLpco6kujEIBoaogA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint-community/eslint-utils/4.4.0_eslint@8.37.0: + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.37.0 + eslint-visitor-keys: 3.4.0 + dev: true + + /@eslint-community/regexpp/4.5.0: + resolution: {integrity: sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc/2.0.2: + resolution: {integrity: sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.5.1 + globals: 13.19.0 + ignore: 5.2.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js/8.37.0: + resolution: {integrity: sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@floating-ui/core/0.6.2: + resolution: {integrity: sha512-jktYRmZwmau63adUG3GKOAVCofBXkk55S/zQ94XOorAHhwqFIOFAy1rSp2N0Wp6/tGbe9V3u/ExlGZypyY17rg==} + dev: true + + /@floating-ui/dom/0.4.5: + resolution: {integrity: sha512-b+prvQgJt8pieaKYMSJBXHxX/DYwdLsAWxKYqnO5dO2V4oo/TYBZJAUQCVNjTWWsrs6o4VDrNcP9+E70HAhJdw==} + dependencies: + '@floating-ui/core': 0.6.2 + dev: true + + /@floating-ui/react-dom-interactions/0.3.1_6ayuu6vm2uqggsikytom4xssc4: + resolution: {integrity: sha512-tP2KEh7EHJr5hokSBHcPGojb+AorDNUf0NYfZGg/M+FsMvCOOsSEeEF0O1NDfETIzDnpbHnCs0DuvCFhSMSStg==} + dependencies: + '@floating-ui/react-dom': 0.6.3_6ayuu6vm2uqggsikytom4xssc4 + aria-hidden: 1.2.2_o2wclmlv6kymw75psj4clbbe6a + point-in-polygon: 1.1.0 + use-isomorphic-layout-effect: 1.1.2_o2wclmlv6kymw75psj4clbbe6a + transitivePeerDependencies: + - '@types/react' + - react + - react-dom + dev: true + + /@floating-ui/react-dom/0.6.3_6ayuu6vm2uqggsikytom4xssc4: + resolution: {integrity: sha512-hC+pS5D6AgS2wWjbmSQ6UR6Kpy+drvWGJIri6e1EDGADTPsCaa4KzCgmCczHrQeInx9tqs81EyDmbKJYY2swKg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/dom': 0.4.5 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + use-isomorphic-layout-effect: 1.1.2_o2wclmlv6kymw75psj4clbbe6a + transitivePeerDependencies: + - '@types/react' + dev: true + + /@humanwhocodes/config-array/0.11.8: + resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer/1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema/1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@jridgewell/gen-mapping/0.1.1: + resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@jridgewell/gen-mapping/0.3.2: + resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/trace-mapping': 0.3.17 + dev: true + + /@jridgewell/resolve-uri/3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array/1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec/1.4.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + dev: true + + /@jridgewell/trace-mapping/0.3.17: + resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@nicolo-ribaudo/eslint-scope-5-internals/5.1.1-v1: + resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} + dependencies: + eslint-scope: 5.1.1 + dev: true + + /@nodelib/fs.scandir/2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat/2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk/1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.14.0 + dev: true + + /@popperjs/core/2.11.6: + resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==} + + /@remix-run/router/1.5.0: + resolution: {integrity: sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==} + engines: {node: '>=14'} + dev: false + + /@rushstack/eslint-patch/1.2.0: + resolution: {integrity: sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==} + dev: true + + /@swc/core-darwin-arm64/1.3.38: + resolution: {integrity: sha512-4ZTJJ/cR0EsXW5UxFCifZoGfzQ07a8s4ayt1nLvLQ5QoB1GTAf9zsACpvWG8e7cmCR0L76R5xt8uJuyr+noIXA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@swc/core-darwin-x64/1.3.38: + resolution: {integrity: sha512-Kim727rNo4Dl8kk0CR8aJQe4zFFtsT1TZGlNrNMUgN1WC3CRX7dLZ6ZJi/VVcTG1cbHp5Fp3mUzwHsMxEh87Mg==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-arm-gnueabihf/1.3.38: + resolution: {integrity: sha512-yaRdnPNU2enlJDRcIMvYVSyodY+Amhf5QuXdUbAj6rkDD6wUs/s9C6yPYrFDmoTltrG+nBv72mUZj+R46wVfSw==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-arm64-gnu/1.3.38: + resolution: {integrity: sha512-iNY1HqKo/wBSu3QOGBUlZaLdBP/EHcwNjBAqIzpb8J64q2jEN02RizqVW0mDxyXktJ3lxr3g7VW9uqklMeXbjQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-arm64-musl/1.3.38: + resolution: {integrity: sha512-LJCFgLZoPRkPCPmux+Q5ctgXRp6AsWhvWuY61bh5bIPBDlaG9pZk94DeHyvtiwT0syhTtXb2LieBOx6NqN3zeA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-x64-gnu/1.3.38: + resolution: {integrity: sha512-hRQGRIWHmv2PvKQM/mMV45mVXckM2+xLB8TYLLgUG66mmtyGTUJPyxjnJkbI86WNGqo18k+lAuMG2mn6QmzYwQ==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-linux-x64-musl/1.3.38: + resolution: {integrity: sha512-PTYSqtsIfPHLKDDNbueI5e0sc130vyHRiFOeeC6qqzA2FAiVvIxuvXHLr0soPvKAR1WyhtYmFB9QarcctemL2w==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@swc/core-win32-arm64-msvc/1.3.38: + resolution: {integrity: sha512-9lHfs5TPNs+QdkyZFhZledSmzBEbqml/J1rqPSb9Fy8zB6QlspixE6OLZ3nTlUOdoGWkcTTdrOn77Sd7YGf1AA==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@swc/core-win32-ia32-msvc/1.3.38: + resolution: {integrity: sha512-SbL6pfA2lqvDKnwTHwOfKWvfHAdcbAwJS4dBkFidr7BiPTgI5Uk8wAPcRb8mBECpmIa9yFo+N0cAFRvMnf+cNw==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@swc/core-win32-x64-msvc/1.3.38: + resolution: {integrity: sha512-UFveLrL6eGvViOD8OVqUQa6QoQwdqwRvLtL5elF304OT8eCPZa8BhuXnWk25X8UcOyns8gFcb8Fhp3oaLi/Rlw==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@swc/core/1.3.38: + resolution: {integrity: sha512-AiEVehRFws//AiiLx9DPDp1WDXt+yAoGD1kMYewhoF6QLdTz8AtYu6i8j/yAxk26L8xnegy0CDwcNnub9qenyQ==} + engines: {node: '>=10'} + requiresBuild: true + optionalDependencies: + '@swc/core-darwin-arm64': 1.3.38 + '@swc/core-darwin-x64': 1.3.38 + '@swc/core-linux-arm-gnueabihf': 1.3.38 + '@swc/core-linux-arm64-gnu': 1.3.38 + '@swc/core-linux-arm64-musl': 1.3.38 + '@swc/core-linux-x64-gnu': 1.3.38 + '@swc/core-linux-x64-musl': 1.3.38 + '@swc/core-win32-arm64-msvc': 1.3.38 + '@swc/core-win32-ia32-msvc': 1.3.38 + '@swc/core-win32-x64-msvc': 1.3.38 + dev: true + + /@tanstack/query-core/4.27.0: + resolution: {integrity: sha512-sm+QncWaPmM73IPwFlmWSKPqjdTXZeFf/7aEmWh00z7yl2FjqophPt0dE1EHW9P1giMC5rMviv7OUbSDmWzXXA==} + dev: false + + /@tanstack/react-query/4.28.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-8cGBV5300RHlvYdS4ea+G1JcZIt5CIuprXYFnsWggkmGoC0b5JaqG0fIX3qwDL9PTNkKvG76NGThIWbpXivMrQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + dependencies: + '@tanstack/query-core': 4.27.0 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + use-sync-external-store: 1.2.0_react@18.2.0 + dev: false + + /@types/hast/2.3.4: + resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==} + dependencies: + '@types/unist': 2.0.6 + dev: false + + /@types/json-schema/7.0.11: + resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} + dev: true + + /@types/json5/0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/lodash.mergewith/4.6.7: + resolution: {integrity: sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A==} + dependencies: + '@types/lodash': 4.14.192 + dev: false + + /@types/lodash/4.14.192: + resolution: {integrity: sha512-km+Vyn3BYm5ytMO13k9KTp27O75rbQ0NFw+U//g+PX7VZyjCioXaRFisqSIJRECljcTv73G3i6BpglNGHgUQ5A==} + + /@types/node/18.15.11: + resolution: {integrity: sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==} + dev: true + + /@types/parse-json/4.0.0: + resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + + /@types/prop-types/15.7.5: + resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + + /@types/react-datepicker/4.10.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-Cq+ks20vBIU6XN67TbkCHu8M7V46Y6vJrKE2n+8q/GfueJyWWTIKeC3Z7cz/d+qxGDq/VCrqA929R0U4lNuztg==} + dependencies: + '@popperjs/core': 2.11.6 + '@types/react': 18.0.31 + date-fns: 2.29.3 + react-popper: 2.3.0_r6q5zrenym2zg7je7hgi674bti + transitivePeerDependencies: + - react + - react-dom + dev: true + + /@types/react-dom/18.0.11: + resolution: {integrity: sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==} + dependencies: + '@types/react': 18.0.31 + dev: true + + /@types/react-syntax-highlighter/15.5.6: + resolution: {integrity: sha512-i7wFuLbIAFlabTeD2I1cLjEOrG/xdMa/rpx2zwzAoGHuXJDhSqp9BSfDlMHSh9JSuNfxHk9eEmMX6D55GiyjGg==} + dependencies: + '@types/react': 18.0.31 + dev: true + + /@types/react/18.0.31: + resolution: {integrity: sha512-EEG67of7DsvRDU6BLLI0p+k1GojDLz9+lZsnCpCRTa/lOokvyPBvp8S5x+A24hME3yyQuIipcP70KJ6H7Qupww==} + dependencies: + '@types/prop-types': 15.7.5 + '@types/scheduler': 0.16.2 + csstype: 3.1.1 + + /@types/scheduler/0.16.2: + resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} + + /@types/semver/7.3.13: + resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} + dev: true + + /@types/unist/2.0.6: + resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} + dev: false + + /@typescript-eslint/eslint-plugin/5.47.0_25x3lcrqkz4tgviwremcxnykiy: + resolution: {integrity: sha512-AHZtlXAMGkDmyLuLZsRpH3p4G/1iARIwc/T0vIem2YB+xW6pZaXYXzCBnZSF/5fdM97R9QqZWZ+h3iW10XgevQ==} + 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 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/parser': 5.47.0_vwh6htx42aidho2qgfca5u5rwm + '@typescript-eslint/scope-manager': 5.47.0 + '@typescript-eslint/type-utils': 5.47.0_vwh6htx42aidho2qgfca5u5rwm + '@typescript-eslint/utils': 5.47.0_vwh6htx42aidho2qgfca5u5rwm + debug: 4.3.4 + eslint: 8.37.0 + ignore: 5.2.1 + natural-compare-lite: 1.4.0 + regexpp: 3.2.0 + semver: 7.3.8 + tsutils: 3.21.0_typescript@5.0.3 + typescript: 5.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/experimental-utils/5.47.0_vwh6htx42aidho2qgfca5u5rwm: + resolution: {integrity: sha512-DAP8xOaTAJLxouU0QrATiw8o/OHxxbUBXtkf9v+bCCU6tbJUn24xwB1dHFw3b5wYq4XvC1z5lYEN0g/Rx1sjzA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@typescript-eslint/utils': 5.47.0_vwh6htx42aidho2qgfca5u5rwm + eslint: 8.37.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/parser/5.47.0_vwh6htx42aidho2qgfca5u5rwm: + resolution: {integrity: sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 5.47.0 + '@typescript-eslint/types': 5.47.0 + '@typescript-eslint/typescript-estree': 5.47.0_typescript@5.0.3 + debug: 4.3.4 + eslint: 8.37.0 + typescript: 5.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager/5.47.0: + resolution: {integrity: sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.47.0 + '@typescript-eslint/visitor-keys': 5.47.0 + dev: true + + /@typescript-eslint/type-utils/5.47.0_vwh6htx42aidho2qgfca5u5rwm: + resolution: {integrity: sha512-1J+DFFrYoDUXQE1b7QjrNGARZE6uVhBqIvdaXTe5IN+NmEyD68qXR1qX1g2u4voA+nCaelQyG8w30SAOihhEYg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 5.47.0_typescript@5.0.3 + '@typescript-eslint/utils': 5.47.0_vwh6htx42aidho2qgfca5u5rwm + debug: 4.3.4 + eslint: 8.37.0 + tsutils: 3.21.0_typescript@5.0.3 + typescript: 5.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types/5.47.0: + resolution: {integrity: sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@typescript-eslint/typescript-estree/5.47.0_typescript@5.0.3: + resolution: {integrity: sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.47.0 + '@typescript-eslint/visitor-keys': 5.47.0 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.3.8 + tsutils: 3.21.0_typescript@5.0.3 + typescript: 5.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils/5.47.0_vwh6htx42aidho2qgfca5u5rwm: + resolution: {integrity: sha512-U9xcc0N7xINrCdGVPwABjbAKqx4GK67xuMV87toI+HUqgXj26m6RBp9UshEXcTrgCkdGYFzgKLt8kxu49RilDw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@types/json-schema': 7.0.11 + '@types/semver': 7.3.13 + '@typescript-eslint/scope-manager': 5.47.0 + '@typescript-eslint/types': 5.47.0 + '@typescript-eslint/typescript-estree': 5.47.0_typescript@5.0.3 + eslint: 8.37.0 + eslint-scope: 5.1.1 + eslint-utils: 3.0.0_eslint@8.37.0 + semver: 7.3.8 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys/5.47.0: + resolution: {integrity: sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.47.0 + eslint-visitor-keys: 3.3.0 + dev: true + + /@vitejs/plugin-react-swc/3.2.0_vite@4.2.1: + resolution: {integrity: sha512-IcBoXL/mcH7JdQr/nfDlDwTdIaH8Rg7LpfQDF4nAht+juHWIuv6WhpKPCSfY4+zztAaB07qdBoFz1XCZsgo3pQ==} + peerDependencies: + vite: ^4 + dependencies: + '@swc/core': 1.3.38 + vite: 4.2.1_hghbulspu73jfdazs4i6yiqype + dev: true + + /@zag-js/element-size/0.3.2: + resolution: {integrity: sha512-bVvvigUGvAuj7PCkE5AbzvTJDTw5f3bg9nQdv+ErhVN8SfPPppLJEmmWdxqsRzrHXgx8ypJt/+Ty0kjtISVDsQ==} + dev: false + + /@zag-js/focus-visible/0.2.2: + resolution: {integrity: sha512-0j2gZq8HiZ51z4zNnSkF1iSkqlwRDvdH+son3wHdoz+7IUdMN/5Exd4TxMJ+gq2Of1DiXReYLL9qqh2PdQ4wgA==} + dev: false + + /acorn-jsx/5.3.2_acorn@8.8.1: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.8.1 + dev: true + + /acorn/8.8.1: + resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /aggregate-error/3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + + /ajv/6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ansi-escapes/4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + + /ansi-regex/5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-regex/6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: true + + /ansi-styles/3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + + /ansi-styles/4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles/6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + + /any-promise/1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + dev: true + + /anymatch/3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + /arg/5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + dev: true + + /argparse/2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /aria-hidden/1.2.2_o2wclmlv6kymw75psj4clbbe6a: + resolution: {integrity: sha512-6y/ogyDTk/7YAe91T3E2PR1ALVKyM2QbTio5HwM+N1Q6CMlCKhvClyIjkckBswa0f2xJhjsfzIGa1yVSe1UMVA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.9.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.0.31 + react: 18.2.0 + tslib: 2.4.1 + + /aria-query/4.2.2: + resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==} + engines: {node: '>=6.0'} + dependencies: + '@babel/runtime': 7.20.6 + '@babel/runtime-corejs3': 7.20.6 + dev: true + + /array-includes/3.1.6: + resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.5 + get-intrinsic: 1.1.3 + is-string: 1.0.7 + dev: true + + /array-union/2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /array.prototype.flat/1.3.1: + resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.5 + es-shim-unscopables: 1.0.0 + dev: true + + /array.prototype.flatmap/1.3.1: + resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.5 + es-shim-unscopables: 1.0.0 + dev: true + + /array.prototype.tosorted/1.1.1: + resolution: {integrity: sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.5 + es-shim-unscopables: 1.0.0 + get-intrinsic: 1.1.3 + dev: true + + /ast-types-flow/0.0.7: + resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==} + dev: true + + /astral-regex/2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + dev: true + + /asynckit/0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /autoprefixer/10.4.14_postcss@8.4.21: + resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.21.5 + caniuse-lite: 1.0.30001473 + fraction.js: 4.2.0 + normalize-range: 0.1.2 + picocolors: 1.0.0 + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + dev: true + + /axe-core/4.6.1: + resolution: {integrity: sha512-lCZN5XRuOnpG4bpMq8v0khrWtUOn+i8lZSb6wHZH56ZfbIEv6XwJV84AAueh9/zi7qPVJ/E4yz6fmsiyOmXR4w==} + engines: {node: '>=4'} + dev: true + + /axios/0.21.4: + resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} + dependencies: + follow-redirects: 1.15.2 + transitivePeerDependencies: + - debug + dev: false + + /axios/1.3.4: + resolution: {integrity: sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==} + dependencies: + follow-redirects: 1.15.2 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /axobject-query/2.2.0: + resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==} + dev: true + + /babel-plugin-macros/3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + dependencies: + '@babel/runtime': 7.20.6 + cosmiconfig: 7.1.0 + resolve: 1.22.1 + + /babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.20.5: + resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.5 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs3/0.6.0_@babel+core@7.20.5: + resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.5 + core-js-compat: 3.26.1 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-regenerator/0.4.1_@babel+core@7.20.5: + resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-transform-react-remove-prop-types/0.4.24: + resolution: {integrity: sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==} + dev: true + + /babel-preset-react-app/10.0.1: + resolution: {integrity: sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==} + dependencies: + '@babel/core': 7.20.5 + '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-decorators': 7.20.5_@babel+core@7.20.5 + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-optional-chaining': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-private-property-in-object': 7.20.5_@babel+core@7.20.5 + '@babel/plugin-transform-flow-strip-types': 7.19.0_@babel+core@7.20.5 + '@babel/plugin-transform-react-display-name': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-runtime': 7.19.6_@babel+core@7.20.5 + '@babel/preset-env': 7.20.2_@babel+core@7.20.5 + '@babel/preset-react': 7.18.6_@babel+core@7.20.5 + '@babel/preset-typescript': 7.18.6_@babel+core@7.20.5 + '@babel/runtime': 7.20.6 + babel-plugin-macros: 3.1.0 + babel-plugin-transform-react-remove-prop-types: 0.4.24 + transitivePeerDependencies: + - supports-color + dev: true + + /balanced-match/1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base64-js/1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /binary-extensions/2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + + /brace-expansion/1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces/3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + + /browserslist/4.21.4: + resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001439 + electron-to-chromium: 1.4.284 + node-releases: 2.0.6 + update-browserslist-db: 1.0.10_browserslist@4.21.4 + dev: true + + /browserslist/4.21.5: + resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001473 + electron-to-chromium: 1.4.284 + node-releases: 2.0.10 + update-browserslist-db: 1.0.10_browserslist@4.21.5 + dev: true + + /bson/4.7.0: + resolution: {integrity: sha512-VrlEE4vuiO1WTpfof4VmaVolCVYkYTgB9iWgYNOrVlnifpME/06fhFRmONgBhClD5pFC1t9ZWqFUQEQAzY43bA==} + engines: {node: '>=6.9.0'} + dependencies: + buffer: 5.7.1 + dev: false + + /buffer/5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + + /call-bind/1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.1.3 + dev: true + + /callsites/3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + /camelcase-css/2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + dev: true + + /caniuse-lite/1.0.30001439: + resolution: {integrity: sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==} + dev: true + + /caniuse-lite/1.0.30001473: + resolution: {integrity: sha512-ewDad7+D2vlyy+E4UJuVfiBsU69IL+8oVmTuZnH5Q6CIUbxNfI50uVpRHbUPDD6SUaN2o0Lh4DhTrvLG/Tn1yg==} + dev: true + + /chalk/2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + /chalk/4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chalk/5.2.0: + resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true + + /character-entities-legacy/1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + dev: false + + /character-entities/1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + dev: false + + /character-reference-invalid/1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + dev: false + + /chokidar/3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + + /classnames/2.3.2: + resolution: {integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==} + dev: false + + /clean-stack/2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: true + + /cli-cursor/3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: true + + /cli-truncate/2.1.0: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} + engines: {node: '>=8'} + dependencies: + slice-ansi: 3.0.0 + string-width: 4.2.3 + dev: true + + /cli-truncate/3.1.0: + resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + slice-ansi: 5.0.0 + string-width: 5.1.2 + dev: true + + /click-to-react-component/1.0.8_6ayuu6vm2uqggsikytom4xssc4: + resolution: {integrity: sha512-YBNYOp00udy+NBEnUmM/3Df0Yco1iHNQ8k0ltlJVcDYK9AuYt14xPoJicBh/BokLqbzkci1p+pbdY5r4JXZC4g==} + peerDependencies: + react: '>=16.8.0' + dependencies: + '@floating-ui/react-dom-interactions': 0.3.1_6ayuu6vm2uqggsikytom4xssc4 + htm: 3.1.1 + react: 18.2.0 + react-merge-refs: 1.1.0 + transitivePeerDependencies: + - '@types/react' + - react-dom + dev: true + + /clsx/1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} + dev: false + + /color-convert/1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + + /color-convert/2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name/1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + /color-name/1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /color2k/2.0.0: + resolution: {integrity: sha512-DWX9eXOC4fbJNiuvdH4QSHvvfLWyFo9TuFp7V9OzdsbPAdrWAuYc8qvFP2bIQ/LKh4LrAVnJ6vhiQYPvAHdtTg==} + dev: false + + /colorette/2.0.19: + resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} + dev: true + + /combined-stream/1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /comma-separated-tokens/1.0.8: + resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} + dev: false + + /commander/10.0.0: + resolution: {integrity: sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==} + engines: {node: '>=14'} + dev: true + + /commander/4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + dev: true + + /compute-scroll-into-view/1.0.20: + resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==} + dev: false + + /concat-map/0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /confusing-browser-globals/1.0.11: + resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + dev: true + + /convert-source-map/1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + /copy-to-clipboard/3.3.3: + resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + dependencies: + toggle-selection: 1.0.6 + dev: false + + /core-js-compat/3.26.1: + resolution: {integrity: sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==} + dependencies: + browserslist: 4.21.4 + dev: true + + /core-js-pure/3.26.1: + resolution: {integrity: sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==} + requiresBuild: true + dev: true + + /cosmiconfig/7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + dependencies: + '@types/parse-json': 4.0.0 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + + /cross-fetch/3.1.5: + resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} + dependencies: + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + dev: false + + /cross-spawn/7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /css-box-model/1.2.1: + resolution: {integrity: sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==} + dependencies: + tiny-invariant: 1.3.1 + dev: false + + /cssesc/3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /csstype/3.1.1: + resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} + + /damerau-levenshtein/1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + dev: true + + /database-ql/1.0.0-beta.2: + resolution: {integrity: sha512-3q1ttPwaOdaOpG8BiKZOs6Jr8g9cxCM4hBbmFP1VOwijAcXNsbEj04dB6WJjX+THFxa3VFSxvReGC0TfHFxo5g==} + dependencies: + bson: 4.7.0 + lodash.clonedeep: 4.5.0 + lodash.set: 4.3.2 + lodash.unset: 4.5.2 + dev: false + + /date-fns/2.29.3: + resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==} + engines: {node: '>=0.11'} + + /dayjs/1.11.7: + resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==} + dev: false + + /debug/2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + + /debug/3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /debug/4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /deep-is/0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /define-properties/1.1.4: + resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} + engines: {node: '>= 0.4'} + dependencies: + has-property-descriptors: 1.0.0 + object-keys: 1.1.1 + dev: true + + /delayed-stream/1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /detect-node-es/1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + dev: false + + /didyoumean/1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + dev: true + + /dir-glob/3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /dlv/1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dev: true + + /doctrine/2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine/3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /eastasianwidth/0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true + + /electron-to-chromium/1.4.284: + resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} + dev: true + + /emoji-regex/8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /emoji-regex/9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + + /error-ex/1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + + /es-abstract/1.20.5: + resolution: {integrity: sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + es-to-primitive: 1.2.1 + function-bind: 1.1.1 + function.prototype.name: 1.1.5 + get-intrinsic: 1.1.3 + get-symbol-description: 1.0.0 + gopd: 1.0.1 + has: 1.0.3 + has-property-descriptors: 1.0.0 + has-symbols: 1.0.3 + internal-slot: 1.0.4 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-weakref: 1.0.2 + object-inspect: 1.12.2 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.4.3 + safe-regex-test: 1.0.0 + string.prototype.trimend: 1.0.6 + string.prototype.trimstart: 1.0.6 + unbox-primitive: 1.0.2 + dev: true + + /es-shim-unscopables/1.0.0: + resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + dependencies: + has: 1.0.3 + dev: true + + /es-to-primitive/1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /esbuild/0.17.14: + resolution: {integrity: sha512-vOO5XhmVj/1XQR9NQ1UPq6qvMYL7QFJU57J5fKBKBKxp17uDt5PgxFDb4A2nEiXhr1qQs4x0F5+66hVVw4ruNw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.14 + '@esbuild/android-arm64': 0.17.14 + '@esbuild/android-x64': 0.17.14 + '@esbuild/darwin-arm64': 0.17.14 + '@esbuild/darwin-x64': 0.17.14 + '@esbuild/freebsd-arm64': 0.17.14 + '@esbuild/freebsd-x64': 0.17.14 + '@esbuild/linux-arm': 0.17.14 + '@esbuild/linux-arm64': 0.17.14 + '@esbuild/linux-ia32': 0.17.14 + '@esbuild/linux-loong64': 0.17.14 + '@esbuild/linux-mips64el': 0.17.14 + '@esbuild/linux-ppc64': 0.17.14 + '@esbuild/linux-riscv64': 0.17.14 + '@esbuild/linux-s390x': 0.17.14 + '@esbuild/linux-x64': 0.17.14 + '@esbuild/netbsd-x64': 0.17.14 + '@esbuild/openbsd-x64': 0.17.14 + '@esbuild/sunos-x64': 0.17.14 + '@esbuild/win32-arm64': 0.17.14 + '@esbuild/win32-ia32': 0.17.14 + '@esbuild/win32-x64': 0.17.14 + dev: true + + /escalade/3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp/1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + /escape-string-regexp/4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + /eslint-config-react-app/7.0.1_vwh6htx42aidho2qgfca5u5rwm: + resolution: {integrity: sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==} + engines: {node: '>=14.0.0'} + peerDependencies: + eslint: ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@babel/core': 7.20.5 + '@babel/eslint-parser': 7.19.1_nlidl7rzdmevvywe7nf3sd6qkm + '@rushstack/eslint-patch': 1.2.0 + '@typescript-eslint/eslint-plugin': 5.47.0_25x3lcrqkz4tgviwremcxnykiy + '@typescript-eslint/parser': 5.47.0_vwh6htx42aidho2qgfca5u5rwm + babel-preset-react-app: 10.0.1 + confusing-browser-globals: 1.0.11 + eslint: 8.37.0 + eslint-plugin-flowtype: 8.0.3_eslint@8.37.0 + eslint-plugin-import: 2.26.0_qg6g2dgq65lf4zcb24aeavdmie + eslint-plugin-jest: 25.7.0_aghi6vfqkgyv45z7jl6cvaq7de + eslint-plugin-jsx-a11y: 6.6.1_eslint@8.37.0 + eslint-plugin-react: 7.31.11_eslint@8.37.0 + eslint-plugin-react-hooks: 4.6.0_eslint@8.37.0 + eslint-plugin-testing-library: 5.9.1_vwh6htx42aidho2qgfca5u5rwm + typescript: 5.0.3 + transitivePeerDependencies: + - '@babel/plugin-syntax-flow' + - '@babel/plugin-transform-react-jsx' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - jest + - supports-color + dev: true + + /eslint-import-resolver-node/0.3.6: + resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==} + dependencies: + debug: 3.2.7 + resolve: 1.22.1 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils/2.7.4_jjcqdxkc7n2r3vdnrbf5rdq2ki: + resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 5.47.0_vwh6htx42aidho2qgfca5u5rwm + debug: 3.2.7 + eslint: 8.37.0 + eslint-import-resolver-node: 0.3.6 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-flowtype/8.0.3_eslint@8.37.0: + resolution: {integrity: sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==} + 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 + dependencies: + eslint: 8.37.0 + lodash: 4.17.21 + string-natural-compare: 3.0.1 + dev: true + + /eslint-plugin-import/2.26.0_qg6g2dgq65lf4zcb24aeavdmie: + resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 5.47.0_vwh6htx42aidho2qgfca5u5rwm + array-includes: 3.1.6 + array.prototype.flat: 1.3.1 + debug: 2.6.9 + doctrine: 2.1.0 + eslint: 8.37.0 + eslint-import-resolver-node: 0.3.6 + eslint-module-utils: 2.7.4_jjcqdxkc7n2r3vdnrbf5rdq2ki + has: 1.0.3 + is-core-module: 2.11.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.values: 1.1.6 + resolve: 1.22.1 + tsconfig-paths: 3.14.1 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-jest/25.7.0_aghi6vfqkgyv45z7jl6cvaq7de: + resolution: {integrity: sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==} + 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 + jest: '*' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + jest: + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 5.47.0_25x3lcrqkz4tgviwremcxnykiy + '@typescript-eslint/experimental-utils': 5.47.0_vwh6htx42aidho2qgfca5u5rwm + eslint: 8.37.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-plugin-jsx-a11y/6.6.1_eslint@8.37.0: + resolution: {integrity: sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + '@babel/runtime': 7.20.6 + aria-query: 4.2.2 + array-includes: 3.1.6 + ast-types-flow: 0.0.7 + axe-core: 4.6.1 + axobject-query: 2.2.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 8.37.0 + has: 1.0.3 + jsx-ast-utils: 3.3.3 + language-tags: 1.0.7 + minimatch: 3.1.2 + semver: 6.3.0 + dev: true + + /eslint-plugin-react-hooks/4.6.0_eslint@8.37.0: + resolution: {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 + dependencies: + eslint: 8.37.0 + dev: true + + /eslint-plugin-react/7.31.11_eslint@8.37.0: + resolution: {integrity: sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + array-includes: 3.1.6 + array.prototype.flatmap: 1.3.1 + array.prototype.tosorted: 1.1.1 + doctrine: 2.1.0 + eslint: 8.37.0 + estraverse: 5.3.0 + jsx-ast-utils: 3.3.3 + minimatch: 3.1.2 + object.entries: 1.1.6 + object.fromentries: 2.0.6 + object.hasown: 1.1.2 + object.values: 1.1.6 + prop-types: 15.8.1 + resolve: 2.0.0-next.4 + semver: 6.3.0 + string.prototype.matchall: 4.0.8 + dev: true + + /eslint-plugin-simple-import-sort/10.0.0_eslint@8.37.0: + resolution: {integrity: sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==} + peerDependencies: + eslint: '>=5.0.0' + dependencies: + eslint: 8.37.0 + dev: true + + /eslint-plugin-testing-library/5.9.1_vwh6htx42aidho2qgfca5u5rwm: + resolution: {integrity: sha512-6BQp3tmb79jLLasPHJmy8DnxREe+2Pgf7L+7o09TSWPfdqqtQfRZmZNetr5mOs3yqZk/MRNxpN3RUpJe0wB4LQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6'} + peerDependencies: + eslint: ^7.5.0 || ^8.0.0 + dependencies: + '@typescript-eslint/utils': 5.47.0_vwh6htx42aidho2qgfca5u5rwm + eslint: 8.37.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-scope/5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + + /eslint-scope/7.1.1: + resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-utils/3.0.0_eslint@8.37.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 8.37.0 + eslint-visitor-keys: 2.1.0 + dev: true + + /eslint-visitor-keys/2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + dev: true + + /eslint-visitor-keys/3.3.0: + resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint-visitor-keys/3.4.0: + resolution: {integrity: sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint/8.37.0: + resolution: {integrity: sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0_eslint@8.37.0 + '@eslint-community/regexpp': 4.5.0 + '@eslint/eslintrc': 2.0.2 + '@eslint/js': 8.37.0 + '@humanwhocodes/config-array': 0.11.8 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.1.1 + eslint-visitor-keys: 3.4.0 + espree: 9.5.1 + esquery: 1.5.0 + esutils: 2.0.3 + 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 + grapheme-splitter: 1.0.4 + ignore: 5.2.1 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-sdsl: 4.2.0 + 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.1 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree/9.5.1: + resolution: {integrity: sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.8.1 + acorn-jsx: 5.3.2_acorn@8.8.1 + eslint-visitor-keys: 3.4.0 + dev: true + + /esquery/1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse/4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse/4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse/5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /esutils/2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /execa/7.1.1: + resolution: {integrity: sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==} + engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 4.3.1 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.1.0 + onetime: 6.0.0 + signal-exit: 3.0.7 + strip-final-newline: 3.0.0 + dev: true + + /fast-deep-equal/3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-glob/3.2.12: + resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify/2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein/2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq/1.14.0: + resolution: {integrity: sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==} + dependencies: + reusify: 1.0.4 + dev: true + + /fault/1.0.4: + resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==} + dependencies: + format: 0.2.2 + dev: false + + /file-entry-cache/6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.0.4 + dev: true + + /fill-range/7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + + /find-root/1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + dev: false + + /find-up/5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache/3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.2.7 + rimraf: 3.0.2 + dev: true + + /flatted/3.2.7: + resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + dev: true + + /focus-lock/0.11.4: + resolution: {integrity: sha512-LzZWJcOBIcHslQ46N3SUu/760iLPSrUtp8omM4gh9du438V2CQdks8TcOu1yvmu2C68nVOBnl1WFiKGPbQ8L6g==} + engines: {node: '>=10'} + dependencies: + tslib: 2.4.1 + dev: false + + /follow-redirects/1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /form-data/4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /format/0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + dev: false + + /fraction.js/4.2.0: + resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} + dev: true + + /framer-motion/10.10.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-eCsyOcJimIRbx9KOzBTO3j9u1rF/H8/o/ybizYqdrzHkEeHx9L2NcEfGWfV0OHTc1JV17ECVzuZpomupEJ4+dw==} + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + tslib: 2.4.1 + optionalDependencies: + '@emotion/is-prop-valid': 0.8.8 + dev: false + + /framesync/6.1.2: + resolution: {integrity: sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==} + dependencies: + tslib: 2.4.0 + dev: false + + /fs.realpath/1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + + /function.prototype.name/1.1.5: + resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.5 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names/1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /gensync/1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /get-intrinsic/1.1.3: + resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-symbols: 1.0.3 + dev: true + + /get-nonce/1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + dev: false + + /get-stream/6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /get-symbol-description/1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + dev: true + + /glob-parent/5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + + /glob-parent/6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob/7.1.6: + resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /glob/7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globals/11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globals/13.19.0: + resolution: {integrity: sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globby/11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.2.12 + ignore: 5.2.1 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /gopd/1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.1.3 + dev: true + + /grapheme-splitter/1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + dev: true + + /has-bigints/1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag/3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + /has-flag/4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors/1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + dependencies: + get-intrinsic: 1.1.3 + dev: true + + /has-symbols/1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag/1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + + /hast-util-parse-selector/2.2.5: + resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==} + dev: false + + /hastscript/6.0.0: + resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} + dependencies: + '@types/hast': 2.3.4 + comma-separated-tokens: 1.0.8 + hast-util-parse-selector: 2.2.5 + property-information: 5.6.0 + space-separated-tokens: 1.1.5 + dev: false + + /highlight.js/10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + dev: false + + /hoist-non-react-statics/3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + dependencies: + react-is: 16.13.1 + dev: false + + /htm/3.1.1: + resolution: {integrity: sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==} + dev: true + + /html-parse-stringify/3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + dependencies: + void-elements: 3.1.0 + dev: false + + /human-signals/4.3.1: + resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} + engines: {node: '>=14.18.0'} + dev: true + + /husky/8.0.3: + resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /i18next-browser-languagedetector/7.0.1: + resolution: {integrity: sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g==} + dependencies: + '@babel/runtime': 7.20.6 + dev: false + + /i18next-http-backend/2.2.0: + resolution: {integrity: sha512-Z4sM7R6tzdLknSPER9GisEBxKPg5FkI07UrQniuroZmS15PHQrcCPLyuGKj8SS68tf+O2aEDYSUnmy1TZqZSbw==} + dependencies: + cross-fetch: 3.1.5 + transitivePeerDependencies: + - encoding + dev: false + + /i18next/22.4.13: + resolution: {integrity: sha512-GX7flMHRRqQA0I1yGLmaZ4Hwt1JfLqagk8QPDPZsqekbKtXsuIngSVWM/s3SLgNkrEXjA+0sMGNuOEkkmyqmWg==} + dependencies: + '@babel/runtime': 7.20.6 + dev: false + + /ieee754/1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + + /ignore/5.2.1: + resolution: {integrity: sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==} + engines: {node: '>= 4'} + dev: true + + /immer/9.0.21: + resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} + dev: false + + /immutable/4.1.0: + resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==} + + /import-fresh/3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + /imurmurhash/0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string/4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /inflight/1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /install/0.13.0: + resolution: {integrity: sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==} + engines: {node: '>= 0.10'} + dev: true + + /internal-slot/1.0.4: + resolution: {integrity: sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.1.3 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /invariant/2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + dependencies: + loose-envify: 1.4.0 + dev: false + + /is-alphabetical/1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + dev: false + + /is-alphanumerical/1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + dev: false + + /is-arrayish/0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + /is-bigint/1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-binary-path/2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + + /is-boolean-object/1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-callable/1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module/2.11.0: + resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} + dependencies: + has: 1.0.3 + + /is-date-object/1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-decimal/1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + dev: false + + /is-extglob/2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + /is-fullwidth-code-point/3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-fullwidth-code-point/4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + dev: true + + /is-glob/4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + + /is-hexadecimal/1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + dev: false + + /is-negative-zero/2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object/1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-number/7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + /is-path-inside/3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-regex/1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-shared-array-buffer/1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-stream/3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /is-string/1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol/1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-weakref/1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + + /isexe/2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /jiti/1.18.2: + resolution: {integrity: sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==} + hasBin: true + dev: true + + /js-sdsl/4.2.0: + resolution: {integrity: sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==} + dev: true + + /js-tokens/4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + /js-yaml/4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsesc/0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + + /jsesc/2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /json-parse-even-better-errors/2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + /json-schema-traverse/0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-stable-stringify-without-jsonify/1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json5/1.0.1: + resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} + hasBin: true + dependencies: + minimist: 1.2.7 + dev: true + + /json5/2.2.2: + resolution: {integrity: sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsx-ast-utils/3.3.3: + resolution: {integrity: sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==} + engines: {node: '>=4.0'} + dependencies: + array-includes: 3.1.6 + object.assign: 4.1.4 + dev: true + + /laf-client-sdk/1.0.0-beta.2: + resolution: {integrity: sha512-0Jbctghkw0D4/k+locZEBpkvHoFRHQ2ZQ60mBUKoz9fLxheK4ddTI71RFckB1aBKhFgSqfH6Hsdhxnl/MGEJWw==} + dependencies: + axios: 0.21.4 + database-ql: 1.0.0-beta.2 + transitivePeerDependencies: + - debug + dev: false + + /language-subtag-registry/0.3.22: + resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} + dev: true + + /language-tags/1.0.7: + resolution: {integrity: sha512-bSytju1/657hFjgUzPAPqszxH62ouE8nQFoFaVlIQfne4wO/wXC9A4+m8jYve7YBBvi59eq0SUpcshvG8h5Usw==} + dependencies: + language-subtag-registry: 0.3.22 + dev: true + + /levn/0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lilconfig/2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + dev: true + + /lines-and-columns/1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + /lint-staged/13.2.0: + resolution: {integrity: sha512-GbyK5iWinax5Dfw5obm2g2ccUiZXNGtAS4mCbJ0Lv4rq6iEtfBSjOYdcbOtAIFtM114t0vdpViDDetjVTSd8Vw==} + engines: {node: ^14.13.1 || >=16.0.0} + hasBin: true + dependencies: + chalk: 5.2.0 + cli-truncate: 3.1.0 + commander: 10.0.0 + debug: 4.3.4 + execa: 7.1.1 + lilconfig: 2.1.0 + listr2: 5.0.8 + micromatch: 4.0.5 + normalize-path: 3.0.0 + object-inspect: 1.12.3 + pidtree: 0.6.0 + string-argv: 0.3.1 + yaml: 2.2.1 + transitivePeerDependencies: + - enquirer + - supports-color + dev: true + + /listr2/5.0.8: + resolution: {integrity: sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==} + engines: {node: ^14.13.1 || >=16.0.0} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + peerDependenciesMeta: + enquirer: + optional: true + dependencies: + cli-truncate: 2.1.0 + colorette: 2.0.19 + log-update: 4.0.0 + p-map: 4.0.0 + rfdc: 1.3.0 + rxjs: 7.8.0 + through: 2.3.8 + wrap-ansi: 7.0.0 + dev: true + + /locate-path/6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.clonedeep/4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + dev: false + + /lodash.debounce/4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + dev: true + + /lodash.merge/4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash.mergewith/4.6.2: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + dev: false + + /lodash.set/4.3.2: + resolution: {integrity: sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==} + dev: false + + /lodash.unset/4.5.2: + resolution: {integrity: sha512-bwKX88k2JhCV9D1vtE8+naDKlLiGrSmf8zi/Y9ivFHwbmRfA8RxS/aVJ+sIht2XOwqoNr4xUPUkGZpc1sHFEKg==} + dev: false + + /lodash/4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + /log-update/4.0.0: + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} + engines: {node: '>=10'} + dependencies: + ansi-escapes: 4.3.2 + cli-cursor: 3.1.0 + slice-ansi: 4.0.0 + wrap-ansi: 6.2.0 + dev: true + + /loose-envify/1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + + /lowlight/1.20.0: + resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==} + dependencies: + fault: 1.0.4 + highlight.js: 10.7.3 + dev: false + + /lru-cache/6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /make-plural/7.2.0: + resolution: {integrity: sha512-WkdI+iaWaBCFM2wUXwos8Z7spg5Dt64Xe/VI6NpRaly21cDtD76N6S97K//UtzV0dHOiXX+E90TnszdXHG0aMg==} + dev: false + + /merge-stream/2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2/1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromatch/4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /mime-db/1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types/2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /mimic-fn/2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /mimic-fn/4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true + + /minimatch/3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimist/1.2.7: + resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} + dev: true + + /monaco-editor/0.36.1: + resolution: {integrity: sha512-/CaclMHKQ3A6rnzBzOADfwdSJ25BFoFT0Emxsc4zYVyav5SkK9iA6lEtIeuN/oRYbwPgviJT+t3l+sjFa28jYg==} + dev: false + + /ms/2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: true + + /ms/2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /mz/2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: true + + /nanoid/3.3.4: + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /natural-compare-lite/1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + dev: true + + /natural-compare/1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /node-fetch/2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-releases/2.0.10: + resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} + dev: true + + /node-releases/2.0.6: + resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} + dev: true + + /normalize-path/3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + /normalize-range/0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-run-path/5.1.0: + resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: true + + /object-assign/4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + /object-hash/3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + dev: true + + /object-inspect/1.12.2: + resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} + dev: true + + /object-inspect/1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + dev: true + + /object-keys/1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign/4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.entries/1.1.6: + resolution: {integrity: sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.5 + dev: true + + /object.fromentries/2.0.6: + resolution: {integrity: sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.5 + dev: true + + /object.hasown/1.1.2: + resolution: {integrity: sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==} + dependencies: + define-properties: 1.1.4 + es-abstract: 1.20.5 + dev: true + + /object.values/1.1.6: + resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.5 + dev: true + + /once/1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime/5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /onetime/6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + + /optionator/0.9.1: + resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.3 + dev: true + + /p-limit/3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate/5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-map/4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + dependencies: + aggregate-error: 3.1.0 + dev: true + + /parent-module/1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + + /parse-entities/2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + dev: false + + /parse-json/5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.18.6 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + /path-exists/4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute/1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key/3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-key/4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + /path-type/4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + /picocolors/1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch/2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + /pidtree/0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + dev: true + + /pify/2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + dev: true + + /pirates/4.0.5: + resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} + engines: {node: '>= 6'} + dev: true + + /point-in-polygon/1.1.0: + resolution: {integrity: sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw==} + dev: true + + /postcss-import/14.1.0_postcss@8.4.21: + resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==} + engines: {node: '>=10.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.4.21 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.1 + dev: true + + /postcss-js/4.0.0_postcss@8.4.21: + resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.3.3 + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.21 + dev: true + + /postcss-load-config/3.1.4_postcss@8.4.21: + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.1.0 + postcss: 8.4.21 + yaml: 1.10.2 + dev: true + + /postcss-nested/6.0.0_postcss@8.4.21: + resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.4.21 + postcss-selector-parser: 6.0.11 + dev: true + + /postcss-selector-parser/6.0.11: + resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss-value-parser/4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + dev: true + + /postcss/8.4.21: + resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.4 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /prelude-ls/1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier-plugin-tailwindcss/0.2.6_prettier@2.8.7: + resolution: {integrity: sha512-F+7XCl9RLF/LPrGdUMHWpsT6TM31JraonAUyE6eBmpqymFvDwyl0ETHsKFHP1NG+sEfv8bmKqnTxEbWQbHPlBA==} + engines: {node: '>=12.17.0'} + peerDependencies: + '@ianvs/prettier-plugin-sort-imports': '*' + '@prettier/plugin-php': '*' + '@prettier/plugin-pug': '*' + '@shopify/prettier-plugin-liquid': '*' + '@shufo/prettier-plugin-blade': '*' + '@trivago/prettier-plugin-sort-imports': '*' + prettier: '>=2.2.0' + prettier-plugin-astro: '*' + prettier-plugin-css-order: '*' + prettier-plugin-import-sort: '*' + prettier-plugin-jsdoc: '*' + prettier-plugin-organize-attributes: '*' + prettier-plugin-organize-imports: '*' + prettier-plugin-style-order: '*' + prettier-plugin-svelte: '*' + prettier-plugin-twig-melody: '*' + peerDependenciesMeta: + '@ianvs/prettier-plugin-sort-imports': + optional: true + '@prettier/plugin-php': + optional: true + '@prettier/plugin-pug': + optional: true + '@shopify/prettier-plugin-liquid': + optional: true + '@shufo/prettier-plugin-blade': + optional: true + '@trivago/prettier-plugin-sort-imports': + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-css-order: + optional: true + prettier-plugin-import-sort: + optional: true + prettier-plugin-jsdoc: + optional: true + prettier-plugin-organize-attributes: + optional: true + prettier-plugin-organize-imports: + optional: true + prettier-plugin-style-order: + optional: true + prettier-plugin-svelte: + optional: true + prettier-plugin-twig-melody: + optional: true + dependencies: + prettier: 2.8.7 + dev: true + + /prettier/2.8.7: + resolution: {integrity: sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /prismjs/1.27.0: + resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==} + engines: {node: '>=6'} + dev: false + + /prismjs/1.29.0: + resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} + engines: {node: '>=6'} + dev: false + + /prop-types/15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + /property-information/5.6.0: + resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} + dependencies: + xtend: 4.0.2 + dev: false + + /proxy-from-env/1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /punycode/2.1.1: + resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} + engines: {node: '>=6'} + dev: true + + /qrcode.react/3.1.0_react@18.2.0: + resolution: {integrity: sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: false + + /queue-microtask/1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /quick-lru/5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: true + + /react-clientside-effect/1.2.6_react@18.2.0: + resolution: {integrity: sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==} + peerDependencies: + react: ^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@babel/runtime': 7.20.6 + react: 18.2.0 + dev: false + + /react-datepicker/4.11.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-50n93o7mQwBEhg05tbopjFKgs8qgi8VBCAOMC4VqrKut72eAjESc/wXS/k5hRtnP0oe2FCGw7MJuIwh37wuXOw==} + peerDependencies: + react: ^16.9.0 || ^17 || ^18 + react-dom: ^16.9.0 || ^17 || ^18 + dependencies: + '@popperjs/core': 2.11.6 + classnames: 2.3.2 + date-fns: 2.29.3 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + react-onclickoutside: 6.12.2_biqbaboplfbrettd7655fr4n2y + react-popper: 2.3.0_r6q5zrenym2zg7je7hgi674bti + dev: false + + /react-dom/18.2.0_react@18.2.0: + resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + peerDependencies: + react: ^18.2.0 + dependencies: + loose-envify: 1.4.0 + react: 18.2.0 + scheduler: 0.23.0 + + /react-fast-compare/3.2.0: + resolution: {integrity: sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==} + + /react-fast-compare/3.2.1: + resolution: {integrity: sha512-xTYf9zFim2pEif/Fw16dBiXpe0hoy5PxcD8+OwBnTtNLfIm3g6WxhKNurY+6OmdH1u6Ta/W/Vl6vjbYP1MFnDg==} + dev: false + + /react-focus-lock/2.9.2_o2wclmlv6kymw75psj4clbbe6a: + resolution: {integrity: sha512-5JfrsOKyA5Zn3h958mk7bAcfphr24jPoMoznJ8vaJF6fUrPQ8zrtEd3ILLOK8P5jvGxdMd96OxWNjDzATfR2qw==} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.20.6 + '@types/react': 18.0.31 + focus-lock: 0.11.4 + prop-types: 15.8.1 + react: 18.2.0 + react-clientside-effect: 1.2.6_react@18.2.0 + use-callback-ref: 1.3.0_o2wclmlv6kymw75psj4clbbe6a + use-sidecar: 1.1.2_o2wclmlv6kymw75psj4clbbe6a + dev: false + + /react-hook-form/7.43.9_react@18.2.0: + resolution: {integrity: sha512-AUDN3Pz2NSeoxQ7Hs6OhQhDr6gtF9YRuutGDwPQqhSUAHJSgGl2VeY3qN19MG0SucpjgDiuMJ4iC5T5uB+eaNQ==} + engines: {node: '>=12.22.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 + dependencies: + react: 18.2.0 + dev: false + + /react-i18next/12.2.0_2rh65uwnd6kial3dj4kteywnti: + resolution: {integrity: sha512-5XeVgSygaGfyFmDd2WcXvINRw2WEC1XviW1LXY/xLOEMzsCFRwKqfnHN+hUjla8ZipbVJR27GCMSuTr0BhBBBQ==} + peerDependencies: + i18next: '>= 19.0.0' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + dependencies: + '@babel/runtime': 7.20.6 + html-parse-stringify: 3.0.1 + i18next: 22.4.13 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /react-icons/4.8.0_react@18.2.0: + resolution: {integrity: sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==} + peerDependencies: + react: '*' + dependencies: + react: 18.2.0 + dev: false + + /react-is/16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + /react-merge-refs/1.1.0: + resolution: {integrity: sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==} + dev: true + + /react-onclickoutside/6.12.2_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-NMXGa223OnsrGVp5dJHkuKxQ4czdLmXSp5jSV9OqiCky9LOpPATn3vLldc+q5fK3gKbEHvr7J1u0yhBh/xYkpA==} + peerDependencies: + react: ^15.5.x || ^16.x || ^17.x || ^18.x + react-dom: ^15.5.x || ^16.x || ^17.x || ^18.x + dependencies: + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + + /react-popper/2.3.0_r6q5zrenym2zg7je7hgi674bti: + resolution: {integrity: sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==} + peerDependencies: + '@popperjs/core': ^2.0.0 + react: ^16.8.0 || ^17 || ^18 + react-dom: ^16.8.0 || ^17 || ^18 + dependencies: + '@popperjs/core': 2.11.6 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + react-fast-compare: 3.2.0 + warning: 4.0.3 + + /react-remove-scroll-bar/2.3.4_o2wclmlv6kymw75psj4clbbe6a: + resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.0.31 + react: 18.2.0 + react-style-singleton: 2.2.1_o2wclmlv6kymw75psj4clbbe6a + tslib: 2.4.1 + dev: false + + /react-remove-scroll/2.5.5_o2wclmlv6kymw75psj4clbbe6a: + resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.0.31 + react: 18.2.0 + react-remove-scroll-bar: 2.3.4_o2wclmlv6kymw75psj4clbbe6a + react-style-singleton: 2.2.1_o2wclmlv6kymw75psj4clbbe6a + tslib: 2.4.1 + use-callback-ref: 1.3.0_o2wclmlv6kymw75psj4clbbe6a + use-sidecar: 1.1.2_o2wclmlv6kymw75psj4clbbe6a + dev: false + + /react-router-dom/6.10.0_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg==} + engines: {node: '>=14'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + dependencies: + '@remix-run/router': 1.5.0 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + react-router: 6.10.0_react@18.2.0 + dev: false + + /react-router/6.10.0_react@18.2.0: + resolution: {integrity: sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ==} + engines: {node: '>=14'} + peerDependencies: + react: '>=16.8' + dependencies: + '@remix-run/router': 1.5.0 + react: 18.2.0 + dev: false + + /react-style-singleton/2.2.1_o2wclmlv6kymw75psj4clbbe6a: + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.0.31 + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 18.2.0 + tslib: 2.4.1 + dev: false + + /react-syntax-highlighter/15.5.0_react@18.2.0: + resolution: {integrity: sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==} + peerDependencies: + react: '>= 0.14.0' + dependencies: + '@babel/runtime': 7.20.6 + highlight.js: 10.7.3 + lowlight: 1.20.0 + prismjs: 1.29.0 + react: 18.2.0 + refractor: 3.6.0 + dev: false + + /react/18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + + /read-cache/1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + dependencies: + pify: 2.3.0 + dev: true + + /readdirp/3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + + /refractor/3.6.0: + resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} + dependencies: + hastscript: 6.0.0 + parse-entities: 2.0.0 + prismjs: 1.27.0 + dev: false + + /regenerate-unicode-properties/10.1.0: + resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + dev: true + + /regenerate/1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + dev: true + + /regenerator-runtime/0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + + /regenerator-transform/0.15.1: + resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} + dependencies: + '@babel/runtime': 7.20.6 + dev: true + + /regexp.prototype.flags/1.4.3: + resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + functions-have-names: 1.2.3 + dev: true + + /regexpp/3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + dev: true + + /regexpu-core/5.2.2: + resolution: {integrity: sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.0 + regjsgen: 0.7.1 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + dev: true + + /regjsgen/0.7.1: + resolution: {integrity: sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==} + dev: true + + /regjsparser/0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + + /resolve-from/4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + /resolve/1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.11.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + /resolve/2.0.0-next.4: + resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} + hasBin: true + dependencies: + is-core-module: 2.11.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /restore-cursor/3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + + /reusify/1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rfdc/1.3.0: + resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} + dev: true + + /rimraf/3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup/3.18.0: + resolution: {integrity: sha512-J8C6VfEBjkvYPESMQYxKHxNOh4A5a3FlP+0BETGo34HEcE4eTlgCrO2+eWzlu2a/sHs2QUkZco+wscH7jhhgWg==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /run-parallel/1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /rxjs/7.8.0: + resolution: {integrity: sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==} + dependencies: + tslib: 2.4.1 + dev: true + + /safe-regex-test/1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + is-regex: 1.1.4 + dev: true + + /sass/1.60.0: + resolution: {integrity: sha512-updbwW6fNb5gGm8qMXzVO7V4sWf7LMXnMly/JEyfbfERbVH46Fn6q02BX7/eHTdKpE7d+oTkMMQpFWNUMfFbgQ==} + engines: {node: '>=12.0.0'} + hasBin: true + dependencies: + chokidar: 3.5.3 + immutable: 4.1.0 + source-map-js: 1.0.2 + + /scheduler/0.23.0: + resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + dependencies: + loose-envify: 1.4.0 + + /semver/6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true + dev: true + + /semver/7.3.8: + resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /shebang-command/2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex/3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /side-channel/1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + object-inspect: 1.12.2 + dev: true + + /signal-exit/3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /slash/3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slice-ansi/3.0.0: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /slice-ansi/4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /slice-ansi/5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + dev: true + + /source-map-js/1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + + /source-map/0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + dev: false + + /space-separated-tokens/1.1.5: + resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} + dev: false + + /string-argv/0.3.1: + resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} + engines: {node: '>=0.6.19'} + dev: true + + /string-natural-compare/3.0.1: + resolution: {integrity: sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==} + dev: true + + /string-width/4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string-width/5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.0.1 + dev: true + + /string.prototype.matchall/4.0.8: + resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.5 + get-intrinsic: 1.1.3 + has-symbols: 1.0.3 + internal-slot: 1.0.4 + regexp.prototype.flags: 1.4.3 + side-channel: 1.0.4 + dev: true + + /string.prototype.trimend/1.0.6: + resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.5 + dev: true + + /string.prototype.trimstart/1.0.6: + resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.5 + dev: true + + /strip-ansi/6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-ansi/7.0.1: + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + + /strip-bom/3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-final-newline/3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: true + + /strip-json-comments/3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /stylis/4.1.3: + resolution: {integrity: sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==} + dev: false + + /sucrase/3.31.0: + resolution: {integrity: sha512-6QsHnkqyVEzYcaiHsOKkzOtOgdJcb8i54x6AV2hDwyZcY9ZyykGZVw6L/YN98xC0evwTP6utsWWrKRaa8QlfEQ==} + engines: {node: '>=8'} + hasBin: true + dependencies: + commander: 4.1.1 + glob: 7.1.6 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.5 + ts-interface-checker: 0.1.13 + dev: true + + /supports-color/5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + + /supports-color/7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + /tailwindcss/3.3.1_postcss@8.4.21: + resolution: {integrity: sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==} + engines: {node: '>=12.13.0'} + hasBin: true + peerDependencies: + postcss: ^8.0.9 + dependencies: + arg: 5.0.2 + chokidar: 3.5.3 + color-name: 1.1.4 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.2.12 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.18.2 + 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.21 + postcss-import: 14.1.0_postcss@8.4.21 + postcss-js: 4.0.0_postcss@8.4.21 + postcss-load-config: 3.1.4_postcss@8.4.21 + postcss-nested: 6.0.0_postcss@8.4.21 + postcss-selector-parser: 6.0.11 + postcss-value-parser: 4.2.0 + quick-lru: 5.1.1 + resolve: 1.22.1 + sucrase: 3.31.0 + transitivePeerDependencies: + - ts-node + dev: true + + /text-table/0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /thenify-all/1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: true + + /thenify/3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: true + + /through/2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + + /tiny-invariant/1.3.1: + resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} + dev: false + + /to-fast-properties/2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + /to-regex-range/5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + + /toggle-selection/1.0.6: + resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} + dev: false + + /tr46/0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /ts-interface-checker/0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + dev: true + + /tsconfig-paths/3.14.1: + resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.1 + minimist: 1.2.7 + strip-bom: 3.0.0 + dev: true + + /tslib/1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + + /tslib/2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + dev: false + + /tslib/2.4.1: + resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} + + /tsutils/3.21.0_typescript@5.0.3: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + 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' + dependencies: + tslib: 1.14.1 + typescript: 5.0.3 + dev: true + + /type-check/0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-fest/0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /type-fest/0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + + /typescript/5.0.3: + resolution: {integrity: sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==} + engines: {node: '>=12.20'} + hasBin: true + dev: true + + /unbox-primitive/1.0.2: + resolution: {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 + dev: true + + /unicode-canonical-property-names-ecmascript/2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + dev: true + + /unicode-match-property-ecmascript/2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + dev: true + + /unicode-match-property-value-ecmascript/2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + dev: true + + /unicode-property-aliases-ecmascript/2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + dev: true + + /update-browserslist-db/1.0.10_browserslist@4.21.4: + resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.4 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + + /update-browserslist-db/1.0.10_browserslist@4.21.5: + resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.5 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + + /uri-js/4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.1.1 + dev: true + + /use-callback-ref/1.3.0_o2wclmlv6kymw75psj4clbbe6a: + resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.0.31 + react: 18.2.0 + tslib: 2.4.1 + dev: false + + /use-isomorphic-layout-effect/1.1.2_o2wclmlv6kymw75psj4clbbe6a: + resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.0.31 + react: 18.2.0 + dev: true + + /use-sidecar/1.1.2_o2wclmlv6kymw75psj4clbbe6a: + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.0.31 + detect-node-es: 1.1.0 + react: 18.2.0 + tslib: 2.4.1 + dev: false + + /use-sync-external-store/1.2.0_react@18.2.0: + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: false + + /util-deprecate/1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /vite/4.2.1_hghbulspu73jfdazs4i6yiqype: + resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 18.15.11 + esbuild: 0.17.14 + postcss: 8.4.21 + resolve: 1.22.1 + rollup: 3.18.0 + sass: 1.60.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /void-elements/3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + dev: false + + /warning/4.0.3: + resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} + dependencies: + loose-envify: 1.4.0 + + /webidl-conversions/3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url/5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /which-boxed-primitive/1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which/2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /word-wrap/1.2.3: + resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} + engines: {node: '>=0.10.0'} + dev: true + + /wrap-ansi/6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi/7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy/1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /xtend/4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: false + + /yallist/4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yaml/1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + + /yaml/2.2.1: + resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==} + engines: {node: '>= 14'} + dev: true + + /yocto-queue/0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true + + /zustand/4.3.6_immer@9.0.21+react@18.2.0: + resolution: {integrity: sha512-6J5zDxjxLE+yukC2XZWf/IyWVKnXT9b9HUv09VJ/bwGCpKNcaTqp7Ws28Xr8jnbvnZcdRaidztAPsXFBIqufiw==} + engines: {node: '>=12.7.0'} + peerDependencies: + immer: '>=9.0' + react: '>=16.8' + peerDependenciesMeta: + immer: + optional: true + react: + optional: true + dependencies: + immer: 9.0.21 + react: 18.2.0 + use-sync-external-store: 1.2.0_react@18.2.0 + dev: false diff --git a/web/prettier.config.cjs b/web/prettier.config.cjs index 1e262534c1..b2048cc562 100644 --- a/web/prettier.config.cjs +++ b/web/prettier.config.cjs @@ -3,4 +3,5 @@ module.exports = { tabWidth: 2, trailingComma: "all", semi: true, + plugins: [require("prettier-plugin-tailwindcss")], }; diff --git a/web/public/favicon.ico b/web/public/favicon.ico index a88d339b90..f3fa36060c 100644 Binary files a/web/public/favicon.ico and b/web/public/favicon.ico differ diff --git a/web/public/homepage/Vector.svg b/web/public/homepage/Vector.svg new file mode 100644 index 0000000000..85a8fbfff0 --- /dev/null +++ b/web/public/homepage/Vector.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/public/homepage/banner.png b/web/public/homepage/banner.png new file mode 100644 index 0000000000..febf1ab68a Binary files /dev/null and b/web/public/homepage/banner.png differ diff --git a/web/public/homepage/bg.png b/web/public/homepage/bg.png new file mode 100644 index 0000000000..19f815390f Binary files /dev/null and b/web/public/homepage/bg.png differ diff --git a/web/public/homepage/cancel_btn.svg b/web/public/homepage/cancel_btn.svg new file mode 100644 index 0000000000..fa43bfa866 --- /dev/null +++ b/web/public/homepage/cancel_btn.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/web/public/homepage/database.png b/web/public/homepage/database.png new file mode 100644 index 0000000000..6e19a962a4 Binary files /dev/null and b/web/public/homepage/database.png differ diff --git a/web/public/homepage/database.svg b/web/public/homepage/database.svg new file mode 100644 index 0000000000..c4f38451ad --- /dev/null +++ b/web/public/homepage/database.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/public/homepage/discord.svg b/web/public/homepage/discord.svg new file mode 100644 index 0000000000..767c1a3d83 --- /dev/null +++ b/web/public/homepage/discord.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/web/public/homepage/discord_2.svg b/web/public/homepage/discord_2.svg new file mode 100644 index 0000000000..484b7d9d0f --- /dev/null +++ b/web/public/homepage/discord_2.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/web/public/homepage/forum.svg b/web/public/homepage/forum.svg new file mode 100644 index 0000000000..2e74815d79 --- /dev/null +++ b/web/public/homepage/forum.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/public/homepage/forum1.svg b/web/public/homepage/forum1.svg new file mode 100644 index 0000000000..50710def9b --- /dev/null +++ b/web/public/homepage/forum1.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/public/homepage/function.png b/web/public/homepage/function.png new file mode 100644 index 0000000000..d8247f635d Binary files /dev/null and b/web/public/homepage/function.png differ diff --git a/web/public/homepage/functions.svg b/web/public/homepage/functions.svg new file mode 100644 index 0000000000..b36a92b6f5 --- /dev/null +++ b/web/public/homepage/functions.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/public/homepage/icon_01.svg b/web/public/homepage/icon_01.svg new file mode 100644 index 0000000000..1cfc70543e --- /dev/null +++ b/web/public/homepage/icon_01.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/public/homepage/icon_02.svg b/web/public/homepage/icon_02.svg new file mode 100644 index 0000000000..756738f882 --- /dev/null +++ b/web/public/homepage/icon_02.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/public/homepage/icon_03.svg b/web/public/homepage/icon_03.svg new file mode 100644 index 0000000000..b5d7a08bf1 --- /dev/null +++ b/web/public/homepage/icon_03.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/public/homepage/icon_04.svg b/web/public/homepage/icon_04.svg new file mode 100644 index 0000000000..1482d553a8 --- /dev/null +++ b/web/public/homepage/icon_04.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/public/homepage/icon_05.svg b/web/public/homepage/icon_05.svg new file mode 100644 index 0000000000..7a44605d40 --- /dev/null +++ b/web/public/homepage/icon_05.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/web/public/homepage/icon_06.png b/web/public/homepage/icon_06.png new file mode 100644 index 0000000000..b481f38fd8 Binary files /dev/null and b/web/public/homepage/icon_06.png differ diff --git a/web/public/homepage/joinbg.svg b/web/public/homepage/joinbg.svg new file mode 100644 index 0000000000..c5b3161ff6 --- /dev/null +++ b/web/public/homepage/joinbg.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/public/homepage/laficon.jpg b/web/public/homepage/laficon.jpg new file mode 100644 index 0000000000..f3fa36060c Binary files /dev/null and b/web/public/homepage/laficon.jpg differ diff --git a/web/public/homepage/logo_icon.svg b/web/public/homepage/logo_icon.svg new file mode 100644 index 0000000000..2a9597fe18 --- /dev/null +++ b/web/public/homepage/logo_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/public/homepage/logo_text.png b/web/public/homepage/logo_text.png new file mode 100644 index 0000000000..6c02e63d3e Binary files /dev/null and b/web/public/homepage/logo_text.png differ diff --git a/web/public/homepage/p1.png b/web/public/homepage/p1.png new file mode 100644 index 0000000000..79b693a493 Binary files /dev/null and b/web/public/homepage/p1.png differ diff --git a/web/public/homepage/p2.png b/web/public/homepage/p2.png new file mode 100644 index 0000000000..5b279b0216 Binary files /dev/null and b/web/public/homepage/p2.png differ diff --git a/web/public/homepage/p3.png b/web/public/homepage/p3.png new file mode 100644 index 0000000000..609b448255 Binary files /dev/null and b/web/public/homepage/p3.png differ diff --git a/web/public/homepage/p4.png b/web/public/homepage/p4.png new file mode 100644 index 0000000000..101e4a78a2 Binary files /dev/null and b/web/public/homepage/p4.png differ diff --git a/web/public/homepage/p5.png b/web/public/homepage/p5.png new file mode 100644 index 0000000000..0a18fd75b4 Binary files /dev/null and b/web/public/homepage/p5.png differ diff --git a/web/public/homepage/play.svg b/web/public/homepage/play.svg new file mode 100644 index 0000000000..d0361519ce --- /dev/null +++ b/web/public/homepage/play.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/public/homepage/storage.png b/web/public/homepage/storage.png new file mode 100644 index 0000000000..eb3099e731 Binary files /dev/null and b/web/public/homepage/storage.png differ diff --git a/web/public/homepage/storage.svg b/web/public/homepage/storage.svg new file mode 100644 index 0000000000..80922d03ef --- /dev/null +++ b/web/public/homepage/storage.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/public/homepage/videobg.png b/web/public/homepage/videobg.png new file mode 100644 index 0000000000..fafe4b1436 Binary files /dev/null and b/web/public/homepage/videobg.png differ diff --git a/web/public/homepage/videomobile.png b/web/public/homepage/videomobile.png new file mode 100644 index 0000000000..e33d3dc3a1 Binary files /dev/null and b/web/public/homepage/videomobile.png differ diff --git a/web/public/homepage/wechat_01.svg b/web/public/homepage/wechat_01.svg new file mode 100644 index 0000000000..527f4c013f --- /dev/null +++ b/web/public/homepage/wechat_01.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/web/public/homepage/wechat_02.svg b/web/public/homepage/wechat_02.svg new file mode 100644 index 0000000000..9171455f3f --- /dev/null +++ b/web/public/homepage/wechat_02.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/web/public/locales/en/translation.json b/web/public/locales/en/translation.json index 2b1453e3fc..a03a409113 100644 --- a/web/public/locales/en/translation.json +++ b/web/public/locales/en/translation.json @@ -6,8 +6,8 @@ "AddPolicy": "Add Access Policy", "AddRules": "Add Rule", "Collection": "Collection", - "CollectionList": "Collection List", - "CollectionName": "Collection Name", + "CollectionList": "Collections", + "CollectionName": "Name", "CollectionPlaceholder": "Please enter a collection name", "ConformDelete": "Are you sure to delete this policy?", "DeleteCollection": "Delete Collection", @@ -31,20 +31,19 @@ "EmptyRuleTip": "This policy has no rules yet,", "Query": "Please enter the ID and press Enter to query", "Search": "Please enter ID to search", - "CreateTagTip": "Press \"Enter\" or \"Space\" to separate tags, each tag can be up to 16 characters", + "CreateTagTip": "Press \"Enter\" to separate tags, each tag can be up to 16 characters", "CollectionNameRule": "The collection name can only start with a letter and consist of 3 to 32 characters including letters, _ or -" }, "Add": "Add ", - "AddData": "new data", + "AddData": "Add data", "AddSuccess": "Added successfully", "Cancel": "Cancel", "Close": "Close", "Confirm": "Confirm", "Copied": "copied", "Copy": "copy", - "Create": "new application", - "CreateNow": "create now", - "CreateTime": "Created time", + "Create": "New application", + "CreateNow": "Create Now", "Custom": "customize", "Days": "days", "Delete": "Delete ", @@ -54,7 +53,7 @@ "Edit": "Edit", "Empty": "Empty", "Generate": "generate", - "InputTip": "please enter", + "InputTip": "Please enter", "IsRequired": " is required", "LimitSelect": "Please select at least one", "Logout": "Logout", @@ -70,16 +69,16 @@ "moreOperations": "More Operations", "openPopover": "Click here to open a popover", "FunctionPanel": { - "AddFunction": "Add Function", + "AddFunction": "New Function", "Code": "Function Template", "ConfirmDeploy": "Confirm Deploy", "CustomDependence": "Custom", "CustomDependenceTip": "No custom dependencies yet", "DeleteDependencyConfirm": "Are you sure you want to delete the npm package?", "Debug": "Run", - "DebugResult": "Run Result", + "DebugResult": "Result", "DeleteConfirm": "Are you sure you want to delete the function?", - "Dependence": "NPM Dependence", + "Dependence": "Dependence", "DependenceAdd": "Add Dependencies", "DependenceEdit": "Edit Dependencies", "DependenceName": "Dependency Package Name", @@ -89,13 +88,12 @@ "DeploySuccess": "Deploy successfully", "Description": "Function Description", "EditFunction": "Edit Function", - "EmptyText": "No function information yet,", "Function": "Function", - "FunctionList": "Function List", + "FunctionList": "Functions", "FunctionName": "Function Name", "FunctionNameTip": "The unique identifier of the function, such as get-user", - "InterfaceDebug": "Interface Debugging", - "Methods": "Request Method", + "InterfaceDebug": "Debug", + "Methods": "Method", "Name": "KEY", "Tags": "Tags", "SearchPlaceholder": "Please enter the function name query", @@ -103,11 +101,13 @@ "SystemDependence": "Built-In", "Value": "Value", "isSupport": "Whether to support", - "FunctionNameRule": "Function names can only contain English or _", + "FunctionNameRule": "Function names must consist of letters, numbers, periods (.), and hyphens (-), matching the regex: /^[a-zA-Z0-9.-]{1,128}$/.", "EmptyDebugTip": "No results yet", "EmptyFunctionTip": "You have not created the function", "UploadButton": "upload", - "LeaveFunctionPage": "About to leave the function edit page" + "LeaveFunctionPage": "About to leave the function edit page", + "PromptDescription": "Use natural language to describe your needs, laf will help you generate code, for example: help me write a hello world, return {hello: 'laf AI'}", + "CreateWithAITip": "Create functions with AI assistance" }, "HomePanel": { "APP": "Android or iOS app", @@ -128,7 +128,7 @@ "WX": "WeChat Mini Program/Public Account", "Welcome": "Welcome to the LAF cloud development platform!", "DeleteApp": "delete apps", - "DeleteTip": "Are you sure you want to delete this app?", + "DeleteTip": "The current operation will permanently delete applications, including functions, data, cloud storage, etc. related data related to the application. After deleting, will not be able to cancel ,please enter {{appId}} confirm", "Duration": "Duration" }, "LogPanel": { @@ -143,16 +143,15 @@ "Setting": "Setting", "SystemSetting": "Application Settings", "UserSetting": "User Info", - "UpdateConfirm": "Update env will restart application, are you sure?", - "BaseInfo": "Basic Information", + "UpdateConfirm": "Continue to update environment variables?", + "BaseInfo": "Basic Info", "DB": "Database", "Delete": "Delete", - "Detail": "Rules details (experimental version)", + "Detail": "Spec Detail", "Disk": "Hard Disk", "Memory": "Memory", "Restart": "Restart", "network": "Outgoing capacity", - "Close": "Close", "AppInfo": "Application Information", "Auth": "Real-name Authentication", "Code": "Code", @@ -160,19 +159,22 @@ "ID": "ID", "IDTip": "Please enter a valid ID number", "Name": "Real name", - "Registered": "Registered Time", + "Registered": "RegTime", "SendCode": "Send Code", - "Tel": "Mobile number", + "Tel": "Mobile", "TelTip": "Please enter a valid Mobile phone number", "ToAuth": "Authenticate Now", "UserInfo": "User Information", "noAuth": "Not Authenticated", - "showAuth": "Go to Auth" + "showAuth": "Go to Auth", + "ShutDown": "ShutDown", + "Subscription": "Subscription Info" }, "StoragePanel": { "All": "Total Capacity", "DeleteConfirm": "The current operation will permanently delete the cloud storage", "DeleteFileTip": "Are you sure you want to delete the file?", + "DeleteFolderTip": "Are you sure you want to delete the whole folder? Notice that it will be a bit slower when a large number of files exist.", "Drag": "Drag and drop here or", "EmptyText": "No Bucket data yet ,", "File": "File", @@ -200,9 +202,9 @@ "CreateBucket": "Create buckets", "EditBucket": "Edit Bucket", "DeleteBucket": "Delete Buckets", - "BucketNameRule": "Can only contain lowercase English, numbers, and the beginning and end cannot be numbers or -", + "BucketNameRule": "The bucket name must consist of lowercase letters, numbers and hyphens (-), with a length between 3 and 32 characters, and cannot start or end with a hyphen (-).", "BucketNamePlaceholder": "bucket-name", - "StorageList": "Cloud Storage List", + "StorageList": "Storages", "EmptyStorageTip": "You have not created a Bucket", "UploadFile": "Upload File", "UploadFolder": "Upload Folder", @@ -211,8 +213,7 @@ "websiteHost": "Enable website hosting", "Inaccessible": "Inaccessible", "isResolved": "Effective", - "cnameHostPreTip": "Add the \"CNAME\" record of the domain to resolve to", - "cnameHostSuffixTip": ", After the resolution takes effect, the custom domain name can be bound.", + "cnameTip": "Add the \"CNAME\" record of the domain to resolve to {{cnameDomain}}, After the resolution takes effect, the custom domain name can be bound.", "editHostTip": "oss-bucket needs to be in read mode to enable website hosting", "CreateWebHosting": "Bind custom domain name", "CustomDomain": "Custom Domain", @@ -243,6 +244,9 @@ "EveryHour": "per hour", "EveryFiveMinutes": "every five minutes" }, + "StatusBar": { + "CurrentApplication": "Current App" + }, "NoData": "Currently no data", "SaveAndRestart": "save and restart", "DataEntry": { @@ -284,5 +288,133 @@ "Price": { "Free": "Free" }, - "star-us-on-github": "Star us on GitHub" -} \ No newline at end of file + "star-us-on-github": "Star us on GitHub", + "AuthPanel": { + "Phone": "Phone", + "PhoneTip": "Please input a valid phone number", + "PhonePlaceholder": "Please input your phone number", + "ValidationCode": "Code", + "getValidationCode": "Send Code", + "Login": "Login", + "LoginTip": "Please input your phone number and verification code", + "LoginWithGithub": "Login with GitHub", + "ValidationCodeTip": "Please input the verification code", + "ForgotPassword": "Forgot Password?", + "Register": "Register", + "ToRegister": "Go to Register", + "ToLogin": "Go to Login", + "PasswordLogin": "Password Login", + "PhoneLogin": "Phone Login", + "Account": "Username", + "AccountPlaceholder": "Please input your username", + "Password": "Password", + "PasswordPlaceholder": "Please input your password", + "ConfirmPassword": "Confirm Password", + "ConfirmPasswordPlaceholder": "Please input your password again", + "PasswordNotMatch": "The two passwords you entered do not match", + "SmsCodeSendSuccess": "Verification code sent successfully", + "ValidationCodePlaceholder": "Please input the verification code", + "ResetPassword": "Reset Password", + "ResetPasswordSuccess": "Reset password successfully", + "NewPassword": "New Password", + "SignUpSuccess": "Sign up successfully" + }, + "Time": "Time", + "CreateTime": "Created", + "EndTime": "Expired", + "Renew": "Renew", + "TotalPrice": "Total", + "Balance": "Balance", + "ChargeNow": "Charge", + "balance is insufficient": "balance is insufficient", + "DeleteApp": "Delete", + "Recharge amount": "Recharge amount", + "Scan with WeChat": "WeChat scan code payment", + "Order Number": "Order Number", + "payment status": "Payment status", + "Monthly": "Monthly", + "CreateFolder": "New Folder", + "Or": "Or", + "Generating": "Generating", + "Start": "Start", + "TryLafAI": "Try 🎉 Laf AI !", + "HomePage": { + "LafLink": "/dashboard", + "DocsLink": "https://doc.laf.run/guide/", + "VideoLink": "https://itceb8-video.oss.laf.run/laf-website-en.mp4", + "WebSite": { + "title": "Laf - Serverless Cloud Development", + "description": "Laf provides cloud functions, cloud databases, object storage and other capabilities, writing code like a blog! Launch the ChatGPT app in 3 minutes!" + }, + "NavBar": { + "title": "Laf is an open-source project, we need your Star", + "home": "Home", + "price": "Price", + "case": "Case", + "aboutUs": "About US", + "faq": "FAQ", + "docs": "Docs", + "forum": "Forum", + "contact": "Contact", + "start": "Start Now", + "stars": "3.9K" + }, + "HomePage": { + "slogan": "Write Code as effortlessly as Blogging", + "start": "Free Start →", + "content1": "Laf is a cloud development platform integrating functions, databases and storage", + "content2": "Publish online anytime, anywhere" + }, + "Ability": { + "title": "Features", + "learn": "Learn more", + "function": "Cloud function", + "functionSub": ", release your first function in 5 seconds.", + "database": "Database", + "databaseSub": ", no need to create a database, ready to use out of the box.", + "storage": "Cloud storage", + "storageSub": ", create your own cloud storage, and manage files is simpler." + }, + "Choice": { + "title": "Advantage", + "open": "Open Source", + "openSub": "Laf follows the Apache License 2.0 open source protocol", + "fast": "More faster", + "fastSub": "There is no cold start time to make your response faster.", + "private": "Private Deployment", + "privateSub": "We support privatization deployment.", + "simple": "More Simple", + "simpleSub": "No need to care about Ops, Everything is Serverless.", + "cheap": "Lower Cost", + "cheapSub": "Minimum cost for million calls is only $0.01", + "service": "Provide efficient services for all developers.", + "serviceSub": "Learn more" + }, + "Join": { + "title": "Join the laf developer community", + "subtitle": "Grow up with us", + "content": "Here you can experience the latest version of Laf at the first time and keep communicating with developers and users in Discord or WeChat groups.", + "WeChat": "WeChat", + "forum": "Forum" + }, + "Footer": { + "laf": "Laf provides ready-to-use features such as cloud functions, cloud databases, and object storage. empowers you to write code with the ease of blogging! Get your ChatGPT application up and running in a mere 3 minutes!", + "product": "Product", + "item1_1": "Laf Cloud", + "item1_2": "Sealos Cloud", + "item1_3": "ChangeLog", + "item1_4": "Vscode Plugin", + "developer": "Developer", + "item2_1": "How to install Laf", + "item2_2": "Open API", + "item2_3": "Contributor's Guide", + "item2_4": "Source Code", + "item2_5": "Docs", + "support": "Support", + "item3_1": "Feedback", + "item3_2": "Forum" + } + }, + "ChatGPT example": "ChatGPT example", + "LinkCopied": "Link Copied" +} diff --git a/web/public/locales/zh-CN/translation.json b/web/public/locales/zh-CN/translation.json index 2b7a0fa1e8..c64f441db4 100644 --- a/web/public/locales/zh-CN/translation.json +++ b/web/public/locales/zh-CN/translation.json @@ -32,7 +32,7 @@ "EmptyDataText": "暂无数据信息,", "EmptyPolicyTip": "您还没有创建策略", "EmptyRuleTip": "此策略还没有规则,", - "CreateTagTip": "按「回车键」或「空格键」分隔标签,每个标签最多由16个字符组成" + "CreateTagTip": "按「回车键」输入标签,每个标签最多由16个字符组成" }, "Add": "添加", "AddData": "新增数据", @@ -44,7 +44,6 @@ "Copy": "复制", "Create": "新建", "CreateNow": "立即创建", - "CreateTime": "创建时间", "Custom": "自定义", "Days": "天", "Delete": "删除", @@ -89,7 +88,6 @@ "DeploySuccess": "发布成功", "Description": "函数描述", "EditFunction": "编辑函数", - "EmptyText": "暂无函数信息,", "Function": "函数", "FunctionList": "函数列表", "FunctionName": "函数名", @@ -103,11 +101,13 @@ "SystemDependence": "内置依赖", "Value": "值", "isSupport": "是否支持", - "FunctionNameRule": "函数名只能包含英文或 _", + "FunctionNameRule": "函数名须由字母、数字、点(.)和划线(-_)组成,匹配正则:/^[a-zA-Z0-9_.-]{1,128}$/", "EmptyDebugTip": "暂无运行结果", "EmptyFunctionTip": "您还没有创建函数", "UploadButton": "上传", - "LeaveFunctionPage": "即将离开函数编辑页面" + "LeaveFunctionPage": "即将离开函数编辑页面", + "PromptDescription": "使用自然语言描述你的需求, laf 会帮你生成代码, 例如: 写一个 hello world ,返回 {hello: 'laf AI'}", + "CreateWithAITip": "使用 AI 辅助创建函数" }, "HomePanel": { "APP": "Android or iOS 应用", @@ -128,7 +128,7 @@ "WX": "微信小程序/公众号", "Welcome": "欢迎来到 LAF 云开发平台!", "DeleteApp": "删除 APP", - "DeleteTip": "你确定想要删除这个 App?", + "DeleteTip": "当前操作将会永久删除应用, 包括函数、数据、云存储等与应用相关的数据, 删除后将无法撤消, 请输入 {{appId}} 后确认", "Duration": "购买时长" }, "LogPanel": { @@ -143,15 +143,14 @@ "Setting": "设置", "SystemSetting": "应用设置", "UserSetting": "用户设置", - "UpdateConfirm": "更新环境变量将重新启动应用,是否继续?", + "UpdateConfirm": "确认更新环境变量?", "AppInfo": "应用信息", "BaseInfo": "基础信息", - "Detail": "规则详情", + "Detail": "规格详情", "Memory": "内存", "Disk": "硬盘", "DB": "数据库", "network": "出网容量", - "Close": "关闭应用", "Delete": "删除应用", "Restart": "重启应用", "UserInfo": "用户信息", @@ -167,12 +166,15 @@ "IDTip": "请输入有效的身份证号码", "CodeTip": "请输入四位数字验证码", "TelTip": "请输入有效的手机号码", - "Registered": "注册时间" + "Registered": "注册时间", + "ShutDown": "关闭应用", + "Subscription": "订阅信息" }, "StoragePanel": { "All": "总容量", "DeleteConfirm": "当前操作将会永久删除云存储", "DeleteFileTip": "确认要删除文件吗?", + "DeleteFolderTip": "确认要删除整个文件夹吗?请注意当有大量文件存在时会稍许有一点慢哦", "Drag": "拖放到此处或者", "EmptyText": "暂无 Bucket 数据,", "File": "文件", @@ -188,7 +190,7 @@ "SearchBucket": "输入 bucket 名进行搜索", "Size": "大小", "Storage": "存储", - "StorageList": "云存储列表", + "StorageList": "云存储", "StorageNameTip": "请输入云存储名称", "Success": "上传成功", "Time": "更新时间", @@ -196,7 +198,7 @@ "Upload": "上传", "Used": "已使用", "UploadTip": "请选择文件或者文件夹上传", - "BucketNameRule": "只能包含小写英文、数字,开头和结尾不能是数字或 -", + "BucketNameRule": "Bucket 名称必须由小写字母、数字和中划线(-)组成,长度在3到32个字符之间,且不能以 - 开头或结尾。", "Bucket": "桶", "BucketName": "Bucket 名称", "CreateBucket": "创建 Bucket", @@ -211,8 +213,7 @@ "isResolved": "已生效", "parsing": "解析中", "websiteHost": "开启网站托管", - "cnameHostPreTip": "添加该域名的\"CNAME\" 解析到", - "cnameHostSuffixTip": "解析生效后即可绑定自定义域名。", + "cnameTip": "请对该域名添加 CNAME 记录,解析到 {{cnameDomain}} ,解析生效后即可绑定自定义域名。", "editHostTip": "开启网站托管需要 bucket 权限是 readonly 模式", "CreateWebHosting": "绑定自定义域名", "CustomDomain": "自定义域名", @@ -243,6 +244,9 @@ "EveryHour": "每小时", "EveryFiveMinutes": "每五分钟" }, + "StatusBar": { + "CurrentApplication": "当前应用" + }, "NoData": "当前无数据", "SaveAndRestart": "保存并重启", "DataEntry": { @@ -284,5 +288,133 @@ "Price": { "Free": "免费" }, - "star-us-on-github": "在 GitHub 上支持我们" -} \ No newline at end of file + "star-us-on-github": "在 GitHub 上支持我们", + "AuthPanel": { + "Phone": "手机号", + "PhoneTip": "请输入有效的手机号码", + "PhonePlaceholder": "请输入手机号", + "ValidationCode": "验证码", + "getValidationCode": "获取验证码", + "Login": "登录", + "LoginTip": "请输入手机号和验证码", + "LoginWithGithub": "GitHub 登录", + "ValidationCodeTip": "请输入验证码", + "ForgotPassword": "忘记密码?", + "Register": "注册", + "ToRegister": "去注册", + "ToLogin": "去登录", + "PasswordLogin": "密码登录", + "PhoneLogin": "手机验证码登录", + "Account": "用户名", + "AccountPlaceholder": "请输入用户名", + "Password": "密码", + "PasswordPlaceholder": "请输入密码", + "ConfirmPassword": "确认密码", + "ConfirmPasswordPlaceholder": "请再次输入密码", + "PasswordNotMatch": "两次输入的密码不一致", + "SmsCodeSendSuccess": "验证码发送成功", + "ValidationCodePlaceholder": "请输入验证码", + "ResetPassword": "重置密码", + "ResetPasswordSuccess": "重置密码成功", + "NewPassword": "新密码", + "SignUpSuccess": "注册成功" + }, + "Time": "时间", + "CreateTime": "创建时间", + "EndTime": "到期时间", + "Renew": "续期", + "TotalPrice": "共需支付", + "Balance": "账户余额", + "ChargeNow": "充值", + "balance is insufficient": "余额不足", + "DeleteApp": "删除应用", + "Recharge amount": "充值金额", + "Scan with WeChat": "微信扫码支付", + "Order Number": "订单号", + "payment status": "支付状态", + "Monthly": "月", + "CreateFolder": "新建文件夹", + "Or": "或", + "Generating": "正在生成", + "Start": "开始生成", + "TryLafAI": "试试 🎉 Laf AI !", + "HomePage": { + "LafLink": "/dashboard", + "DocsLink": "https://doc.laf.run/guide/", + "VideoLink": "https://itceb8-video.oss.laf.run/laf-website.mp4", + "WebSite": { + "title": "Laf 云开发官网", + "description": "Laf 是一个集函数、数据库、存储为一体的云开发平台,随时随地,发布上线" + }, + "NavBar": { + "title": "如果你喜欢 Laf 的话,请在 Github 上给我们一个 Star 吧!", + "home": "主页", + "price": "价格", + "case": "案例", + "aboutUs": "关于我们", + "docs": "文档", + "contact": "联系我们", + "forum": "开发者社区", + "faq": "FAQ", + "start": "立即体验", + "stars": "3.9K" + }, + "HomePage": { + "slogan": "像写博客一样写代码", + "start": "立即体验", + "content1": "Laf 是一个集函数、数据库、存储为一体的云开发平台", + "content2": "随时随地,发布上线" + }, + "Ability": { + "title": "Laf 的能力", + "learn": "了解详情", + "function": "云函数", + "functionSub": ", 5秒发布你的第一个函数。", + "database": "数据库", + "databaseSub": ", 无需创建数据库, 开箱即用.", + "storage": "云存储", + "storageSub": ",创建属于你的云存储,管理文件更简单。" + }, + "Choice": { + "title": "为什么选择 Laf", + "open": "更开放", + "openSub": "Laf 遵循 Apache License 2.0 开源协议", + "fast": "请求更快", + "fastSub": "没有冷启时间让你的请求响应更快", + "private": "支持私有化部署", + "privateSub": "无厂商绑定,可交付于任何环境", + "simple": "开发更简单", + "simpleSub": "无需关心部署、运维,一切都是 Serverless", + "cheap": "高性价比", + "cheapSub": "百万次调用,最低仅需 0.01 元", + "service": "我们致力于为所有开发者提供敏捷高效的服务", + "serviceSub": "了解详情" + }, + "Join": { + "title": "加入 Laf 开发者社区", + "subtitle": "和我们一起成长", + "content": "在这里你可以在第一时间体验 Laf 的最新版本,以及在 Discord 或微信群与开发者和用户保持沟通", + "WeChat": "微信", + "forum": "开发者社区" + }, + "Footer": { + "laf": "Laf 是一个 Serverless 框架,提供开箱即用的云函数,云数据库,对象存储等能力,是一个干净清爽的开发平台,像写博客一样写代码!三分钟上线 ChatGPT 应用!", + "product": "产品", + "item1_1": "Laf 公有云", + "item1_2": "Sealos", + "item1_3": "更新日志", + "item1_4": "Vscode 插件", + "developer": "开发者", + "item2_1": "私有化部署", + "item2_2": "开放 API", + "item2_3": "贡献者指南", + "item2_4": "源码", + "item2_5": "文档", + "support": "支持", + "item3_1": "问题反馈", + "item3_2": "开发者社区" + } + }, + "ChatGPT example": "ChatGPT 示例", + "LinkCopied": "链接复制成功" +} diff --git a/web/public/locales/zh/translation.json b/web/public/locales/zh/translation.json index f085f5a409..c64f441db4 100644 --- a/web/public/locales/zh/translation.json +++ b/web/public/locales/zh/translation.json @@ -32,7 +32,7 @@ "EmptyDataText": "暂无数据信息,", "EmptyPolicyTip": "您还没有创建策略", "EmptyRuleTip": "此策略还没有规则,", - "CreateTagTip": "按「回车键」或「空格键」分隔标签,每个标签最多由16个字符组成" + "CreateTagTip": "按「回车键」输入标签,每个标签最多由16个字符组成" }, "Add": "添加", "AddData": "新增数据", @@ -44,7 +44,6 @@ "Copy": "复制", "Create": "新建", "CreateNow": "立即创建", - "CreateTime": "创建时间", "Custom": "自定义", "Days": "天", "Delete": "删除", @@ -89,7 +88,6 @@ "DeploySuccess": "发布成功", "Description": "函数描述", "EditFunction": "编辑函数", - "EmptyText": "暂无函数信息,", "Function": "函数", "FunctionList": "函数列表", "FunctionName": "函数名", @@ -103,11 +101,13 @@ "SystemDependence": "内置依赖", "Value": "值", "isSupport": "是否支持", - "FunctionNameRule": "函数名只能包含英文或 _", + "FunctionNameRule": "函数名须由字母、数字、点(.)和划线(-_)组成,匹配正则:/^[a-zA-Z0-9_.-]{1,128}$/", "EmptyDebugTip": "暂无运行结果", "EmptyFunctionTip": "您还没有创建函数", "UploadButton": "上传", - "LeaveFunctionPage": "即将离开函数编辑页面" + "LeaveFunctionPage": "即将离开函数编辑页面", + "PromptDescription": "使用自然语言描述你的需求, laf 会帮你生成代码, 例如: 写一个 hello world ,返回 {hello: 'laf AI'}", + "CreateWithAITip": "使用 AI 辅助创建函数" }, "HomePanel": { "APP": "Android or iOS 应用", @@ -128,7 +128,7 @@ "WX": "微信小程序/公众号", "Welcome": "欢迎来到 LAF 云开发平台!", "DeleteApp": "删除 APP", - "DeleteTip": "你确定想要删除这个 App?", + "DeleteTip": "当前操作将会永久删除应用, 包括函数、数据、云存储等与应用相关的数据, 删除后将无法撤消, 请输入 {{appId}} 后确认", "Duration": "购买时长" }, "LogPanel": { @@ -143,15 +143,14 @@ "Setting": "设置", "SystemSetting": "应用设置", "UserSetting": "用户设置", - "UpdateConfirm": "更新环境变量将重新启动应用,是否继续?", + "UpdateConfirm": "确认更新环境变量?", "AppInfo": "应用信息", "BaseInfo": "基础信息", - "Detail": "规则详情", + "Detail": "规格详情", "Memory": "内存", "Disk": "硬盘", "DB": "数据库", "network": "出网容量", - "Close": "关闭应用", "Delete": "删除应用", "Restart": "重启应用", "UserInfo": "用户信息", @@ -167,12 +166,15 @@ "IDTip": "请输入有效的身份证号码", "CodeTip": "请输入四位数字验证码", "TelTip": "请输入有效的手机号码", - "Registered": "注册时间" + "Registered": "注册时间", + "ShutDown": "关闭应用", + "Subscription": "订阅信息" }, "StoragePanel": { "All": "总容量", "DeleteConfirm": "当前操作将会永久删除云存储", "DeleteFileTip": "确认要删除文件吗?", + "DeleteFolderTip": "确认要删除整个文件夹吗?请注意当有大量文件存在时会稍许有一点慢哦", "Drag": "拖放到此处或者", "EmptyText": "暂无 Bucket 数据,", "File": "文件", @@ -188,7 +190,7 @@ "SearchBucket": "输入 bucket 名进行搜索", "Size": "大小", "Storage": "存储", - "StorageList": "云存储列表", + "StorageList": "云存储", "StorageNameTip": "请输入云存储名称", "Success": "上传成功", "Time": "更新时间", @@ -196,7 +198,7 @@ "Upload": "上传", "Used": "已使用", "UploadTip": "请选择文件或者文件夹上传", - "BucketNameRule": "只能包含小写英文、数字,开头和结尾不能是数字或 -", + "BucketNameRule": "Bucket 名称必须由小写字母、数字和中划线(-)组成,长度在3到32个字符之间,且不能以 - 开头或结尾。", "Bucket": "桶", "BucketName": "Bucket 名称", "CreateBucket": "创建 Bucket", @@ -211,8 +213,7 @@ "isResolved": "已生效", "parsing": "解析中", "websiteHost": "开启网站托管", - "cnameHostPreTip": "请对该域名添加 CNAME 记录,解析到", - "cnameHostSuffixTip": ",解析生效后即可绑定自定义域名。", + "cnameTip": "请对该域名添加 CNAME 记录,解析到 {{cnameDomain}} ,解析生效后即可绑定自定义域名。", "editHostTip": "开启网站托管需要 bucket 权限是 readonly 模式", "CreateWebHosting": "绑定自定义域名", "CustomDomain": "自定义域名", @@ -243,6 +244,9 @@ "EveryHour": "每小时", "EveryFiveMinutes": "每五分钟" }, + "StatusBar": { + "CurrentApplication": "当前应用" + }, "NoData": "当前无数据", "SaveAndRestart": "保存并重启", "DataEntry": { @@ -284,5 +288,133 @@ "Price": { "Free": "免费" }, - "star-us-on-github": "在 GitHub 上支持我们" -} \ No newline at end of file + "star-us-on-github": "在 GitHub 上支持我们", + "AuthPanel": { + "Phone": "手机号", + "PhoneTip": "请输入有效的手机号码", + "PhonePlaceholder": "请输入手机号", + "ValidationCode": "验证码", + "getValidationCode": "获取验证码", + "Login": "登录", + "LoginTip": "请输入手机号和验证码", + "LoginWithGithub": "GitHub 登录", + "ValidationCodeTip": "请输入验证码", + "ForgotPassword": "忘记密码?", + "Register": "注册", + "ToRegister": "去注册", + "ToLogin": "去登录", + "PasswordLogin": "密码登录", + "PhoneLogin": "手机验证码登录", + "Account": "用户名", + "AccountPlaceholder": "请输入用户名", + "Password": "密码", + "PasswordPlaceholder": "请输入密码", + "ConfirmPassword": "确认密码", + "ConfirmPasswordPlaceholder": "请再次输入密码", + "PasswordNotMatch": "两次输入的密码不一致", + "SmsCodeSendSuccess": "验证码发送成功", + "ValidationCodePlaceholder": "请输入验证码", + "ResetPassword": "重置密码", + "ResetPasswordSuccess": "重置密码成功", + "NewPassword": "新密码", + "SignUpSuccess": "注册成功" + }, + "Time": "时间", + "CreateTime": "创建时间", + "EndTime": "到期时间", + "Renew": "续期", + "TotalPrice": "共需支付", + "Balance": "账户余额", + "ChargeNow": "充值", + "balance is insufficient": "余额不足", + "DeleteApp": "删除应用", + "Recharge amount": "充值金额", + "Scan with WeChat": "微信扫码支付", + "Order Number": "订单号", + "payment status": "支付状态", + "Monthly": "月", + "CreateFolder": "新建文件夹", + "Or": "或", + "Generating": "正在生成", + "Start": "开始生成", + "TryLafAI": "试试 🎉 Laf AI !", + "HomePage": { + "LafLink": "/dashboard", + "DocsLink": "https://doc.laf.run/guide/", + "VideoLink": "https://itceb8-video.oss.laf.run/laf-website.mp4", + "WebSite": { + "title": "Laf 云开发官网", + "description": "Laf 是一个集函数、数据库、存储为一体的云开发平台,随时随地,发布上线" + }, + "NavBar": { + "title": "如果你喜欢 Laf 的话,请在 Github 上给我们一个 Star 吧!", + "home": "主页", + "price": "价格", + "case": "案例", + "aboutUs": "关于我们", + "docs": "文档", + "contact": "联系我们", + "forum": "开发者社区", + "faq": "FAQ", + "start": "立即体验", + "stars": "3.9K" + }, + "HomePage": { + "slogan": "像写博客一样写代码", + "start": "立即体验", + "content1": "Laf 是一个集函数、数据库、存储为一体的云开发平台", + "content2": "随时随地,发布上线" + }, + "Ability": { + "title": "Laf 的能力", + "learn": "了解详情", + "function": "云函数", + "functionSub": ", 5秒发布你的第一个函数。", + "database": "数据库", + "databaseSub": ", 无需创建数据库, 开箱即用.", + "storage": "云存储", + "storageSub": ",创建属于你的云存储,管理文件更简单。" + }, + "Choice": { + "title": "为什么选择 Laf", + "open": "更开放", + "openSub": "Laf 遵循 Apache License 2.0 开源协议", + "fast": "请求更快", + "fastSub": "没有冷启时间让你的请求响应更快", + "private": "支持私有化部署", + "privateSub": "无厂商绑定,可交付于任何环境", + "simple": "开发更简单", + "simpleSub": "无需关心部署、运维,一切都是 Serverless", + "cheap": "高性价比", + "cheapSub": "百万次调用,最低仅需 0.01 元", + "service": "我们致力于为所有开发者提供敏捷高效的服务", + "serviceSub": "了解详情" + }, + "Join": { + "title": "加入 Laf 开发者社区", + "subtitle": "和我们一起成长", + "content": "在这里你可以在第一时间体验 Laf 的最新版本,以及在 Discord 或微信群与开发者和用户保持沟通", + "WeChat": "微信", + "forum": "开发者社区" + }, + "Footer": { + "laf": "Laf 是一个 Serverless 框架,提供开箱即用的云函数,云数据库,对象存储等能力,是一个干净清爽的开发平台,像写博客一样写代码!三分钟上线 ChatGPT 应用!", + "product": "产品", + "item1_1": "Laf 公有云", + "item1_2": "Sealos", + "item1_3": "更新日志", + "item1_4": "Vscode 插件", + "developer": "开发者", + "item2_1": "私有化部署", + "item2_2": "开放 API", + "item2_3": "贡献者指南", + "item2_4": "源码", + "item2_5": "文档", + "support": "支持", + "item3_1": "问题反馈", + "item3_2": "开发者社区" + } + }, + "ChatGPT example": "ChatGPT 示例", + "LinkCopied": "链接复制成功" +} diff --git a/web/public/logo.png b/web/public/logo.png index 834e9d9f11..f3fa36060c 100644 Binary files a/web/public/logo.png and b/web/public/logo.png differ diff --git a/web/public/logo_light.png b/web/public/logo_light.png new file mode 100644 index 0000000000..ac824431b2 Binary files /dev/null and b/web/public/logo_light.png differ diff --git a/web/public/logo_text.png b/web/public/logo_text.png new file mode 100644 index 0000000000..6c02e63d3e Binary files /dev/null and b/web/public/logo_text.png differ diff --git a/web/src/App.css b/web/src/App.css index 771d58cde4..abe15a886b 100644 --- a/web/src/App.css +++ b/web/src/App.css @@ -20,7 +20,7 @@ /* 滚动条滑块 */ ::-webkit-scrollbar-thumb { border-radius: 4px; - background: rgba(0, 0, 0, 0.5); + background: rgba(0, 0, 0, 0.2); } html, @@ -28,7 +28,7 @@ body { height: 100%; } -/* oevrrides chakra default value */ +/* overrides chakra default value */ body { background-repeat: no-repeat !important; background-size: cover !important; @@ -36,12 +36,12 @@ body { font-size: 12px; } -[data-theme=light] body { +[data-theme="light"] body { background-color: #f1f3f5 !important; background-image: url("/bg.png") !important; } -[data-theme=dark] ::-webkit-scrollbar-thumb { +[data-theme="dark"] ::-webkit-scrollbar-thumb { /* 滚动条滑块 */ background: rgba(21, 22, 26, 0.4); } @@ -64,4 +64,4 @@ a { color: white; background: black; } -} \ No newline at end of file +} diff --git a/web/src/App.tsx b/web/src/App.tsx index c4e9d26e4e..0e2102241a 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -9,6 +9,7 @@ import "@/utils/i18n"; import theme from "./chakraTheme"; import darkTheme from "./chakraThemeDark"; +import { CHAKRA_UI_COLOR_MODE_KEY } from "./constants"; import routes from "./routes"; import "./App.css"; @@ -32,10 +33,10 @@ const queryClient = new QueryClient({ function APP() { useTranslation(); - const [colorMode, setColorMode] = useState(localStorage.getItem("chakra-ui-color-mode")); + const [colorMode, setColorMode] = useState(localStorage.getItem(CHAKRA_UI_COLOR_MODE_KEY)); useEffect(() => { function onColorModeChange() { - const colorMode = localStorage.getItem("chakra-ui-color-mode"); + const colorMode = localStorage.getItem(CHAKRA_UI_COLOR_MODE_KEY); setColorMode(colorMode); } window.addEventListener("ColorModeChange", onColorModeChange); diff --git a/web/src/apis/typing.d.ts b/web/src/apis/typing.d.ts index 457356f928..3547b50d6b 100644 --- a/web/src/apis/typing.d.ts +++ b/web/src/apis/typing.d.ts @@ -1,4 +1,4 @@ -export type TApplication = { +export type TApplicationDetail = { id: string; name: string; appid: string; @@ -22,18 +22,19 @@ export type TApplication = { function_debug_token: string; host?: string; origin?: string; + subscription: TSubscription; }; export type TBundle = { id: string; - appid: string; name: string; displayName: string; + priority: number; + state: string; resource: TResource; - price: number; - specialPrice: number; - createdAt: string; - updatedAt: string; + limitCountPerUser: number; + notes: { content: string }[]; + subscriptionOptions: TSubscriptionOption[]; }; export type TResource = { @@ -44,15 +45,24 @@ export type TResource = { databaseCapacity: number; storageCapacity: number; networkTrafficOutbound: number; - limitCountPerUser: number; limitCountOfCloudFunction: number; limitCountOfBucket: number; limitCountOfDatabasePolicy: number; limitCountOfTrigger: number; + limitCountOfWebsiteHosting: number; + reservedTimeAfterExpired: number; limitDatabaseTPS: number; limitStorageTPS: number; }; +export type TSubscriptionOption = { + name: string; + displayName: string; + duration: number; + price: number; + specialPrice: number; +}; + export type TRuntime = { id: string; name: string; @@ -215,6 +225,7 @@ export type TFunction = { createdAt: string; updatedAt: string; createdBy: string; + params: any; }; export type TMethod = "GET" | "POST" | "PUT" | "DELETE" | "HEAD" | "OPTIONS" | "PATCH"; @@ -257,3 +268,76 @@ export type TProfile = { createdAt: string; updatedAt: string; }; + +export type TApplicationItem = { + id: string; + name: string; + appid: string; + regionId: string; + runtimeId: string; + tags: Array; + state: string; + phase: string; + createdAt: string; + updatedAt: string; + lockedAt: string; + createdBy: string; + bundle: { + id: string; + appid: string; + bundleId: string; + name: string; + displayName: string; + resource: { + limitCPU: number; + limitMemory: number; + requestCPU: number; + requestMemory: number; + databaseCapacity: number; + storageCapacity: number; + networkTrafficOutbound: number; + limitCountOfCloudFunction: number; + limitCountOfBucket: number; + limitCountOfDatabasePolicy: number; + limitCountOfTrigger: number; + limitCountOfWebsiteHosting: number; + reservedTimeAfterExpired: number; + limitDatabaseTPS: number; + limitStorageTPS: number; + }; + createdAt: string; + updatedAt: string; + }; + runtime: { + id: string; + name: string; + type: string; + image: { + main: string; + init: string; + sidecar: any; + }; + state: string; + version: string; + latest: boolean; + }; + subscription: { + id: string; + input: { + name: string; + state: string; + runtimeId: string; + regionId: string; + }; + bundleId: string; + appid: string; + state: string; + phase: string; + renewalPlan: string; + expiredAt: string; + lockedAt: string; + createdAt: string; + updatedAt: string; + createdBy: string; + }; +}; diff --git a/web/src/apis/v1/accounts.ts b/web/src/apis/v1/accounts.ts new file mode 100644 index 0000000000..c4d2a65cff --- /dev/null +++ b/web/src/apis/v1/accounts.ts @@ -0,0 +1,79 @@ +// @ts-ignore +/* eslint-disable */ +/////////////////////////////////////////////////////////////////////// +// // +// this file is autogenerated by service-generate // +// do not edit this file manually // +// // +/////////////////////////////////////////////////////////////////////// +/// +import request from "@/utils/request"; +import useGlobalStore from "@/pages/globalStore"; + +/** + * Get account info + */ +export async function AccountControllerFindOne( + params: Paths.AccountControllerFindOne.BodyParameters | any, +): Promise { + // /v1/accounts + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/accounts`, { + method: "GET", + params: params, + }); +} + +/** + * Get charge order + */ +export async function AccountControllerGetChargeOrder( + params: Paths.AccountControllerGetChargeOrder.BodyParameters | any, +): Promise { + // /v1/accounts/charge-order/{id} + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/accounts/charge-order/${_params.id}`, { + method: "GET", + params: params, + }); +} + +/** + * Create charge order + */ +export async function AccountControllerCharge( + params: Definitions.CreateChargeOrderDto | any, +): Promise { + // /v1/accounts/charge-order + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/accounts/charge-order`, { + method: "POST", + data: params, + }); +} + +/** + * + */ +export async function AccountControllerWechatNotify( + params: Paths.AccountControllerWechatNotify.BodyParameters | any, +): Promise { + // /v1/accounts/payment/wechat-notify + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/accounts/payment/wechat-notify`, { + method: "POST", + data: params, + }); +} diff --git a/web/src/apis/v1/api-auto.d.ts b/web/src/apis/v1/api-auto.d.ts index f0150ea086..b5280511c0 100644 --- a/web/src/apis/v1/api-auto.d.ts +++ b/web/src/apis/v1/api-auto.d.ts @@ -12,20 +12,13 @@ declare namespace Definitions { methods?: string[]; code?: string /* The source code of the function */; tags?: string[]; + params?: {}; }; export type CompileFunctionDto = { code?: string /* The source code of the function */; }; - export type CreateApplicationDto = { - name?: string; - state?: string; - regionId?: string; - bundleId?: string; - runtimeId?: string; - }; - export type UpdateApplicationDto = { name?: string; state?: string; @@ -84,13 +77,56 @@ declare namespace Definitions { pat?: string /* PAT */; }; - export type CreatePATDto = { - name?: string; - expiresIn?: number; + export type PasswdSignupDto = { + username?: string /* username, 3-64 characters */; + password?: string /* password, 8-64 characters */; + phone?: string /* phone */; + code?: string /* verify code */; + type?: string /* type */; }; - export type DeleteDependencyDto = { + export type PasswdSigninDto = { + username?: string /* username */; + password?: string /* password, 8-64 characters */; + }; + + export type PasswdResetDto = { + password?: string /* new password, 8-64 characters */; + phone?: string /* phone */; + code?: string /* verify code */; + type?: string /* type */; + }; + + export type PasswdCheckDto = { + username?: string /* username | phone | email */; + }; + + export type SendPhoneCodeDto = { + phone?: string /* phone */; + type?: string /* verify code type */; + }; + + export type PhoneSigninDto = { + phone?: string /* phone */; + code?: string; + username?: string /* username */; + password?: string /* password, 8-64 characters */; + }; + + export type BindPhoneDto = { + phone?: string /* phone number */; + code?: string /* sms verify code */; + }; + + export type BindUsernameDto = { + username?: string /* username */; + phone?: string /* phone */; + code?: string /* sms verify code */; + }; + + export type CreatePATDto = { name?: string; + expiresIn?: number; }; export type CreateTriggerDto = { @@ -98,9 +134,58 @@ declare namespace Definitions { cron?: string; target?: string; }; + + export type DeleteDependencyDto = { + name?: string; + }; + + export type CreateSubscriptionDto = { + name?: string; + state?: string; + regionId?: string; + bundleId?: string; + runtimeId?: string; + duration?: number; + }; + + export type RenewSubscriptionDto = { + duration?: number; + }; + + export type UpgradeSubscriptionDto = {}; + + export type CreateChargeOrderDto = { + amount?: number; + channel?: string; + currency?: string; + }; } declare namespace Paths { + namespace AuthControllerCode2token { + export type QueryParameters = any; + + export type BodyParameters = any; + + export type Responses = any; + } + + namespace AuthControllerGetSignupUrl { + export type QueryParameters = any; + + export type BodyParameters = any; + + export type Responses = any; + } + + namespace AuthControllerGetSigninUrl { + export type QueryParameters = any; + + export type BodyParameters = any; + + export type Responses = any; + } + namespace AppControllerGetRuntimes { export type QueryParameters = any; @@ -157,14 +242,6 @@ declare namespace Paths { export type Responses = any; } - namespace ApplicationControllerCreate { - export type QueryParameters = any; - - export type BodyParameters = Definitions.CreateApplicationDto; - - export type Responses = any; - } - namespace ApplicationControllerFindAll { export type QueryParameters = any; @@ -189,7 +266,7 @@ declare namespace Paths { export type Responses = any; } - namespace ApplicationControllerRemove { + namespace EnvironmentVariableControllerUpdateAll { export type QueryParameters = any; export type BodyParameters = any; @@ -421,15 +498,15 @@ declare namespace Paths { export type Responses = any; } - namespace AuthControllerGetSigninUrl { + namespace AuthControllerPat2token { export type QueryParameters = any; - export type BodyParameters = any; + export type BodyParameters = Definitions.Pat2TokenDto; export type Responses = any; } - namespace AuthControllerGetSignupUrl { + namespace AuthControllerGetProfile { export type QueryParameters = any; export type BodyParameters = any; @@ -437,23 +514,55 @@ declare namespace Paths { export type Responses = any; } - namespace AuthControllerCode2token { + namespace UserPasswordControllerSignup { export type QueryParameters = any; - export type BodyParameters = any; + export type BodyParameters = Definitions.PasswdSignupDto; export type Responses = any; } - namespace AuthControllerPat2token { + namespace UserPasswordControllerSignin { export type QueryParameters = any; - export type BodyParameters = Definitions.Pat2TokenDto; + export type BodyParameters = Definitions.PasswdSigninDto; export type Responses = any; } - namespace AuthControllerGetProfile { + namespace UserPasswordControllerReset { + export type QueryParameters = any; + + export type BodyParameters = Definitions.PasswdResetDto; + + export type Responses = any; + } + + namespace UserPasswordControllerCheck { + export type QueryParameters = any; + + export type BodyParameters = Definitions.PasswdCheckDto; + + export type Responses = any; + } + + namespace PhoneControllerSendCode { + export type QueryParameters = any; + + export type BodyParameters = Definitions.SendPhoneCodeDto; + + export type Responses = any; + } + + namespace PhoneControllerSignin { + export type QueryParameters = any; + + export type BodyParameters = Definitions.PhoneSigninDto; + + export type Responses = any; + } + + namespace AuthenticationControllerGetProviders { export type QueryParameters = any; export type BodyParameters = any; @@ -461,6 +570,22 @@ declare namespace Paths { export type Responses = any; } + namespace AuthenticationControllerBindPhone { + export type QueryParameters = any; + + export type BodyParameters = Definitions.BindPhoneDto; + + export type Responses = any; + } + + namespace AuthenticationControllerBindUsername { + export type QueryParameters = any; + + export type BodyParameters = Definitions.BindUsernameDto; + + export type Responses = any; + } + namespace PatControllerCreate { export type QueryParameters = any; @@ -485,6 +610,30 @@ declare namespace Paths { export type Responses = any; } + namespace TriggerControllerCreate { + export type QueryParameters = any; + + export type BodyParameters = Definitions.CreateTriggerDto; + + export type Responses = any; + } + + namespace TriggerControllerFindAll { + export type QueryParameters = any; + + export type BodyParameters = any; + + export type Responses = any; + } + + namespace TriggerControllerRemove { + export type QueryParameters = any; + + export type BodyParameters = any; + + export type Responses = any; + } + namespace LogControllerGetLogs { export type QueryParameters = any; @@ -525,15 +674,23 @@ declare namespace Paths { export type Responses = any; } - namespace TriggerControllerCreate { + namespace RegionControllerGetRegions { export type QueryParameters = any; - export type BodyParameters = Definitions.CreateTriggerDto; + export type BodyParameters = any; export type Responses = any; } - namespace TriggerControllerFindAll { + namespace SubscriptionControllerCreate { + export type QueryParameters = any; + + export type BodyParameters = Definitions.CreateSubscriptionDto; + + export type Responses = any; + } + + namespace SubscriptionControllerFindAll { export type QueryParameters = any; export type BodyParameters = any; @@ -541,7 +698,7 @@ declare namespace Paths { export type Responses = any; } - namespace TriggerControllerRemove { + namespace SubscriptionControllerFindOne { export type QueryParameters = any; export type BodyParameters = any; @@ -549,7 +706,55 @@ declare namespace Paths { export type Responses = any; } - namespace RegionControllerGetRegions { + namespace SubscriptionControllerRenew { + export type QueryParameters = any; + + export type BodyParameters = Definitions.RenewSubscriptionDto; + + export type Responses = any; + } + + namespace SubscriptionControllerUpgrade { + export type QueryParameters = any; + + export type BodyParameters = Definitions.UpgradeSubscriptionDto; + + export type Responses = any; + } + + namespace SubscriptionControllerRemove { + export type QueryParameters = any; + + export type BodyParameters = any; + + export type Responses = any; + } + + namespace AccountControllerFindOne { + export type QueryParameters = any; + + export type BodyParameters = any; + + export type Responses = any; + } + + namespace AccountControllerGetChargeOrder { + export type QueryParameters = any; + + export type BodyParameters = any; + + export type Responses = any; + } + + namespace AccountControllerCharge { + export type QueryParameters = any; + + export type BodyParameters = Definitions.CreateChargeOrderDto; + + export type Responses = any; + } + + namespace AccountControllerWechatNotify { export type QueryParameters = any; export type BodyParameters = any; diff --git a/web/src/apis/v1/applications.ts b/web/src/apis/v1/applications.ts index 5f09a104ed..7a2ae000f5 100644 --- a/web/src/apis/v1/applications.ts +++ b/web/src/apis/v1/applications.ts @@ -8,23 +8,7 @@ /////////////////////////////////////////////////////////////////////// /// import request from "@/utils/request"; - -/** - * Create a new application - */ -export async function ApplicationControllerCreate( - params: Definitions.CreateApplicationDto | any, -): Promise { - // /v1/applications - let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), - ...params, - }; - return request(`/v1/applications`, { - method: "POST", - data: params, - }); -} +import useGlobalStore from "@/pages/globalStore"; /** * Get user application list @@ -34,7 +18,7 @@ export async function ApplicationControllerFindAll( ): Promise { // /v1/applications let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/applications`, { @@ -51,7 +35,7 @@ export async function ApplicationControllerFindOne( ): Promise { // /v1/applications/{appid} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/applications/${_params.appid}`, { @@ -68,7 +52,7 @@ export async function ApplicationControllerUpdate( ): Promise { // /v1/applications/{appid} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/applications/${_params.appid}`, { @@ -76,20 +60,3 @@ export async function ApplicationControllerUpdate( data: params, }); } - -/** - * Delete an application - */ -export async function ApplicationControllerRemove( - params: Paths.ApplicationControllerRemove.BodyParameters | any, -): Promise { - // /v1/applications/{appid} - let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), - ...params, - }; - return request(`/v1/applications/${_params.appid}`, { - method: "DELETE", - data: params, - }); -} diff --git a/web/src/apis/v1/apps.ts b/web/src/apis/v1/apps.ts index 828a91f5f0..eadc02b4a6 100644 --- a/web/src/apis/v1/apps.ts +++ b/web/src/apis/v1/apps.ts @@ -8,6 +8,7 @@ /////////////////////////////////////////////////////////////////////// /// import request from "@/utils/request"; +import useGlobalStore from "@/pages/globalStore"; /** * Create a new function @@ -17,7 +18,7 @@ export async function FunctionControllerCreate( ): Promise { // /v1/apps/{appid}/functions let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/functions`, { @@ -34,7 +35,7 @@ export async function FunctionControllerFindAll( ): Promise { // /v1/apps/{appid}/functions let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/functions`, { @@ -51,7 +52,7 @@ export async function FunctionControllerFindOne( ): Promise { // /v1/apps/{appid}/functions/{name} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/functions/${_params.name}`, { @@ -68,7 +69,7 @@ export async function FunctionControllerUpdate( ): Promise { // /v1/apps/{appid}/functions/{name} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/functions/${_params.name}`, { @@ -85,7 +86,7 @@ export async function FunctionControllerRemove( ): Promise { // /v1/apps/{appid}/functions/{name} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/functions/${_params.name}`, { @@ -102,7 +103,7 @@ export async function FunctionControllerCompile( ): Promise { // /v1/apps/{appid}/functions/{name}/compile let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/functions/${_params.name}/compile`, { @@ -111,6 +112,23 @@ export async function FunctionControllerCompile( }); } +/** + * Update environment variables (replace all) + */ +export async function EnvironmentVariableControllerUpdateAll( + params: Paths.EnvironmentVariableControllerUpdateAll.BodyParameters | any, +): Promise { + // /v1/apps/{appid}/environments + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/apps/${_params.appid}/environments`, { + method: "POST", + data: params, + }); +} + /** * Set a environment variable (create/update) */ @@ -119,11 +137,11 @@ export async function EnvironmentVariableControllerAdd( ): Promise { // /v1/apps/{appid}/environments let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/environments`, { - method: "POST", + method: "PATCH", data: params, }); } @@ -136,7 +154,7 @@ export async function EnvironmentVariableControllerGet( ): Promise { // /v1/apps/{appid}/environments let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/environments`, { @@ -153,7 +171,7 @@ export async function EnvironmentVariableControllerDelete( ): Promise { // /v1/apps/{appid}/environments/{name} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/environments/${_params.name}`, { @@ -170,7 +188,7 @@ export async function BucketControllerCreate( ): Promise { // /v1/apps/{appid}/buckets let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/buckets`, { @@ -187,7 +205,7 @@ export async function BucketControllerFindAll( ): Promise { // /v1/apps/{appid}/buckets let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/buckets`, { @@ -204,7 +222,7 @@ export async function BucketControllerFindOne( ): Promise { // /v1/apps/{appid}/buckets/{name} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/buckets/${_params.name}`, { @@ -221,7 +239,7 @@ export async function BucketControllerUpdate( ): Promise { // /v1/apps/{appid}/buckets/{name} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/buckets/${_params.name}`, { @@ -238,7 +256,7 @@ export async function BucketControllerRemove( ): Promise { // /v1/apps/{appid}/buckets/{name} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/buckets/${_params.name}`, { @@ -255,7 +273,7 @@ export async function CollectionControllerCreate( ): Promise { // /v1/apps/{appid}/collections let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/collections`, { @@ -272,7 +290,7 @@ export async function CollectionControllerFindAll( ): Promise { // /v1/apps/{appid}/collections let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/collections`, { @@ -289,7 +307,7 @@ export async function CollectionControllerFindOne( ): Promise { // /v1/apps/{appid}/collections/{name} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/collections/${_params.name}`, { @@ -306,7 +324,7 @@ export async function CollectionControllerUpdate( ): Promise { // /v1/apps/{appid}/collections/{name} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/collections/${_params.name}`, { @@ -323,7 +341,7 @@ export async function CollectionControllerRemove( ): Promise { // /v1/apps/{appid}/collections/{name} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/collections/${_params.name}`, { @@ -340,7 +358,7 @@ export async function PolicyControllerCreate( ): Promise { // /v1/apps/{appid}/policies let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/policies`, { @@ -357,7 +375,7 @@ export async function PolicyControllerFindAll( ): Promise { // /v1/apps/{appid}/policies let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/policies`, { @@ -374,7 +392,7 @@ export async function PolicyControllerUpdate( ): Promise { // /v1/apps/{appid}/policies/{name} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/policies/${_params.name}`, { @@ -391,7 +409,7 @@ export async function PolicyControllerRemove( ): Promise { // /v1/apps/{appid}/policies/{name} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/policies/${_params.name}`, { @@ -408,7 +426,7 @@ export async function DatabaseControllerProxy( ): Promise { // /v1/apps/{appid}/databases/proxy let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/databases/proxy`, { @@ -425,7 +443,7 @@ export async function PolicyRuleControllerCreate( ): Promise { // /v1/apps/{appid}/policies/{name}/rules let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/policies/${_params.name}/rules`, { @@ -442,7 +460,7 @@ export async function PolicyRuleControllerFindAll( ): Promise { // /v1/apps/{appid}/policies/{name}/rules let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/policies/${_params.name}/rules`, { @@ -459,7 +477,7 @@ export async function PolicyRuleControllerUpdate( ): Promise { // /v1/apps/{appid}/policies/{name}/rules/{collection} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/policies/${_params.name}/rules/${_params.collection}`, { @@ -476,7 +494,7 @@ export async function PolicyRuleControllerRemove( ): Promise { // /v1/apps/{appid}/policies/{name}/rules/{collection} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/policies/${_params.name}/rules/${_params.collection}`, { @@ -493,7 +511,7 @@ export async function WebsiteControllerCreate( ): Promise { // /v1/apps/{appid}/websites let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/websites`, { @@ -510,7 +528,7 @@ export async function WebsiteControllerFindAll( ): Promise { // /v1/apps/{appid}/websites let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/websites`, { @@ -527,7 +545,7 @@ export async function WebsiteControllerFindOne( ): Promise { // /v1/apps/{appid}/websites/{id} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/websites/${_params.id}`, { @@ -544,7 +562,7 @@ export async function WebsiteControllerBindDomain( ): Promise { // /v1/apps/{appid}/websites/{id} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/websites/${_params.id}`, { @@ -561,7 +579,7 @@ export async function WebsiteControllerRemove( ): Promise { // /v1/apps/{appid}/websites/{id} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/websites/${_params.id}`, { @@ -578,7 +596,7 @@ export async function WebsiteControllerCheckResolved( ): Promise { // /v1/apps/{appid}/websites/{id}/resolved let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/websites/${_params.id}/resolved`, { @@ -587,6 +605,57 @@ export async function WebsiteControllerCheckResolved( }); } +/** + * Create a cron trigger + */ +export async function TriggerControllerCreate( + params: Definitions.CreateTriggerDto | any, +): Promise { + // /v1/apps/{appid}/triggers + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/apps/${_params.appid}/triggers`, { + method: "POST", + data: params, + }); +} + +/** + * Get trigger list of an application + */ +export async function TriggerControllerFindAll( + params: Paths.TriggerControllerFindAll.BodyParameters | any, +): Promise { + // /v1/apps/{appid}/triggers + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/apps/${_params.appid}/triggers`, { + method: "GET", + params: params, + }); +} + +/** + * Remove a cron trigger + */ +export async function TriggerControllerRemove( + params: Paths.TriggerControllerRemove.BodyParameters | any, +): Promise { + // /v1/apps/{appid}/triggers/{id} + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/apps/${_params.appid}/triggers/${_params.id}`, { + method: "DELETE", + data: params, + }); +} + /** * Get function logs */ @@ -595,7 +664,7 @@ export async function LogControllerGetLogs( ): Promise { // /v1/apps/{appid}/logs/functions let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/logs/functions`, { @@ -612,7 +681,7 @@ export async function DependencyControllerAdd( ): Promise { // /v1/apps/{appid}/dependencies let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/dependencies`, { @@ -629,7 +698,7 @@ export async function DependencyControllerUpdate( ): Promise { // /v1/apps/{appid}/dependencies let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/dependencies`, { @@ -646,7 +715,7 @@ export async function DependencyControllerGetDependencies( ): Promise { // /v1/apps/{appid}/dependencies let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/dependencies`, { @@ -663,7 +732,7 @@ export async function DependencyControllerRemove( ): Promise { // /v1/apps/{appid}/dependencies let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/apps/${_params.appid}/dependencies`, { @@ -671,54 +740,3 @@ export async function DependencyControllerRemove( data: params, }); } - -/** - * Create a cron trigger - */ -export async function TriggerControllerCreate( - params: Definitions.CreateTriggerDto | any, -): Promise { - // /v1/apps/{appid}/triggers - let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), - ...params, - }; - return request(`/v1/apps/${_params.appid}/triggers`, { - method: "POST", - data: params, - }); -} - -/** - * Get trigger list of an application - */ -export async function TriggerControllerFindAll( - params: Paths.TriggerControllerFindAll.BodyParameters | any, -): Promise { - // /v1/apps/{appid}/triggers - let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), - ...params, - }; - return request(`/v1/apps/${_params.appid}/triggers`, { - method: "GET", - params: params, - }); -} - -/** - * Remove a cron trigger - */ -export async function TriggerControllerRemove( - params: Paths.TriggerControllerRemove.BodyParameters | any, -): Promise { - // /v1/apps/{appid}/triggers/{id} - let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), - ...params, - }; - return request(`/v1/apps/${_params.appid}/triggers/${_params.id}`, { - method: "DELETE", - data: params, - }); -} diff --git a/web/src/apis/v1/auth.ts b/web/src/apis/v1/auth.ts new file mode 100644 index 0000000000..03a7083efb --- /dev/null +++ b/web/src/apis/v1/auth.ts @@ -0,0 +1,164 @@ +// @ts-ignore +/* eslint-disable */ +/////////////////////////////////////////////////////////////////////// +// // +// this file is autogenerated by service-generate // +// do not edit this file manually // +// // +/////////////////////////////////////////////////////////////////////// +/// +import request from "@/utils/request"; +import useGlobalStore from "@/pages/globalStore"; + +/** + * Signup by user-password + */ +export async function UserPasswordControllerSignup( + params: Definitions.PasswdSignupDto | any, +): Promise { + // /v1/auth/passwd/signup + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/auth/passwd/signup`, { + method: "POST", + data: params, + }); +} + +/** + * Signin by user-password + */ +export async function UserPasswordControllerSignin( + params: Definitions.PasswdSigninDto | any, +): Promise { + // /v1/auth/passwd/signin + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/auth/passwd/signin`, { + method: "POST", + data: params, + }); +} + +/** + * Reset password + */ +export async function UserPasswordControllerReset( + params: Definitions.PasswdResetDto | any, +): Promise { + // /v1/auth/passwd/reset + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/auth/passwd/reset`, { + method: "POST", + data: params, + }); +} + +/** + * Check if user-password is set + */ +export async function UserPasswordControllerCheck( + params: Definitions.PasswdCheckDto | any, +): Promise { + // /v1/auth/passwd/check + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/auth/passwd/check`, { + method: "POST", + data: params, + }); +} + +/** + * Send phone verify code + */ +export async function PhoneControllerSendCode( + params: Definitions.SendPhoneCodeDto | any, +): Promise { + // /v1/auth/phone/sms/code + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/auth/phone/sms/code`, { + method: "POST", + data: params, + }); +} + +/** + * Signin by phone and verify code + */ +export async function PhoneControllerSignin( + params: Definitions.PhoneSigninDto | any, +): Promise { + // /v1/auth/phone/signin + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/auth/phone/signin`, { + method: "POST", + data: params, + }); +} + +/** + * Auth providers + */ +export async function AuthenticationControllerGetProviders( + params: Paths.AuthenticationControllerGetProviders.BodyParameters | any, +): Promise { + // /v1/auth/providers + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/auth/providers`, { + method: "GET", + params: params, + }); +} + +/** + * Bind username + */ +export async function AuthenticationControllerBindPhone( + params: Definitions.BindPhoneDto | any, +): Promise { + // /v1/auth/bind/phone + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/auth/bind/phone`, { + method: "POST", + data: params, + }); +} + +/** + * Bind username + */ +export async function AuthenticationControllerBindUsername( + params: Definitions.BindUsernameDto | any, +): Promise { + // /v1/auth/bind/username + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/auth/bind/username`, { + method: "POST", + data: params, + }); +} diff --git a/web/src/apis/v1/code2token.ts b/web/src/apis/v1/code2token.ts index 84c9d46ce3..92ba63ae7a 100644 --- a/web/src/apis/v1/code2token.ts +++ b/web/src/apis/v1/code2token.ts @@ -8,6 +8,7 @@ /////////////////////////////////////////////////////////////////////// /// import request from "@/utils/request"; +import useGlobalStore from "@/pages/globalStore"; /** * Get user token by auth code @@ -17,7 +18,7 @@ export async function AuthControllerCode2token( ): Promise { // /v1/code2token let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/code2token`, { diff --git a/web/src/apis/v1/login.ts b/web/src/apis/v1/login.ts index bf44b54456..6393c43747 100644 --- a/web/src/apis/v1/login.ts +++ b/web/src/apis/v1/login.ts @@ -8,6 +8,7 @@ /////////////////////////////////////////////////////////////////////// /// import request from "@/utils/request"; +import useGlobalStore from "@/pages/globalStore"; /** * Redirect to login page @@ -17,7 +18,7 @@ export async function AuthControllerGetSigninUrl( ): Promise { // /v1/login let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/login`, { diff --git a/web/src/apis/v1/pat2token.ts b/web/src/apis/v1/pat2token.ts index a72abb2ee5..5a32849ae9 100644 --- a/web/src/apis/v1/pat2token.ts +++ b/web/src/apis/v1/pat2token.ts @@ -8,6 +8,7 @@ /////////////////////////////////////////////////////////////////////// /// import request from "@/utils/request"; +import useGlobalStore from "@/pages/globalStore"; /** * Get user token by PAT @@ -17,7 +18,7 @@ export async function AuthControllerPat2token( ): Promise { // /v1/pat2token let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/pat2token`, { diff --git a/web/src/apis/v1/pats.ts b/web/src/apis/v1/pats.ts index 5b932b35c9..ae88425fb6 100644 --- a/web/src/apis/v1/pats.ts +++ b/web/src/apis/v1/pats.ts @@ -8,6 +8,7 @@ /////////////////////////////////////////////////////////////////////// /// import request from "@/utils/request"; +import useGlobalStore from "@/pages/globalStore"; /** * Create a PAT @@ -17,7 +18,7 @@ export async function PatControllerCreate( ): Promise { // /v1/pats let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/pats`, { @@ -34,7 +35,7 @@ export async function PatControllerFindAll( ): Promise { // /v1/pats let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/pats`, { @@ -51,7 +52,7 @@ export async function PatControllerRemove( ): Promise { // /v1/pats/{id} let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/pats/${_params.id}`, { diff --git a/web/src/apis/v1/profile.ts b/web/src/apis/v1/profile.ts index acb253a60e..983acf8b25 100644 --- a/web/src/apis/v1/profile.ts +++ b/web/src/apis/v1/profile.ts @@ -8,6 +8,7 @@ /////////////////////////////////////////////////////////////////////// /// import request from "@/utils/request"; +import useGlobalStore from "@/pages/globalStore"; /** * Get current user profile @@ -17,7 +18,7 @@ export async function AuthControllerGetProfile( ): Promise { // /v1/profile let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/profile`, { diff --git a/web/src/apis/v1/regions.ts b/web/src/apis/v1/regions.ts index 57d92e13ad..9aa3d852c2 100644 --- a/web/src/apis/v1/regions.ts +++ b/web/src/apis/v1/regions.ts @@ -8,6 +8,7 @@ /////////////////////////////////////////////////////////////////////// /// import request from "@/utils/request"; +import useGlobalStore from "@/pages/globalStore"; /** * Get region list @@ -17,7 +18,7 @@ export async function RegionControllerGetRegions( ): Promise { // /v1/regions let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/regions`, { diff --git a/web/src/apis/v1/register.ts b/web/src/apis/v1/register.ts index c17831f3c1..8efd18f407 100644 --- a/web/src/apis/v1/register.ts +++ b/web/src/apis/v1/register.ts @@ -8,6 +8,7 @@ /////////////////////////////////////////////////////////////////////// /// import request from "@/utils/request"; +import useGlobalStore from "@/pages/globalStore"; /** * Redirect to register page @@ -17,7 +18,7 @@ export async function AuthControllerGetSignupUrl( ): Promise { // /v1/register let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/register`, { diff --git a/web/src/apis/v1/runtimes.ts b/web/src/apis/v1/runtimes.ts index bf09613687..9a3909f231 100644 --- a/web/src/apis/v1/runtimes.ts +++ b/web/src/apis/v1/runtimes.ts @@ -8,6 +8,7 @@ /////////////////////////////////////////////////////////////////////// /// import request from "@/utils/request"; +import useGlobalStore from "@/pages/globalStore"; /** * Get application runtime list @@ -17,7 +18,7 @@ export async function AppControllerGetRuntimes( ): Promise { // /v1/runtimes let _params: { [key: string]: any } = { - appid: localStorage.getItem("app"), + appid: useGlobalStore.getState().currentApp?.appid || "", ...params, }; return request(`/v1/runtimes`, { diff --git a/web/src/apis/v1/subscriptions.ts b/web/src/apis/v1/subscriptions.ts new file mode 100644 index 0000000000..04ac6087d1 --- /dev/null +++ b/web/src/apis/v1/subscriptions.ts @@ -0,0 +1,113 @@ +// @ts-ignore +/* eslint-disable */ +/////////////////////////////////////////////////////////////////////// +// // +// this file is autogenerated by service-generate // +// do not edit this file manually // +// // +/////////////////////////////////////////////////////////////////////// +/// +import request from "@/utils/request"; +import useGlobalStore from "@/pages/globalStore"; + +/** + * Create a new subscription + */ +export async function SubscriptionControllerCreate( + params: Definitions.CreateSubscriptionDto | any, +): Promise { + // /v1/subscriptions + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/subscriptions`, { + method: "POST", + data: params, + }); +} + +/** + * Get user's subscriptions + */ +export async function SubscriptionControllerFindAll( + params: Paths.SubscriptionControllerFindAll.BodyParameters | any, +): Promise { + // /v1/subscriptions + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/subscriptions`, { + method: "GET", + params: params, + }); +} + +/** + * Get subscription by appid + */ +export async function SubscriptionControllerFindOne( + params: Paths.SubscriptionControllerFindOne.BodyParameters | any, +): Promise { + // /v1/subscriptions/{appid} + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/subscriptions/${_params.appid}`, { + method: "GET", + params: params, + }); +} + +/** + * Renew a subscription + */ +export async function SubscriptionControllerRenew( + params: Definitions.RenewSubscriptionDto | any, +): Promise { + // /v1/subscriptions/{id}/renewal + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/subscriptions/${_params.id}/renewal`, { + method: "POST", + data: params, + }); +} + +/** + * Upgrade a subscription - TODO + */ +export async function SubscriptionControllerUpgrade( + params: Definitions.UpgradeSubscriptionDto | any, +): Promise { + // /v1/subscriptions/{id}/upgrade + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/subscriptions/${_params.id}/upgrade`, { + method: "PATCH", + data: params, + }); +} + +/** + * Delete a subscription + */ +export async function SubscriptionControllerRemove( + params: Paths.SubscriptionControllerRemove.BodyParameters | any, +): Promise { + // /v1/subscriptions/{id} + let _params: { [key: string]: any } = { + appid: useGlobalStore.getState().currentApp?.appid || "", + ...params, + }; + return request(`/v1/subscriptions/${_params.id}`, { + method: "DELETE", + data: params, + }); +} diff --git a/web/src/assets/login_bg.svg b/web/src/assets/login_bg.svg new file mode 100644 index 0000000000..ba979fb941 --- /dev/null +++ b/web/src/assets/login_bg.svg @@ -0,0 +1,465 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/src/chakraTheme.ts b/web/src/chakraTheme.ts index 2cff9f1d49..d5f3b8e5e6 100644 --- a/web/src/chakraTheme.ts +++ b/web/src/chakraTheme.ts @@ -6,6 +6,8 @@ import { defineStyleConfig, extendTheme, } from "@chakra-ui/react"; + +import { COLOR_MODE } from "./constants"; const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(tagAnatomy.keys); const Tag = defineMultiStyleConfig({ @@ -46,8 +48,8 @@ const Tag = defineMultiStyleConfig({ }), inputTag: definePartsStyle({ container: { - backgroundColor: "lafWhite.600", - borderColor: "lafWhite.600", + backgroundColor: "lafWhite.100", + borderColor: "lafWhite.100", borderWidth: 1, color: "grayModern.900", height: "28px", @@ -127,6 +129,27 @@ const Button = defineStyleConfig({ bg: "error.100", }, }, + + thirdly: { + color: "primary.500", + bg: "primary.100", + _hover: { + bg: "primary.200", + }, + border: "1px solid", + rounded: "md", + }, + + thirdly_disabled: { + bg: "grayModern.100", + color: "grayModern.500", + _hover: { + bg: "grayModern.100", + cursor: "not-allowed", + }, + border: "1px solid", + rounded: "md", + }, }, // The default size and variant values defaultProps: { @@ -323,7 +346,7 @@ const Menu = { }; const theme = extendTheme({ - initialColorMode: "dark", // 'dark | 'light' + initialColorMode: COLOR_MODE.dark, // 'dark | 'light' useSystemColorMode: false, fontSizes: { sm: "12px", diff --git a/web/src/chakraThemeDark.ts b/web/src/chakraThemeDark.ts index de459aa855..6cc3a6e1af 100644 --- a/web/src/chakraThemeDark.ts +++ b/web/src/chakraThemeDark.ts @@ -6,6 +6,8 @@ import { defineStyleConfig, extendTheme, } from "@chakra-ui/react"; + +import { COLOR_MODE } from "./constants"; const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(tagAnatomy.keys); const Tag = defineMultiStyleConfig({ @@ -50,7 +52,6 @@ const Tag = defineMultiStyleConfig({ borderColor: "lafWhite.600", borderWidth: 1, color: "grayModern.900", - height: "28px", }, }), inputTagActive: definePartsStyle({ @@ -59,7 +60,6 @@ const Tag = defineMultiStyleConfig({ borderColor: "primary.500", borderWidth: 1, color: "primary.500", - height: "28px", }, }), }, @@ -106,6 +106,16 @@ const Button = defineStyleConfig({ }, }, + thirdly: { + color: "lafDark.1000", + bg: "lafDark.300", + _hover: { + bg: "lafDark.400", + }, + border: "1px solid", + rounded: "md", + }, + plain: { bg: "grayModern.100", color: "grayModern.500", @@ -325,7 +335,7 @@ const Menu = { }; const theme = extendTheme({ - initialColorMode: "dark", // 'dark | 'light' + initialColorMode: COLOR_MODE.dark, // 'dark | 'light' useSystemColorMode: false, fontSizes: { sm: "12px", diff --git a/web/src/components/ChargeButton/index.tsx b/web/src/components/ChargeButton/index.tsx index 33aea8af0d..483a9fc49c 100644 --- a/web/src/components/ChargeButton/index.tsx +++ b/web/src/components/ChargeButton/index.tsx @@ -1,7 +1,9 @@ -import React from "react"; +import React, { useEffect } from "react"; import { Button, Input, + InputGroup, + InputLeftAddon, Modal, ModalBody, ModalCloseButton, @@ -10,34 +12,116 @@ import { ModalOverlay, useDisclosure, } from "@chakra-ui/react"; +import { useMutation, useQuery } from "@tanstack/react-query"; import { t } from "i18next"; import { QRCodeSVG } from "qrcode.react"; -export default function ChargeButton(props: { children: React.ReactElement }) { +import { CHARGE_CHANNEL, CURRENCY } from "@/constants"; +import { convertMoney, formatPrice } from "@/utils/format"; + +import { AccountControllerCharge, AccountControllerGetChargeOrder } from "@/apis/v1/accounts"; +import { useAccountQuery } from "@/pages/home/service"; + +export default function ChargeButton(props: { amount?: number; children: React.ReactElement }) { const { children } = props; const { isOpen, onOpen, onClose } = useDisclosure(); + + const initialAmount = props.amount && props.amount > 0 ? props.amount : 100; + + const [amount, setAmount] = React.useState(initialAmount); + + const [phaseStatus, setPhaseStatus] = React.useState<"Pending" | "Paid" | undefined>(); + + const createChargeOrder = useMutation( + ["AccountControllerCharge"], + (params: any) => AccountControllerCharge(params), + {}, + ); + + const accountQuery = useAccountQuery(); + + useQuery( + ["AccountControllerGetChargeOrder"], + () => + AccountControllerGetChargeOrder({ + id: createChargeOrder.data?.data?.order?.id, + }), + { + enabled: !!createChargeOrder.data?.data?.order?.id && isOpen, + refetchInterval: phaseStatus === "Pending" && isOpen ? 1000 : false, + onSuccess: (data) => { + setPhaseStatus(data.phase); + if (data.phase === "Paid") { + accountQuery.refetch(); + onClose(); + } + }, + }, + ); + + useEffect(() => { + const initialAmount = props.amount && props.amount > 0 ? props.amount : 100; + setAmount(initialAmount); + }, [props.amount]); + return ( <> {React.cloneElement(children, { onClick: onOpen })} - + {t("Charge")} - -
-

当前余额

-

¥ 0.00

-

充值金额

- - + +
+

{t("Balance")}

+

+ {formatPrice(accountQuery.data?.balance)} +

+

{t("Recharge amount")}

+ + + { + setAmount(Number(event.target.value)); + }} + /> + +
-
-

订单号:a2b6fc440f9978d53d7b4ad0a52e752e

- -

微信扫码支付

-
+ {createChargeOrder.data?.data?.result?.code_url && ( +
+

{t("Scan with WeChat")}

+ +

+ {t("Order Number")}:{createChargeOrder.data?.data?.order?.id} +

+

+ {t("payment status")}: {phaseStatus} +

+
+ )}
diff --git a/web/src/components/CommonIcon/index.ts b/web/src/components/CommonIcon/index.ts index 4b3c7ec578..e1f2273fc7 100644 --- a/web/src/components/CommonIcon/index.ts +++ b/web/src/components/CommonIcon/index.ts @@ -23,3 +23,39 @@ export const DarkModeIcon = createIcon({ viewBox: "0 0 32 32", d: "M9.353 2.939a1 1 0 01.22 1.08 8 8 0 0010.408 10.408 1 1 0 011.301 1.3A10.003 10.003 0 0112 22C6.477 22 2 17.523 2 12c0-4.207 2.598-7.805 6.273-9.282a1 1 0 011.08.22z", }); + +export const LangIcon = createIcon({ + displayName: "LangIcon", + viewBox: "0 0 20 20", + d: "M10 18.3333C5.39752 18.3333 1.66669 14.6025 1.66669 9.99996C1.66669 5.39746 5.39752 1.66663 10 1.66663C14.6025 1.66663 18.3334 5.39746 18.3334 9.99996C18.3334 14.6025 14.6025 18.3333 10 18.3333ZM8.09169 16.3891C7.26953 14.6452 6.79325 12.7585 6.68919 10.8333H3.38502C3.54718 12.1157 4.07829 13.3234 4.91383 14.3097C5.74937 15.296 6.85336 16.0184 8.09169 16.3891ZM8.35835 10.8333C8.48419 12.8658 9.06502 14.775 10 16.46C10.9603 14.7304 11.5212 12.8079 11.6417 10.8333H8.35835ZM16.615 10.8333H13.3109C13.2068 12.7585 12.7305 14.6452 11.9084 16.3891C13.1467 16.0184 14.2507 15.296 15.0862 14.3097C15.9218 13.3234 16.4529 12.1157 16.615 10.8333ZM3.38502 9.16663H6.68919C6.79325 7.24145 7.26953 5.3547 8.09169 3.61079C6.85336 3.98153 5.74937 4.70392 4.91383 5.69021C4.07829 6.67649 3.54718 7.88421 3.38502 9.16663ZM8.35919 9.16663H11.6409C11.5206 7.19212 10.96 5.26957 10 3.53996C9.03975 5.2695 8.47882 7.19206 8.35835 9.16663H8.35919ZM11.9084 3.61079C12.7305 5.3547 13.2068 7.24145 13.3109 9.16663H16.615C16.4529 7.88421 15.9218 6.67649 15.0862 5.69021C14.2507 4.70392 13.1467 3.98153 11.9084 3.61079Z", +}); + +export const GithubIcon = createIcon({ + displayName: "GithubIcon", + viewBox: "0 0 20 20", + d: "M9.99996 1.66663C5.39579 1.66663 1.66663 5.39579 1.66663 9.99996C1.66568 11.7494 2.21564 13.4546 3.23847 14.8739C4.26131 16.2931 5.70508 17.3542 7.36496 17.9066C7.78163 17.9791 7.93746 17.7291 7.93746 17.51C7.93746 17.3125 7.92663 16.6566 7.92663 15.9583C5.83329 16.3441 5.29163 15.4483 5.12496 14.9791C5.03079 14.7391 4.62496 14 4.27079 13.8016C3.97913 13.6458 3.56246 13.26 4.25996 13.25C4.91663 13.2391 5.38496 13.8541 5.54163 14.1041C6.29163 15.3641 7.48996 15.01 7.96829 14.7916C8.04163 14.25 8.25996 13.8858 8.49996 13.6775C6.64579 13.4691 4.70829 12.75 4.70829 9.56246C4.70829 8.65579 5.03079 7.90663 5.56246 7.32246C5.47913 7.11413 5.18746 6.25996 5.64579 5.11413C5.64579 5.11413 6.34329 4.89579 7.93746 5.96913C8.61585 5.78084 9.31677 5.68608 10.0208 5.68746C10.7291 5.68746 11.4375 5.78079 12.1041 5.96829C13.6975 4.88496 14.3958 5.11496 14.3958 5.11496C14.8541 6.26079 14.5625 7.11496 14.4791 7.32329C15.01 7.90663 15.3333 8.64579 15.3333 9.56246C15.3333 12.7608 13.3858 13.4691 11.5316 13.6775C11.8333 13.9375 12.0941 14.4375 12.0941 15.2191C12.0941 16.3333 12.0833 17.2291 12.0833 17.5108C12.0833 17.7291 12.24 17.9891 12.6566 17.9058C14.3108 17.3473 15.7482 16.2841 16.7665 14.8659C17.7849 13.4477 18.3328 11.7459 18.3333 9.99996C18.3333 5.39579 14.6041 1.66663 9.99996 1.66663Z", +}); + +export const WechatIcon = createIcon({ + displayName: "WechatIcon", + viewBox: "0 0 32 32", + d: "M18.574 13.711C18.8112 13.7079 19.0378 13.6123 19.2055 13.4445C19.3733 13.2768 19.4689 13.0502 19.472 12.813C19.472 12.315 19.073 11.915 18.574 11.915C18.075 11.915 17.676 12.315 17.676 12.813C17.676 13.313 18.076 13.711 18.574 13.711ZM14.149 13.711C14.3862 13.7079 14.6128 13.6123 14.7805 13.4445C14.9483 13.2768 15.0439 13.0502 15.047 12.813C15.047 12.315 14.647 11.915 14.149 11.915C13.649 11.915 13.251 12.315 13.251 12.813C13.251 13.313 13.65 13.711 14.149 13.711ZM20.716 18.751C20.6519 18.7866 20.6008 18.8416 20.5699 18.908C20.539 18.9745 20.5299 19.0491 20.544 19.121C20.544 19.169 20.544 19.218 20.569 19.268C20.667 19.685 20.863 20.349 20.863 20.374C20.863 20.447 20.888 20.496 20.888 20.546C20.888 20.575 20.8823 20.6037 20.8712 20.6304C20.86 20.6572 20.8437 20.6815 20.8232 20.7019C20.8027 20.7224 20.7783 20.7385 20.7515 20.7495C20.7247 20.7605 20.696 20.7661 20.667 20.766C20.617 20.766 20.593 20.742 20.544 20.718L19.095 19.882C18.9892 19.8238 18.8716 19.7903 18.751 19.784C18.678 19.784 18.604 19.784 18.555 19.808C17.867 20.005 17.155 20.103 16.394 20.103C12.734 20.103 9.787 17.646 9.787 14.598C9.787 11.551 12.734 9.093 16.394 9.093C20.053 9.093 23 11.551 23 14.598C23 16.245 22.116 17.744 20.716 18.752V18.751ZM16.673 8.099C16.5797 8.0959 16.4864 8.09423 16.393 8.094C12.219 8.094 8.787 10.954 8.787 14.599C8.787 15.153 8.867 15.689 9.015 16.199H8.926C8.05226 16.1902 7.18347 16.0664 6.342 15.831C6.268 15.806 6.194 15.806 6.12 15.806C5.97221 15.8091 5.82793 15.8516 5.702 15.929L3.954 16.934C3.904 16.959 3.855 16.984 3.806 16.984C3.73463 16.9832 3.66641 16.9545 3.61594 16.9041C3.56548 16.8536 3.53678 16.7854 3.536 16.714C3.536 16.64 3.56 16.591 3.585 16.517C3.609 16.493 3.831 15.683 3.954 15.193C3.954 15.143 3.978 15.07 3.978 15.021C3.97773 14.9353 3.95764 14.8508 3.9193 14.7741C3.88097 14.6974 3.82542 14.6307 3.757 14.579C2.058 13.376 1 11.586 1 9.598C1 5.945 4.57 3 8.95 3C12.715 3 15.88 5.169 16.673 8.098V8.099ZM11.519 8.517C12.092 8.517 12.545 8.04 12.545 7.491C12.545 6.918 12.092 6.465 11.519 6.465C10.946 6.465 10.493 6.918 10.493 7.491C10.493 8.064 10.946 8.517 11.519 8.517ZM6.259 8.517C6.832 8.517 7.286 8.04 7.286 7.491C7.286 6.918 6.832 6.465 6.259 6.465C5.687 6.465 5.233 6.918 5.233 7.491C5.233 8.064 5.687 8.517 6.259 8.517Z", +}); + +export const ForumIcon = createIcon({ + displayName: "ForumIcon", + viewBox: "0 0 32 32", + d: "M13.6228 19.7399C13.0966 19.8365 12.5542 19.8869 12.0001 19.8869C7.06474 19.8869 3.06384 15.886 3.06384 10.9507C3.06384 6.0153 7.06474 2.0144 12.0001 2.0144C16.9354 2.0144 20.9363 6.0153 20.9363 10.9507C20.9363 13.948 19.4606 16.6007 17.1962 18.2218L14.312 21.9195C14.2207 22.0365 14.0341 21.9907 14.0074 21.8447L13.6228 19.7399ZM9.3375 7.88363C8.97081 7.88363 8.62735 8.06321 8.41812 8.36435L6.63897 10.9249L6.62574 10.9318L6.62997 10.9379L6.62574 10.944L6.63897 10.9508L8.41844 13.5115C8.62768 13.8126 8.9711 13.9921 9.33777 13.9921L10.7393 13.9921L9.1522 10.9379L10.7393 7.88363H9.3375ZM13.9095 14.0177C13.3236 14.0177 12.8487 13.5428 12.8487 12.957C12.8487 12.3711 13.3236 11.8962 13.9095 11.8962H16.3137C16.8995 11.8962 17.3744 12.3711 17.3744 12.957C17.3744 13.5428 16.8995 14.0177 16.3137 14.0177H13.9095Z", +}); + +export const DiscordIcon = createIcon({ + displayName: "DiscordIcon", + viewBox: "0 0 32 32", + d: "M15.0831 17.7969C14.8161 17.862 14.5475 17.9197 14.2773 17.97C12.8114 18.2459 11.3063 18.2403 9.84252 17.9534C9.58615 17.9034 9.22324 17.8152 8.75545 17.6903L7.22224 19.683C3.43832 19.5615 2 17.0261 2 17.0261C2 11.3977 4.46546 6.83466 4.46546 6.83466C6.93091 4.94853 9.27651 5.00014 9.27651 5.00014L9.9474 5.87412C10.0092 5.86545 10.0715 5.8599 10.1338 5.85747C11.4127 5.68795 12.7087 5.69356 13.986 5.87412L14.7218 5.00014C14.7218 5.00014 17.0691 4.94853 19.5329 6.83633C19.5329 6.83633 22 11.3977 22 17.0261C22 17.0261 20.5434 19.5598 16.7594 19.683L15.0831 17.7969ZM8.69356 11.8369C7.69307 11.8369 6.90232 12.586 6.90232 13.5016C6.90232 14.4172 7.70971 15.1664 8.69356 15.1664C9.6924 15.1664 10.4831 14.4172 10.4831 13.5016C10.4998 12.586 9.69406 11.8369 8.69356 11.8369ZM15.0994 11.8369C14.1006 11.8369 13.3098 12.586 13.3098 13.5016C13.3098 14.4172 14.1172 15.1664 15.0994 15.1664C16.0999 15.1664 16.8907 14.4172 16.8907 13.5016C16.8907 12.586 16.0999 11.8369 15.0994 11.8369Z", +}); + +export const MenuIcon = createIcon({ + displayName: "MenuIcon", + viewBox: "0 0 24 24", + d: "M3 4H21V6H3V4ZM3 11H21V13H3V11ZM3 18H21V20H3V18Z", +}); diff --git a/web/src/components/ConfirmButton/index.tsx b/web/src/components/ConfirmButton/index.tsx index a8efaf968b..eae7fe522e 100644 --- a/web/src/components/ConfirmButton/index.tsx +++ b/web/src/components/ConfirmButton/index.tsx @@ -16,7 +16,7 @@ import { t } from "i18next"; interface ConfirmButtonProps { onSuccessAction: () => void; headerText: string; - bodyText: string; + bodyText: string | React.ReactElement | any; confirmButtonText?: string; children: React.ReactElement; } diff --git a/web/src/components/Content/index.tsx b/web/src/components/Content/index.tsx index 97e21757e8..32c86e01a7 100644 --- a/web/src/components/Content/index.tsx +++ b/web/src/components/Content/index.tsx @@ -1,5 +1,5 @@ import React from "react"; export default function Content(props: { children: React.ReactNode }) { - return
{props.children}
; + return
{props.children}
; } diff --git a/web/src/components/CopyText/index.tsx b/web/src/components/CopyText/index.tsx index 2f82fe33f7..e1fe5ce175 100644 --- a/web/src/components/CopyText/index.tsx +++ b/web/src/components/CopyText/index.tsx @@ -15,7 +15,13 @@ export default function CopyText(props: { const { onCopy, setValue } = useClipboard(""); const { showSuccess } = useGlobalStore(); - const { children = , text, tip, className, hideToolTip } = props; + const { + children = , + text, + tip, + className, + hideToolTip, + } = props; useEffect(() => { setValue(text || ""); diff --git a/web/src/components/DependenceList/index.module.scss b/web/src/components/DependenceList/index.module.scss index c1819792e2..d4f3e67bcc 100644 --- a/web/src/components/DependenceList/index.module.scss +++ b/web/src/components/DependenceList/index.module.scss @@ -13,14 +13,5 @@ span { vertical-align: middle; } - - &:hover, - &.active { - background-color: var(--chakra-colors-primary-100); - } - - &.active { - background-color: var(--chakra-colors-primary-300); - } } } diff --git a/web/src/components/DependenceList/index.tsx b/web/src/components/DependenceList/index.tsx index b091f75a31..f115b67707 100644 --- a/web/src/components/DependenceList/index.tsx +++ b/web/src/components/DependenceList/index.tsx @@ -1,6 +1,9 @@ import React from "react"; +import { useColorMode } from "@chakra-ui/react"; import clsx from "clsx"; +import { COLOR_MODE } from "@/constants"; + import styles from "./index.module.scss"; function DependenceList(props: { children: React.ReactNode; style?: React.CSSProperties }) { @@ -20,11 +23,17 @@ function Item(props: { onClick: () => void; }) { const { children, isActive, onClick, className, style } = props; + const { colorMode } = useColorMode(); + const darkMode = colorMode === COLOR_MODE.dark; + return (
  • diff --git a/web/src/components/DotBadge/index.tsx b/web/src/components/DotBadge/index.tsx index 5488214cba..dc2e3d91e9 100644 --- a/web/src/components/DotBadge/index.tsx +++ b/web/src/components/DotBadge/index.tsx @@ -31,7 +31,7 @@ export default function DotBadge({ } return ( - + {text} ); diff --git a/web/src/components/EditableTable/index.tsx b/web/src/components/EditableTable/index.tsx index d2f4b3a5cb..2e69f0bdd0 100644 --- a/web/src/components/EditableTable/index.tsx +++ b/web/src/components/EditableTable/index.tsx @@ -13,6 +13,8 @@ import { import clsx from "clsx"; import { t } from "i18next"; +import { COLOR_MODE } from "@/constants"; + import EditableTr, { TColumnItem, TConfiguration } from "./EditableTr"; import NormalTr from "./NormalTr"; @@ -32,7 +34,7 @@ const EditableTable = function (props: { const tableRef = useRef(null); const { colorMode } = useColorMode(); - const darkMode = colorMode === "dark"; + const darkMode = colorMode === COLOR_MODE.dark; useEffect(() => { setColumnList(column); @@ -80,7 +82,7 @@ const EditableTable = function (props: { return ( <>
    diff --git a/web/src/components/Editor/CodeViewer.tsx b/web/src/components/Editor/CodeViewer.tsx new file mode 100644 index 0000000000..4f1f2b1892 --- /dev/null +++ b/web/src/components/Editor/CodeViewer.tsx @@ -0,0 +1,255 @@ +import SyntaxHighlighter from "react-syntax-highlighter"; + +import { COLOR_MODE } from "@/constants"; + +type CodeViewerProps = { + code: string; + language: string; + showNumber?: boolean; + colorMode?: string; +}; + +const CodeViewerStyle: any = { + hljs: { + display: "block", + overflowX: "auto", + padding: "0.5em", + color: "#000", + background: "#f8f8ff", + }, + "hljs-comment": { + color: "#408080", + fontStyle: "italic", + }, + "hljs-quote": { + color: "#408080", + fontStyle: "italic", + }, + "hljs-keyword": { + color: "#954121", + }, + "hljs-selector-tag": { + color: "#954121", + }, + "hljs-literal": { + color: "#954121", + }, + "hljs-subst": { + color: "#954121", + }, + "hljs-number": { + color: "#b0caa4", + }, + "hljs-string": { + color: "#0451a5", + }, + + "hljs-selector-id": { + color: "#19469d", + }, + "hljs-selector-class": { + color: "#19469d", + }, + "hljs-section": { + color: "#19469d", + }, + "hljs-type": { + color: "#19469d", + }, + "hljs-params": { + color: "#00f", + }, + "hljs-title": { + color: "#458", + fontWeight: "bold", + }, + "hljs-tag": { + color: "#000080", + fontWeight: "normal", + }, + "hljs-name": { + color: "#000080", + fontWeight: "normal", + }, + "hljs-attr": { + color: "#a31515", + fontWeight: "normal", + }, + "hljs-attribute": { + color: "#000080", + fontWeight: "normal", + }, + "hljs-variable": { + color: "#008080", + }, + "hljs-template-variable": { + color: "#008080", + }, + "hljs-regexp": { + color: "#b68", + }, + "hljs-link": { + color: "#b68", + }, + "hljs-symbol": { + color: "#990073", + }, + "hljs-bullet": { + color: "#990073", + }, + "hljs-built_in": { + color: "#0086b3", + }, + "hljs-builtin-name": { + color: "#0086b3", + }, + "hljs-meta": { + color: "#999", + fontWeight: "bold", + }, + "hljs-deletion": { + background: "#fdd", + }, + "hljs-addition": { + background: "#dfd", + }, + "hljs-emphasis": { + fontStyle: "italic", + }, + "hljs-strong": { + fontWeight: "bold", + }, +}; + +const JSONViewerDarkStyle: any = { + hljs: { + display: "block", + overflowX: "auto", + padding: "0.5em", + color: "#000", + background: "#f8f8ff", + }, + "hljs-comment": { + color: "#408080", + fontStyle: "italic", + }, + "hljs-quote": { + color: "#408080", + fontStyle: "italic", + }, + "hljs-keyword": { + color: "#954121", + }, + "hljs-selector-tag": { + color: "#954121", + }, + "hljs-literal": { + color: "#954121", + }, + "hljs-subst": { + color: "#954121", + }, + "hljs-number": { + color: "#b0caa4", + }, + "hljs-string": { + color: "#ce9178", + }, + + "hljs-selector-id": { + color: "#19469d", + }, + "hljs-selector-class": { + color: "#19469d", + }, + "hljs-section": { + color: "#19469d", + }, + "hljs-type": { + color: "#19469d", + }, + "hljs-params": { + color: "#00f", + }, + "hljs-title": { + color: "#458", + fontWeight: "bold", + }, + "hljs-tag": { + color: "#000080", + fontWeight: "normal", + }, + "hljs-name": { + color: "#000080", + fontWeight: "normal", + }, + "hljs-attr": { + color: "#9bdcfe", + fontWeight: "normal", + }, + "hljs-attribute": { + color: "#000080", + fontWeight: "normal", + }, + "hljs-variable": { + color: "#008080", + }, + "hljs-template-variable": { + color: "#008080", + }, + "hljs-regexp": { + color: "#b68", + }, + "hljs-link": { + color: "#b68", + }, + "hljs-symbol": { + color: "#990073", + }, + "hljs-bullet": { + color: "#990073", + }, + "hljs-built_in": { + color: "#0086b3", + }, + "hljs-builtin-name": { + color: "#0086b3", + }, + "hljs-meta": { + color: "#999", + fontWeight: "bold", + }, + "hljs-deletion": { + background: "#fdd", + }, + "hljs-addition": { + background: "#dfd", + }, + "hljs-emphasis": { + fontStyle: "italic", + }, + "hljs-strong": { + fontWeight: "bold", + }, +}; +export default function CodeViewer(props: CodeViewerProps) { + const { code, language, colorMode = COLOR_MODE.light } = props; + const lightTheme = { background: "#fdfdfe" }; + const darkTheme = { + background: "#202631", + color: "#f0f0f0", + }; + + return ( +
    + + {code} + +
    + ); +} diff --git a/web/src/components/Editor/CommonDiffEditor.tsx b/web/src/components/Editor/CommonDiffEditor.tsx index c268681697..29594bd843 100644 --- a/web/src/components/Editor/CommonDiffEditor.tsx +++ b/web/src/components/Editor/CommonDiffEditor.tsx @@ -1,6 +1,9 @@ import { useEffect, useRef } from "react"; +import { useColorMode } from "@chakra-ui/react"; import * as monaco from "monaco-editor/esm/vs/editor/editor.api"; +import { COLOR_MODE } from "@/constants"; + import "./userWorker"; function CommonDiffEditor(props: { original: string; modified: string }) { @@ -10,6 +13,8 @@ function CommonDiffEditor(props: { original: string; modified: string }) { const monacoEl = useRef(null); + const { colorMode } = useColorMode(); + useEffect(() => { if (monacoEl && !editorRef.current) { editorRef.current = monaco.editor.createDiffEditor(monacoEl.current!, { @@ -21,6 +26,12 @@ function CommonDiffEditor(props: { original: string; modified: string }) { renderOverviewRuler: false, fontSize: 14, scrollBeyondLastLine: false, + scrollbar: { + verticalScrollbarSize: 4, + horizontalScrollbarSize: 6, + alwaysConsumeMouseWheel: false, + }, + theme: colorMode === COLOR_MODE.dark ? "lafEditorThemeDark" : "lafEditorTheme", }); editorRef.current.setModel({ @@ -30,7 +41,7 @@ function CommonDiffEditor(props: { original: string; modified: string }) { } return () => {}; - }, [modified, original]); + }, [colorMode, modified, original]); return
    ; } diff --git a/web/src/components/Editor/ENVEditor.tsx b/web/src/components/Editor/ENVEditor.tsx new file mode 100644 index 0000000000..230bace75c --- /dev/null +++ b/web/src/components/Editor/ENVEditor.tsx @@ -0,0 +1,134 @@ +import { useEffect, useRef } from "react"; +import * as monaco from "monaco-editor/esm/vs/editor/editor.api"; + +import { COLOR_MODE } from "@/constants"; + +import "./userWorker"; + +const languageId = "dotenv"; + +monaco.languages.register({ + id: languageId, +}); + +monaco.languages.setMonarchTokensProvider(languageId, { + tokenizer: { + root: [ + [/^\w+(?==)/, "key"], + [/(=)([^=]*)$/, ["operator", "value"]], + [/^#.*/, "comment"], + // new lines + [/.*/, "value"], + ], + }, +}); + +monaco.editor.defineTheme("dotenvTheme", { + base: "vs", + inherit: true, + colors: { + "editor.background": "#ffffff00", + "editorLineNumber.foreground": "#aaa", + "editorOverviewRuler.border": "#ffffff00", + "editor.lineHighlightBackground": "#F7F8FA", + "scrollbarSlider.background": "#E8EAEC", + "editorIndentGuide.activeBackground": "#ddd", + "editorIndentGuide.background": "#eee", + }, + rules: [ + { token: "key", foreground: "953800" }, + { token: "value", foreground: "2E4C7E" }, + { token: "operator", foreground: "CF212E" }, + { token: "comment", foreground: "0A3069" }, + ], +}); + +monaco?.editor.defineTheme("dotenvDarkTheme", { + base: "vs-dark", + inherit: true, + rules: [], + colors: { + "editor.foreground": "#ffffff", + "editor.background": "#202631", + }, +}); + +function ENVEditor(props: { + value: string; + height?: string; + style?: any; + colorMode?: string; + onChange?: (value: string | undefined) => void; +}) { + const { value, style = {}, onChange, height = "95%", colorMode = COLOR_MODE.light } = props; + + const editorRef = useRef(); + const subscriptionRef = useRef(undefined); + const monacoEl = useRef(null); + + useEffect(() => { + if (monacoEl && !editorRef.current) { + editorRef.current = monaco.editor.create(monacoEl.current!, { + language: languageId, + theme: colorMode === COLOR_MODE.dark ? "dotenvDarkTheme" : "dotenvTheme", + lineNumbers: "off", + guides: { + indentation: false, + }, + automaticLayout: true, + minimap: { + enabled: false, + }, + scrollbar: { + verticalScrollbarSize: 4, + horizontalScrollbarSize: 8, + alwaysConsumeMouseWheel: false, + }, + lineNumbersMinChars: 0, + fontSize: 13, + lineHeight: 22, + scrollBeyondLastLine: false, + folding: false, + overviewRulerBorder: false, + tabSize: 2, // tab 缩进长度 + }); + } + + return () => {}; + }, [colorMode, value]); + + // onChange + useEffect(() => { + subscriptionRef.current?.dispose(); + + if (onChange) { + subscriptionRef.current = editorRef.current?.onDidChangeModelContent((event) => { + onChange(editorRef.current?.getValue()); + }); + } + }, [onChange]); + + useEffect(() => { + if (monacoEl && editorRef.current && value !== editorRef.current?.getValue()) { + editorRef.current?.getModel()?.setValue(value); + editorRef.current?.layout(); + } + }, [value]); + + // useEffect(() => { + // if (monacoEl && editorRef.current) { + // editorRef.current.updateOptions({ + // theme: colorMode === COLOR_MODE.dark ? "JSONEditorThemeDark" : "JSONEditorTheme", + // }); + // } + // }, [colorMode]); + + return ( +
    + ); +} + +export default ENVEditor; diff --git a/web/src/components/Editor/FunctionEditor.tsx b/web/src/components/Editor/FunctionEditor.tsx index 837f348ddd..83a87e5564 100644 --- a/web/src/components/Editor/FunctionEditor.tsx +++ b/web/src/components/Editor/FunctionEditor.tsx @@ -1,11 +1,16 @@ -import { useEffect, useRef } from "react"; +import { CSSProperties, useEffect, useRef } from "react"; import { debounce } from "lodash"; import * as monaco from "monaco-editor/esm/vs/editor/editor.api"; +import { COLOR_MODE, Pages } from "@/constants"; + import "./userWorker"; import { AutoImportTypings } from "./typesResolve"; +import useHotKey, { DEFAULT_SHORTCUTS } from "@/hooks/useHotKey"; +import useGlobalStore from "@/pages/globalStore"; + const autoImportTypings = new AutoImportTypings(); const parseImports = debounce(autoImportTypings.parse, 1500).bind(autoImportTypings); @@ -29,7 +34,12 @@ monaco.languages.typescript.typescriptDefaults.setCompilerOptions({ monaco?.editor.defineTheme("lafEditorTheme", { base: "vs", inherit: true, - rules: [], + rules: [ + { + foreground: "#0066ff", + token: "keyword", + }, + ], colors: { "editorLineNumber.foreground": "#aaa", "editorOverviewRuler.border": "#fff", @@ -50,8 +60,22 @@ monaco?.editor.defineTheme("lafEditorThemeDark", { }, ], colors: { + // https://github.com/microsoft/monaco-editor/discussions/3838 "editor.foreground": "#ffffff", "editor.background": "#202631", + "editorIndentGuide.activeBackground": "#fff", + "editorIndentGuide.background": "#eee", + "editor.selectionBackground": "#101621", + "menu.selectionBackground": "#101621", + "dropdown.background": "#1a202c", + "dropdown.foreground": "#f0f0f0", + "dropdown.border": "#fff", + "quickInputList.focusBackground": "#1a202c", + "editorWidget.background": "#1a202c", + "editorWidget.foreground": "#f0f0f0", + "editorWidget.border": "#1a202c", + "input.background": "#1a202c", + "list.hoverBackground": "#2a303c", }, }); @@ -69,31 +93,59 @@ const updateModel = (path: string, value: string, editorRef: any) => { function FunctionEditor(props: { value: string; className?: string; - onChange: (value: string | undefined) => void; + style?: CSSProperties; + onChange?: (value: string | undefined) => void; path: string; height?: string; colorMode?: string; + readOnly?: boolean; }) { - const { value, onChange, path, height = "100%", className, colorMode = "light" } = props; + const { + value, + onChange, + path, + height = "100%", + className, + style = {}, + colorMode = COLOR_MODE.light, + readOnly = false, + } = props; + const editorRef = useRef(); const subscriptionRef = useRef(undefined); const monacoEl = useRef(null); + const globalStore = useGlobalStore((state) => state); + + useHotKey( + DEFAULT_SHORTCUTS.send_request, + () => { + // format + editorRef.current?.trigger("keyboard", "editor.action.formatDocument", {}); + }, + { + enabled: globalStore.currentPageId === Pages.function, + }, + ); + useEffect(() => { if (monacoEl && !editorRef.current) { editorRef.current = monaco.editor.create(monacoEl.current!, { minimap: { enabled: false, }, + readOnly: readOnly, language: "typescript", automaticLayout: true, scrollbar: { - verticalScrollbarSize: 6, + verticalScrollbarSize: 4, + horizontalScrollbarSize: 8, }, + formatOnPaste: true, overviewRulerLanes: 0, lineNumbersMinChars: 4, fontSize: 14, - theme: colorMode === "dark" ? "lafEditorThemeDark" : "lafEditorTheme", + theme: colorMode === COLOR_MODE.dark ? "lafEditorThemeDark" : "lafEditorTheme", scrollBeyondLastLine: false, }); @@ -105,7 +157,7 @@ function FunctionEditor(props: { } return () => {}; - }, [colorMode, path, value]); + }, [colorMode, path, readOnly, value]); useEffect(() => { if (monacoEl && editorRef.current) { @@ -116,7 +168,7 @@ function FunctionEditor(props: { useEffect(() => { if (monacoEl && editorRef.current) { editorRef.current.updateOptions({ - theme: colorMode === "dark" ? "lafEditorThemeDark" : "lafEditorTheme", + theme: colorMode === COLOR_MODE.dark ? "lafEditorThemeDark" : "lafEditorTheme", }); } }, [colorMode]); @@ -132,7 +184,7 @@ function FunctionEditor(props: { } }, [onChange]); - return
    ; + return
    ; } export default FunctionEditor; diff --git a/web/src/components/Editor/JsonEditor.tsx b/web/src/components/Editor/JSONEditor.tsx similarity index 80% rename from web/src/components/Editor/JsonEditor.tsx rename to web/src/components/Editor/JSONEditor.tsx index e9790ac6d3..a97f6fcaa2 100644 --- a/web/src/components/Editor/JsonEditor.tsx +++ b/web/src/components/Editor/JSONEditor.tsx @@ -1,9 +1,11 @@ import { useEffect, useRef } from "react"; import * as monaco from "monaco-editor/esm/vs/editor/editor.api"; +import { COLOR_MODE } from "@/constants"; + import "./userWorker"; -monaco?.editor.defineTheme("JsonEditorTheme", { +monaco?.editor.defineTheme("JSONEditorTheme", { base: "vs", inherit: true, rules: [], @@ -18,7 +20,7 @@ monaco?.editor.defineTheme("JsonEditorTheme", { }, }); -monaco?.editor.defineTheme("JsonEditorThemeDark", { +monaco?.editor.defineTheme("JSONEditorThemeDark", { base: "vs-dark", inherit: true, rules: [], @@ -28,13 +30,13 @@ monaco?.editor.defineTheme("JsonEditorThemeDark", { }, }); -function JsonEditor(props: { +function JSONEditor(props: { value: string; height?: string; colorMode?: string; onChange?: (value: string | undefined) => void; }) { - const { value, onChange, height = "95%", colorMode = "light" } = props; + const { value, onChange, height = "90%", colorMode = COLOR_MODE.light } = props; const editorRef = useRef(); const subscriptionRef = useRef(undefined); @@ -52,15 +54,16 @@ function JsonEditor(props: { enabled: false, }, scrollbar: { - verticalScrollbarSize: 0, + verticalScrollbarSize: 4, + horizontalScrollbarSize: 8, alwaysConsumeMouseWheel: false, }, lineNumbersMinChars: 0, - fontSize: 14, + fontSize: 12, scrollBeyondLastLine: false, folding: false, overviewRulerBorder: false, - theme: colorMode === "dark" ? "JsonEditorThemeDark" : "JsonEditorTheme", + theme: colorMode === COLOR_MODE.dark ? "JSONEditorThemeDark" : "JSONEditorTheme", tabSize: 2, // tab 缩进长度 model: monaco.editor.createModel(value, "json"), }); @@ -89,7 +92,7 @@ function JsonEditor(props: { useEffect(() => { if (monacoEl && editorRef.current) { editorRef.current.updateOptions({ - theme: colorMode === "dark" ? "JsonEditorThemeDark" : "JsonEditorTheme", + theme: colorMode === COLOR_MODE.dark ? "JSONEditorThemeDark" : "JSONEditorTheme", }); } }, [colorMode]); @@ -97,4 +100,4 @@ function JsonEditor(props: { return
    ; } -export default JsonEditor; +export default JSONEditor; diff --git a/web/src/components/Editor/JSONViewer.tsx b/web/src/components/Editor/JSONViewer.tsx index 7b14caa017..26f39f2d2d 100644 --- a/web/src/components/Editor/JSONViewer.tsx +++ b/web/src/components/Editor/JSONViewer.tsx @@ -1,10 +1,13 @@ import SyntaxHighlighter from "react-syntax-highlighter"; -type JSONViewerProp = { +import { COLOR_MODE } from "@/constants"; + +type JSONViewerProps = { code: string; language?: string; showNumber?: boolean; colorMode?: string; + className?: string; }; const JSONViewerStyle: any = { @@ -36,7 +39,7 @@ const JSONViewerStyle: any = { color: "#954121", }, "hljs-number": { - color: "#b0caa4", + color: "#01A99D", }, "hljs-string": { color: "#0451a5", @@ -234,8 +237,8 @@ const JSONViewerDarkStyle: any = { fontWeight: "bold", }, }; -export default function JSONViewer(prop: JSONViewerProp) { - const { code, language = "json", colorMode = "light" } = prop; +export default function JSONViewer(props: JSONViewerProps) { + const { code, language = "json", colorMode = COLOR_MODE.light, ...rest } = props; const lightTheme = { background: "#fdfdfe" }; const darkTheme = { background: "#202631", @@ -243,12 +246,20 @@ export default function JSONViewer(prop: JSONViewerProp) { }; return ( - - {code} - + + {code} + +
    ); } diff --git a/web/src/components/Editor/typesResolve/globals.ts b/web/src/components/Editor/typesResolve/globals.ts index 178b0112be..4f9086c5cf 100644 --- a/web/src/components/Editor/typesResolve/globals.ts +++ b/web/src/components/Editor/typesResolve/globals.ts @@ -1,6 +1,12 @@ +import { requestType } from "./requestType"; import { responseType } from "./responseType"; +import { readableStreamTypes, streamTypes, writableStreamTypes } from "./streamType"; export const globalDeclare = ` +${streamTypes} +${readableStreamTypes} +${writableStreamTypes} +${requestType} ${responseType} declare class FunctionConsole { @@ -75,6 +81,11 @@ interface FunctionContext { */ method?: string; + /** + * Express request object + */ + request?: HttpRequest; + /** * Express response object */ diff --git a/web/src/components/Editor/typesResolve/requestType.ts b/web/src/components/Editor/typesResolve/requestType.ts new file mode 100644 index 0000000000..e579d7974d --- /dev/null +++ b/web/src/components/Editor/typesResolve/requestType.ts @@ -0,0 +1,486 @@ +const incomingMessageType = ` + class IncomingMessage extends Readable { + constructor(socket: Socket); + /** + * The 'message.aborted' property will be 'true' if the request has + * been aborted. + * @since v10.1.0 + * @deprecated Since v17.0.0,v16.12.0 - Check 'message.destroyed' from stream.Readable. + */ + aborted: boolean; + /** + * In case of server request, the HTTP version sent by the client. In the case of + * client response, the HTTP version of the connected-to server. + * Probably either ''1.1'' or ''1.0''. + * + * Also 'message.httpVersionMajor' is the first integer and'message.httpVersionMinor' is the second. + * @since v0.1.1 + */ + httpVersion: string; + httpVersionMajor: number; + httpVersionMinor: number; + /** + * The 'message.complete' property will be 'true' if a complete HTTP message has + * been received and successfully parsed. + * + * This property is particularly useful as a means of determining if a client or + * server fully transmitted a message before a connection was terminated: + * + * '''js + * const req = http.request({ + * host: '127.0.0.1', + * port: 8080, + * method: 'POST' + * }, (res) => { + * res.resume(); + * res.on('end', () => { + * if (!res.complete) + * console.error( + * 'The connection was terminated while the message was still being sent'); + * }); + * }); + * ''' + * @since v0.3.0 + */ + complete: boolean; + /** + * Alias for 'message.socket'. + * @since v0.1.90 + * @deprecated Since v16.0.0 - Use 'socket'. + */ + connection: Socket; + /** + * The 'net.Socket' object associated with the connection. + * + * With HTTPS support, use 'request.socket.getPeerCertificate()' to obtain the + * client's authentication details. + * + * This property is guaranteed to be an instance of the 'net.Socket' class, + * a subclass of 'stream.Duplex', unless the user specified a socket + * type other than 'net.Socket' or internally nulled. + * @since v0.3.0 + */ + socket: Socket; + /** + * The request/response headers object. + * + * Key-value pairs of header names and values. Header names are lower-cased. + * + * '''js + * // Prints something like: + * // + * // { 'user-agent': 'curl/7.22.0', + * // host: '127.0.0.1:8000', + * // accept: '*' } + * console.log(request.getHeaders()); + * ''' + * + * Duplicates in raw headers are handled in the following ways, depending on the + * header name: + * + * * Duplicates of 'age', 'authorization', 'content-length', 'content-type','etag', 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since','last-modified', 'location', + * 'max-forwards', 'proxy-authorization', 'referer','retry-after', 'server', or 'user-agent' are discarded. + * * 'set-cookie' is always an array. Duplicates are added to the array. + * * For duplicate 'cookie' headers, the values are joined together with '; '. + * * For all other headers, the values are joined together with ', '. + * @since v0.1.5 + */ + headers: IncomingHttpHeaders; + /** + * The raw request/response headers list exactly as they were received. + * + * The keys and values are in the same list. It is _not_ a + * list of tuples. So, the even-numbered offsets are key values, and the + * odd-numbered offsets are the associated values. + * + * Header names are not lowercased, and duplicates are not merged. + * + * '''js + * // Prints something like: + * // + * // [ 'user-agent', + * // 'this is invalid because there can be only one', + * // 'User-Agent', + * // 'curl/7.22.0', + * // 'Host', + * // '127.0.0.1:8000', + * // 'ACCEPT', + * // '*' ] + * console.log(request.rawHeaders); + * ''' + * @since v0.11.6 + */ + rawHeaders: string[]; + /** + * The request/response trailers object. Only populated at the ''end'' event. + * @since v0.3.0 + */ + trailers: NodeJS.Dict; + /** + * The raw request/response trailer keys and values exactly as they were + * received. Only populated at the ''end'' event. + * @since v0.11.6 + */ + rawTrailers: string[]; + /** + * Calls 'message.socket.setTimeout(msecs, callback)'. + * @since v0.5.9 + */ + setTimeout(msecs: number, callback?: () => void): this; + /** + * **Only valid for request obtained from {@link Server}.** + * + * The request method as a string. Read only. Examples: ''GET'', ''DELETE''. + * @since v0.1.1 + */ + method?: string | undefined; + /** + * **Only valid for request obtained from {@link Server}.** + * + * Request URL string. This contains only the URL that is present in the actual + * HTTP request. Take the following request: + * + * '''http + * GET /status?name=ryan HTTP/1.1 + * Accept: text/plain + * ''' + * + * To parse the URL into its parts: + * + * '''js + * new URL(request.url, 'http://\${request.getHeaders().host}'); + * ''' + * + * When 'request.url' is ''/status?name=ryan'' and'request.getHeaders().host' is ''localhost:3000'': + * + * '''console + * $ node + * > new URL(request.url, 'http://\${request.getHeaders().host}') + * URL { + * href: 'http://localhost:3000/status?name=ryan', + * origin: 'http://localhost:3000', + * protocol: 'http:', + * username: '', + * password: '', + * host: 'localhost:3000', + * hostname: 'localhost', + * port: '3000', + * pathname: '/status', + * search: '?name=ryan', + * searchParams: URLSearchParams { 'name' => 'ryan' }, + * hash: '' + * } + * ''' + * @since v0.1.90 + */ + url?: string | undefined; + /** + * **Only valid for response obtained from {@link ClientRequest}.** + * + * The 3-digit HTTP response status code. E.G. '404'. + * @since v0.1.1 + */ + statusCode?: number | undefined; + /** + * **Only valid for response obtained from {@link ClientRequest}.** + * + * The HTTP response status message (reason phrase). E.G. 'OK' or 'Internal Server Error'. + * @since v0.11.10 + */ + statusMessage?: string | undefined; + /** + * Calls 'destroy()' on the socket that received the 'IncomingMessage'. If 'error'is provided, an ''error'' event is emitted on the socket and 'error' is passed + * as an argument to any listeners on the event. + * @since v0.3.0 + */ + destroy(error?: Error): this; +} +`; + +export const requestType = ` + ${incomingMessageType} + +/** + * @see https://expressjs.com/en/api.html#req.params + * + * @example + * app.get('/user/:id', (req, res) => res.send(req.params.id)); // implicitly 'ParamsDictionary' + * app.get(/user\/(.*)/, (req, res) => res.send(req.params[0])); + * app.get('/user/*', (req, res) => res.send(req.params[0])); + */ +interface HttpRequest extends IncomingMessage { + /** + * Return request header. + * + * The 'Referrer' header field is special-cased, + * both 'Referrer' and 'Referer' are interchangeable. + * + * Examples: + * + * req.get('Content-Type'); + * // => "text/plain" + * + * req.get('content-type'); + * // => "text/plain" + * + * req.get('Something'); + * // => undefined + * + * Aliased as 'req.header()'. + */ + get(name: 'set-cookie'): string[] | undefined; + get(name: string): string | undefined; + + header(name: 'set-cookie'): string[] | undefined; + header(name: string): string | undefined; + + /** + * Check if the given 'type(s)' is acceptable, returning + * the best match when true, otherwise 'undefined', in which + * case you should respond with 406 "Not Acceptable". + * + * The 'type' value may be a single mime type string + * such as "application/json", the extension name + * such as "json", a comma-delimted list such as "json, html, text/plain", + * or an array '["json", "html", "text/plain"]'. When a list + * or array is given the _best_ match, if any is returned. + * + * Examples: + * + * // Accept: text/html + * req.accepts('html'); + * // => "html" + * + * // Accept: text/*, application/json + * req.accepts('html'); + * // => "html" + * req.accepts('text/html'); + * // => "text/html" + * req.accepts('json, text'); + * // => "json" + * req.accepts('application/json'); + * // => "application/json" + * + * // Accept: text/*, application/json + * req.accepts('image/png'); + * req.accepts('png'); + * // => undefined + * + * // Accept: text/*;q=.5, application/json + * req.accepts(['html', 'json']); + * req.accepts('html, json'); + * // => "json" + */ + accepts(): string[]; + accepts(type: string): string | false; + accepts(type: string[]): string | false; + accepts(...type: string[]): string | false; + + /** + * Returns the first accepted charset of the specified character sets, + * based on the request's Accept-Charset HTTP header field. + * If none of the specified charsets is accepted, returns false. + * + * For more information, or if you have issues or concerns, see accepts. + */ + acceptsCharsets(): string[]; + acceptsCharsets(charset: string): string | false; + acceptsCharsets(charset: string[]): string | false; + acceptsCharsets(...charset: string[]): string | false; + + /** + * Returns the first accepted encoding of the specified encodings, + * based on the request's Accept-Encoding HTTP header field. + * If none of the specified encodings is accepted, returns false. + * + * For more information, or if you have issues or concerns, see accepts. + */ + acceptsEncodings(): string[]; + acceptsEncodings(encoding: string): string | false; + acceptsEncodings(encoding: string[]): string | false; + acceptsEncodings(...encoding: string[]): string | false; + + /** + * Returns the first accepted language of the specified languages, + * based on the request's Accept-Language HTTP header field. + * If none of the specified languages is accepted, returns false. + * + * For more information, or if you have issues or concerns, see accepts. + */ + acceptsLanguages(): string[]; + acceptsLanguages(lang: string): string | false; + acceptsLanguages(lang: string[]): string | false; + acceptsLanguages(...lang: string[]): string | false; + + /** + * Parse Range header field, capping to the given 'size'. + * + * Unspecified ranges such as "0-" require knowledge of your resource length. In + * the case of a byte range this is of course the total number of bytes. + * If the Range header field is not given 'undefined' is returned. + * If the Range header field is given, return value is a result of range-parser. + * See more ./types/range-parser/index.d.ts + * + * NOTE: remember that ranges are inclusive, so for example "Range: users=0-3" + * should respond with 4 users when available, not 3. + * + */ + range(size: number, options?: RangeParserOptions): RangeParserRanges | RangeParserResult | undefined; + + /** + * Return an array of Accepted media types + * ordered from highest quality to lowest. + */ + accepted: MediaType[]; + + /** + * @deprecated since 4.11 Use either req.params, req.body or req.query, as applicable. + * + * Return the value of param 'name' when present or 'defaultValue'. + * + * - Checks route placeholders, ex: _/user/:id_ + * - Checks body params, ex: id=12, {"id":12} + * - Checks query string params, ex: ?id=12 + * + * To utilize request bodies, 'req.body' + * should be an object. This can be done by using + * the 'connect.bodyParser()' middleware. + */ + param(name: string, defaultValue?: any): string; + + /** + * Check if the incoming request contains the "Content-Type" + * header field, and it contains the give mime 'type'. + * + * Examples: + * + * // With Content-Type: text/html; charset=utf-8 + * req.is('html'); + * req.is('text/html'); + * req.is('text/*'); + * // => true + * + * // When Content-Type is application/json + * req.is('json'); + * req.is('application/json'); + * req.is('application/*'); + * // => true + * + * req.is('html'); + * // => false + */ + is(type: string | string[]): string | false | null; + + /** + * Return the protocol string "http" or "https" + * when requested with TLS. When the "trust proxy" + * setting is enabled the "X-Forwarded-Proto" header + * field will be trusted. If you're running behind + * a reverse proxy that supplies https for you this + * may be enabled. + */ + protocol: string; + + /** + * Short-hand for: + * + * req.protocol == 'https' + */ + secure: boolean; + + /** + * Return the remote address, or when + * "trust proxy" is 'true' return + * the upstream addr. + */ + ip: string; + + /** + * When "trust proxy" is 'true', parse + * the "X-Forwarded-For" ip address list. + * + * For example if the value were "client, proxy1, proxy2" + * you would receive the array '["client", "proxy1", "proxy2"]' + * where "proxy2" is the furthest down-stream. + */ + ips: string[]; + + /** + * Return subdomains as an array. + * + * Subdomains are the dot-separated parts of the host before the main domain of + * the app. By default, the domain of the app is assumed to be the last two + * parts of the host. This can be changed by setting "subdomain offset". + * + * For example, if the domain is "tobi.ferrets.example.com": + * If "subdomain offset" is not set, req.subdomains is '["ferrets", "tobi"]'. + * If "subdomain offset" is 3, req.subdomains is '["tobi"]'. + */ + subdomains: string[]; + + /** + * Short-hand for 'url.parse(req.url).pathname'. + */ + path: string; + + /** + * Parse the "Host" header field hostname. + */ + hostname: string; + + /** + * @deprecated Use hostname instead. + */ + host: string; + + /** + * Check if the request is fresh, aka + * Last-Modified and/or the ETag + * still match. + */ + fresh: boolean; + + /** + * Check if the request is stale, aka + * "Last-Modified" and / or the "ETag" for the + * resource has changed. + */ + stale: boolean; + + /** + * Check if the request was an _XMLHttpRequest_. + */ + xhr: boolean; + + //body: { username: string; password: string; remember: boolean; title: string; }; + body: ReqBody; + + //cookies: { string; remember: boolean; }; + cookies: any; + + method: string; + + params: P; + + query: ReqQuery; + + route: any; + + signedCookies: any; + + originalUrl: string; + + url: string; + + baseUrl: string; + + app: Application; + + /** + * After middleware.init executed, Request will contain res and next properties + * See: express/lib/middleware/init.js + */ + res?: Response | undefined; + next?: NextFunction | undefined; +} +`; diff --git a/web/src/components/Editor/typesResolve/responseType.ts b/web/src/components/Editor/typesResolve/responseType.ts index c6587c2d85..c4c6086bb0 100644 --- a/web/src/components/Editor/typesResolve/responseType.ts +++ b/web/src/components/Editor/typesResolve/responseType.ts @@ -1,6 +1,6 @@ const outgoingMessageType = ` -declare class OutgoingMessage extends Stream { +declare class OutgoingMessage extends Writable { readonly req: IncomingMessage; chunkedEncoding: boolean; shouldKeepAlive: boolean; @@ -135,8 +135,7 @@ declare class OutgoingMessage extends Stream { export const responseType = ` ${outgoingMessageType} -// declare class ServerResponse extends OutgoingMessage{ -declare class ServerResponse { +declare class ServerResponse extends OutgoingMessage{ statusCode: number; statusMessage: string; diff --git a/web/src/components/Editor/typesResolve/streamType.ts b/web/src/components/Editor/typesResolve/streamType.ts new file mode 100644 index 0000000000..ed73fe6346 --- /dev/null +++ b/web/src/components/Editor/typesResolve/streamType.ts @@ -0,0 +1,753 @@ +export const streamTypes = ` +class Stream extends EventEmitter { + constructor(opts?: ReadableOptions); + pipe( + destination: T, + options?: { + end?: boolean | undefined; + } + ): T; +} +`; + +export const readableStreamTypes = ` +interface StreamOptions extends Abortable { + emitClose?: boolean | undefined; + highWaterMark?: number | undefined; + objectMode?: boolean | undefined; + construct?(this: T, callback: (error?: Error | null) => void): void; + destroy?(this: T, error: Error | null, callback: (error: Error | null) => void): void; + autoDestroy?: boolean | undefined; +} +interface ReadableOptions extends StreamOptions { + encoding?: BufferEncoding | undefined; + read?(this: Readable, size: number): void; +} +/** + * @since v0.9.4 + */ +class Readable extends Stream implements NodeJS.ReadableStream { + /** + * A utility method for creating Readable Streams out of iterators. + */ + static from(iterable: Iterable | AsyncIterable, options?: ReadableOptions): Readable; + /** + * Returns whether the stream has been read from or cancelled. + * @since v16.8.0 + */ + static isDisturbed(stream: Readable | NodeJS.ReadableStream): boolean; + /** + * Returns whether the stream was destroyed or errored before emitting ''end''. + * @since v16.8.0 + * @experimental + */ + readonly readableAborted: boolean; + /** + * Is 'true' if it is safe to call 'readable.read()', which means + * the stream has not been destroyed or emitted ''error'' or ''end''. + * @since v11.4.0 + */ + readable: boolean; + /** + * Returns whether ''data'' has been emitted. + * @since v16.7.0 + * @experimental + */ + readonly readableDidRead: boolean; + /** + * Getter for the property 'encoding' of a given 'Readable' stream. The 'encoding'property can be set using the 'readable.setEncoding()' method. + * @since v12.7.0 + */ + readonly readableEncoding: BufferEncoding | null; + /** + * Becomes 'true' when ''end'' event is emitted. + * @since v12.9.0 + */ + readonly readableEnded: boolean; + /** + * This property reflects the current state of a 'Readable' stream as described + * in the 'Three states' section. + * @since v9.4.0 + */ + readonly readableFlowing: boolean | null; + /** + * Returns the value of 'highWaterMark' passed when creating this 'Readable'. + * @since v9.3.0 + */ + readonly readableHighWaterMark: number; + /** + * This property contains the number of bytes (or objects) in the queue + * ready to be read. The value provides introspection data regarding + * the status of the 'highWaterMark'. + * @since v9.4.0 + */ + readonly readableLength: number; + /** + * Getter for the property 'objectMode' of a given 'Readable' stream. + * @since v12.3.0 + */ + readonly readableObjectMode: boolean; + /** + * Is 'true' after 'readable.destroy()' has been called. + * @since v8.0.0 + */ + destroyed: boolean; + constructor(opts?: ReadableOptions); + _construct?(callback: (error?: Error | null) => void): void; + _read(size: number): void; + /** + * The 'readable.read()' method pulls some data out of the internal buffer and + * returns it. If no data available to be read, 'null' is returned. By default, + * the data will be returned as a 'Buffer' object unless an encoding has been + * specified using the 'readable.setEncoding()' method or the stream is operating + * in object mode. + * + * The optional 'size' argument specifies a specific number of bytes to read. If'size' bytes are not available to be read, 'null' will be returned _unless_the stream has ended, in which + * case all of the data remaining in the internal + * buffer will be returned. + * + * If the 'size' argument is not specified, all of the data contained in the + * internal buffer will be returned. + * + * The 'size' argument must be less than or equal to 1 GiB. + * + * The 'readable.read()' method should only be called on 'Readable' streams + * operating in paused mode. In flowing mode, 'readable.read()' is called + * automatically until the internal buffer is fully drained. + * + * '''js + * const readable = getReadableStreamSomehow(); + * + * // 'readable' may be triggered multiple times as data is buffered in + * readable.on('readable', () => { + * let chunk; + * console.log('Stream is readable (new data received in buffer)'); + * // Use a loop to make sure we read all currently available data + * while (null !== (chunk = readable.read())) { + * console.log('Read \${chunk.length} bytes of data...'); + * } + * }); + * + * // 'end' will be triggered once when there is no more data available + * readable.on('end', () => { + * console.log('Reached end of stream.'); + * }); + * ''' + * + * Each call to 'readable.read()' returns a chunk of data, or 'null'. The chunks + * are not concatenated. A 'while' loop is necessary to consume all data + * currently in the buffer. When reading a large file '.read()' may return 'null', + * having consumed all buffered content so far, but there is still more data to + * come not yet buffered. In this case a new ''readable'' event will be emitted + * when there is more data in the buffer. Finally the ''end'' event will be + * emitted when there is no more data to come. + * + * Therefore to read a file's whole contents from a 'readable', it is necessary + * to collect chunks across multiple ''readable'' events: + * + * '''js + * const chunks = []; + * + * readable.on('readable', () => { + * let chunk; + * while (null !== (chunk = readable.read())) { + * chunks.push(chunk); + * } + * }); + * + * readable.on('end', () => { + * const content = chunks.join(''); + * }); + * ''' + * + * A 'Readable' stream in object mode will always return a single item from + * a call to 'readable.read(size)', regardless of the value of the'size' argument. + * + * If the 'readable.read()' method returns a chunk of data, a ''data'' event will + * also be emitted. + * + * Calling {@link read} after the ''end'' event has + * been emitted will return 'null'. No runtime error will be raised. + * @since v0.9.4 + * @param size Optional argument to specify how much data to read. + */ + read(size?: number): any; + /** + * The 'readable.setEncoding()' method sets the character encoding for + * data read from the 'Readable' stream. + * + * By default, no encoding is assigned and stream data will be returned as'Buffer' objects. Setting an encoding causes the stream data + * to be returned as strings of the specified encoding rather than as 'Buffer'objects. For instance, calling 'readable.setEncoding('utf8')' will cause the + * output data to be interpreted as UTF-8 data, and passed as strings. Calling'readable.setEncoding('hex')' will cause the data to be encoded in hexadecimal + * string format. + * + * The 'Readable' stream will properly handle multi-byte characters delivered + * through the stream that would otherwise become improperly decoded if simply + * pulled from the stream as 'Buffer' objects. + * + * '''js + * const readable = getReadableStreamSomehow(); + * readable.setEncoding('utf8'); + * readable.on('data', (chunk) => { + * assert.equal(typeof chunk, 'string'); + * console.log('Got %d characters of string data:', chunk.length); + * }); + * ''' + * @since v0.9.4 + * @param encoding The encoding to use. + */ + setEncoding(encoding: BufferEncoding): this; + /** + * The 'readable.pause()' method will cause a stream in flowing mode to stop + * emitting ''data'' events, switching out of flowing mode. Any data that + * becomes available will remain in the internal buffer. + * + * '''js + * const readable = getReadableStreamSomehow(); + * readable.on('data', (chunk) => { + * console.log('Received \${chunk.length} bytes of data.'); + * readable.pause(); + * console.log('There will be no additional data for 1 second.'); + * setTimeout(() => { + * console.log('Now data will start flowing again.'); + * readable.resume(); + * }, 1000); + * }); + * ''' + * + * The 'readable.pause()' method has no effect if there is a ''readable''event listener. + * @since v0.9.4 + */ + pause(): this; + /** + * The 'readable.resume()' method causes an explicitly paused 'Readable' stream to + * resume emitting ''data'' events, switching the stream into flowing mode. + * + * The 'readable.resume()' method can be used to fully consume the data from a + * stream without actually processing any of that data: + * + * '''js + * getReadableStreamSomehow() + * .resume() + * .on('end', () => { + * console.log('Reached the end, but did not read anything.'); + * }); + * ''' + * + * The 'readable.resume()' method has no effect if there is a ''readable''event listener. + * @since v0.9.4 + */ + resume(): this; + /** + * The 'readable.isPaused()' method returns the current operating state of the'Readable'. This is used primarily by the mechanism that underlies the'readable.pipe()' method. In most + * typical cases, there will be no reason to + * use this method directly. + * + * '''js + * const readable = new stream.Readable(); + * + * readable.isPaused(); // === false + * readable.pause(); + * readable.isPaused(); // === true + * readable.resume(); + * readable.isPaused(); // === false + * ''' + * @since v0.11.14 + */ + isPaused(): boolean; + /** + * The 'readable.unpipe()' method detaches a 'Writable' stream previously attached + * using the {@link pipe} method. + * + * If the 'destination' is not specified, then _all_ pipes are detached. + * + * If the 'destination' is specified, but no pipe is set up for it, then + * the method does nothing. + * + * '''js + * const fs = require('fs'); + * const readable = getReadableStreamSomehow(); + * const writable = fs.createWriteStream('file.txt'); + * // All the data from readable goes into 'file.txt', + * // but only for the first second. + * readable.pipe(writable); + * setTimeout(() => { + * console.log('Stop writing to file.txt.'); + * readable.unpipe(writable); + * console.log('Manually close the file stream.'); + * writable.end(); + * }, 1000); + * ''' + * @since v0.9.4 + * @param destination Optional specific stream to unpipe + */ + unpipe(destination?: NodeJS.WritableStream): this; + /** + * Passing 'chunk' as 'null' signals the end of the stream (EOF) and behaves the + * same as 'readable.push(null)', after which no more data can be written. The EOF + * signal is put at the end of the buffer and any buffered data will still be + * flushed. + * + * The 'readable.unshift()' method pushes a chunk of data back into the internal + * buffer. This is useful in certain situations where a stream is being consumed by + * code that needs to "un-consume" some amount of data that it has optimistically + * pulled out of the source, so that the data can be passed on to some other party. + * + * The 'stream.unshift(chunk)' method cannot be called after the ''end'' event + * has been emitted or a runtime error will be thrown. + * + * Developers using 'stream.unshift()' often should consider switching to + * use of a 'Transform' stream instead. See the 'API for stream implementers' section for more information. + * + * '''js + * // Pull off a header delimited by \n\n. + * // Use unshift() if we get too much. + * // Call the callback with (error, header, stream). + * const { StringDecoder } = require('string_decoder'); + * function parseHeader(stream, callback) { + * stream.on('error', callback); + * stream.on('readable', onReadable); + * const decoder = new StringDecoder('utf8'); + * let header = ''; + * function onReadable() { + * let chunk; + * while (null !== (chunk = stream.read())) { + * const str = decoder.write(chunk); + * if (str.match(/\n\n/)) { + * // Found the header boundary. + * const split = str.split(/\n\n/); + * header += split.shift(); + * const remaining = split.join('\n\n'); + * const buf = Buffer.from(remaining, 'utf8'); + * stream.removeListener('error', callback); + * // Remove the 'readable' listener before unshifting. + * stream.removeListener('readable', onReadable); + * if (buf.length) + * stream.unshift(buf); + * // Now the body of the message can be read from the stream. + * callback(null, header, stream); + * } else { + * // Still reading the header. + * header += str; + * } + * } + * } + * } + * ''' + * + * Unlike {@link push}, 'stream.unshift(chunk)' will not + * end the reading process by resetting the internal reading state of the stream. + * This can cause unexpected results if 'readable.unshift()' is called during a + * read (i.e. from within a {@link _read} implementation on a + * custom stream). Following the call to 'readable.unshift()' with an immediate {@link push} will reset the reading state appropriately, + * however it is best to simply avoid calling 'readable.unshift()' while in the + * process of performing a read. + * @since v0.9.11 + * @param chunk Chunk of data to unshift onto the read queue. For streams not operating in object mode, 'chunk' must be a string, 'Buffer', 'Uint8Array' or 'null'. For object mode + * streams, 'chunk' may be any JavaScript value. + * @param encoding Encoding of string chunks. Must be a valid 'Buffer' encoding, such as ''utf8'' or ''ascii''. + */ + unshift(chunk: any, encoding?: BufferEncoding): void; + /** + * Prior to Node.js 0.10, streams did not implement the entire 'stream' module API + * as it is currently defined. (See 'Compatibility' for more information.) + * + * When using an older Node.js library that emits ''data'' events and has a {@link pause} method that is advisory only, the'readable.wrap()' method can be used to create a 'Readable' + * stream that uses + * the old stream as its data source. + * + * It will rarely be necessary to use 'readable.wrap()' but the method has been + * provided as a convenience for interacting with older Node.js applications and + * libraries. + * + * '''js + * const { OldReader } = require('./old-api-module.js'); + * const { Readable } = require('stream'); + * const oreader = new OldReader(); + * const myReader = new Readable().wrap(oreader); + * + * myReader.on('readable', () => { + * myReader.read(); // etc. + * }); + * ''' + * @since v0.9.4 + * @param stream An "old style" readable stream + */ + wrap(stream: NodeJS.ReadableStream): this; + push(chunk: any, encoding?: BufferEncoding): boolean; + _destroy(error: Error | null, callback: (error?: Error | null) => void): void; + /** + * Destroy the stream. Optionally emit an ''error'' event, and emit a ''close''event (unless 'emitClose' is set to 'false'). After this call, the readable + * stream will release any internal resources and subsequent calls to 'push()'will be ignored. + * + * Once 'destroy()' has been called any further calls will be a no-op and no + * further errors except from '_destroy()' may be emitted as ''error''. + * + * Implementors should not override this method, but instead implement 'readable._destroy()'. + * @since v8.0.0 + * @param error Error which will be passed as payload in ''error'' event + */ + destroy(error?: Error): this; + /** + * Event emitter + * The defined events on documents including: + * 1. close + * 2. data + * 3. end + * 4. error + * 5. pause + * 6. readable + * 7. resume + */ + addListener(event: 'close', listener: () => void): this; + addListener(event: 'data', listener: (chunk: any) => void): this; + addListener(event: 'end', listener: () => void): this; + addListener(event: 'error', listener: (err: Error) => void): this; + addListener(event: 'pause', listener: () => void): this; + addListener(event: 'readable', listener: () => void): this; + addListener(event: 'resume', listener: () => void): this; + addListener(event: string | symbol, listener: (...args: any[]) => void): this; + emit(event: 'close'): boolean; + emit(event: 'data', chunk: any): boolean; + emit(event: 'end'): boolean; + emit(event: 'error', err: Error): boolean; + emit(event: 'pause'): boolean; + emit(event: 'readable'): boolean; + emit(event: 'resume'): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + on(event: 'close', listener: () => void): this; + on(event: 'data', listener: (chunk: any) => void): this; + on(event: 'end', listener: () => void): this; + on(event: 'error', listener: (err: Error) => void): this; + on(event: 'pause', listener: () => void): this; + on(event: 'readable', listener: () => void): this; + on(event: 'resume', listener: () => void): this; + on(event: string | symbol, listener: (...args: any[]) => void): this; + once(event: 'close', listener: () => void): this; + once(event: 'data', listener: (chunk: any) => void): this; + once(event: 'end', listener: () => void): this; + once(event: 'error', listener: (err: Error) => void): this; + once(event: 'pause', listener: () => void): this; + once(event: 'readable', listener: () => void): this; + once(event: 'resume', listener: () => void): this; + once(event: string | symbol, listener: (...args: any[]) => void): this; + prependListener(event: 'close', listener: () => void): this; + prependListener(event: 'data', listener: (chunk: any) => void): this; + prependListener(event: 'end', listener: () => void): this; + prependListener(event: 'error', listener: (err: Error) => void): this; + prependListener(event: 'pause', listener: () => void): this; + prependListener(event: 'readable', listener: () => void): this; + prependListener(event: 'resume', listener: () => void): this; + prependListener(event: string | symbol, listener: (...args: any[]) => void): this; + prependOnceListener(event: 'close', listener: () => void): this; + prependOnceListener(event: 'data', listener: (chunk: any) => void): this; + prependOnceListener(event: 'end', listener: () => void): this; + prependOnceListener(event: 'error', listener: (err: Error) => void): this; + prependOnceListener(event: 'pause', listener: () => void): this; + prependOnceListener(event: 'readable', listener: () => void): this; + prependOnceListener(event: 'resume', listener: () => void): this; + prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this; + removeListener(event: 'close', listener: () => void): this; + removeListener(event: 'data', listener: (chunk: any) => void): this; + removeListener(event: 'end', listener: () => void): this; + removeListener(event: 'error', listener: (err: Error) => void): this; + removeListener(event: 'pause', listener: () => void): this; + removeListener(event: 'readable', listener: () => void): this; + removeListener(event: 'resume', listener: () => void): this; + removeListener(event: string | symbol, listener: (...args: any[]) => void): this; + [Symbol.asyncIterator](): AsyncIterableIterator; +} +`; + +export const writableStreamTypes = ` +interface WritableOptions extends StreamOptions { + decodeStrings?: boolean | undefined; + defaultEncoding?: BufferEncoding | undefined; + write?(this: Writable, chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void): void; + writev?( + this: Writable, + chunks: Array<{ + chunk: any; + encoding: BufferEncoding; + }>, + callback: (error?: Error | null) => void + ): void; + final?(this: Writable, callback: (error?: Error | null) => void): void; +} +/** +* @since v0.9.4 +*/ +class Writable extends Stream implements NodeJS.WritableStream { + /** + * Is 'true' if it is safe to call 'writable.write()', which means + * the stream has not been destroyed, errored or ended. + * @since v11.4.0 + */ + readonly writable: boolean; + /** + * Is 'true' after 'writable.end()' has been called. This property + * does not indicate whether the data has been flushed, for this use 'writable.writableFinished' instead. + * @since v12.9.0 + */ + readonly writableEnded: boolean; + /** + * Is set to 'true' immediately before the ''finish'' event is emitted. + * @since v12.6.0 + */ + readonly writableFinished: boolean; + /** + * Return the value of 'highWaterMark' passed when creating this 'Writable'. + * @since v9.3.0 + */ + readonly writableHighWaterMark: number; + /** + * This property contains the number of bytes (or objects) in the queue + * ready to be written. The value provides introspection data regarding + * the status of the 'highWaterMark'. + * @since v9.4.0 + */ + readonly writableLength: number; + /** + * Getter for the property 'objectMode' of a given 'Writable' stream. + * @since v12.3.0 + */ + readonly writableObjectMode: boolean; + /** + * Number of times 'writable.uncork()' needs to be + * called in order to fully uncork the stream. + * @since v13.2.0, v12.16.0 + */ + readonly writableCorked: number; + /** + * Is 'true' after 'writable.destroy()' has been called. + * @since v8.0.0 + */ + destroyed: boolean; + constructor(opts?: WritableOptions); + _write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void): void; + _writev?( + chunks: Array<{ + chunk: any; + encoding: BufferEncoding; + }>, + callback: (error?: Error | null) => void + ): void; + _construct?(callback: (error?: Error | null) => void): void; + _destroy(error: Error | null, callback: (error?: Error | null) => void): void; + _final(callback: (error?: Error | null) => void): void; + /** + * The 'writable.write()' method writes some data to the stream, and calls the + * supplied 'callback' once the data has been fully handled. If an error + * occurs, the 'callback' will be called with the error as its + * first argument. The 'callback' is called asynchronously and before ''error'' is + * emitted. + * + * The return value is 'true' if the internal buffer is less than the'highWaterMark' configured when the stream was created after admitting 'chunk'. + * If 'false' is returned, further attempts to write data to the stream should + * stop until the ''drain'' event is emitted. + * + * While a stream is not draining, calls to 'write()' will buffer 'chunk', and + * return false. Once all currently buffered chunks are drained (accepted for + * delivery by the operating system), the ''drain'' event will be emitted. + * It is recommended that once 'write()' returns false, no more chunks be written + * until the ''drain'' event is emitted. While calling 'write()' on a stream that + * is not draining is allowed, Node.js will buffer all written chunks until + * maximum memory usage occurs, at which point it will abort unconditionally. + * Even before it aborts, high memory usage will cause poor garbage collector + * performance and high RSS (which is not typically released back to the system, + * even after the memory is no longer required). Since TCP sockets may never + * drain if the remote peer does not read the data, writing a socket that is + * not draining may lead to a remotely exploitable vulnerability. + * + * Writing data while the stream is not draining is particularly + * problematic for a 'Transform', because the 'Transform' streams are paused + * by default until they are piped or a ''data'' or ''readable'' event handler + * is added. + * + * If the data to be written can be generated or fetched on demand, it is + * recommended to encapsulate the logic into a 'Readable' and use {@link pipe}. However, if calling 'write()' is preferred, it is + * possible to respect backpressure and avoid memory issues using the ''drain'' event: + * + * '''js + * function write(data, cb) { + * if (!stream.write(data)) { + * stream.once('drain', cb); + * } else { + * process.nextTick(cb); + * } + * } + * + * // Wait for cb to be called before doing any other write. + * write('hello', () => { + * console.log('Write completed, do more writes now.'); + * }); + * ''' + * + * A 'Writable' stream in object mode will always ignore the 'encoding' argument. + * @since v0.9.4 + * @param chunk Optional data to write. For streams not operating in object mode, 'chunk' must be a string, 'Buffer' or 'Uint8Array'. For object mode streams, 'chunk' may be any + * JavaScript value other than 'null'. + * @param [encoding='utf8'] The encoding, if 'chunk' is a string. + * @param callback Callback for when this chunk of data is flushed. + * @return 'false' if the stream wishes for the calling code to wait for the ''drain'' event to be emitted before continuing to write additional data; otherwise 'true'. + */ + write(chunk: any, callback?: (error: Error | null | undefined) => void): boolean; + write(chunk: any, encoding: BufferEncoding, callback?: (error: Error | null | undefined) => void): boolean; + /** + * The 'writable.setDefaultEncoding()' method sets the default 'encoding' for a 'Writable' stream. + * @since v0.11.15 + * @param encoding The new default encoding + */ + setDefaultEncoding(encoding: BufferEncoding): this; + /** + * Calling the 'writable.end()' method signals that no more data will be written + * to the 'Writable'. The optional 'chunk' and 'encoding' arguments allow one + * final additional chunk of data to be written immediately before closing the + * stream. + * + * Calling the {@link write} method after calling {@link end} will raise an error. + * + * '''js + * // Write 'hello, ' and then end with 'world!'. + * const fs = require('fs'); + * const file = fs.createWriteStream('example.txt'); + * file.write('hello, '); + * file.end('world!'); + * // Writing more now is not allowed! + * ''' + * @since v0.9.4 + * @param chunk Optional data to write. For streams not operating in object mode, 'chunk' must be a string, 'Buffer' or 'Uint8Array'. For object mode streams, 'chunk' may be any + * JavaScript value other than 'null'. + * @param encoding The encoding if 'chunk' is a string + * @param callback Callback for when the stream is finished. + */ + end(cb?: () => void): this; + end(chunk: any, cb?: () => void): this; + end(chunk: any, encoding: BufferEncoding, cb?: () => void): this; + /** + * The 'writable.cork()' method forces all written data to be buffered in memory. + * The buffered data will be flushed when either the {@link uncork} or {@link end} methods are called. + * + * The primary intent of 'writable.cork()' is to accommodate a situation in which + * several small chunks are written to the stream in rapid succession. Instead of + * immediately forwarding them to the underlying destination, 'writable.cork()'buffers all the chunks until 'writable.uncork()' is called, which will pass them + * all to 'writable._writev()', if present. This prevents a head-of-line blocking + * situation where data is being buffered while waiting for the first small chunk + * to be processed. However, use of 'writable.cork()' without implementing'writable._writev()' may have an adverse effect on throughput. + * + * See also: 'writable.uncork()', 'writable._writev()'. + * @since v0.11.2 + */ + cork(): void; + /** + * The 'writable.uncork()' method flushes all data buffered since {@link cork} was called. + * + * When using 'writable.cork()' and 'writable.uncork()' to manage the buffering + * of writes to a stream, it is recommended that calls to 'writable.uncork()' be + * deferred using 'process.nextTick()'. Doing so allows batching of all'writable.write()' calls that occur within a given Node.js event loop phase. + * + * '''js + * stream.cork(); + * stream.write('some '); + * stream.write('data '); + * process.nextTick(() => stream.uncork()); + * ''' + * + * If the 'writable.cork()' method is called multiple times on a stream, the + * same number of calls to 'writable.uncork()' must be called to flush the buffered + * data. + * + * '''js + * stream.cork(); + * stream.write('some '); + * stream.cork(); + * stream.write('data '); + * process.nextTick(() => { + * stream.uncork(); + * // The data will not be flushed until uncork() is called a second time. + * stream.uncork(); + * }); + * ''' + * + * See also: 'writable.cork()'. + * @since v0.11.2 + */ + uncork(): void; + /** + * Destroy the stream. Optionally emit an ''error'' event, and emit a ''close''event (unless 'emitClose' is set to 'false'). After this call, the writable + * stream has ended and subsequent calls to 'write()' or 'end()' will result in + * an 'ERR_STREAM_DESTROYED' error. + * This is a destructive and immediate way to destroy a stream. Previous calls to'write()' may not have drained, and may trigger an 'ERR_STREAM_DESTROYED' error. + * Use 'end()' instead of destroy if data should flush before close, or wait for + * the ''drain'' event before destroying the stream. + * + * Once 'destroy()' has been called any further calls will be a no-op and no + * further errors except from '_destroy()' may be emitted as ''error''. + * + * Implementors should not override this method, + * but instead implement 'writable._destroy()'. + * @since v8.0.0 + * @param error Optional, an error to emit with ''error'' event. + */ + destroy(error?: Error): this; + /** + * Event emitter + * The defined events on documents including: + * 1. close + * 2. drain + * 3. error + * 4. finish + * 5. pipe + * 6. unpipe + */ + addListener(event: 'close', listener: () => void): this; + addListener(event: 'drain', listener: () => void): this; + addListener(event: 'error', listener: (err: Error) => void): this; + addListener(event: 'finish', listener: () => void): this; + addListener(event: 'pipe', listener: (src: Readable) => void): this; + addListener(event: 'unpipe', listener: (src: Readable) => void): this; + addListener(event: string | symbol, listener: (...args: any[]) => void): this; + emit(event: 'close'): boolean; + emit(event: 'drain'): boolean; + emit(event: 'error', err: Error): boolean; + emit(event: 'finish'): boolean; + emit(event: 'pipe', src: Readable): boolean; + emit(event: 'unpipe', src: Readable): boolean; + emit(event: string | symbol, ...args: any[]): boolean; + on(event: 'close', listener: () => void): this; + on(event: 'drain', listener: () => void): this; + on(event: 'error', listener: (err: Error) => void): this; + on(event: 'finish', listener: () => void): this; + on(event: 'pipe', listener: (src: Readable) => void): this; + on(event: 'unpipe', listener: (src: Readable) => void): this; + on(event: string | symbol, listener: (...args: any[]) => void): this; + once(event: 'close', listener: () => void): this; + once(event: 'drain', listener: () => void): this; + once(event: 'error', listener: (err: Error) => void): this; + once(event: 'finish', listener: () => void): this; + once(event: 'pipe', listener: (src: Readable) => void): this; + once(event: 'unpipe', listener: (src: Readable) => void): this; + once(event: string | symbol, listener: (...args: any[]) => void): this; + prependListener(event: 'close', listener: () => void): this; + prependListener(event: 'drain', listener: () => void): this; + prependListener(event: 'error', listener: (err: Error) => void): this; + prependListener(event: 'finish', listener: () => void): this; + prependListener(event: 'pipe', listener: (src: Readable) => void): this; + prependListener(event: 'unpipe', listener: (src: Readable) => void): this; + prependListener(event: string | symbol, listener: (...args: any[]) => void): this; + prependOnceListener(event: 'close', listener: () => void): this; + prependOnceListener(event: 'drain', listener: () => void): this; + prependOnceListener(event: 'error', listener: (err: Error) => void): this; + prependOnceListener(event: 'finish', listener: () => void): this; + prependOnceListener(event: 'pipe', listener: (src: Readable) => void): this; + prependOnceListener(event: 'unpipe', listener: (src: Readable) => void): this; + prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this; + removeListener(event: 'close', listener: () => void): this; + removeListener(event: 'drain', listener: () => void): this; + removeListener(event: 'error', listener: (err: Error) => void): this; + removeListener(event: 'finish', listener: () => void): this; + removeListener(event: 'pipe', listener: (src: Readable) => void): this; + removeListener(event: 'unpipe', listener: (src: Readable) => void): this; + removeListener(event: string | symbol, listener: (...args: any[]) => void): this; +} +`; diff --git a/web/src/components/EmptyBox/index.tsx b/web/src/components/EmptyBox/index.tsx index 54b7737f89..5f4305f982 100644 --- a/web/src/components/EmptyBox/index.tsx +++ b/web/src/components/EmptyBox/index.tsx @@ -10,7 +10,7 @@ export default function EmptyBox(props: { }) { const { children, hideIcon, className } = props; return ( -
    +
    {hideIcon ? null : ( + void }) { - + {t("Or")} diff --git a/web/src/components/Grid/index.tsx b/web/src/components/Grid/index.tsx index 7cf4fc8aee..9d781cf29d 100644 --- a/web/src/components/Grid/index.tsx +++ b/web/src/components/Grid/index.tsx @@ -40,8 +40,8 @@ function Col(props: { return (
    void; }) { + const { colorMode } = useColorMode(); + const darkMode = colorMode === COLOR_MODE.dark; + return (
    {React.cloneElement(props.icon, { height: "20px", diff --git a/web/src/components/IconWrap/index.tsx b/web/src/components/IconWrap/index.tsx index 8e30640c0b..439052d2f7 100644 --- a/web/src/components/IconWrap/index.tsx +++ b/web/src/components/IconWrap/index.tsx @@ -2,6 +2,8 @@ import React from "react"; import { Center, Tooltip, useColorMode } from "@chakra-ui/react"; import clsx from "clsx"; +import { COLOR_MODE } from "@/constants"; + export default function IconWrap(props: { size?: number; children: React.ReactNode; @@ -13,12 +15,12 @@ export default function IconWrap(props: { }) { const { size = 20, tooltip, placement = "top", showBg = false, className } = props; const { colorMode } = useColorMode(); - const darkMode = colorMode === "dark"; + const darkMode = colorMode === COLOR_MODE.dark; return (
    any }) { const { value, onChange } = props; const [inputV, setInputV] = useState(""); + const { colorMode } = useColorMode(); + const darkMode = colorMode === COLOR_MODE.dark; const handleEnter = (e: any) => { - if (e.key === "Enter" || e.key === " ") { + if (e.key === "Enter") { e.preventDefault(); const input = inputV.trim().slice(0, 16); if (input !== "" && !value.some((x) => x === input)) { @@ -19,18 +24,15 @@ export default function InputTag(props: { value: string[]; onChange: (value: str onChange(value.filter((name) => name !== item)); }; return ( - <> - handleEnter(e)} - onChange={(e) => setInputV(e.target.value)} - /> - {value.length > 0 ? ( -
    - {value.map((item) => ( - +
    + {value.length > 0 + ? value.map((item) => ( + {item} { @@ -38,9 +40,19 @@ export default function InputTag(props: { value: string[]; onChange: (value: str }} /> - ))} -
    - ) : null} - + )) + : null} + handleEnter(e)} + onChange={(e) => { + // onChange([e.target.value]); + setInputV(e.target.value); + }} + /> +
    ); } diff --git a/web/src/components/Panel/index.tsx b/web/src/components/Panel/index.tsx index 4b221e1c6b..2a89fe8d62 100644 --- a/web/src/components/Panel/index.tsx +++ b/web/src/components/Panel/index.tsx @@ -17,7 +17,7 @@ const Panel = (props: { style={style} bg={bg} onClick={onClick} - className={clsx("rounded px-4 flex flex-col w-full", className)} + className={clsx("flex w-full flex-col rounded px-4", className)} > {props.children} diff --git a/web/src/components/Resize/index.tsx b/web/src/components/Resize/index.tsx index 0e4d05db5f..77e42e4f9c 100644 --- a/web/src/components/Resize/index.tsx +++ b/web/src/components/Resize/index.tsx @@ -41,16 +41,16 @@ export default function Resize(props: { {display === "none" ? null : (
    -
    +
    {type === "x" && width <= 20 ? (
    {reverse ? : } @@ -61,15 +61,15 @@ export default function Resize(props: { className={clsx( type === "x" && isDragging ? "h-full " : "h-0", type === "y" && isDragging ? "w-full " : "w-0", - isDragging ? " border-primary-400 border" : "", - "transition-all absolute z-10 overflow-hidden", + isDragging ? " border border-primary-400" : "", + "absolute z-10 overflow-hidden transition-all", )} >
    diff --git a/web/src/constants/index.ts b/web/src/constants/index.ts index 9ea9ab1791..26b0a18ce8 100644 --- a/web/src/constants/index.ts +++ b/web/src/constants/index.ts @@ -54,3 +54,24 @@ export enum BUCKET_POLICY_TYPE { export enum BUCKET_STATUS { Active = "Active", } + +export enum CHARGE_CHANNEL { + WeChat = "WeChat", + Alipay = "Alipay", +} + +export enum CURRENCY { + CNY = "CNY", + USD = "USD", +} + +export const Routes = { + dashboard: "/dashboard", +}; + +export const CHAKRA_UI_COLOR_MODE_KEY = "chakra-ui-color-mode"; + +export const COLOR_MODE = { + light: "light", + dark: "dark", +}; diff --git a/web/src/hooks/useAwsS3.ts b/web/src/hooks/useAwsS3.ts index 4961ba6e89..bcf7109eb6 100644 --- a/web/src/hooks/useAwsS3.ts +++ b/web/src/hooks/useAwsS3.ts @@ -45,7 +45,27 @@ function useAwsS3() { }; const deleteFile = async (bucket: string, key: string) => { - const res = await s3.deleteObject({ Bucket: bucket, Key: key }).promise(); + const { Versions } = await s3 + .listObjectVersions({ + Bucket: bucket, + Prefix: key, + }) + .promise(); + const res = await s3 + .deleteObjects({ + Bucket: bucket, + Delete: { + Objects: Versions.map(({ Key, VersionId }: { Key: string; VersionId: string }) => ({ + Key, + VersionId, + })), + Quiet: true, + }, + }) + .promise(); + if (res?.Errors?.length === 0 && Versions.length >= 1000) { + await deleteFile(bucket, key); + } return res; }; diff --git a/web/src/layouts/Auth/index.module.scss b/web/src/layouts/Auth/index.module.scss new file mode 100644 index 0000000000..5a3197fd60 --- /dev/null +++ b/web/src/layouts/Auth/index.module.scss @@ -0,0 +1,8 @@ +.container { + height: 100vh; + width: 100vw; + background-image: url("@/assets/login_bg.svg"); + background-repeat: no-repeat; + background-position: left bottom; + background-size: 60%; +} diff --git a/web/src/layouts/Auth/index.tsx b/web/src/layouts/Auth/index.tsx new file mode 100644 index 0000000000..9b98349ef2 --- /dev/null +++ b/web/src/layouts/Auth/index.tsx @@ -0,0 +1,37 @@ +import { Outlet } from "react-router-dom"; +import { useColorMode } from "@chakra-ui/react"; +import clsx from "clsx"; + +import { COLOR_MODE } from "@/constants"; + +import styles from "./index.module.scss"; + +export default function LoginReg() { + const { colorMode } = useColorMode(); + const darkMode = colorMode === COLOR_MODE.dark; + return ( +
    +
    +
    + Welcome to laf ! +
    +
    + life is short, you need laf. +
    +
    + +
    + ); +} diff --git a/web/src/layouts/Basic.tsx b/web/src/layouts/Basic.tsx index 3537724720..110418fa4f 100644 --- a/web/src/layouts/Basic.tsx +++ b/web/src/layouts/Basic.tsx @@ -15,7 +15,7 @@ export default function BasicLayout() { return (
    - <> +
    {loading ? (
    @@ -23,8 +23,8 @@ export default function BasicLayout() { ) : ( )} - -
    +
    +
    Made with ️ by laf team
    diff --git a/web/src/layouts/Function.tsx b/web/src/layouts/Function.tsx index b84f50269d..c85e3604af 100644 --- a/web/src/layouts/Function.tsx +++ b/web/src/layouts/Function.tsx @@ -1,14 +1,17 @@ import { useEffect } from "react"; import { Outlet, useParams } from "react-router-dom"; -import { Badge, Center, Spinner } from "@chakra-ui/react"; +import { Badge, Center, Spinner, useColorMode } from "@chakra-ui/react"; import { useQuery } from "@tanstack/react-query"; +import clsx from "clsx"; -import { APP_PHASE_STATUS, Pages } from "@/constants/index"; +import { APP_PHASE_STATUS, COLOR_MODE, Pages } from "@/constants/index"; import { ApplicationControllerFindOne } from "@/apis/v1/applications"; import useGlobalStore from "@/pages/globalStore"; export default function FunctionLayout() { + const { colorMode } = useColorMode(); + const darkMode = colorMode === COLOR_MODE.dark; const { init, loading, setCurrentApp, currentApp, setCurrentPage } = useGlobalStore( (state) => state, ); @@ -62,7 +65,12 @@ export default function FunctionLayout() { {currentApp?.phase !== APP_PHASE_STATUS.Started && currentApp?.phase !== APP_PHASE_STATUS.Stopped && currentApp?.phase !== APP_PHASE_STATUS.Deleted ? ( -
    +
    { - localStorage.clear(); - (window as any).location.href = (VITE_SERVER_BASE_URL + "/v1/login") as string; + localStorage.removeItem("token"); + window.location.href = "/login"; }} > {t("Logout")} diff --git a/web/src/layouts/Header/index.tsx b/web/src/layouts/Header/index.tsx index aad4957a52..00c57143a4 100644 --- a/web/src/layouts/Header/index.tsx +++ b/web/src/layouts/Header/index.tsx @@ -4,6 +4,9 @@ import { useTranslation } from "react-i18next"; import { FiGithub } from "react-icons/fi"; +import { useColorMode } from "@chakra-ui/react"; + +import { COLOR_MODE } from "@/constants"; import UserSetting from "./UserSetting"; @@ -12,14 +15,22 @@ import useGlobalStore from "@/pages/globalStore"; export default function Header(props: { size: "sm" | "lg" }) { const { userInfo } = useGlobalStore((state) => state); const { t } = useTranslation(); + const { colorMode } = useColorMode(); return ( -
    +
    - logo + + logo + diff --git a/web/src/layouts/LoginReg.tsx b/web/src/layouts/LoginReg.tsx deleted file mode 100644 index 627b1530f8..0000000000 --- a/web/src/layouts/LoginReg.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { Outlet } from "react-router-dom"; - -export default function LoginReg() { - return ( -
    - -
    - ); -} diff --git a/web/src/pages/403.tsx b/web/src/pages/403.tsx index 3a4baf1e4b..2fc20d0e0f 100644 --- a/web/src/pages/403.tsx +++ b/web/src/pages/403.tsx @@ -3,20 +3,22 @@ import { ArrowForwardIcon } from "@chakra-ui/icons"; import { Button, Center, HStack } from "@chakra-ui/react"; import { t } from "i18next"; +import { Routes } from "@/constants"; + export default function Index() { const navigate = useNavigate(); return ( -
    -
    +
    +

    403

    -

    +

    {t(`403Message`)}

    diff --git a/web/src/pages/404.tsx b/web/src/pages/404.tsx index 3ca1725260..7cf98d0706 100644 --- a/web/src/pages/404.tsx +++ b/web/src/pages/404.tsx @@ -3,20 +3,22 @@ import { ArrowForwardIcon } from "@chakra-ui/icons"; import { Button, Center, HStack } from "@chakra-ui/react"; import { t } from "i18next"; +import { Routes } from "@/constants"; + export default function Index() { const navigate = useNavigate(); return ( -
    -
    +
    +

    404

    -

    +

    {t(`404Message`)}

    diff --git a/web/src/pages/LoginCallback.tsx b/web/src/pages/LoginCallback.tsx index 76f6e44ac6..84b5592b75 100644 --- a/web/src/pages/LoginCallback.tsx +++ b/web/src/pages/LoginCallback.tsx @@ -2,6 +2,8 @@ import { useNavigate, useSearchParams } from "react-router-dom"; import { Center, Spinner } from "@chakra-ui/react"; import { useQuery } from "@tanstack/react-query"; +import { Routes } from "@/constants"; + import { AuthControllerCode2token } from "@/apis/v1/code2token"; export default function LoginCallBack() { @@ -17,7 +19,7 @@ export default function LoginCallBack() { if (!tokenRes.isLoading && tokenRes.data?.data) { localStorage.setItem("token", tokenRes.data?.data); - navigate("/", { replace: true }); + navigate(Routes.dashboard, { replace: true }); } return ( diff --git a/web/src/pages/app/database/BottomPanel/index.tsx b/web/src/pages/app/database/BottomPanel/index.tsx index 36c568b06a..d10b6d6bee 100644 --- a/web/src/pages/app/database/BottomPanel/index.tsx +++ b/web/src/pages/app/database/BottomPanel/index.tsx @@ -9,7 +9,7 @@ function BottomPanel() { const store = useCustomSettingStore(); return ( - +
    -
    - +
    +
    ); diff --git a/web/src/pages/app/database/CollectionDataList/mods/DataPanel/index.tsx b/web/src/pages/app/database/CollectionDataList/mods/DataPanel/index.tsx index 3fb5242479..86638a326d 100644 --- a/web/src/pages/app/database/CollectionDataList/mods/DataPanel/index.tsx +++ b/web/src/pages/app/database/CollectionDataList/mods/DataPanel/index.tsx @@ -13,12 +13,13 @@ import { t } from "i18next"; import { throttle } from "lodash"; import CopyText from "@/components/CopyText"; -import JsonEditor from "@/components/Editor/JsonEditor"; +import JSONEditor from "@/components/Editor/JSONEditor"; import JSONViewer from "@/components/Editor/JSONViewer"; import EmptyBox from "@/components/EmptyBox"; import IconWrap from "@/components/IconWrap"; import Pagination from "@/components/Pagination"; import Panel from "@/components/Panel"; +import { COLOR_MODE } from "@/constants"; import getPageInfo from "@/utils/getPageInfo"; import AddDataModal from "../../../mods/AddDataModal/index"; @@ -143,7 +144,7 @@ export default function DataPanel() { return ( <> - +
    -
    +
    -
    +
    {entryDataQuery.status !== "loading" && entryDataQuery?.data?.list?.length! === 0 && (
    {t("CollectionPanel.EmptyDataText")} - + {t("CreateNow")} @@ -243,7 +244,7 @@ export default function DataPanel() { setKey="_id" isActive={(item: any) => currentData.data?._id === item._id} customStyle={{ - "border-lafWhite-600": colorMode === "light", + "border-lafWhite-600": colorMode === COLOR_MODE.light, }} onClick={(data: any) => { setCurrentData({ @@ -263,7 +264,7 @@ export default function DataPanel() { showBg tooltip={t("Copy").toString()} size={32} - className="ml-2 hover:bg-gray-200 group/icon" + className="group/icon ml-2 hover:bg-gray-200" > -
    - + { diff --git a/web/src/pages/app/database/CollectionDataList/mods/IndexPanel/index.tsx b/web/src/pages/app/database/CollectionDataList/mods/IndexPanel/index.tsx index 6821e93b3d..1549608c2b 100644 --- a/web/src/pages/app/database/CollectionDataList/mods/IndexPanel/index.tsx +++ b/web/src/pages/app/database/CollectionDataList/mods/IndexPanel/index.tsx @@ -6,10 +6,10 @@ import AddIndexModal from "./addIndexModal"; export default function IndexPanel() { return (
    -
    +
    -
    +
    diff --git a/web/src/pages/app/database/CollectionListPanel/index.tsx b/web/src/pages/app/database/CollectionListPanel/index.tsx index 03296352e9..f9655b5a34 100644 --- a/web/src/pages/app/database/CollectionListPanel/index.tsx +++ b/web/src/pages/app/database/CollectionListPanel/index.tsx @@ -2,7 +2,7 @@ import { useState } from "react"; import { useTranslation } from "react-i18next"; import { BiRefresh } from "react-icons/bi"; import { AddIcon, CopyIcon, Search2Icon } from "@chakra-ui/icons"; -import { Center, Input, InputGroup, InputLeftElement, Spinner } from "@chakra-ui/react"; +import { Badge, Center, Input, InputGroup, InputLeftElement, Spinner } from "@chakra-ui/react"; import CopyText from "@/components/CopyText"; import EmptyBox from "@/components/EmptyBox"; @@ -21,7 +21,7 @@ import useDBMStore from "../store"; export default function CollectionListPanel() { const store = useDBMStore((store) => store); const { t } = useTranslation(); - const collectionListQuery = useCollectionListQuery({ + const { data: res, ...collectionListQuery } = useCollectionListQuery({ onSuccess: (data) => { if (data.data.length === 0) { store.setCurrentDB(undefined); @@ -35,13 +35,22 @@ export default function CollectionListPanel() { return ( { store.setCurrentShow("DB"); }} > + {t("CollectionPanel.CollectionList").toString()} + {res?.data.length >= 10 ? ( + + {res?.data.length} + + ) : null} + + } actions={[ , ]} /> -
    +
    -
    +
    {collectionListQuery.isFetching ? ( -
    +
    ) : null} - {collectionListQuery?.data?.data?.length ? ( + {res?.data?.length ? ( - {collectionListQuery?.data?.data + {res?.data .filter((db: any) => db.name.indexOf(search) >= 0) .map((db: any) => { return ( @@ -94,8 +103,8 @@ export default function CollectionListPanel() { store.setCurrentDB(db); }} > -
    -
    +
    +
    {db.name}
    diff --git a/web/src/pages/app/database/PolicyDataList/index.tsx b/web/src/pages/app/database/PolicyDataList/index.tsx index fb5cc26111..3585fc722c 100644 --- a/web/src/pages/app/database/PolicyDataList/index.tsx +++ b/web/src/pages/app/database/PolicyDataList/index.tsx @@ -5,11 +5,12 @@ import clsx from "clsx"; import { t } from "i18next"; import CopyText from "@/components/CopyText"; -import JsonEditor from "@/components/Editor/JsonEditor"; +import JSONEditor from "@/components/Editor/JSONEditor"; import JSONViewer from "@/components/Editor/JSONViewer"; import EmptyBox from "@/components/EmptyBox"; import IconWrap from "@/components/IconWrap"; import Panel from "@/components/Panel"; +import { COLOR_MODE } from "@/constants"; import AddPolicyModal from "../mods/AddPolicyModal"; import AddRulesModal from "../mods/AddRulesModal"; @@ -36,7 +37,7 @@ export default function PolicyDataList() { }); const { colorMode } = useColorMode(); - const darkMode = colorMode === "dark"; + const darkMode = colorMode === COLOR_MODE.dark; useEffect(() => { setCurrentData(undefined); @@ -72,7 +73,7 @@ export default function PolicyDataList() {
    {t("CollectionPanel.EmptyPolicyText")} - + {t("CreateNow")} @@ -84,7 +85,7 @@ export default function PolicyDataList() { return ( <> - + { setCurrentData(data); @@ -106,9 +107,9 @@ export default function PolicyDataList() { {t("CollectionPanel.RulesNum")} : {rulesListQuery?.data?.data?.length || 0} -
    +
    {rulesListQuery.isFetching ? ( -
    +
    ) : rulesListQuery?.data?.data.length ? ( @@ -127,11 +128,11 @@ export default function PolicyDataList() { return ( <>
    - + {t("CollectionPanel.Collection")}:{item.collectionName}
    @@ -145,7 +146,7 @@ export default function PolicyDataList() { showBg tooltip={t("Copy").toString()} size={32} - className="ml-2 hover:bg-rose-100 group/icon" + className="group/icon ml-2 hover:bg-rose-100" > - + {t("CollectionPanel.SelectCollection")}: {currentData?.collectionName} - + {t("CollectionPanel.RulesContent")}
    - { @@ -198,7 +199,7 @@ export default function PolicyDataList() { rulesListQuery.refetch(); }} > - + {t("CreateNow")} diff --git a/web/src/pages/app/database/PolicyListPanel/index.tsx b/web/src/pages/app/database/PolicyListPanel/index.tsx index 54eca9b3e1..d1360d4808 100644 --- a/web/src/pages/app/database/PolicyListPanel/index.tsx +++ b/web/src/pages/app/database/PolicyListPanel/index.tsx @@ -1,8 +1,8 @@ /**************************** * cloud functions list sidebar ***************************/ +import { useTranslation } from "react-i18next"; import { AddIcon, DeleteIcon } from "@chakra-ui/icons"; -import { t } from "i18next"; import ConfirmButton from "@/components/ConfirmButton"; import EmptyBox from "@/components/EmptyBox"; @@ -17,6 +17,7 @@ import AddPolicyModal from "../mods/AddPolicyModal"; import { useDeletePolicyMutation, usePolicyListQuery } from "../service"; import useDBMStore from "../store"; export default function PolicyListPanel() { + const { t } = useTranslation(); const deletePolicyMutation = useDeletePolicyMutation(); const store = useDBMStore((state) => state); const policyQuery = usePolicyListQuery((data) => { @@ -55,8 +56,8 @@ export default function PolicyListPanel() { store.setCurrentPolicy(item); }} > -
    -
    +
    +
    {item.name}
    diff --git a/web/src/pages/app/database/RightComponent/DeleteButton.tsx b/web/src/pages/app/database/RightComponent/DeleteButton.tsx index adb01b0555..9f6ae86668 100644 --- a/web/src/pages/app/database/RightComponent/DeleteButton.tsx +++ b/web/src/pages/app/database/RightComponent/DeleteButton.tsx @@ -23,7 +23,7 @@ export default function DeleteButton(props: { data: any; deleteMethod: any }) { placement="left" > = (props) => { const { title, isLoading, children, onSave, show } = props; const { colorMode } = useColorMode(); - const darkMode = colorMode === "dark"; + const darkMode = colorMode === COLOR_MODE.dark; return (
    - + {title}
    - + {store.currentShow === "DB" ? : } + ); } diff --git a/web/src/pages/app/database/mods/AddDataModal/index.tsx b/web/src/pages/app/database/mods/AddDataModal/index.tsx index 54f54c7f7d..2b650a94b5 100644 --- a/web/src/pages/app/database/mods/AddDataModal/index.tsx +++ b/web/src/pages/app/database/mods/AddDataModal/index.tsx @@ -20,7 +20,8 @@ import { import clsx from "clsx"; import { t } from "i18next"; -import JsonEditor from "@/components/Editor/JsonEditor"; +import JSONEditor from "@/components/Editor/JSONEditor"; +import { COLOR_MODE } from "@/constants"; import { useAddDataMutation } from "../../service"; @@ -76,7 +77,7 @@ const AddDataModal = (props: { } }; const { colorMode } = useColorMode(); - const darkMode = colorMode === "dark"; + const darkMode = colorMode === COLOR_MODE.dark; const { isOpen, onOpen, onClose } = useDisclosure(); @@ -97,7 +98,7 @@ const AddDataModal = (props: { - {error} + {error} - + )} /> diff --git a/web/src/pages/app/database/mods/AddRulesModal/index.tsx b/web/src/pages/app/database/mods/AddRulesModal/index.tsx index 29f84735d8..7d1539bce5 100644 --- a/web/src/pages/app/database/mods/AddRulesModal/index.tsx +++ b/web/src/pages/app/database/mods/AddRulesModal/index.tsx @@ -21,7 +21,8 @@ import { import clsx from "clsx"; import { t } from "i18next"; -import JsonEditor from "@/components/Editor/JsonEditor"; +import JSONEditor from "@/components/Editor/JSONEditor"; +import { COLOR_MODE } from "@/constants"; import { useCollectionListQuery, useCreateRulesMutation } from "../../service"; @@ -59,11 +60,10 @@ const AddRulesModal = (props: { } try { const res = await createRulesMutation.mutateAsync(data); - if (res.error) { - throw new Error(res?.error); + if (!res.error) { + props.onSuccessSubmit(res.data); + onClose(); } - props.onSuccessSubmit(res.data); - onClose(); } catch (errors) { setError(errors?.toString()); return; @@ -72,7 +72,7 @@ const AddRulesModal = (props: { const { isOpen, onOpen, onClose } = useDisclosure(); const { colorMode } = useColorMode(); - const darkMode = colorMode === "dark"; + const darkMode = colorMode === COLOR_MODE.dark; return ( <> @@ -135,7 +135,7 @@ const AddRulesModal = (props: { "bg-lafDark-300": darkMode, })} > - + )} /> diff --git a/web/src/pages/app/database/mods/DeleteCollectionModal/index.tsx b/web/src/pages/app/database/mods/DeleteCollectionModal/index.tsx index a0e8c46d6f..b6bcb619c0 100644 --- a/web/src/pages/app/database/mods/DeleteCollectionModal/index.tsx +++ b/web/src/pages/app/database/mods/DeleteCollectionModal/index.tsx @@ -61,12 +61,12 @@ function DeleteCollectionModal(props: { database: any }) {

    {t("CollectionPanel.DeleteCollectionTip")} - {database.name} + {database.name} {t("DeleteTip")}。

    {t("CollectionPanel.InputName")} - {database.name} + {database.name} {t("ToConfirm")}。

    diff --git a/web/src/pages/app/database/service.ts b/web/src/pages/app/database/service.ts index da52748c35..9d8ba749e4 100644 --- a/web/src/pages/app/database/service.ts +++ b/web/src/pages/app/database/service.ts @@ -69,7 +69,6 @@ export const useEntryDataQuery = (params: any, onSuccess: (data: any) => void) = }; export const useCreateDBMutation = (config?: { onSuccess: (data: any) => void }) => { - const globalStore = useGlobalStore(); const queryClient = useQueryClient(); return useMutation( (values: any) => { @@ -77,9 +76,7 @@ export const useCreateDBMutation = (config?: { onSuccess: (data: any) => void }) }, { onSuccess: async (data) => { - if (data.error) { - globalStore.showError(data.error); - } else { + if (!data.error) { await queryClient.invalidateQueries(queryKeys.useCollectionListQuery); config?.onSuccess && config.onSuccess(data); } @@ -98,9 +95,7 @@ export const useDeleteDBMutation = (config?: { onSuccess: (data: any) => void }) }, { onSuccess: async (data) => { - if (data.error) { - globalStore.showError(data.error); - } else { + if (!data.error) { store.setCurrentDB(undefined); await queryClient.invalidateQueries(queryKeys.useCollectionListQuery); globalStore.showSuccess(t("DeleteSuccess")); @@ -131,8 +126,6 @@ export const useAddDataMutation = (config?: { onSuccess: (data: any) => void }) globalStore.showSuccess(t("AddSuccess")); queryClient.invalidateQueries([queryKeys.useEntryDataQuery(currentDB?.name || "")]); config && config.onSuccess(data); - } else { - globalStore.showError(data.error); } }, }, @@ -149,7 +142,7 @@ export const useUpdateDataMutation = (config?: { onSuccess: (data: any) => void async (values: any) => { const query = db.collection(currentDB?.name!).where({ _id: values._id }); delete values._id; - const result = query.update({ ...values }); + const result = query.update({ ...values }, { merge: false }); return result; }, { @@ -213,9 +206,7 @@ export const useCreatePolicyMutation = () => { }, { onSuccess: async (data) => { - if (data.error) { - globalStore.showError(data.error); - } else { + if (!data.error) { globalStore.showSuccess(t("AddSuccess")); await queryClient.invalidateQueries(queryKeys.usePolicyListQuery); store.setCurrentPolicy(data.data); @@ -234,11 +225,10 @@ export const useUpdatePolicyMutation = () => { }, { onSuccess(data) { - if (data.error) { - globalStore.showError(data.error); - } else { + if (!data.error) { globalStore.showSuccess(t("UpdateSuccess")); queryClient.invalidateQueries(queryKeys.usePolicyListQuery); + } else { } }, }, @@ -255,9 +245,7 @@ export const useDeletePolicyMutation = () => { }, { onSuccess: async (data) => { - if (data.error) { - globalStore.showError(data.error); - } else { + if (!data.error) { store.setCurrentPolicy(undefined); globalStore.showSuccess(t("DeleteSuccess")); await queryClient.invalidateQueries(queryKeys.usePolicyListQuery); @@ -310,9 +298,7 @@ export const useUpdateRulesMutation = (onSuccess?: (data: any) => void) => { }, { onSuccess(data) { - if (data.error) { - globalStore.showError(data.error); - } else { + if (!data.error) { globalStore.showSuccess(t("UpdateSuccess")); onSuccess && onSuccess(data.data); } @@ -330,9 +316,7 @@ export const useDeleteRuleMutation = (onSuccess?: () => void) => { }, { onSuccess(data) { - if (data.error) { - globalStore.showError(data.error); - } else { + if (!data.error) { globalStore.showSuccess(t("DeleteSuccess")); onSuccess && onSuccess(); } diff --git a/web/src/pages/app/database/store.ts b/web/src/pages/app/database/store.ts index 4667b43f68..85f6f9a052 100644 --- a/web/src/pages/app/database/store.ts +++ b/web/src/pages/app/database/store.ts @@ -1,4 +1,4 @@ -import create from "zustand"; +import { create } from "zustand"; import { devtools } from "zustand/middleware"; import { immer } from "zustand/middleware/immer"; diff --git a/web/src/pages/app/functions/index.tsx b/web/src/pages/app/functions/index.tsx index 1f1a0c6d5f..aea67c47dd 100644 --- a/web/src/pages/app/functions/index.tsx +++ b/web/src/pages/app/functions/index.tsx @@ -2,12 +2,14 @@ * cloud functions index page ***************************/ -import { useRef } from "react"; +import { useEffect, useRef, useState } from "react"; import Content from "@/components/Content"; import { Col, Row } from "@/components/Grid"; import Resize from "@/components/Resize"; +import StatusBar from "../mods/StatusBar"; + import ConsolePanel from "./mods/ConsolePanel"; import DebugPanel from "./mods/DebugPanel"; import DependencePanel from "./mods/DependencePanel"; @@ -18,6 +20,18 @@ import useCustomSettingStore from "@/pages/customSetting"; function FunctionPage() { const containerRef = useRef(null); const functionPageConfig = useCustomSettingStore((store) => store.layoutInfo.functionPage); + const [showOverlay, setShowOverlay] = useState(false); + + useEffect(() => { + function handleMouseUp() { + setShowOverlay(false); + } + document.addEventListener("mouseup", handleMouseUp); + return () => { + document.removeEventListener("mouseup", handleMouseUp); + }; + }, []); + return ( @@ -50,17 +64,24 @@ function FunctionPage() { - +
    { + setShowOverlay(true); + }} + > + +
    - + + ); } diff --git a/web/src/pages/app/functions/mods/BottomPanel/index.tsx b/web/src/pages/app/functions/mods/BottomPanel/index.tsx index cf4453338e..a5f8a0141c 100644 --- a/web/src/pages/app/functions/mods/BottomPanel/index.tsx +++ b/web/src/pages/app/functions/mods/BottomPanel/index.tsx @@ -9,7 +9,7 @@ function BottomPanel() { const store = useCustomSettingStore(); return ( - +
    +
    @@ -153,7 +156,7 @@ function BodyParamsTab(props: { onChange(values: { contentType: string; data: an <> diff --git a/web/src/pages/app/functions/mods/DebugPanel/HeaderParamsTab/index.tsx b/web/src/pages/app/functions/mods/DebugPanel/HeaderParamsTab/index.tsx index d7df03e0c9..9b3ee08e75 100644 --- a/web/src/pages/app/functions/mods/DebugPanel/HeaderParamsTab/index.tsx +++ b/web/src/pages/app/functions/mods/DebugPanel/HeaderParamsTab/index.tsx @@ -38,7 +38,7 @@ function HeaderParamsTab(props: { onChange(values: Params[]): void }) {
    -
    {t("FunctionPanel.Name")}
    +
    diff --git a/web/src/pages/app/functions/mods/DebugPanel/QueryParamsTab/index.tsx b/web/src/pages/app/functions/mods/DebugPanel/QueryParamsTab/index.tsx index 5a4b79ff9f..35a62493bd 100644 --- a/web/src/pages/app/functions/mods/DebugPanel/QueryParamsTab/index.tsx +++ b/web/src/pages/app/functions/mods/DebugPanel/QueryParamsTab/index.tsx @@ -13,9 +13,9 @@ type FormValues = { params: Params[]; }; -function HeaderParamsTab(props: { onChange(values: Params[]): void }) { - const { onChange } = props; - const { register, control, watch } = useForm({ +function HeaderParamsTab(props: { onChange(values: Params[]): void; paramsList: Params[] }) { + const { onChange, paramsList } = props; + const { register, control, watch, setValue } = useForm({ defaultValues: { params: [{ name: "", value: "" }], }, @@ -34,11 +34,15 @@ function HeaderParamsTab(props: { onChange(values: Params[]): void }) { // eslint-disable-next-line react-hooks/exhaustive-deps }, [watch]); + useEffect(() => { + setValue("params", paramsList ?? []); + }, [setValue, paramsList]); + return (
    -
    {t("FunctionPanel.Name")}
    +
    diff --git a/web/src/pages/app/functions/mods/DebugPanel/index.tsx b/web/src/pages/app/functions/mods/DebugPanel/index.tsx index 50278dd7c8..28faff5b90 100644 --- a/web/src/pages/app/functions/mods/DebugPanel/index.tsx +++ b/web/src/pages/app/functions/mods/DebugPanel/index.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; import { Button, Center, @@ -14,16 +15,15 @@ import { } from "@chakra-ui/react"; import axios from "axios"; import clsx from "clsx"; -import { t } from "i18next"; import { keyBy, mapValues } from "lodash"; import JSONViewer from "@/components/Editor/JSONViewer"; import { Row } from "@/components/Grid"; import Panel from "@/components/Panel"; import Resize from "@/components/Resize"; -import { Pages } from "@/constants"; +import { COLOR_MODE, Pages } from "@/constants"; -import { useCompileMutation } from "../../service"; +import { useCompileMutation, useUpdateFunctionMutation } from "../../service"; import useFunctionStore from "../../store"; import BodyParamsTab from "./BodyParamsTab"; @@ -38,10 +38,12 @@ import useGlobalStore from "@/pages/globalStore"; const HAS_BODY_PARAMS_METHODS: (TMethod | undefined)[] = ["POST", "PUT", "PATCH", "DELETE"]; -export default function DebugPanel(props: { containerRef: any }) { +export default function DebugPanel(props: { containerRef: any; showOverlay: boolean }) { + const { t } = useTranslation(); const { getFunctionUrl, currentFunction, setCurrentRequestId } = useFunctionStore( (state) => state, ); + const updateFunctionMutation = useUpdateFunctionMutation(); const globalStore = useGlobalStore((state) => state); const functionCache = useFunctionCache(); @@ -52,7 +54,7 @@ export default function DebugPanel(props: { containerRef: any }) { const compileMutation = useCompileMutation(); const { colorMode } = useColorMode(); - const darkMode = colorMode === "dark"; + const darkMode = colorMode === COLOR_MODE.dark; const [queryParams, setQueryParams] = useState([]); const [bodyParams, setBodyParams] = useState<{ contentType: string; data: any }>(); @@ -83,6 +85,22 @@ export default function DebugPanel(props: { containerRef: any }) { name: currentFunction!.name, }); + const params = { + queryParams: queryParams, + bodyParams: bodyParams, + headerParams: headerParams, + }; + + updateFunctionMutation.mutateAsync({ + description: currentFunction?.desc, + code: functionCache.getCache(currentFunction!.id, currentFunction!.source?.code), + methods: currentFunction?.methods, + websocket: currentFunction?.websocket, + name: currentFunction?.name, + tags: currentFunction?.tags, + params: params, + }); + if (!compileRes.error) { const _funcData = JSON.stringify(compileRes.data); const res = await axios({ @@ -110,10 +128,10 @@ export default function DebugPanel(props: { containerRef: any }) { return ( <> - + - + + + + {t("HomePage.NavBar.docs")} + + {/* 历史请求 */} - -
    -
    + + +
    {t("FunctionPanel.Methods")} { search(e.target.value); }} @@ -314,7 +313,7 @@ const AddDependenceModal = () => { {checkList.length > 0 && ( { if (!isEdit) { setIsShowChecked((pre) => !pre); diff --git a/web/src/pages/app/functions/mods/DependencePanel/index.tsx b/web/src/pages/app/functions/mods/DependencePanel/index.tsx index 18eeae7b40..a5298c5f11 100644 --- a/web/src/pages/app/functions/mods/DependencePanel/index.tsx +++ b/web/src/pages/app/functions/mods/DependencePanel/index.tsx @@ -4,7 +4,7 @@ import { useTranslation } from "react-i18next"; import { CloseIcon } from "@chakra-ui/icons"; -import { Badge, Center, Tab, TabList, TabPanel, TabPanels, Tabs, Tooltip } from "@chakra-ui/react"; +import { Badge, Center, Tab, TabList, TabPanel, TabPanels, Tabs } from "@chakra-ui/react"; import ConfirmButton from "@/components/ConfirmButton"; import FileTypeIcon, { FileType } from "@/components/FileTypeIcon"; @@ -14,20 +14,24 @@ import SectionList from "@/components/SectionList"; import AddDependenceModal from "./AddDependenceModal"; import { TPackage, useDelPackageMutation, usePackageQuery } from "./service"; +import useCustomSettingStore from "@/pages/customSetting"; import useGlobalStore from "@/pages/globalStore"; export default function DependenceList() { const packageQuery = usePackageQuery(); const globalStore = useGlobalStore((state) => state); const delPackageMutation = useDelPackageMutation(() => { - globalStore.updateCurrentApp(); + globalStore.updateCurrentApp(globalStore.currentApp!); }); const { t } = useTranslation(); + const store = useCustomSettingStore(); + const builtinPackage: TPackage[] = []; const customPackage: TPackage[] = []; - const SECTION_HEIGHT = 180; + const { height } = store.getLayoutInfo("functionPage", "DependencePanel"); + const SECTION_HEIGHT = height - 90; packageQuery?.data?.data?.forEach((packageItem: TPackage) => { if (packageItem.builtin) { @@ -76,28 +80,26 @@ export default function DependenceList() { className="group" > -
    - +
    + {packageItem?.name}
    -
    - +
    + {packageItem?.spec} {!packageItem?.builtin ? ( - - - { - delPackageMutation.mutate({ name: packageItem?.name }); - }} - headerText={String(t("Delete"))} - bodyText={String(t("FunctionPanel.DeleteDependencyConfirm"))} - > - - - + + { + delPackageMutation.mutate({ name: packageItem?.name }); + }} + headerText={String(t("Delete"))} + bodyText={String(t("FunctionPanel.DeleteDependencyConfirm"))} + > + + ) : null}
    @@ -123,11 +125,11 @@ export default function DependenceList() { className="group" >
    - + {packageItem?.name}
    -
    +
    {packageItem?.spec}
    diff --git a/web/src/pages/app/functions/mods/EditorPanel/FunctionDetailPopOver.tsx b/web/src/pages/app/functions/mods/EditorPanel/FunctionDetailPopOver.tsx index e2c84d5672..ab83fa4cca 100644 --- a/web/src/pages/app/functions/mods/EditorPanel/FunctionDetailPopOver.tsx +++ b/web/src/pages/app/functions/mods/EditorPanel/FunctionDetailPopOver.tsx @@ -29,7 +29,7 @@ const FunctionDetailPopOver = () => { -

    +

    {currentFunction.name}{" "}

    @@ -37,9 +37,9 @@ const FunctionDetailPopOver = () => { 更新于 {formatDate(currentFunction.updatedAt)}

    {currentFunction.desc}

    -
    +
    {currentFunction.tags.map((item: string) => ( - + {item} ))} diff --git a/web/src/pages/app/functions/mods/EditorPanel/index.tsx b/web/src/pages/app/functions/mods/EditorPanel/index.tsx index 1283a7f0cc..9a073b09c9 100644 --- a/web/src/pages/app/functions/mods/EditorPanel/index.tsx +++ b/web/src/pages/app/functions/mods/EditorPanel/index.tsx @@ -1,16 +1,18 @@ +import { useTranslation } from "react-i18next"; import { HStack, Input, useColorMode } from "@chakra-ui/react"; import clsx from "clsx"; -import { t } from "i18next"; import CopyText from "@/components/CopyText"; import FunctionEditor from "@/components/Editor/FunctionEditor"; import EmptyBox from "@/components/EmptyBox"; import Panel from "@/components/Panel"; +import { COLOR_MODE } from "@/constants"; import { useFunctionListQuery } from "../../service"; import useFunctionStore from "../../store"; import DeployButton from "../DeployButton"; import CreateModal from "../FunctionPanel/CreateModal"; +import PromptModal from "../FunctionPanel/CreateModal/PromptModal"; import FunctionDetailPopOver from "./FunctionDetailPopOver"; @@ -20,31 +22,32 @@ function EditorPanel() { const store = useFunctionStore((store) => store); const { currentFunction, updateFunctionCode, getFunctionUrl } = store; const { colorMode } = useColorMode(); + const { t } = useTranslation(); const functionCache = useFunctionCache(); const functionListQuery = useFunctionListQuery(); - const darkMode = colorMode === "dark"; + const darkMode = colorMode === COLOR_MODE.dark; return ( {currentFunction?.name ? ( - - + + {currentFunction?.name} {currentFunction?.id && functionCache.getCache(currentFunction?.id, currentFunction?.source?.code) !== currentFunction?.source?.code && ( - + )} {currentFunction?.desc ? ( - + {currentFunction?.desc} ) : null} @@ -52,7 +55,7 @@ function EditorPanel() { - + @@ -62,21 +65,34 @@ function EditorPanel() { {!functionListQuery.isFetching && functionListQuery.data?.data?.length === 0 && ( -
    - {t("FunctionPanel.EmptyText")} - - - {t("CreateNow")} - - -
    + <> +
    + + + {t("CreateNow")} + + + +

    {t("Or")}

    + + + + {t("TryLafAI")} + + +
    +
    )} {currentFunction?.name && ( { diff --git a/web/src/pages/app/functions/mods/FunctionPanel/CreateModal/PromptModal.tsx b/web/src/pages/app/functions/mods/FunctionPanel/CreateModal/PromptModal.tsx new file mode 100644 index 0000000000..cefffd718b --- /dev/null +++ b/web/src/pages/app/functions/mods/FunctionPanel/CreateModal/PromptModal.tsx @@ -0,0 +1,277 @@ +import React, { useState } from "react"; +import { Controller, useForm } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import { + Button, + Checkbox, + CheckboxGroup, + FormControl, + FormErrorMessage, + FormLabel, + HStack, + Input, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + Progress, + Switch, + Textarea, + useColorMode, + useDisclosure, + VStack, +} from "@chakra-ui/react"; +import { useMutation } from "@tanstack/react-query"; +import axios from "axios"; + +import CodeViewer from "@/components/Editor/CodeViewer"; +// import FunctionEditor from "@/components/Editor/FunctionEditor"; +import InputTag from "@/components/InputTag"; +import { SUPPORTED_METHODS } from "@/constants"; + +import { useCreateFunctionMutation, useUpdateFunctionMutation } from "../../../service"; +import useFunctionStore from "../../../store"; + +import { TMethod } from "@/apis/typing"; +import useGlobalStore from "@/pages/globalStore"; + +const PromptModal = (props: { functionItem?: any; children?: React.ReactElement }) => { + const { isOpen, onOpen, onClose } = useDisclosure(); + const store = useFunctionStore(); + const { showSuccess } = useGlobalStore(); + const { t } = useTranslation(); + + const { functionItem, children = null } = props; + const isEdit = !!functionItem; + + const CancelToken = axios.CancelToken; + let source = CancelToken.source(); + const { colorMode } = useColorMode(); + + const [aiGenerateCode, setAiGenerateCode] = useState(""); + + const { data: generateCodeRes, ...generateCode } = useMutation((params: any) => { + return axios({ + url: "https://itceb8.laf.run/laf-gpt", + method: "POST", + data: params, + cancelToken: source.token, + responseType: "stream", + onDownloadProgress: function (progressEvent) { + const xhr = progressEvent.event.target; + + const { responseText } = xhr; + setAiGenerateCode(responseText.replace("```ts", "").replace("```", "")); + const ele = document.querySelector("#scroll_footer"); + if (ele) ele.scrollIntoView(); + }, + }); + }); + + const defaultValues = { + name: functionItem?.name || "", + description: functionItem?.desc || "", + websocket: !!functionItem?.websocket, + methods: functionItem?.methods || ["GET", "POST"], + code: "", + tags: functionItem?.tags || [], + }; + + type FormData = { + name: string; + description: string; + websocket: boolean; + methods: TMethod[]; + code: string; + tags: string[]; + }; + + const { + register, + handleSubmit, + control, + setFocus, + getValues, + reset, + formState: { errors }, + } = useForm({ + defaultValues, + }); + + const createFunctionMutation = useCreateFunctionMutation(); + const updateFunctionMutation = useUpdateFunctionMutation(); + + const onSubmit = async (data: any) => { + let res: any = await createFunctionMutation.mutateAsync({ + ...data, + code: aiGenerateCode, + }); + + if (!res.error) { + showSuccess(isEdit ? "update success" : "create success"); + onClose(); + generateCode.reset(); + store.setCurrentFunction(res.data); + reset(defaultValues); + } + }; + + return ( + <> + {children && + React.cloneElement(children, { + onClick: () => { + onOpen(); + reset(defaultValues); + setTimeout(() => { + setFocus("name"); + }, 0); + }, + })} + + + + + + {isEdit ? t("FunctionPanel.EditFunction") : t("FunctionPanel.AddFunction")} + + + + + + + {t("FunctionPanel.FunctionName")} + + {errors.name && errors.name.message} + + + + + {t("FunctionPanel.Description")} +
    {t("FunctionPanel.Name")}