From 8053e114cf4429d6cc06e8f6363fc4655673b0e3 Mon Sep 17 00:00:00 2001 From: Scaffolder Date: Mon, 3 Aug 2026 21:12:35 +0000 Subject: [PATCH] initial commit Change-Id: Ifa2442bb2e786af351ef5f575ca69828870c8b6e --- .eslintignore | 1 + .eslintrc.json | 24 + .gitea/workflows/build-push.yml | 84 + .gitea/workflows/deploy.yml | 186 + .gitea/workflows/integration-test.yml | 161 + .gitea/workflows/sonar.yaml | 445 + .gitignore | 42 + .platform/initialized.md | 9 + .prettierignore | 4 + .prettierrc | 3 + .vscode/extensions.json | 8 + Dockerfile | 24 + README.md | 74 + catalog-info.yaml | 67 + config/nohttp/allowlist.lines | 11 + e2e/.eslintrc.json | 16 + e2e/jest.config.ts | 19 + e2e/project.json | 20 + e2e/src/server/server.spec.ts | 10 + e2e/src/support/global-setup.ts | 10 + e2e/src/support/global-teardown.ts | 7 + e2e/src/support/test-setup.ts | 10 + e2e/tsconfig.json | 13 + e2e/tsconfig.spec.json | 10 + jest.config.ts | 15 + jest.preset.js | 3 + nx.json | 46 + package-lock.json | 9898 +++++++++++++++++ package.json | 58 + project-logo.png | Bin 0 -> 53176 bytes project.json | 75 + score.yaml | 58 + src/app/models/http-exception.model.ts | 12 + src/app/routes/article/article.controller.ts | 243 + src/app/routes/article/article.mapper.ts | 16 + src/app/routes/article/article.model.ts | 10 + src/app/routes/article/article.service.ts | 652 ++ src/app/routes/article/author.mapper.ts | 12 + src/app/routes/article/comment.model.ts | 9 + src/app/routes/auth/auth.controller.ts | 70 + src/app/routes/auth/auth.service.ts | 183 + src/app/routes/auth/auth.ts | 28 + src/app/routes/auth/register-input.model.ts | 8 + src/app/routes/auth/registered-user.model.ts | 8 + src/app/routes/auth/token.utils.ts | 8 + src/app/routes/auth/user-request.d.ts | 9 + src/app/routes/auth/user.model.ts | 17 + src/app/routes/profile/profile.controller.ts | 67 + src/app/routes/profile/profile.model.ts | 6 + src/app/routes/profile/profile.service.ts | 60 + src/app/routes/profile/profile.utils.ts | 13 + src/app/routes/routes.ts | 13 + src/app/routes/tag/tag.controller.ts | 22 + src/app/routes/tag/tag.model.ts | 3 + src/app/routes/tag/tag.service.ts | 40 + src/assets/images/demo-avatar.png | Bin 0 -> 1711 bytes src/assets/images/smiley-cyrus.jpeg | Bin 0 -> 1343 bytes .../nohttp-checkstyle-suppressions.xml | 19 + src/main.ts | 57 + .../20210924225358_initial/migration.sql | 114 + .../migration.sql | 36 + .../20211105153605_api_url/migration.sql | 2 + .../migration.sql | 11 + src/prisma/migrations/migration_lock.toml | 3 + src/prisma/prisma-client.ts | 23 + src/prisma/schema.prisma | 56 + src/prisma/seed.ts | 66 + src/tests/prisma-mock.ts | 17 + src/tests/services/article.service.test.ts | 144 + src/tests/services/auth.service.test.ts | 254 + src/tests/services/profile.service.test.ts | 145 + src/tests/services/tag.service.test.ts | 6 + src/tests/utils/profile.utils.test.ts | 79 + tsconfig.app.json | 17 + tsconfig.json | 30 + tsconfig.spec.json | 14 + 76 files changed, 14013 insertions(+) create mode 100644 .eslintignore create mode 100644 .eslintrc.json create mode 100644 .gitea/workflows/build-push.yml create mode 100644 .gitea/workflows/deploy.yml create mode 100644 .gitea/workflows/integration-test.yml create mode 100644 .gitea/workflows/sonar.yaml create mode 100644 .gitignore create mode 100644 .platform/initialized.md create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 .vscode/extensions.json create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 catalog-info.yaml create mode 100644 config/nohttp/allowlist.lines create mode 100644 e2e/.eslintrc.json create mode 100644 e2e/jest.config.ts create mode 100644 e2e/project.json create mode 100644 e2e/src/server/server.spec.ts create mode 100644 e2e/src/support/global-setup.ts create mode 100644 e2e/src/support/global-teardown.ts create mode 100644 e2e/src/support/test-setup.ts create mode 100644 e2e/tsconfig.json create mode 100644 e2e/tsconfig.spec.json create mode 100644 jest.config.ts create mode 100644 jest.preset.js create mode 100644 nx.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 project-logo.png create mode 100644 project.json create mode 100644 score.yaml create mode 100644 src/app/models/http-exception.model.ts create mode 100644 src/app/routes/article/article.controller.ts create mode 100644 src/app/routes/article/article.mapper.ts create mode 100644 src/app/routes/article/article.model.ts create mode 100644 src/app/routes/article/article.service.ts create mode 100644 src/app/routes/article/author.mapper.ts create mode 100644 src/app/routes/article/comment.model.ts create mode 100644 src/app/routes/auth/auth.controller.ts create mode 100644 src/app/routes/auth/auth.service.ts create mode 100644 src/app/routes/auth/auth.ts create mode 100644 src/app/routes/auth/register-input.model.ts create mode 100644 src/app/routes/auth/registered-user.model.ts create mode 100644 src/app/routes/auth/token.utils.ts create mode 100644 src/app/routes/auth/user-request.d.ts create mode 100644 src/app/routes/auth/user.model.ts create mode 100644 src/app/routes/profile/profile.controller.ts create mode 100644 src/app/routes/profile/profile.model.ts create mode 100644 src/app/routes/profile/profile.service.ts create mode 100644 src/app/routes/profile/profile.utils.ts create mode 100644 src/app/routes/routes.ts create mode 100644 src/app/routes/tag/tag.controller.ts create mode 100644 src/app/routes/tag/tag.model.ts create mode 100644 src/app/routes/tag/tag.service.ts create mode 100644 src/assets/images/demo-avatar.png create mode 100644 src/assets/images/smiley-cyrus.jpeg create mode 100644 src/checkstyle/nohttp-checkstyle-suppressions.xml create mode 100644 src/main.ts create mode 100644 src/prisma/migrations/20210924225358_initial/migration.sql create mode 100644 src/prisma/migrations/20211001143221_implicit_tags/migration.sql create mode 100644 src/prisma/migrations/20211105153605_api_url/migration.sql create mode 100644 src/prisma/migrations/20211221184529_deprecated_preview/migration.sql create mode 100644 src/prisma/migrations/migration_lock.toml create mode 100644 src/prisma/prisma-client.ts create mode 100644 src/prisma/schema.prisma create mode 100644 src/prisma/seed.ts create mode 100644 src/tests/prisma-mock.ts create mode 100644 src/tests/services/article.service.test.ts create mode 100644 src/tests/services/auth.service.test.ts create mode 100644 src/tests/services/profile.service.test.ts create mode 100644 src/tests/services/tag.service.test.ts create mode 100644 src/tests/utils/profile.utils.test.ts create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.spec.json diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +node_modules diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..04e28f7 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,24 @@ +{ + "root": true, + "ignorePatterns": ["!**/*"], + "plugins": ["@nx"], + "overrides": [ + { + "files": ["*.ts", "*.tsx"], + "extends": ["plugin:@nx/typescript"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "extends": ["plugin:@nx/javascript"], + "rules": {} + }, + { + "files": ["*.spec.ts", "*.spec.tsx", "*.spec.js", "*.spec.jsx"], + "env": { + "jest": true + }, + "rules": {} + } + ] +} diff --git a/.gitea/workflows/build-push.yml b/.gitea/workflows/build-push.yml new file mode 100644 index 0000000..7c6e9ca --- /dev/null +++ b/.gitea/workflows/build-push.yml @@ -0,0 +1,84 @@ +name: Build and Push to ACR + +on: + push: + branches: [ dev ] + workflow_dispatch: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + AZURE_FEDERATED_TOKEN_FILE: /var/run/secrets/azure/tokens/azure-identity-token + +jobs: + build: + name: Build and Push + runs-on: ubuntu-latest + if: >- + github.ref != 'refs/heads/main' && ( + github.event_name == 'workflow_dispatch' || + (github.event_name == 'push' && github.event.before != '0000000000000000000000000000000000000000') + ) + permissions: + contents: read + id-token: write + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install Azure CLI + run: | + command -v az &>/dev/null || curl -sL https://aka.ms/InstallAzureCLIDeb | bash + + - name: Install Docker CLI + run: | + command -v docker &>/dev/null || (apt-get update -qq && apt-get install -y docker.io) + docker --version + + - name: Azure login (OIDC) + run: | + az login \ + --service-principal \ + --username "$AZURE_CLIENT_ID" \ + --tenant "$AZURE_TENANT_ID" \ + --federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)" + echo "✓ Azure login successful" + + - name: Get ACR details + run: | + ACR_NAME=$(az acr list --query "[0].name" -o tsv) + ACR_NAME="${ACR_NAME:-bstagecjotdevacr}" + echo "ACR_NAME=$ACR_NAME" >> $GITHUB_ENV + echo "ACR_LOGIN_SERVER=${ACR_NAME}.azurecr.io" >> $GITHUB_ENV + echo "✓ Using ACR: ${ACR_NAME}.azurecr.io" + + - name: ACR Login + run: | + ACR_TOKEN=$(az acr login --name "$ACR_NAME" --expose-token --output tsv --query accessToken) + docker login "$ACR_LOGIN_SERVER" \ + --username 00000000-0000-0000-0000-000000000000 \ + --password "$ACR_TOKEN" + echo "✓ ACR login successful" + + - name: Build and Push Docker image + run: | + IMAGE_TAG="${{ gitea.sha }}" + IMAGE_FULL="${ACR_LOGIN_SERVER}/reno-realworld-5:${IMAGE_TAG}" + IMAGE_LATEST="${ACR_LOGIN_SERVER}/reno-realworld-5:latest" + docker build -t "$IMAGE_FULL" -t "$IMAGE_LATEST" . + docker push "$IMAGE_FULL" + docker push "$IMAGE_LATEST" + echo "IMAGE_FULL=$IMAGE_FULL" >> $GITHUB_ENV + echo "✓ Pushed: $IMAGE_FULL" + + - name: Build Summary + run: | + echo "### ✅ Build Successful" >> $GITHUB_STEP_SUMMARY + echo "| | |" >> $GITHUB_STEP_SUMMARY + echo "|---|---|" >> $GITHUB_STEP_SUMMARY + echo "| **Service** | reno-realworld-5 |" >> $GITHUB_STEP_SUMMARY + echo "| **Commit** | ${{ gitea.sha }} |" >> $GITHUB_STEP_SUMMARY + echo "| **Image** | $IMAGE_FULL |" >> $GITHUB_STEP_SUMMARY diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..280ce24 --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,186 @@ +name: Deploy to Orchestrator + +on: + workflow_run: + workflows: ["Build and Push to ACR"] + types: [completed] + branches: [ "dev", "staging", "prod" ] + workflow_dispatch: + inputs: + environment: + description: 'Target environment' + required: true + default: 'dev' + type: choice + options: + - dev + - staging + - prod + +env: + PO_API_URL: https://api.dev.orchestrator.crucible.kyndemo.live + PO_ORG_ID: crucible + PO_AUTH_TOKEN: ${{ secrets.PO_AUTH_TOKEN }} + # ONE ORCHESTRATOR PROJECT PER APPLICATION. + # + # This used to be the shared `apps-cluster` project with one environment per app, which + # made every app a peer of every other: the Orchestrator tab on any component listed the + # entire estate, and an app had exactly one environment named after itself, so there was + # nowhere for dev/staging/prod to live. + # + # That shape existed to avoid a Terraform pull request against config/projects.tf for every + # scaffolded app. That constraint turned out not to be real -- `octl create project`, + # `octl create runner-rule` and `octl create environment` are all runtime operations, so + # the workflow below builds the whole thing on first deploy and needs no repository change. + PROJECT_ID: reno-realworld-5 + # The runner a project's workloads execute on. This is NOT cosmetic: the Kubernetes and + # Helm providers are ambient, so a workload lands in whichever cluster its runner lives in, + # and Terraform state is keyed per runner. A project bound to the wrong runner deploys to + # the wrong cluster, and repointing it afterwards orphans the state it already owns. + PO_RUNNER_ID: crucible-orchestrator-dev-apps-dev-runner + OCTL_VERSION: 1.0.0 + IMAGE: bstagecjotdevacr.azurecr.io/reno-realworld-5 + +jobs: + guard: + name: Platform guard + runs-on: ubuntu-latest + outputs: + ready: ${{ steps.check.outputs.ready }} + steps: + - uses: actions/checkout@v4 + - name: Check platform initialized + id: check + run: | + if [ -f ".platform/initialized.md" ]; then + echo "ready=true" >> $GITHUB_OUTPUT + else + echo "ready=false" >> $GITHUB_OUTPUT + echo "Skipping: .platform/initialized.md not found" + fi + + deploy: + name: Deploy to Orchestrator + needs: guard + if: >- + (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success' && needs.guard.outputs.ready == 'true') || + (github.event_name == 'workflow_dispatch') + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install octl + run: | + set -euo pipefail + curl -fsSLo /tmp/octl.tar.gz \ + "https://github.com/stellwerk-labs/platform-orchestrator-cli/releases/download/v${OCTL_VERSION}/platform-orchestrator-cli_${OCTL_VERSION}_linux_amd64.tar.gz" + tar xzf /tmp/octl.tar.gz -C /tmp + install -m 755 /tmp/octl /usr/local/bin/octl + octl --version + + - name: Derive environment + run: | + # The environment is now a STAGE of this application -- dev, staging, prod -- because + # the project is the application. It used to be the component id, which was the only + # option while every app shared one project and had to be distinguishable inside it. + DISPATCH_ENV="${{ github.event.inputs.environment }}" + if [ -n "$DISPATCH_ENV" ]; then + ENV_ID="$DISPATCH_ENV" + else + # On a workflow_run the branch is the triggering run's, not this job's checkout. + BRANCH="${{ github.event.workflow_run.head_branch }}" + BRANCH="${BRANCH:-${GITHUB_REF_NAME}}" + case "$BRANCH" in + staging) ENV_ID=staging ;; + prod|main|master) ENV_ID=prod ;; + *) ENV_ID=dev ;; + esac + echo "Branch '$BRANCH' maps to environment '$ENV_ID'" + fi + echo "ENV_ID=$ENV_ID" >> $GITHUB_ENV + echo "Deploying $PROJECT_ID to environment: $ENV_ID" + + - name: Ensure the project and its runner binding exist + run: | + set -euo pipefail + # Created on first deploy rather than by a pull request against config/projects.tf. + # None of this needs a repository change: project, runner rule and environment are + # all runtime objects. + # + # Neither create is idempotent, so both fall through to a read on the second run. + octl create project "$PROJECT_ID" \ + --set display_name='reno-realworld-5' || \ + octl get project "$PROJECT_ID" + + # The runner rule is what routes this project's deployments to the apps cluster. + # Creating it twice would leave two rules matching the same project, so it is + # created only when absent -- `create` would happily add a duplicate. + if octl get runner-rules -o json 2>/dev/null | grep -q "\"project_id\": *\"$PROJECT_ID\""; then + echo "Runner rule for '$PROJECT_ID' already exists." + else + octl create runner-rule \ + --set project_id="$PROJECT_ID" \ + --set runner_id="$PO_RUNNER_ID" \ + --no-prompt + fi + + - name: Ensure the environment exists + run: | + set -euo pipefail + # Project and environment ids are POSITIONAL; only env_type_id and display_name go + # through --set. `dev` and `stable` are the only environment TYPES that exist, so + # staging rides on the dev type -- the type governs policy, the id governs identity. + case "$ENV_ID" in + prod) ENV_TYPE=stable ;; + *) ENV_TYPE=dev ;; + esac + octl create environment "$PROJECT_ID" "$ENV_ID" \ + --set env_type_id="$ENV_TYPE" \ + --set display_name="$ENV_ID" || \ + octl get environment "$PROJECT_ID" "$ENV_ID" + + - name: Deploy the Score workload + run: | + set -euo pipefail + # `octl score deploy` is ADDITIVE — it adds or updates a workload in the manifest and + # never removes one. That is the opposite of `octl deploy`, where omission is + # deletion. Do not substitute one for the other. + # No --show-logs: octl 1.0.0 has no such flag and exits 1 with `unknown flag` + # BEFORE contacting the orchestrator, so the whole deploy dies on an argument + # typo. Its nearest relatives are --runner-logs-level (default `info`, already + # what we want) and --skip-logs (which suppresses storage). Neither streams the + # runner's logs into this job, so there is nothing to substitute -- the runner + # logs are read from the orchestrator, not from here. + # The tag must be the commit the BUILD built, and it must be the WHOLE sha. + # + # build-push.yml tags with `` -- all 40 characters -- so the + # 7-character `${GITHUB_SHA:0:7}` this used to pass named a tag that has never + # existed in the registry. + # + # And on a workflow_run, GITHUB_SHA is the DEFAULT branch's head, while the build + # that produced the image ran on `dev`. They coincide only while the branches are + # level. `workflow_run.head_sha` is the triggering run's own commit, which is by + # definition the one that was built; `github.sha` covers the workflow_dispatch case, + # where there is no triggering run. + IMAGE_TAG="${{ github.event.workflow_run.head_sha || github.sha }}" + echo "Deploying ${IMAGE}:${IMAGE_TAG}" + + octl score deploy "$PROJECT_ID" "$ENV_ID" score.yaml \ + --default-image "${IMAGE}:${IMAGE_TAG}" \ + --no-prompt + + - name: Deployment summary + if: always() + run: | + # Same commit the deploy step resolved, abbreviated for reading only -- the + # deployed tag is the full sha. + DEPLOYED_SHA="${{ github.event.workflow_run.head_sha || github.sha }}" + SHORT_SHA="${DEPLOYED_SHA:0:7}" + echo "## Deployment Result" >> $GITHUB_STEP_SUMMARY + echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY + echo "|---|---|" >> $GITHUB_STEP_SUMMARY + echo "| Project | \`$PROJECT_ID\` |" >> $GITHUB_STEP_SUMMARY + echo "| Environment | \`$ENV_ID\` |" >> $GITHUB_STEP_SUMMARY + echo "| Commit | \`$SHORT_SHA\` |" >> $GITHUB_STEP_SUMMARY + echo "[View in Orchestrator Console](https://console.dev.orchestrator.crucible.kyndemo.live/orgs/$PO_ORG_ID/projects/$PROJECT_ID/environments/$ENV_ID)" >> $GITHUB_STEP_SUMMARY diff --git a/.gitea/workflows/integration-test.yml b/.gitea/workflows/integration-test.yml new file mode 100644 index 0000000..a49a4bf --- /dev/null +++ b/.gitea/workflows/integration-test.yml @@ -0,0 +1,161 @@ + +name: Integration Test + +on: + pull_request: + branches: [ "main" ] + workflow_dispatch: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + # ── Job 1: Platform Conformance ─────────────────────────────────────────── + platform-check: + name: Platform Conformance + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Validate catalog-info.yaml + run: | + if [ ! -f catalog-info.yaml ]; then + echo "✗ catalog-info.yaml not found" + exit 1 + fi + python3 -c "import yaml; list(yaml.safe_load_all(open('catalog-info.yaml')))" 2>/dev/null \ + || (pip install pyyaml -q && python3 -c "import yaml; list(yaml.safe_load_all(open('catalog-info.yaml')))") + echo "✓ catalog-info.yaml is valid YAML" + + - name: Check platform initialized + run: | + if [ -f ".platform/initialized.md" ]; then + echo "✓ Platform initialized" + else + echo "⚠ .platform/initialized.md not found — skipping guard" + fi + + # ── Job 2: Unit Tests + Container Smoke ─────────────────────────────────── + smoke-test: + name: Unit Tests + Container Smoke + runs-on: ubuntu-latest + needs: platform-check + timeout-minutes: 20 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Free disk space + run: | + docker system prune -f 2>/dev/null || true + df -h / 2>/dev/null || true + + - name: Install Docker CLI + run: command -v docker &>/dev/null || (apt-get update -qq && apt-get install -y docker.io) + + - name: Build container image + run: | + if [ -f Dockerfile ]; then + docker build -t ci-image:test . + else + echo "No Dockerfile found — skipping container smoke test" + echo "SKIP_SMOKE=true" >> $GITHUB_ENV + fi + + - name: Start service and wait for health + if: env.SKIP_SMOKE != 'true' + run: | + CONTAINER_NAME="ci-${GITHUB_RUN_ID}" + + # Nothing sets CONTAINER_PORT, so this used to be 8080 on every run, for every + # application. That is fine for Spring Boot and wrong for everything else -- an + # Express app on 3000 was probed on 8080, found nothing, and failed the smoke test + # after burning the full 180 second health timeout. + # + # score.yaml is the one file in this repository that knows the answer: the agent + # writes targetPort from the port it detected in the application's own source. So + # read it, exactly as the health-path probe below discovers its path instead of + # assuming one. Both defaults stay as a last resort for a repo without a score.yaml. + PORT="${CONTAINER_PORT:-}" + if [ -z "${PORT}" ] && [ -f score.yaml ]; then + PORT=$(grep -oE 'targetPort:[[:space:]]*[0-9]+' score.yaml | head -1 | tr -dc '0-9') + [ -n "${PORT}" ] && echo "Detected container port ${PORT} from score.yaml" + fi + PORT="${PORT:-8080}" + echo "CONTAINER_NAME=${CONTAINER_NAME}" >> $GITHUB_ENV + echo "CONTAINER_PORT=${PORT}" >> $GITHUB_ENV + + docker run -d --name "${CONTAINER_NAME}" -e OTEL_SDK_DISABLED=true ci-image:test + + for i in $(seq 1 10); do + CONTAINER_IP=$(docker inspect "${CONTAINER_NAME}" --format '{{.NetworkSettings.IPAddress}}' 2>/dev/null) + [ -n "${CONTAINER_IP}" ] && break + sleep 1 + done + echo "CONTAINER_IP=${CONTAINER_IP}" >> $GITHUB_ENV + + # This factory renovates arbitrary applications, so it cannot know the health path + # in advance. The previous hardcoded /health is wrong for the single most likely + # input: a Spring Boot app serves /actuator/health and 404s on /health, so the + # smoke test sat through its full 180s timeout against a container that was up and + # answering the whole time. + # + # Probe candidates instead, and settle on whichever answers. `/` is last and is a + # legitimate result -- it proves the container serves HTTP, which is all this test + # claims. HEALTH_ENDPOINT still wins if the caller sets it. + CANDIDATES="${HEALTH_ENDPOINT:-} /actuator/health /health /healthz /health/live /api/health /" + echo "Probing for a health endpoint on ${CONTAINER_IP}:${PORT} (up to 180s)..." + DEADLINE=$(($(date +%s) + 180)) + HEALTH_PATH="" + while [ -z "${HEALTH_PATH}" ]; do + for c in ${CANDIDATES}; do + if curl -sf -o /dev/null "http://${CONTAINER_IP}:${PORT}${c}" 2>/dev/null; then + HEALTH_PATH="$c"; break + fi + done + [ -n "${HEALTH_PATH}" ] && break + if [ $(date +%s) -ge $DEADLINE ]; then + echo "Timeout: no candidate path answered (${CANDIDATES})" + docker logs "${CONTAINER_NAME}" 2>&1 | tail -30 + exit 1 + fi + if ! docker ps --filter "name=${CONTAINER_NAME}" --format '{{.Status}}' | grep -q Up; then + echo "Container exited:" + docker logs "${CONTAINER_NAME}" 2>&1 | tail -30 + exit 1 + fi + echo " still waiting..."; sleep 3 + done + echo "HEALTH_PATH=${HEALTH_PATH}" >> $GITHUB_ENV + echo "✓ Service healthy at ${CONTAINER_IP}:${PORT}${HEALTH_PATH}" + + - name: Validate health response + if: env.SKIP_SMOKE != 'true' + run: | + curl -sf "http://${CONTAINER_IP}:${CONTAINER_PORT}${HEALTH_PATH}" > /tmp/health.json + echo "Health response:" + cat /tmp/health.json + echo "" + echo "✓ Container smoke test: PASSED" + + - name: Cleanup + if: always() + run: docker rm -f "ci-${GITHUB_RUN_ID}" 2>/dev/null || true + + - name: Post commit status + if: always() + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + JOB_STATUS: ${{ job.status }} + run: | + STATE=$([[ "$JOB_STATUS" == "success" ]] && echo "success" || echo "failure") + DESC=$([[ "$STATE" == "success" ]] && echo "All checks passed" || echo "Some checks failed") + curl -sf -X POST \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + "${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/statuses/${GITHUB_SHA}" \ + -d "{\"state\":\"${STATE}\",\"context\":\"Integration Test / Unit Tests + Container Smoke (workflow_dispatch)\",\"description\":\"${DESC}\"}" \ + || true diff --git a/.gitea/workflows/sonar.yaml b/.gitea/workflows/sonar.yaml new file mode 100644 index 0000000..7b98fe0 --- /dev/null +++ b/.gitea/workflows/sonar.yaml @@ -0,0 +1,445 @@ + +name: SonarQube Analysis + +on: + pull_request: + types: [opened, synchronize, reopened] + +concurrency: + group: ${{ gitea.workflow }}-${{ gitea.ref }} + cancel-in-progress: true + +jobs: + sonarqube: + name: Build, Test & Analyse + runs-on: ubuntu-latest + timeout-minutes: 15 + + env: + SONAR_PROJECT_KEY: reno-realworld-5 + SONAR_ADMIN_TOKEN: ${{ secrets.SONAR_ADMIN_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + BACKSTAGE_CLEANUP_TOKEN: ${{ secrets.BACKSTAGE_CLEANUP_TOKEN }} + BACKSTAGE_URL: https://backstage.dev.crucible.kyndemo.live + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + # This factory renovates arbitrary applications, so the analysis cannot assume one of + # them. Everything below used to be Maven unconditionally, and the very first Java step + # was `chmod +x mvnw` -- which on a Node repository fails with + # "cannot access 'mvnw': No such file or directory" and takes the whole run with it. + # + # Two paths, chosen from what is actually in the repository: + # + # maven pom.xml present -> mvnw verify + sonar-maven-plugin, with JaCoCo + # cli anything else -> sonar-scanner CLI, which analyses JS/TS, Python, Go + # and more without needing that language's build + # + # `cli` rather than `node` because the fallback is genuinely language-agnostic: a Python + # or Go repository gets analysed too, just without coverage. Only Node adds a test step, + # because it is the one runtime whose coverage format the scanner reads for free. + - name: Detect project type + run: | + set -euo pipefail + if [ -f pom.xml ]; then + KIND=maven + else + KIND=cli + fi + echo "PROJECT_KIND=${KIND}" >> $GITHUB_ENV + echo "Detected project kind: ${KIND}" + if [ "${KIND}" = "cli" ] && [ -f package.json ]; then + echo "HAS_NPM=true" >> $GITHUB_ENV + echo "package.json present — will run tests for coverage." + fi + + # Deliberately NOT gated on PROJECT_KIND. Maven needs it to build, and sonar-scanner is + # itself a Java program that ships no JRE -- so on the CLI path a Node image without + # java would fail inside the scanner's wrapper script with a bare "java: not found". + # Installing it once here is cheaper than diagnosing that. + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + - name: Make Maven wrapper executable + if: env.PROJECT_KIND == 'maven' + run: chmod +x mvnw + + - name: Cache Maven packages + if: env.PROJECT_KIND == 'maven' + uses: actions/cache@v4 + with: + path: ~/.m2/repository + key: maven-${{ runner.os }}-${{ hashFiles('**/pom.xml') }} + restore-keys: maven-${{ runner.os }}- + + # The sonar-maven-plugin caches here. The CLI scanner keeps its own cache under + # ~/.sonar too, so this is useful on both paths -- but the key must not be keyed on + # pom.xml, which does not exist on the CLI path and would collapse every non-Maven + # repository onto one shared key. + - name: Cache SonarQube analysis data + uses: actions/cache@v4 + with: + path: ~/.sonar/cache + key: sonar-${{ runner.os }}-${{ hashFiles('**/pom.xml', '**/package-lock.json', '**/go.sum', '**/requirements.txt') }} + restore-keys: sonar-${{ runner.os }}- + + - name: Validate required secrets + run: | + [[ -n "$SONAR_ADMIN_TOKEN" ]] || { echo "::error::SONAR_ADMIN_TOKEN is not set"; exit 1; } + [[ -n "$SONAR_HOST_URL" ]] || { echo "::error::SONAR_HOST_URL is not set"; exit 1; } + [[ -n "$SONAR_PROJECT_KEY" ]] || { echo "::error::SONAR_PROJECT_KEY is not set"; exit 1; } + + SONAR_HOST_URL="${SONAR_HOST_URL%/}" + + AUTH_RESPONSE=$(curl -s -o /tmp/sonar-auth-response.json -w "%{http_code}" \ + -u "${SONAR_ADMIN_TOKEN}:" \ + "${SONAR_HOST_URL}/api/authentication/validate") + + if [[ "$AUTH_RESPONSE" != "200" ]]; then + echo "::error::SonarQube is unreachable or returned HTTP ${AUTH_RESPONSE} — check SONAR_HOST_URL" + exit 1 + fi + + TOKEN_VALID=$(jq -r '.valid' /tmp/sonar-auth-response.json 2>/dev/null || echo "false") + if [[ "$TOKEN_VALID" != "true" ]]; then + echo "::error::SONAR_ADMIN_TOKEN is invalid or has been revoked (SonarQube returned valid=false)" + exit 1 + fi + + echo "✅ SONAR_ADMIN_TOKEN verified against ${SONAR_HOST_URL}" + + - name: Bootstrap SonarQube project and generate scan token + id: sonar-bootstrap + run: | + PROJECT_COUNT=$(curl -sf \ + -u "${SONAR_ADMIN_TOKEN}:" \ + "${SONAR_HOST_URL}/api/projects/search?projects=${SONAR_PROJECT_KEY}" \ + | jq '.paging.total') + + if [[ "$PROJECT_COUNT" == "0" ]]; then + echo "Project '${SONAR_PROJECT_KEY}' not found — creating it..." + curl -sf -X POST \ + -u "${SONAR_ADMIN_TOKEN}:" \ + "${SONAR_HOST_URL}/api/projects/create" \ + --data-urlencode "name=${SONAR_PROJECT_KEY}" \ + --data-urlencode "project=${SONAR_PROJECT_KEY}" \ + --data-urlencode "mainBranch=main" \ + --data-urlencode "visibility=private" + echo "✅ Project created." + else + echo "✅ Project '${SONAR_PROJECT_KEY}' already exists — skipping creation." + fi + + # The token name MUST be unique per run. It used to be `gitea-scan-`, + # shared by every job analysing this project, and each job both revokes that name + # before generating and revokes it again on cleanup. Concurrent jobs therefore + # destroyed each other's credentials and every analysis failed with + # `Not authorized. Please check the user token in 'sonar.token'` -- an error that + # reads like a permissions problem and is not one. Observed on reno-rehearsal-6, + # where three overlapping jobs failed in a chain: + # + # 18:37:39 job A generates the shared name + # 18:37:40 job B revokes it, generates its own + # 18:38:16 job C revokes it, generates its own + # 18:38:53 job A analysis -> Not authorized (killed at 18:37:40) + # 18:38:53 job A cleanup revokes the name -> kills job C's live token + # 18:39:26 job C analysis -> Not authorized (killed at 18:38:53) + # + # The `concurrency:` block above does not prevent this: Gitea Actions does not + # honour it, so the overlap is real no matter what the workflow declares. Scoping + # the name to the run id removes the shared resource instead of relying on + # serialisation, and the cleanup step revokes that same per-run name so tokens + # still do not accumulate. + TOKEN_NAME="gitea-scan-${SONAR_PROJECT_KEY}-${GITHUB_RUN_ID}" + echo "TOKEN_NAME=${TOKEN_NAME}" >> "$GITHUB_ENV" + + curl -sf -X POST \ + -u "${SONAR_ADMIN_TOKEN}:" \ + "${SONAR_HOST_URL}/api/user_tokens/revoke" \ + --data-urlencode "name=${TOKEN_NAME}" \ + > /dev/null 2>&1 || true + + SCAN_TOKEN=$(curl -sf -X POST \ + -u "${SONAR_ADMIN_TOKEN}:" \ + "${SONAR_HOST_URL}/api/user_tokens/generate" \ + --data-urlencode "name=${TOKEN_NAME}" \ + --data-urlencode "type=PROJECT_ANALYSIS_TOKEN" \ + --data-urlencode "projectKey=${SONAR_PROJECT_KEY}" \ + | jq -r '.token') + + # `jq -r` prints the string "null" for a missing key, which is non-empty and would + # sail past a bare -n test, then fail much later as an authorisation error. + if [[ -z "$SCAN_TOKEN" || "$SCAN_TOKEN" == "null" ]]; then + echo "::error::Failed to generate scan token '${TOKEN_NAME}'"; exit 1 + fi + + echo "✅ Scan token generated for project '${SONAR_PROJECT_KEY}'" + echo "::add-mask::${SCAN_TOKEN}" + echo "SCAN_TOKEN=${SCAN_TOKEN}" >> "$GITHUB_ENV" + + # Spring projects carry io.spring.nohttp, a Checkstyle rule that fails the build on any + # `http://` URL anywhere under ${basedir}. The platform artifacts this factory adds + # contain one legitimately -- the in-cluster OTLP collector, which is plaintext by + # design and has no https:// form -- so the app's own quality gate rejects the + # modernisation: + # + # [ERROR] score.yaml:[7,37] (extension) NoHttp: http:// URLs are not allowed + # [ERROR] overlays/otel/kustomization.yaml:[13,81] ... + # [ERROR] overlays/otel/patches/otel-patch.yaml:[17,19] ... + # + # The two -D properties on the build below cannot fix it: the SuppressionFilter in + # nohttp-checkstyle.xml reads a FIXED path, ${config_loc}/nohttp-checkstyle-suppressions.xml, + # so the only lever is the content of that file. Hence editing it rather than passing + # a flag. + # + # Scoped deliberately: `checks="NoHttp"` only, and only the paths this platform owns. + # Every other Checkstyle rule still applies to them, and NoHttp still applies to all + # application source -- which is the rule's actual purpose. + - name: Allowlist platform artifacts for nohttp + if: env.PROJECT_KIND == 'maven' + run: | + set -euo pipefail + SUPPRESSIONS=src/checkstyle/nohttp-checkstyle-suppressions.xml + if [ ! -f "$SUPPRESSIONS" ]; then + echo "No nohttp suppressions file — project does not use nohttp, nothing to do." + exit 0 + fi + if grep -q 'crucible-platform-artifacts' "$SUPPRESSIONS"; then + echo "Platform artifacts already allowlisted." + exit 0 + fi + grep -q '' "$SUPPRESSIONS" || { + echo "::error::$SUPPRESSIONS has no closing tag"; exit 1; } + + # awk, not python3 or sed -i: this job runs in whatever image the app's build needs, + # so only POSIX tooling is safe to assume. + awk ' + /<\/suppressions>/ && !inserted { + print "\t"; + print "\t"; + print "\t"; + print "\t"; + print "\t"; + print "\t"; + print "\t"; + inserted = 1 + } + { print } + ' "$SUPPRESSIONS" > "$SUPPRESSIONS.new" && mv "$SUPPRESSIONS.new" "$SUPPRESSIONS" + + echo "Allowlisted platform artifacts for NoHttp:" + cat "$SUPPRESSIONS" + + - name: Build and test + if: env.PROJECT_KIND == 'maven' + run: | + ./mvnw -B verify \ + -Dtest='!PostgresIntegrationTests,!MySqlIntegrationTests' \ + -Dnohttp.checkstyle.suppressions.file=src/checkstyle/nohttp-checkstyle-suppressions.xml \ + -Dcheckstyle.suppressionsFile=src/checkstyle/nohttp-checkstyle-suppressions.xml + + - name: SonarQube analysis + if: env.PROJECT_KIND == 'maven' + run: | + ./mvnw -B org.sonarsource.scanner.maven:sonar-maven-plugin:4.0.0.4121:sonar \ + -Dsonar.projectKey="${SONAR_PROJECT_KEY}" \ + -Dsonar.host.url="${SONAR_HOST_URL}" \ + -Dsonar.token="${SCAN_TOKEN}" \ + -Dsonar.java.source=17 \ + -Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml + + # ── Non-Maven path ──────────────────────────────────────────────────── + # + # Everything below runs only when there is no pom.xml, and feeds the SAME quality gate: + # the scan token, the gate poll, the Backstage notification and the token revoke are all + # language-agnostic and are not duplicated. + + - name: Set up Node + if: env.PROJECT_KIND == 'cli' && env.HAS_NPM == 'true' + uses: actions/setup-node@v4 + with: + node-version: '20' + + # Tests must not fail the job. A quality gate reports on what it measured; a repository + # with no test script, or one whose suite needs a database this job does not have, still + # deserves to be analysed. Coverage simply goes unreported, and the gate says so. + - name: Install and test + if: env.PROJECT_KIND == 'cli' && env.HAS_NPM == 'true' + continue-on-error: true + env: + # Prisma validates DATABASE_URL when the client is constructed, and construction + # happens at import time -- including in suites that mock every query and never + # open a connection. A placeholder is enough to let those run; nothing here + # connects to it. Without it the RealWorld service tests fail on + # `Environment variable not found: DATABASE_URL` (7 of 27), which is not a finding + # about the code, and coverage goes unreported for a suite that would have passed. + DATABASE_URL: postgresql://test:test@localhost:5432/test + run: | + set -uo pipefail + if [ -f package-lock.json ]; then npm ci; else npm install; fi + npm test --if-present -- --coverage 2>/dev/null || npm test --if-present || true + if [ -f coverage/lcov.info ]; then + echo "SONAR_LCOV=coverage/lcov.info" >> $GITHUB_ENV + echo "Found coverage/lcov.info — it will be reported." + else + echo "::notice::No coverage/lcov.info produced; analysing without coverage." + fi + + - name: SonarQube analysis (scanner CLI) + if: env.PROJECT_KIND == 'cli' + run: | + set -euo pipefail + # Pinned. `latest` would move the analyser under a quality gate that is supposed to + # mean the same thing from one run to the next. + SCANNER_VERSION=6.2.1.4610 + SCANNER_DIR="sonar-scanner-${SCANNER_VERSION}-linux-x64" + + # This job runs in whatever image the application's build needs, so unzip is not a + # given -- the same reason the nohttp step above uses awk rather than python3. + command -v unzip >/dev/null 2>&1 || { + (apt-get update -qq && apt-get install -y -qq unzip) >/dev/null 2>&1 \ + || { echo "::error::unzip is unavailable and could not be installed"; exit 1; } + } + + curl -sSLo /tmp/sonar-scanner.zip \ + "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SCANNER_VERSION}-linux-x64.zip" + unzip -q /tmp/sonar-scanner.zip -d /opt + export PATH="/opt/${SCANNER_DIR}/bin:${PATH}" + + # The scanner is a Java program and ships no JRE. Most build images have one; if + # this repository's does not, say so plainly rather than surface a bare + # "java: not found" from inside the wrapper script. + command -v java >/dev/null 2>&1 || { + echo "::error::sonar-scanner needs a JRE and none is on PATH in this image." + exit 1 + } + + # Excluded because they are this platform's artifacts, not the application's code, + # and counting them would move the gate for reasons the developer cannot act on. + # Mirrors the nohttp allowlist on the Maven path. + ARGS=( + -Dsonar.projectKey="${SONAR_PROJECT_KEY}" + -Dsonar.host.url="${SONAR_HOST_URL}" + -Dsonar.token="${SCAN_TOKEN}" + -Dsonar.sources=. + -Dsonar.exclusions="**/node_modules/**,**/coverage/**,**/dist/**,**/build/**,k6/**,overlays/**,.platform/**,.gitea/**" + ) + if [ -n "${SONAR_LCOV:-}" ]; then + ARGS+=(-Dsonar.javascript.lcov.reportPaths="${SONAR_LCOV}") + fi + sonar-scanner "${ARGS[@]}" + + - name: Quality Gate check + id: quality-gate + run: | + echo "Waiting for SonarQube to process the analysis..." + for i in $(seq 1 24); do + RESPONSE=$(curl -sf -u "${SCAN_TOKEN}:" \ + "${SONAR_HOST_URL}/api/qualitygates/project_status?projectKey=${SONAR_PROJECT_KEY}" || true) + STATUS=$(echo "$RESPONSE" | jq -r '.projectStatus.status' 2>/dev/null || echo "NONE") + if [[ "$STATUS" =~ ^(OK|ERROR|WARN)$ ]]; then break; fi + echo " Status: ${STATUS:-pending} — retrying in 5s..." + sleep 5 + done + + echo "" + echo "══════════════════════════════════════════" + echo " Quality Gate: $STATUS" + echo "══════════════════════════════════════════" + + echo "$RESPONSE" | jq -r ' + .projectStatus.conditions[] | + if .status == "ERROR" then " ❌ \(.metricKey): \(.actualValue) (threshold: \(.errorThreshold), comparator: \(.comparator))" + elif .status == "WARN" then " ⚠️ \(.metricKey): \(.actualValue) (threshold: \(.errorThreshold), comparator: \(.comparator))" + else " ✅ \(.metricKey): \(.actualValue)" + end' + + echo "══════════════════════════════════════════" + + FAILED=$(echo "$RESPONSE" | jq '[.projectStatus.conditions[] | select(.status == "ERROR")] | length') + if [[ "$FAILED" -gt 0 ]]; then + echo "::error::Quality Gate FAILED — $FAILED metric(s) did not meet threshold" + exit 1 + fi + + - name: Notify Backstage on quality gate failure + if: always() && steps.quality-gate.outcome == 'failure' + run: | + echo "--- Backstage notification debug ---" + echo "BACKSTAGE_URL: ${BACKSTAGE_URL:-}" + echo "BACKSTAGE_CLEANUP_TOKEN set: $([[ -n "$BACKSTAGE_CLEANUP_TOKEN" ]] && echo yes || echo no)" + echo "SONAR_PROJECT_KEY: ${SONAR_PROJECT_KEY:-}" + echo "GITHUB_HEAD_REF: ${GITHUB_HEAD_REF:-}" + + if [[ -z "$BACKSTAGE_URL" ]]; then + echo "::error::BACKSTAGE_URL is not set — cannot send notification" + exit 0 + fi + if [[ -z "$BACKSTAGE_CLEANUP_TOKEN" ]]; then + echo "::error::BACKSTAGE_CLEANUP_TOKEN is not set — cannot send notification" + exit 0 + fi + + # Built with jq rather than a quoted heredoc-by-hand. The previous version + # interpolated shell variables into a \"-escaped string and got one line wrong -- + # `"description": "Quality gate failed for ...` was unescaped, so bash closed the + # string early and tried to run `gate` as a command. Nobody saw it because this + # step only runs when the quality gate fails. jq also escapes the branch name and + # project key, which are attacker-adjacent (a branch may contain a quote). + PAYLOAD=$(jq -nc \ + --arg project "${SONAR_PROJECT_KEY}" \ + --arg branch "${GITHUB_HEAD_REF}" \ + --arg link "${SONAR_HOST_URL}/dashboard?id=${SONAR_PROJECT_KEY}" \ + '{ + recipients: { type: "entity", entityRef: "group:default/platform-engineering" }, + payload: { + title: "SonarQube Quality Gate Failed", + description: "Quality gate failed for \($project) on branch \($branch).", + link: $link, + severity: "high", + topic: "sonarqube-quality-gate" + } + }') + + echo "Sending notification to: ${BACKSTAGE_URL}/api/notifications" + + HTTP_CODE=$(curl -s -o /tmp/bs-notify-response.json -w "%{http_code}" \ + -X POST "${BACKSTAGE_URL}/api/notifications" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${BACKSTAGE_CLEANUP_TOKEN}" \ + -d "${PAYLOAD}") + + echo "HTTP response code: ${HTTP_CODE}" + echo "Response body:" + cat /tmp/bs-notify-response.json 2>/dev/null || echo "" + + if [[ "$HTTP_CODE" -ge 200 && "$HTTP_CODE" -lt 300 ]]; then + echo "✅ Backstage notification sent" + else + echo "⚠️ Backstage notification failed (HTTP ${HTTP_CODE})" + fi + + - name: Revoke scan token + if: always() + run: | + # Revoke THIS run's token, never the bare `gitea-scan-` name -- that + # name belongs to no single job, and revoking it here is what killed a concurrent + # job's live credential. TOKEN_NAME is empty if bootstrap never ran, in which case + # there is nothing to revoke and a blank name would be a no-op request at best. + if [[ -z "${TOKEN_NAME:-}" ]]; then + echo "No scan token was generated — nothing to revoke." + exit 0 + fi + curl -sf -X POST \ + -u "${SONAR_ADMIN_TOKEN}:" \ + "${SONAR_HOST_URL}/api/user_tokens/revoke" \ + --data-urlencode "name=${TOKEN_NAME}" \ + && echo "✅ Scan token revoked (${TOKEN_NAME})" \ + || echo "⚠️ Token revocation failed" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dd0dbd6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +dist +tmp +/out-tsc + +# dependencies +node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/extensions.json +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings +.env + +# System Files +.DS_Store +Thumbs.db + +.nx/cache diff --git a/.platform/initialized.md b/.platform/initialized.md new file mode 100644 index 0000000..0e4dbd3 --- /dev/null +++ b/.platform/initialized.md @@ -0,0 +1,9 @@ +# Platform Initialized + +This file marks the repository as platform-initialized for the Humanitec v2 deploy workflow. + +Created by the Backstage Application Renovation Factory template. + +**Profile**: `db-only` +**Component**: `reno-realworld-5` +**Project**: `reno-realworld-5` diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..d155fdb --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +# Add files here to ignore them from prettier formatting +/dist +/coverage +/.nx/cache \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..544138b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..64553b1 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "nrwl.angular-console", + "esbenp.prettier-vscode", + "firsttris.vscode-jest-runner", + "dbaeumer.vscode-eslint" + ] +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..175f958 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +# This file is generated by Nx. +# +# Build the docker image with `npx nx docker-build api`. +# Tip: Modify "docker-build" options in project.json to change docker build args. +# +# Run the container with `docker run -p 3000:3000 -t api`. +FROM docker.io/node:lts-alpine + +ENV HOST=0.0.0.0 +ENV PORT=3000 + +WORKDIR /app + +RUN addgroup --system api && \ + adduser --system -G api api + +COPY dist/api api +RUN chown -R api:api . + +# You can remove this install step if you build with `--bundle` option. +# The bundled output will include external dependencies. +RUN npm --prefix api --omit=dev -f install + +CMD [ "node", "api" ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..778a80b --- /dev/null +++ b/README.md @@ -0,0 +1,74 @@ +# ![Node/Express/Prisma Example App](project-logo.png) + +[![Build Status](https://travis-ci.org/anishkny/node-express-realworld-example-app.svg?branch=master)](https://travis-ci.org/anishkny/node-express-realworld-example-app) + +> ### Example Node (Express + Prisma) codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the [RealWorld](https://github.com/gothinkster/realworld-example-apps) API spec. + + + +## Getting Started + +### Prerequisites + +Run the following command to install dependencies: + +```shell +npm install +``` + +### Environment variables + +This project depends on some environment variables. +If you are running this project locally, create a `.env` file at the root for these variables. +Your host provider should included a feature to set them there directly to avoid exposing them. + +Here are the required ones: + +``` +DATABASE_URL= +JWT_SECRET= +NODE_ENV=production +``` + +### Generate your Prisma client + +Run the following command to generate the Prisma Client which will include types based on your database schema: + +```shell +npx prisma generate +``` + +### Apply any SQL migration script + +Run the following command to create/update your database based on existing sql migration scripts: + +```shell +npx prisma migrate deploy +``` + +### Run the project + +Run the following command to run the project: + +```shell +npx nx serve api +``` + +### Seed the database + +The project includes a seed script to populate the database: + +```shell +npx prisma db seed +``` + +## Deploy on a remote server + +Run the following command to: +- install dependencies +- apply any new migration sql scripts +- run the server + +```shell +npm ci && npx prisma migrate deploy && node dist/api/main.js +``` diff --git a/catalog-info.yaml b/catalog-info.yaml new file mode 100644 index 0000000..e765609 --- /dev/null +++ b/catalog-info.yaml @@ -0,0 +1,67 @@ + +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: reno-realworld-5 + description: 'reno-realworld-5 — renovated onto the crucible platform orchestrator' + annotations: + gitea.kyndemo.live/project-slug: validate/reno-realworld-5 + gitea.kyndemo.live/repo-slug: validate/reno-realworld-5 + # The orchestrator names each environment's namespace ns-xxxxx at deploy time, so a + # namespace can never be known here -- pinning one only hides the workload. Omitted + # deliberately: the Kubernetes plugin then searches every namespace it is given. + # + # kubernetes-id matches the label the score-workload module propagates from the Score + # metadata.labels block. The previous selector, app.humanitec.io/name=..., was a + # Humanitec SaaS label that nothing on this platform has ever set. + backstage.io/kubernetes-id: reno-realworld-5 + backstage.io/techdocs-ref: dir:. + # Vestigial key names, live values. These drive the Orchestrator tab, which reads + # humanitec.dev/orgId and humanitec.dev/projectId; renaming the keys would break every + # entity already in the catalog, so the names stay and the values point at crucible. + humanitec.dev/orgId: crucible + # THE PROJECT IS THE APPLICATION. This was `apps-cluster`, a single project shared by + # every renovated app, which is why the Orchestrator tab on any one component listed the + # whole estate -- the tab shows a project's environments, and every app's environment + # lived in that one project. Now each app owns a project, so the tab shows this app's + # stages and nothing else. The deploy workflow creates the project, its runner rule and + # its environments on first deploy. + humanitec.dev/projectId: reno-realworld-5 + # The environments are now STAGES of this application -- dev, staging, prod -- rather + # than one environment named after the component. + humanitec.dev/appId: reno-realworld-5 + cjot.io/target-domain: apps + sonarqube.org/project-key: reno-realworld-5 + grafana/grafana-instance: "default" + grafana/alert-label-selector: "app=reno-realworld-5" + grafana/dashboard-selector: "uid == 'otel-app-observability-v2'" + grafana.com/dashboard-url: "https://grafana.kyndemo.live/d/otel-app-observability-v2/opentelemetry-application-observability?orgId=1&var-app=reno-realworld-5" + tags: + - platform-orchestrator + - renovation + - postgresql + links: + # console.humanitec.dev is the dead SaaS. This is the live crucible console, deep-linked + # to the per-application environment the deploy workflow creates. + - url: https://console.dev.orchestrator.crucible.kyndemo.live/orgs/crucible/projects/reno-realworld-5/environments/dev + title: Orchestrator Console + icon: dashboard + - url: https://reno-realworld-5.apps.dev.crucible.kyndemo.live + title: Live Application + icon: web + - url: https://gitea.kyndemo.live/validate/reno-realworld-5 + title: Source Repository + icon: github + - url: https://gitea.kyndemo.live/validate/reno-realworld-5/actions + title: CI/CD Pipelines + icon: code + - url: https://grafana.kyndemo.live/d/otel-app-observability-v2/opentelemetry-application-observability?orgId=1&var-app=reno-realworld-5 + title: Grafana Dashboard + icon: dashboard +spec: + type: service + lifecycle: experimental + owner: platform-engineering + dependsOn: + - resource:default/cjot-aks + - resource:default/ho-v2-postgresql diff --git a/config/nohttp/allowlist.lines b/config/nohttp/allowlist.lines new file mode 100644 index 0000000..cc1fc2f --- /dev/null +++ b/config/nohttp/allowlist.lines @@ -0,0 +1,11 @@ +// Platform-scaffolded internal cluster URLs (not reachable over HTTPS) +// These use Kubernetes service DNS which only supports plain HTTP inside the cluster +^http://.*\.svc\.cluster\.local.*$ + +// OpenTelemetry collector endpoints (gRPC/HTTP on internal cluster network) +^http://otel-collector.*$ +^http://.*otel.*$ + +// k6 load test target URLs (internal service mesh) +^http://frontend\..*$ +^http://localhost.*$ diff --git a/e2e/.eslintrc.json b/e2e/.eslintrc.json new file mode 100644 index 0000000..20a1095 --- /dev/null +++ b/e2e/.eslintrc.json @@ -0,0 +1,16 @@ +{ + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx"], + "extends": ["plugin:@nx/typescript"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "extends": ["plugin:@nx/javascript"], + "rules": {} + } + ], + "plugins": ["@nx"] +} diff --git a/e2e/jest.config.ts b/e2e/jest.config.ts new file mode 100644 index 0000000..776ea12 --- /dev/null +++ b/e2e/jest.config.ts @@ -0,0 +1,19 @@ +/* eslint-disable */ +export default { + displayName: 'e2e', + preset: '../jest.preset.js', + globalSetup: '/src/support/global-setup.ts', + globalTeardown: '/src/support/global-teardown.ts', + setupFiles: ['/src/support/test-setup.ts'], + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': [ + 'ts-jest', + { + tsconfig: '/tsconfig.spec.json', + }, + ], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../coverage/e2e', +}; diff --git a/e2e/project.json b/e2e/project.json new file mode 100644 index 0000000..9be5047 --- /dev/null +++ b/e2e/project.json @@ -0,0 +1,20 @@ +{ + "name": "e2e", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "implicitDependencies": ["api"], + "projectType": "application", + "targets": { + "e2e": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{e2eProjectRoot}"], + "options": { + "jestConfig": "e2e/jest.config.ts", + "passWithNoTests": true + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"] + } + } +} diff --git a/e2e/src/server/server.spec.ts b/e2e/src/server/server.spec.ts new file mode 100644 index 0000000..51717c7 --- /dev/null +++ b/e2e/src/server/server.spec.ts @@ -0,0 +1,10 @@ +import axios from 'axios'; + +describe('GET /', () => { + it('should return a message', async () => { + const res = await axios.get(`/`); + + expect(res.status).toBe(200); + expect(res.data).toEqual({ message: 'Hello API' }); + }); +}); diff --git a/e2e/src/support/global-setup.ts b/e2e/src/support/global-setup.ts new file mode 100644 index 0000000..c1f5144 --- /dev/null +++ b/e2e/src/support/global-setup.ts @@ -0,0 +1,10 @@ +/* eslint-disable */ +var __TEARDOWN_MESSAGE__: string; + +module.exports = async function () { + // Start services that that the app needs to run (e.g. database, docker-compose, etc.). + console.log('\nSetting up...\n'); + + // Hint: Use `globalThis` to pass variables to global teardown. + globalThis.__TEARDOWN_MESSAGE__ = '\nTearing down...\n'; +}; diff --git a/e2e/src/support/global-teardown.ts b/e2e/src/support/global-teardown.ts new file mode 100644 index 0000000..32ea345 --- /dev/null +++ b/e2e/src/support/global-teardown.ts @@ -0,0 +1,7 @@ +/* eslint-disable */ + +module.exports = async function () { + // Put clean up logic here (e.g. stopping services, docker-compose, etc.). + // Hint: `globalThis` is shared between setup and teardown. + console.log(globalThis.__TEARDOWN_MESSAGE__); +}; diff --git a/e2e/src/support/test-setup.ts b/e2e/src/support/test-setup.ts new file mode 100644 index 0000000..07f2870 --- /dev/null +++ b/e2e/src/support/test-setup.ts @@ -0,0 +1,10 @@ +/* eslint-disable */ + +import axios from 'axios'; + +module.exports = async function () { + // Configure axios for tests to use. + const host = process.env.HOST ?? 'localhost'; + const port = process.env.PORT ?? '3000'; + axios.defaults.baseURL = `http://${host}:${port}`; +}; diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json new file mode 100644 index 0000000..9f8b535 --- /dev/null +++ b/e2e/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + } +} diff --git a/e2e/tsconfig.spec.json b/e2e/tsconfig.spec.json new file mode 100644 index 0000000..59079a5 --- /dev/null +++ b/e2e/tsconfig.spec.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", "src/**/*.ts"] +} diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 0000000..bfc7f45 --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,15 @@ +/* eslint-disable */ +export default { + displayName: 'api', + preset: './jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: './coverage/api', + testMatch: [ + '/src/**/__tests__/**/*.[jt]s?(x)', + '/src/**/*(*.)@(spec|test).[jt]s?(x)', + ], +}; diff --git a/jest.preset.js b/jest.preset.js new file mode 100644 index 0000000..f078ddc --- /dev/null +++ b/jest.preset.js @@ -0,0 +1,3 @@ +const nxPreset = require('@nx/jest/preset').default; + +module.exports = { ...nxPreset }; diff --git a/nx.json b/nx.json new file mode 100644 index 0000000..f5beac6 --- /dev/null +++ b/nx.json @@ -0,0 +1,46 @@ +{ + "$schema": "./node_modules/nx/schemas/nx-schema.json", + "targetDefaults": { + "build": { + "cache": true, + "dependsOn": ["^build"], + "inputs": ["production", "^production"] + }, + "lint": { + "cache": true, + "inputs": [ + "default", + "{workspaceRoot}/.eslintrc.json", + "{workspaceRoot}/.eslintignore", + "{workspaceRoot}/eslint.config.js" + ] + }, + "@nx/jest:jest": { + "cache": true, + "inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"], + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + } + }, + "namedInputs": { + "default": ["{projectRoot}/**/*", "sharedGlobals"], + "production": [ + "default", + "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)", + "!{projectRoot}/tsconfig.spec.json", + "!{projectRoot}/jest.config.[jt]s", + "!{projectRoot}/src/test-setup.[jt]s", + "!{projectRoot}/test-setup.[jt]s", + "!{projectRoot}/.eslintrc.json", + "!{projectRoot}/eslint.config.js" + ], + "sharedGlobals": [] + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..95e7c45 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,9898 @@ +{ + "name": "@api/source", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@api/source", + "version": "0.0.0", + "license": "MIT", + "dependencies": { + "@ngneat/falso": "^7.1.1", + "@prisma/client": "^4.16.1", + "axios": "^1.0.0", + "bcryptjs": "^2.4.3", + "body-parser": "^1.20.2", + "cors": "^2.8.5", + "express": "~4.18.1", + "express-jwt": "^8.4.1", + "jsonwebtoken": "^9.0.2", + "slugify": "^1.6.0", + "tslib": "^2.3.0" + }, + "devDependencies": { + "@nx/esbuild": "17.2.6", + "@nx/eslint": "17.2.6", + "@nx/eslint-plugin": "17.2.6", + "@nx/jest": "17.2.6", + "@nx/js": "17.2.6", + "@nx/node": "17.2.6", + "@nx/workspace": "17.2.6", + "@swc-node/register": "~1.6.7", + "@swc/core": "~1.3.85", + "@types/bcryptjs": "^2.4.6", + "@types/cors": "^2.8.17", + "@types/express": "~4.17.13", + "@types/jest": "^29.4.0", + "@types/node": "18.16.9", + "@typescript-eslint/eslint-plugin": "^6.9.1", + "@typescript-eslint/parser": "^6.9.1", + "esbuild": "^0.19.2", + "eslint": "~8.48.0", + "eslint-config-prettier": "^9.0.0", + "jest": "^29.4.1", + "jest-environment-node": "^29.4.1", + "jest-mock-extended": "^3.0.5", + "nx": "17.2.6", + "prettier": "^2.6.2", + "prisma": "^4.16.1", + "ts-jest": "^29.1.0", + "ts-node": "10.9.1", + "typescript": "~5.2.2" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz", + "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.6", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.6.tgz", + "integrity": "sha512-cBXU1vZni/CpGF29iTu4YRbOZt3Wat6zCoMDxRF1MayiEc4URxOj31tT65HUM0CRpMowA3HCJaAOVOUnMf96cw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz", + "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz", + "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.6", + "@babel/types": "^7.23.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz", + "integrity": "sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.6.tgz", + "integrity": "sha512-D7Ccq9LfkBFnow3azZGJvZYgcfeqAw3I1e5LoTpj6UKIFQilh8yqXsIGcRIqbBdsPWIz+Ze7ZZfggSj62Qp+Fg==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.23.6", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/plugin-syntax-decorators": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.23.3.tgz", + "integrity": "sha512-cf7Niq4/+/juY67E0PbgH0TDhLQ5J7zS8C/Q5FFx+DWyrRa9sUQdTXkjqKu8zGvuqr7vw1muKiukseihU+PJDA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", + "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", + "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", + "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz", + "integrity": "sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", + "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", + "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz", + "integrity": "sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz", + "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", + "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.3", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", + "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.6.tgz", + "integrity": "sha512-kF1Zg62aPseQ11orDhFRw+aPG/eynNQtI+TyY+m33qJa2cJ5EEvza2P2BNTIA9E5MyqFABHEyY6CPHwgdy9aNg==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "babel-plugin-polyfill-corejs2": "^0.4.6", + "babel-plugin-polyfill-corejs3": "^0.8.5", + "babel-plugin-polyfill-regenerator": "^0.5.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz", + "integrity": "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.23.6", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", + "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", + "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.6.tgz", + "integrity": "sha512-2XPn/BqKkZCpzYhUUNZ1ssXw7DcXfKQEjv/uXZUXgaebCMYmkEsfZ2yY+vv+xtXv50WmL5SGhyB6/xsWxIvvOQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.3", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.23.3", + "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.4", + "@babel/plugin-transform-async-to-generator": "^7.23.3", + "@babel/plugin-transform-block-scoped-functions": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.4", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.4", + "@babel/plugin-transform-classes": "^7.23.5", + "@babel/plugin-transform-computed-properties": "^7.23.3", + "@babel/plugin-transform-destructuring": "^7.23.3", + "@babel/plugin-transform-dotall-regex": "^7.23.3", + "@babel/plugin-transform-duplicate-keys": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.4", + "@babel/plugin-transform-exponentiation-operator": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.4", + "@babel/plugin-transform-for-of": "^7.23.6", + "@babel/plugin-transform-function-name": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.4", + "@babel/plugin-transform-literals": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", + "@babel/plugin-transform-member-expression-literals": "^7.23.3", + "@babel/plugin-transform-modules-amd": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.3", + "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", + "@babel/plugin-transform-numeric-separator": "^7.23.4", + "@babel/plugin-transform-object-rest-spread": "^7.23.4", + "@babel/plugin-transform-object-super": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.4", + "@babel/plugin-transform-optional-chaining": "^7.23.4", + "@babel/plugin-transform-parameters": "^7.23.3", + "@babel/plugin-transform-private-methods": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", + "@babel/plugin-transform-property-literals": "^7.23.3", + "@babel/plugin-transform-regenerator": "^7.23.3", + "@babel/plugin-transform-reserved-words": "^7.23.3", + "@babel/plugin-transform-shorthand-properties": "^7.23.3", + "@babel/plugin-transform-spread": "^7.23.3", + "@babel/plugin-transform-sticky-regex": "^7.23.3", + "@babel/plugin-transform-template-literals": "^7.23.3", + "@babel/plugin-transform-typeof-symbol": "^7.23.3", + "@babel/plugin-transform-unicode-escapes": "^7.23.3", + "@babel/plugin-transform-unicode-property-regex": "^7.23.3", + "@babel/plugin-transform-unicode-regex": "^7.23.3", + "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.6", + "babel-plugin-polyfill-corejs3": "^0.8.5", + "babel-plugin-polyfill-regenerator": "^0.5.3", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", + "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-typescript": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "node_modules/@babel/runtime": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz", + "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz", + "integrity": "sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.10.tgz", + "integrity": "sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz", + "integrity": "sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.10.tgz", + "integrity": "sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz", + "integrity": "sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz", + "integrity": "sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz", + "integrity": "sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz", + "integrity": "sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz", + "integrity": "sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz", + "integrity": "sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz", + "integrity": "sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz", + "integrity": "sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz", + "integrity": "sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz", + "integrity": "sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz", + "integrity": "sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz", + "integrity": "sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz", + "integrity": "sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz", + "integrity": "sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz", + "integrity": "sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz", + "integrity": "sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz", + "integrity": "sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz", + "integrity": "sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz", + "integrity": "sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "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.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@ngneat/falso": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@ngneat/falso/-/falso-7.1.1.tgz", + "integrity": "sha512-/5HuJDaZHXl3WVdgvYBAM52OSYbSKfiNazVOZOw/3KjeZ6dQW9F0QCG+W6z52lUu5MZvp/TkPGaVRtoz6h9T1w==", + "dependencies": { + "seedrandom": "3.0.5", + "uuid": "8.3.2" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nrwl/devkit": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-17.2.6.tgz", + "integrity": "sha512-uZVqc2qhi+WdSqLV9aIcE+5ck+IUSQ47Cc5bslWrssQjBncqGavHYDuU4ZLuKK5HxCuZqlQjvo7TsF7LeOjNiA==", + "dev": true, + "dependencies": { + "@nx/devkit": "17.2.6" + } + }, + "node_modules/@nrwl/esbuild": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nrwl/esbuild/-/esbuild-17.2.6.tgz", + "integrity": "sha512-FeuBbwguK6MzUOgXUp6AJWRgjZtB98vLgT/+BwhBrDaPDaUaHCMpqMmLPLCPZPuA1g0bX08AIvVKL2rZaim7yw==", + "dev": true, + "dependencies": { + "@nx/esbuild": "17.2.6" + } + }, + "node_modules/@nrwl/eslint-plugin-nx": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-17.2.6.tgz", + "integrity": "sha512-xQDmFeIc+VR3q6scSSciSNVSdcRI52FFTTlDw4/pZCJk59LJTt6GgnqeL0Aj4EIgELfZQLOsKrxIoup5gzKlrQ==", + "dev": true, + "dependencies": { + "@nx/eslint-plugin": "17.2.6" + } + }, + "node_modules/@nrwl/jest": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nrwl/jest/-/jest-17.2.6.tgz", + "integrity": "sha512-YZ6yFFw1lq7nSCZTkP8qMbIeYX/yJ6Ko6iXPECPQViy4W6E9WEVnWU52RkovoKSN+CuhienzJCxne7DALLLr3w==", + "dev": true, + "dependencies": { + "@nx/jest": "17.2.6" + } + }, + "node_modules/@nrwl/js": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nrwl/js/-/js-17.2.6.tgz", + "integrity": "sha512-oFnyaVOpVG3XrkIXQMs5TM6hrRRBe38jRX79d51S41yLuiOrHgpJlMmii1wafevM1Dpk9UlAvPh7v8OffgDZtg==", + "dev": true, + "dependencies": { + "@nx/js": "17.2.6" + } + }, + "node_modules/@nrwl/node": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nrwl/node/-/node-17.2.6.tgz", + "integrity": "sha512-ZsD18byFJ7OqFIzWFnnYOsR/vVZyyNbCPoiygqyviMakI1xBDjQ1/Ea2nUXjdC45iaaQ2/+PkVA1v7k23cmbAg==", + "dev": true, + "dependencies": { + "@nx/node": "17.2.6" + } + }, + "node_modules/@nrwl/tao": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-17.2.6.tgz", + "integrity": "sha512-cgtUKTRSxDZ94S9IpC27/qYZJ1YttJDET+veKrtRYvwnHFgkq1peyeTTtnM25yJon7PRdm2lYrlIVdPm0vXupw==", + "dev": true, + "dependencies": { + "nx": "17.2.6", + "tslib": "^2.3.0" + }, + "bin": { + "tao": "index.js" + } + }, + "node_modules/@nrwl/workspace": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nrwl/workspace/-/workspace-17.2.6.tgz", + "integrity": "sha512-ACMnIxblNEAsjFfkpNspENxlm/jMpF9hr3aKioyoFAUmATxO7lJt8VuA43slI1oVgtTfWpOcM0aSRP/07kVW6Q==", + "dev": true, + "dependencies": { + "@nx/workspace": "17.2.6" + } + }, + "node_modules/@nx/devkit": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-17.2.6.tgz", + "integrity": "sha512-a9GPw0KiLhvv2RBLPlWgaVDZRvgww4ANBwv7LuGvk8FNgxF5vkQMM5WyKpvxKJhmh1EZ+T9JsGWAFrK7skW9Bw==", + "dev": true, + "dependencies": { + "@nrwl/devkit": "17.2.6", + "ejs": "^3.1.7", + "enquirer": "~2.3.6", + "ignore": "^5.0.4", + "semver": "7.5.3", + "tmp": "~0.2.1", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "nx": ">= 16 <= 18" + } + }, + "node_modules/@nx/esbuild": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/esbuild/-/esbuild-17.2.6.tgz", + "integrity": "sha512-Dx+EeyGN8YvTi1ybeWYnESstfXmPUhm/xfPy+uZVpXpoLa8qM/4XPVZ+lqV97k2t8ApVLK6I4yYNcbX697pTVg==", + "dev": true, + "dependencies": { + "@nrwl/esbuild": "17.2.6", + "@nx/devkit": "17.2.6", + "@nx/js": "17.2.6", + "chalk": "^4.1.0", + "fast-glob": "3.2.7", + "fs-extra": "^11.1.0", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "esbuild": "~0.19.2" + }, + "peerDependenciesMeta": { + "esbuild": { + "optional": true + } + } + }, + "node_modules/@nx/eslint": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/eslint/-/eslint-17.2.6.tgz", + "integrity": "sha512-gDtIf6T3vCf7XO2lWvVulFcNmx2l6kKGZypEpLMGtfdAUai/aaBbNHbbwcsOZiPvWtNo64mGBZX5Qv6aPb9oPg==", + "dev": true, + "dependencies": { + "@nx/devkit": "17.2.6", + "@nx/js": "17.2.6", + "@nx/linter": "17.2.6", + "tslib": "^2.3.0", + "typescript": "~5.2.2" + }, + "peerDependencies": { + "eslint": "^8.0.0", + "js-yaml": "4.1.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "js-yaml": { + "optional": true + } + } + }, + "node_modules/@nx/eslint-plugin": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/eslint-plugin/-/eslint-plugin-17.2.6.tgz", + "integrity": "sha512-P9+G9r6fz0RP/muchPFHyicfA4o80kUD8oRmrJJAjI3KolpRk3Kld7GAbXPkunnGuMcf/nSJxaUkt+QCe5zOhQ==", + "dev": true, + "dependencies": { + "@nrwl/eslint-plugin-nx": "17.2.6", + "@nx/devkit": "17.2.6", + "@nx/js": "17.2.6", + "@typescript-eslint/type-utils": "^6.9.1", + "@typescript-eslint/utils": "^6.9.1", + "chalk": "^4.1.0", + "confusing-browser-globals": "^1.0.9", + "jsonc-eslint-parser": "^2.1.0", + "semver": "7.5.3", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.9.1", + "eslint-config-prettier": "^9.0.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/@nx/jest": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/jest/-/jest-17.2.6.tgz", + "integrity": "sha512-lWdzwkNfVQPCcr3gb3OrtUX/wjI9Oxm6Q9cKezPydCWtrZnEQii/aRi9/AncCGBf0Rx6hLT0yaiIAvJKlCk9qg==", + "dev": true, + "dependencies": { + "@jest/reporters": "^29.4.1", + "@jest/test-result": "^29.4.1", + "@nrwl/jest": "17.2.6", + "@nx/devkit": "17.2.6", + "@nx/js": "17.2.6", + "@phenomnomnominal/tsquery": "~5.0.1", + "chalk": "^4.1.0", + "identity-obj-proxy": "3.0.0", + "jest-config": "^29.4.1", + "jest-resolve": "^29.4.1", + "jest-util": "^29.4.1", + "resolve.exports": "1.1.0", + "tslib": "^2.3.0" + } + }, + "node_modules/@nx/js": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/js/-/js-17.2.6.tgz", + "integrity": "sha512-jjWzEg63C7vBu6Lo890N8gIcEji+8/ggf5My2kCmAnJehqIg8/B0Bq0x9shIxAT7qZgyLxHbC3VWg5ictS6aEw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.22.9", + "@babel/plugin-proposal-decorators": "^7.22.7", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-runtime": "^7.22.9", + "@babel/preset-env": "^7.22.9", + "@babel/preset-typescript": "^7.22.5", + "@babel/runtime": "^7.22.6", + "@nrwl/js": "17.2.6", + "@nx/devkit": "17.2.6", + "@nx/workspace": "17.2.6", + "@phenomnomnominal/tsquery": "~5.0.1", + "babel-plugin-const-enum": "^1.0.1", + "babel-plugin-macros": "^2.8.0", + "babel-plugin-transform-typescript-metadata": "^0.3.1", + "chalk": "^4.1.0", + "columnify": "^1.6.0", + "detect-port": "^1.5.1", + "fast-glob": "3.2.7", + "fs-extra": "^11.1.0", + "ignore": "^5.0.4", + "js-tokens": "^4.0.0", + "minimatch": "3.0.5", + "npm-package-arg": "11.0.1", + "npm-run-path": "^4.0.1", + "ora": "5.3.0", + "semver": "7.5.3", + "source-map-support": "0.5.19", + "ts-node": "10.9.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "verdaccio": "^5.0.4" + }, + "peerDependenciesMeta": { + "verdaccio": { + "optional": true + } + } + }, + "node_modules/@nx/js/node_modules/babel-plugin-macros": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", + "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.7.2", + "cosmiconfig": "^6.0.0", + "resolve": "^1.12.0" + } + }, + "node_modules/@nx/js/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nx/linter": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/linter/-/linter-17.2.6.tgz", + "integrity": "sha512-TTS3WPZQNVdFgTykdX3jbELcN0IsYpKPv8TGOzqkJbRfvsF2jjZzQggWujg1iXBdWRKdaWYDi8SUi+4wocemIg==", + "dev": true, + "dependencies": { + "@nx/eslint": "17.2.6" + } + }, + "node_modules/@nx/node": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/node/-/node-17.2.6.tgz", + "integrity": "sha512-kf0yttlSF3kwL8feTOHPQUGJO3p3aqTji6Qd3ZDdh2KiSMMRu6czg+/MDcrCFN/Hanczp+js/qiKxuwwRp43uw==", + "dev": true, + "dependencies": { + "@nrwl/node": "17.2.6", + "@nx/devkit": "17.2.6", + "@nx/eslint": "17.2.6", + "@nx/jest": "17.2.6", + "@nx/js": "17.2.6", + "tslib": "^2.3.0" + } + }, + "node_modules/@nx/nx-darwin-arm64": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-17.2.6.tgz", + "integrity": "sha512-ezU5u7hkEwI2xzsFSjyr53uNURBvga40LQlpEnS/CbqRifHHhTKisCy+r2+kRhiOwTeR+I+/2D3zPyIyN3aEHQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-darwin-x64": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-17.2.6.tgz", + "integrity": "sha512-wUIwbM/7LMxlFkEOlbxR/s2qaRuD69yXc70f2rtxsskwJ4GOF5kfc1jk2YaDs9qswI+FgQVgbeZu8pgF+slY7Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-freebsd-x64": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-17.2.6.tgz", + "integrity": "sha512-uBKEGqG4txVCpBirRzt1QwuOLzfA0s9dlUP7n5t4qJuaf9OXuVcDXay8g84WT1jx4PPtipyv/wyIFu3r7v8kZw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm-gnueabihf": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-17.2.6.tgz", + "integrity": "sha512-dSDVz2BktaPHMkrJojFCx+V+QFLDF0KzoHorESzZmHZTfumr0xtJ1COWCU+gYmLptc+8OgwCzCPWXHhcDgji/A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-gnu": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-17.2.6.tgz", + "integrity": "sha512-AD99Kk47Yxn3IJ89aCT1oVpNX1XNECAYay97yhqf2tiBsDv9hC43PppOdjI0dNP5VRBTrr6EsWdhvE0uNJ3RJw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-musl": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-17.2.6.tgz", + "integrity": "sha512-MOX/EJyzseEnzbFxY7V6es/xta6WQ0cDDrl6i6qjCRnoRTFFVMsL0Fb4dtVbv7fd75O41P+OBGpG70MYx2SOxw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-gnu": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-17.2.6.tgz", + "integrity": "sha512-16xTSszGPY25INDUr4pzLXWcO3va1764iVFiHRTuJr5siDymY7zSj+DPKFmewzqF2358Y5m8AtMotY0FqKciYg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-musl": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-17.2.6.tgz", + "integrity": "sha512-F/nIq8bcZd2cNuBiQbyJwur7CpeRBCt0qKDF38HQ2l3HhQv+jwk4T6115LMQqwZb9e6kt6BAFsY+6O7I6t3pCw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-arm64-msvc": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-17.2.6.tgz", + "integrity": "sha512-1lAKKKiH7eduzqcPDB03iPz38yNXn3Y4Q/3jULjaRc3EFAplfBsYVwJ9kGjXPZSrpt/AY7w5ATY55/r5B3gQnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-x64-msvc": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-17.2.6.tgz", + "integrity": "sha512-LrJySMWrO5oWMrP4VOWM1hr3c4rtxHGCcRy19VwqvaAPDrnsg0qfPjv4q1C9YyIU8sj+T3oJs1yZdnNntlN8ew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/workspace": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/@nx/workspace/-/workspace-17.2.6.tgz", + "integrity": "sha512-mss1RggPBWpggMJ7ok83iHx/PdlevhDqayLvjguRKjPwk0rTBRUuvY78AkKo2RbMOQyywNMt09MNz5FOmfCfqg==", + "dev": true, + "dependencies": { + "@nrwl/workspace": "17.2.6", + "@nx/devkit": "17.2.6", + "chalk": "^4.1.0", + "enquirer": "~2.3.6", + "nx": "17.2.6", + "tslib": "^2.3.0", + "yargs-parser": "21.1.1" + } + }, + "node_modules/@phenomnomnominal/tsquery": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-5.0.1.tgz", + "integrity": "sha512-3nVv+e2FQwsW8Aw6qTU6f+1rfcJ3hrcnvH/mu9i8YhxO+9sqbOfpL8m6PbET5+xKOlz/VSbp0RoYWYCtIsnmuA==", + "dev": true, + "dependencies": { + "esquery": "^1.4.0" + }, + "peerDependencies": { + "typescript": "^3 || ^4 || ^5" + } + }, + "node_modules/@prisma/client": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.16.2.tgz", + "integrity": "sha512-qCoEyxv1ZrQ4bKy39GnylE8Zq31IRmm8bNhNbZx7bF2cU5aiCCnSa93J2imF88MBjn7J9eUQneNxUQVJdl/rPQ==", + "hasInstallScript": true, + "dependencies": { + "@prisma/engines-version": "4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/engines": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.16.2.tgz", + "integrity": "sha512-vx1nxVvN4QeT/cepQce68deh/Turxy5Mr+4L4zClFuK1GlxN3+ivxfuv+ej/gvidWn1cE1uAhW7ALLNlYbRUAw==", + "devOptional": true, + "hasInstallScript": true + }, + "node_modules/@prisma/engines-version": { + "version": "4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81.tgz", + "integrity": "sha512-q617EUWfRIDTriWADZ4YiWRZXCa/WuhNgLTVd+HqWLffjMSPzyM5uOWoauX91wvQClSKZU4pzI4JJLQ9Kl62Qg==" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@swc-node/core": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@swc-node/core/-/core-1.10.6.tgz", + "integrity": "sha512-lDIi/rPosmKIknWzvs2/Fi9zWRtbkx8OJ9pQaevhsoGzJSal8Pd315k1W5AIrnknfdAB4HqRN12fk6AhqnrEEw==", + "dev": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@swc/core": ">= 1.3" + } + }, + "node_modules/@swc-node/register": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@swc-node/register/-/register-1.6.8.tgz", + "integrity": "sha512-74ijy7J9CWr1Z88yO+ykXphV29giCrSpANQPQRooE0bObpkTO1g4RzQovIfbIaniBiGDDVsYwDoQ3FIrCE8HcQ==", + "dev": true, + "dependencies": { + "@swc-node/core": "^1.10.6", + "@swc-node/sourcemap-support": "^0.3.0", + "colorette": "^2.0.19", + "debug": "^4.3.4", + "pirates": "^4.0.5", + "tslib": "^2.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@swc/core": ">= 1.3", + "typescript": ">= 4.3" + } + }, + "node_modules/@swc-node/sourcemap-support": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@swc-node/sourcemap-support/-/sourcemap-support-0.3.0.tgz", + "integrity": "sha512-gqBJSmJMWomZFxlppaKea7NeAqFrDrrS0RMt24No92M3nJWcyI9YKGEQKl+EyJqZ5gh6w1s0cTklMHMzRwA1NA==", + "dev": true, + "dependencies": { + "source-map-support": "^0.5.21", + "tslib": "^2.5.0" + } + }, + "node_modules/@swc-node/sourcemap-support/node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/@swc/core": { + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.101.tgz", + "integrity": "sha512-w5aQ9qYsd/IYmXADAnkXPGDMTqkQalIi+kfFf/MHRKTpaOL7DHjMXwPp/n8hJ0qNjRvchzmPtOqtPBiER50d8A==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@swc/counter": "^0.1.1", + "@swc/types": "^0.1.5" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.3.101", + "@swc/core-darwin-x64": "1.3.101", + "@swc/core-linux-arm-gnueabihf": "1.3.101", + "@swc/core-linux-arm64-gnu": "1.3.101", + "@swc/core-linux-arm64-musl": "1.3.101", + "@swc/core-linux-x64-gnu": "1.3.101", + "@swc/core-linux-x64-musl": "1.3.101", + "@swc/core-win32-arm64-msvc": "1.3.101", + "@swc/core-win32-ia32-msvc": "1.3.101", + "@swc/core-win32-x64-msvc": "1.3.101" + }, + "peerDependencies": { + "@swc/helpers": "^0.5.0" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.101.tgz", + "integrity": "sha512-mNFK+uHNPRXSnfTOG34zJOeMl2waM4hF4a2NY7dkMXrPqw9CoJn4MwTXJcyMiSz1/BnNjjTCHF3Yhj0jPxmkzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.101.tgz", + "integrity": "sha512-B085j8XOx73Fg15KsHvzYWG262bRweGr3JooO1aW5ec5pYbz5Ew9VS5JKYS03w2UBSxf2maWdbPz2UFAxg0whw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.101.tgz", + "integrity": "sha512-9xLKRb6zSzRGPqdz52Hy5GuB1lSjmLqa0lST6MTFads3apmx4Vgs8Y5NuGhx/h2I8QM4jXdLbpqQlifpzTlSSw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.101.tgz", + "integrity": "sha512-oE+r1lo7g/vs96Weh2R5l971dt+ZLuhaUX+n3BfDdPxNHfObXgKMjO7E+QS5RbGjv/AwiPCxQmbdCp/xN5ICJA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.101.tgz", + "integrity": "sha512-OGjYG3H4BMOTnJWJyBIovCez6KiHF30zMIu4+lGJTCrxRI2fAjGLml3PEXj8tC3FMcud7U2WUn6TdG0/te2k6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.101.tgz", + "integrity": "sha512-/kBMcoF12PRO/lwa8Z7w4YyiKDcXQEiLvM+S3G9EvkoKYGgkkz4Q6PSNhF5rwg/E3+Hq5/9D2R+6nrkF287ihg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.101.tgz", + "integrity": "sha512-kDN8lm4Eew0u1p+h1l3JzoeGgZPQ05qDE0czngnjmfpsH2sOZxVj1hdiCwS5lArpy7ktaLu5JdRnx70MkUzhXw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.101.tgz", + "integrity": "sha512-9Wn8TTLWwJKw63K/S+jjrZb9yoJfJwCE2RV5vPCCWmlMf3U1AXj5XuWOLUX+Rp2sGKau7wZKsvywhheWm+qndQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.101.tgz", + "integrity": "sha512-onO5KvICRVlu2xmr4//V2je9O2XgS1SGKpbX206KmmjcJhXN5EYLSxW9qgg+kgV5mip+sKTHTAu7IkzkAtElYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.3.101", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.101.tgz", + "integrity": "sha512-T3GeJtNQV00YmiVw/88/nxJ/H43CJvFnpvBHCVn17xbahiVUOPOduh3rc9LgAkKiNt/aV8vU3OJR+6PhfMR7UQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.2.tgz", + "integrity": "sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==", + "dev": true + }, + "node_modules/@swc/types": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz", + "integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==", + "dev": true + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.4", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz", + "integrity": "sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/bcryptjs": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.6.tgz", + "integrity": "sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==", + "dev": true + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.41", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz", + "integrity": "sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.11", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz", + "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz", + "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.16.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.9.tgz", + "integrity": "sha512-IeB32oIV4oGArLrd7znD2rkHQ6EDCM+2Sr76dJnrHwv9OHBTTM6nuDLK9bmikXzPa0ZlWMWtRGo/Uw4mrzQedA==" + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.10", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz", + "integrity": "sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.15.0.tgz", + "integrity": "sha512-j5qoikQqPccq9QoBAupOP+CBu8BaJ8BLjaXSioDISeTZkVO3ig7oSIKh3H+rEpee7xCXtWwSB4KIL5l6hWZzpg==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/type-utils": "6.15.0", + "@typescript-eslint/utils": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.15.0.tgz", + "integrity": "sha512-MkgKNnsjC6QwcMdlNAel24jjkEO/0hQaMDLqP4S9zq5HBAUJNQB6y+3DwLjX7b3l2b37eNAxMPLwb3/kh8VKdA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/typescript-estree": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.15.0.tgz", + "integrity": "sha512-+BdvxYBltqrmgCNu4Li+fGDIkW9n//NrruzG9X1vBzaNK+ExVXPoGB71kneaVw/Jp+4rH/vaMAGC6JfMbHstVg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.15.0.tgz", + "integrity": "sha512-CnmHKTfX6450Bo49hPg2OkIm/D/TVYV7jO1MCfPYGwf6x3GO0VU8YMO5AYMn+u3X05lRRxA4fWCz87GFQV6yVQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.15.0", + "@typescript-eslint/utils": "6.15.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.15.0.tgz", + "integrity": "sha512-yXjbt//E4T/ee8Ia1b5mGlbNj9fB9lJP4jqLbZualwpP2BCQ5is6BcWwxpIsY4XKAhmdv3hrW92GdtJbatC6dQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.15.0.tgz", + "integrity": "sha512-7mVZJN7Hd15OmGuWrp2T9UvqR2Ecg+1j/Bp1jXUEY2GZKV6FXlOIoqVDmLpBiEiq3katvj/2n2mR0SDwtloCew==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/visitor-keys": "6.15.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.15.0.tgz", + "integrity": "sha512-eF82p0Wrrlt8fQSRL0bGXzK5nWPRV2dYQZdajcfzOD9+cQz9O7ugifrJxclB+xVOvWvagXfqS4Es7vpLP4augw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.15.0", + "@typescript-eslint/types": "6.15.0", + "@typescript-eslint/typescript-estree": "6.15.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.15.0.tgz", + "integrity": "sha512-1zvtdC1a9h5Tb5jU9x3ADNXO9yjP8rXlaoChu0DQX40vf5ACVpYIVIZhIMZ6d5sDXH7vq4dsZBT1fEGj8D2n2w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.15.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "node_modules/@yarnpkg/parsers": { + "version": "3.0.0-rc.46", + "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz", + "integrity": "sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==", + "dev": true, + "dependencies": { + "js-yaml": "^3.10.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.15.0" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@zkochan/js-yaml": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz", + "integrity": "sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", + "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "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/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", + "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-const-enum": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-const-enum/-/babel-plugin-const-enum-1.2.0.tgz", + "integrity": "sha512-o1m/6iyyFnp9MRsK1dHF3bneqyf3AlM2q3A/YbgQr2pCat6B6XJVDv2TXqzfY2RYUi4mak6WAksSBPlyYGx9dg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-typescript": "^7.3.3", + "@babel/traverse": "^7.16.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.7.tgz", + "integrity": "sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.4", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.7.tgz", + "integrity": "sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.4", + "core-js-compat": "^3.33.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.4.tgz", + "integrity": "sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.4" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-transform-typescript-metadata": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-typescript-metadata/-/babel-plugin-transform-typescript-metadata-0.3.2.tgz", + "integrity": "sha512-mWEvCQTgXQf48yDqgN7CH50waTyYBeP2Lpqx4nNWab9sxEpdXVeKgfj1qYI2/TgUPQtNFZ85i3PemRtnXVYYJg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "dev": true, + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001570", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz", + "integrity": "sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/columnify": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz", + "integrity": "sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==", + "dev": true, + "dependencies": { + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/core-js-compat": { + "version": "3.34.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.34.0.tgz", + "integrity": "sha512-4ZIyeNbW/Cn1wkMMDy+mvrRUxrwFNjKwbhCfQpDd+eLgYipDqp8oGFGtLmhh18EDPKA0g3VUBYOxQGGwvWLVpA==", + "dev": true, + "dependencies": { + "browserslist": "^4.22.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/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" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", + "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-port": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", + "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", + "dev": true, + "dependencies": { + "address": "^1.0.1", + "debug": "4" + }, + "bin": { + "detect": "bin/detect-port.js", + "detect-port": "bin/detect-port.js" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, + "node_modules/dotenv-expand": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", + "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.615", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.615.tgz", + "integrity": "sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/esbuild": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.10.tgz", + "integrity": "sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.10", + "@esbuild/android-arm": "0.19.10", + "@esbuild/android-arm64": "0.19.10", + "@esbuild/android-x64": "0.19.10", + "@esbuild/darwin-arm64": "0.19.10", + "@esbuild/darwin-x64": "0.19.10", + "@esbuild/freebsd-arm64": "0.19.10", + "@esbuild/freebsd-x64": "0.19.10", + "@esbuild/linux-arm": "0.19.10", + "@esbuild/linux-arm64": "0.19.10", + "@esbuild/linux-ia32": "0.19.10", + "@esbuild/linux-loong64": "0.19.10", + "@esbuild/linux-mips64el": "0.19.10", + "@esbuild/linux-ppc64": "0.19.10", + "@esbuild/linux-riscv64": "0.19.10", + "@esbuild/linux-s390x": "0.19.10", + "@esbuild/linux-x64": "0.19.10", + "@esbuild/netbsd-x64": "0.19.10", + "@esbuild/openbsd-x64": "0.19.10", + "@esbuild/sunos-x64": "0.19.10", + "@esbuild/win32-arm64": "0.19.10", + "@esbuild/win32-ia32": "0.19.10", + "@esbuild/win32-x64": "0.19.10" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", + "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.48.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "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/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/express": { + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "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" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express-jwt": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-8.4.1.tgz", + "integrity": "sha512-IZoZiDv2yZJAb3QrbaSATVtTCYT11OcqgFGoTN4iKVyN6NBkBkhtVIixww5fmakF0Upt5HfOxJuS6ZmJVeOtTQ==", + "dependencies": { + "@types/jsonwebtoken": "^9", + "express-unless": "^2.1.3", + "jsonwebtoken": "^9.0.0" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/express-unless": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-2.1.3.tgz", + "integrity": "sha512-wj4tLMyCVYuIIKHGt0FhCtIViBcwzWejX0EjNxveAa6dG+0XBCQhMbx+PnkLkFCxLC69qoFrxds4pIyL88inaQ==" + }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "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" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/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/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", + "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/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==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", + "dev": true, + "dependencies": { + "harmony-reflect": "^1.4.6" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", + "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock-extended": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/jest-mock-extended/-/jest-mock-extended-3.0.5.tgz", + "integrity": "sha512-/eHdaNPUAXe7f65gHH5urc8SbRVWjYxBqmCgax2uqOBJy8UUcCBMN1upj1eZ8y/i+IqpyEm4Kq0VKss/GCCTdw==", + "dev": true, + "dependencies": { + "ts-essentials": "^7.0.3" + }, + "peerDependencies": { + "jest": "^24.0.0 || ^25.0.0 || ^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0", + "typescript": "^3.0.0 || ^4.0.0 || ^5.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve/node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-eslint-parser": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz", + "integrity": "sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==", + "dev": true, + "dependencies": { + "acorn": "^8.5.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "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/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "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.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsonwebtoken/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", + "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-machine-id": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz", + "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-package-arg": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.1.tgz", + "integrity": "sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.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==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nx": { + "version": "17.2.6", + "resolved": "https://registry.npmjs.org/nx/-/nx-17.2.6.tgz", + "integrity": "sha512-lBHp0e0AMBwYwpT44a8b0j29szspmYUhY1okqNctz/3ifuonNFG9WGfbzRO4YKOrVkfNsuaomHVAE6gtqo55ng==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@nrwl/tao": "17.2.6", + "@yarnpkg/lockfile": "^1.1.0", + "@yarnpkg/parsers": "3.0.0-rc.46", + "@zkochan/js-yaml": "0.0.6", + "axios": "^1.5.1", + "chalk": "^4.1.0", + "cli-cursor": "3.1.0", + "cli-spinners": "2.6.1", + "cliui": "^8.0.1", + "dotenv": "~16.3.1", + "dotenv-expand": "~10.0.0", + "enquirer": "~2.3.6", + "figures": "3.2.0", + "flat": "^5.0.2", + "fs-extra": "^11.1.0", + "glob": "7.1.4", + "ignore": "^5.0.4", + "jest-diff": "^29.4.1", + "js-yaml": "4.1.0", + "jsonc-parser": "3.2.0", + "lines-and-columns": "~2.0.3", + "minimatch": "3.0.5", + "node-machine-id": "1.1.12", + "npm-run-path": "^4.0.1", + "open": "^8.4.0", + "semver": "7.5.3", + "string-width": "^4.2.3", + "strong-log-transformer": "^2.1.0", + "tar-stream": "~2.2.0", + "tmp": "~0.2.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0", + "yargs": "^17.6.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "nx": "bin/nx.js", + "nx-cloud": "bin/nx-cloud.js" + }, + "optionalDependencies": { + "@nx/nx-darwin-arm64": "17.2.6", + "@nx/nx-darwin-x64": "17.2.6", + "@nx/nx-freebsd-x64": "17.2.6", + "@nx/nx-linux-arm-gnueabihf": "17.2.6", + "@nx/nx-linux-arm64-gnu": "17.2.6", + "@nx/nx-linux-arm64-musl": "17.2.6", + "@nx/nx-linux-x64-gnu": "17.2.6", + "@nx/nx-linux-x64-musl": "17.2.6", + "@nx/nx-win32-arm64-msvc": "17.2.6", + "@nx/nx-win32-x64-msvc": "17.2.6" + }, + "peerDependencies": { + "@swc-node/register": "^1.6.7", + "@swc/core": "^1.3.85" + }, + "peerDependenciesMeta": { + "@swc-node/register": { + "optional": true + }, + "@swc/core": { + "optional": true + } + } + }, + "node_modules/nx/node_modules/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "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": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", + "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prisma": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.16.2.tgz", + "integrity": "sha512-SYCsBvDf0/7XSJyf2cHTLjLeTLVXYfqp7pG5eEVafFLeT0u/hLFz/9W196nDRGUOo1JfPatAEb+uEnTQImQC1g==", + "devOptional": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/engines": "4.16.2" + }, + "bin": { + "prisma": "build/index.js", + "prisma2": "build/index.js" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/proc-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", + "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.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/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "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/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, + "node_modules/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slugify": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", + "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strong-log-transformer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", + "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", + "dev": true, + "dependencies": { + "duplexer": "^0.1.1", + "minimist": "^1.2.0", + "through": "^2.3.4" + }, + "bin": { + "sl-log-transformer": "bin/sl-log-transformer.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "dev": true, + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-essentials": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", + "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", + "dev": true, + "peerDependencies": { + "typescript": ">=3.7.0" + } + }, + "node_modules/ts-jest": { + "version": "29.1.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", + "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tsconfig-paths/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/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/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/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", + "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", + "dev": true, + "dependencies": { + "builtins": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..2e3b26c --- /dev/null +++ b/package.json @@ -0,0 +1,58 @@ +{ + "name": "@api/source", + "version": "0.0.0", + "license": "MIT", + "scripts": { + "start": "nx serve", + "build": "nx build", + "test": "nx test" + }, + "private": true, + "prisma": { + "seed": "ts-node --transpile-only --compiler-options {\"module\":\"CommonJS\"} src/prisma/seed.ts", + "schema": "src/prisma/schema.prisma" + }, + "dependencies": { + "@ngneat/falso": "^7.1.1", + "@prisma/client": "^4.16.1", + "axios": "^1.0.0", + "bcryptjs": "^2.4.3", + "body-parser": "^1.20.2", + "cors": "^2.8.5", + "express": "~4.18.1", + "express-jwt": "^8.4.1", + "jsonwebtoken": "^9.0.2", + "slugify": "^1.6.0", + "tslib": "^2.3.0" + }, + "devDependencies": { + "@nx/esbuild": "17.2.6", + "@nx/eslint": "17.2.6", + "@nx/eslint-plugin": "17.2.6", + "@nx/jest": "17.2.6", + "@nx/js": "17.2.6", + "@nx/node": "17.2.6", + "@nx/workspace": "17.2.6", + "@swc-node/register": "~1.6.7", + "@swc/core": "~1.3.85", + "@types/bcryptjs": "^2.4.6", + "@types/cors": "^2.8.17", + "@types/express": "~4.17.13", + "@types/jest": "^29.4.0", + "@types/node": "18.16.9", + "@typescript-eslint/eslint-plugin": "^6.9.1", + "@typescript-eslint/parser": "^6.9.1", + "esbuild": "^0.19.2", + "eslint": "~8.48.0", + "eslint-config-prettier": "^9.0.0", + "jest": "^29.4.1", + "jest-environment-node": "^29.4.1", + "jest-mock-extended": "^3.0.5", + "nx": "17.2.6", + "prettier": "^2.6.2", + "prisma": "^4.16.1", + "ts-jest": "^29.1.0", + "ts-node": "10.9.1", + "typescript": "~5.2.2" + } +} diff --git a/project-logo.png b/project-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ef92a4be8c6cb93a3e9c78d72787e558a40cd149 GIT binary patch literal 53176 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

-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 T4&^Tm3_#%N>gTe~DWM4fEO&TD literal 0 HcmV?d00001 diff --git a/project.json b/project.json new file mode 100644 index 0000000..b76611b --- /dev/null +++ b/project.json @@ -0,0 +1,75 @@ +{ + "name": "api", + "$schema": "node_modules/nx/schemas/project-schema.json", + "sourceRoot": "src", + "projectType": "application", + "targets": { + "build": { + "executor": "@nx/esbuild:esbuild", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "production", + "options": { + "platform": "node", + "outputPath": "dist/api", + "format": ["cjs"], + "bundle": false, + "main": "src/main.ts", + "tsConfig": "tsconfig.app.json", + "assets": ["src/assets/**/**"], + "generatePackageJson": true, + "esbuildOptions": { + "sourcemap": true, + "outExtension": { + ".js": ".js" + } + } + }, + "configurations": { + "development": {}, + "production": { + "generateLockfile": true, + "esbuildOptions": { + "sourcemap": false, + "outExtension": { + ".js": ".js" + } + } + } + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "api:build" + }, + "configurations": { + "development": { + "buildTarget": "api:build:development" + }, + "production": { + "buildTarget": "api:build:production" + } + } + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["./src"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectName}"], + "options": { + "jestConfig": "jest.config.ts" + } + }, + "docker-build": { + "dependsOn": ["build"], + "command": "docker build -f Dockerfile . -t api" + } + }, + "tags": [] +} diff --git a/score.yaml b/score.yaml new file mode 100644 index 0000000..73fa955 --- /dev/null +++ b/score.yaml @@ -0,0 +1,58 @@ +apiVersion: score.dev/v1b1 +metadata: + name: reno-realworld-5 + labels: + app: reno-realworld-5 + +containers: + main: + image: . + variables: + # The Watcher's OTel work lands in overlays/otel/, which only ArgoCD reads. On the + # orchestrator path nothing consumes that overlay, so without these variables the + # renovated app emits no telemetry at all and never appears in Grafana. + OTEL_SERVICE_NAME: "reno-realworld-5" + OTEL_EXPORTER_OTLP_ENDPOINT: "http://otel-collector.monitoring.svc.cluster.local:4318" + OTEL_EXPORTER_OTLP_PROTOCOL: "http/protobuf" + OTEL_RESOURCE_ATTRIBUTES: "service.name=reno-realworld-5" + OTEL_METRICS_EXPORTER: "otlp" + OTEL_TRACES_EXPORTER: "otlp" + OTEL_LOGS_EXPORTER: "none" + DATABASE_URL: "postgresql://${resources.db.username}:${resources.db.password}@${resources.db.host}:${resources.db.port}/${resources.db.name}" + +service: + ports: + web: + port: 80 + targetPort: 8080 + +resources: + env: + type: environment + + # Gives the renovated workload a public HTTPS URL. Without this the deploy still goes + # green and the pod still runs -- there is simply no Ingress, no certificate and no + # hostname, so the demo's payoff (curl the renovated app) has nothing to hit. + # + # hostname is hardcoded to the apps domain deliberately: it is the only domain the apps + # cluster serves, and both the wildcard A record (*.apps.dev) and the cert-manager + # ClusterIssuer are scoped to exactly it. + # + # service_port is the Score `service.ports.web.port` below (80), NOT the container port. + # An Ingress naming a Service or port that does not exist fails at neither plan nor + # apply -- it surfaces only as nginx answering 503. + # + # CAVEAT: modernization-factory's generate_score_yaml rewrites BOTH `port` and + # `targetPort` to the detected application port whenever that port is not 8080. An app + # on 3000 therefore ends up with a Service on 3000 and this Ingress pointing at a port + # that no longer exists. Apps already listening on 8080 (Spring PetClinic among them) + # skip that patch entirely and are unaffected. + ingress: + type: workload-ingress + params: + name: reno-realworld-5 + hostname: reno-realworld-5.apps.dev.crucible.kyndemo.live + service_name: reno-realworld-5 + service_port: 80 + db: + type: postgres diff --git a/src/app/models/http-exception.model.ts b/src/app/models/http-exception.model.ts new file mode 100644 index 0000000..575f3aa --- /dev/null +++ b/src/app/models/http-exception.model.ts @@ -0,0 +1,12 @@ +class HttpException extends Error { + errorCode: number; + constructor( + errorCode: number, + public readonly message: string | any, + ) { + super(message); + this.errorCode = errorCode; + } +} + +export default HttpException; diff --git a/src/app/routes/article/article.controller.ts b/src/app/routes/article/article.controller.ts new file mode 100644 index 0000000..ff03702 --- /dev/null +++ b/src/app/routes/article/article.controller.ts @@ -0,0 +1,243 @@ +import { NextFunction, Request, Response, Router } from 'express'; +import auth from '../auth/auth'; +import { + addComment, + createArticle, + deleteArticle, + deleteComment, + favoriteArticle, + getArticle, + getArticles, + getCommentsByArticle, + getFeed, + unfavoriteArticle, + updateArticle, +} from './article.service'; + +const router = Router(); + +/** + * Get paginated articles + * @auth optional + * @route {GET} /articles + * @queryparam offset number of articles dismissed from the first one + * @queryparam limit number of articles returned + * @queryparam tag + * @queryparam author + * @queryparam favorited + * @returns articles: list of articles + */ +router.get('/articles', auth.optional, async (req: Request, res: Response, next: NextFunction) => { + try { + const result = await getArticles(req.query, req.auth?.user?.id); + res.json(result); + } catch (error) { + next(error); + } +}); + +/** + * Get paginated feed articles + * @auth required + * @route {GET} /articles/feed + * @returns articles list of articles + */ +router.get( + '/articles/feed', + auth.required, + async (req: Request, res: Response, next: NextFunction) => { + try { + const result = await getFeed( + Number(req.query.offset), + Number(req.query.limit), + req.auth?.user?.id, + ); + res.json(result); + } catch (error) { + next(error); + } + }, +); + +/** + * Create article + * @route {POST} /articles + * @bodyparam title + * @bodyparam description + * @bodyparam body + * @bodyparam tagList list of tags + * @returns article created article + */ +router.post('/articles', auth.required, async (req: Request, res: Response, next: NextFunction) => { + try { + const article = await createArticle(req.body.article, req.auth?.user?.id); + res.status(201).json({ article }); + } catch (error) { + next(error); + } +}); + +/** + * Get unique article + * @auth optional + * @route {GET} /article/:slug + * @param slug slug of the article (based on the title) + * @returns article + */ +router.get( + '/articles/:slug', + auth.optional, + async (req: Request, res: Response, next: NextFunction) => { + try { + const article = await getArticle(req.params.slug, req.auth?.user?.id); + res.json({ article }); + } catch (error) { + next(error); + } + }, +); + +/** + * Update article + * @auth required + * @route {PUT} /articles/:slug + * @param slug slug of the article (based on the title) + * @bodyparam title new title + * @bodyparam description new description + * @bodyparam body new content + * @returns article updated article + */ +router.put( + '/articles/:slug', + auth.required, + async (req: Request, res: Response, next: NextFunction) => { + try { + const article = await updateArticle(req.body.article, req.params.slug, req.auth?.user?.id); + res.json({ article }); + } catch (error) { + next(error); + } + }, +); + +/** + * Delete article + * @auth required + * @route {DELETE} /article/:id + * @param slug slug of the article + */ +router.delete( + '/articles/:slug', + auth.required, + async (req: Request, res: Response, next: NextFunction) => { + try { + await deleteArticle(req.params.slug, req.auth?.user!.id); + res.sendStatus(204); + } catch (error) { + next(error); + } + }, +); + +/** + * Get comments from an article + * @auth optional + * @route {GET} /articles/:slug/comments + * @param slug slug of the article (based on the title) + * @returns comments list of comments + */ +router.get( + '/articles/:slug/comments', + auth.optional, + async (req: Request, res: Response, next: NextFunction) => { + try { + const comments = await getCommentsByArticle(req.params.slug, req.auth?.user?.id); + res.json({ comments }); + } catch (error) { + next(error); + } + }, +); + +/** + * Add comment to article + * @auth required + * @route {POST} /articles/:slug/comments + * @param slug slug of the article (based on the title) + * @bodyparam body content of the comment + * @returns comment created comment + */ +router.post( + '/articles/:slug/comments', + auth.required, + async (req: Request, res: Response, next: NextFunction) => { + try { + const comment = await addComment(req.body.comment.body, req.params.slug, req.auth?.user?.id); + res.json({ comment }); + } catch (error) { + next(error); + } + }, +); + +/** + * Delete comment + * @auth required + * @route {DELETE} /articles/:slug/comments/:id + * @param slug slug of the article (based on the title) + * @param id id of the comment + */ +router.delete( + '/articles/:slug/comments/:id', + auth.required, + async (req: Request, res: Response, next: NextFunction) => { + try { + await deleteComment(Number(req.params.id), req.auth?.user?.id); + res.status(200).json({}); + } catch (error) { + next(error); + } + }, +); + +/** + * Favorite article + * @auth required + * @route {POST} /articles/:slug/favorite + * @param slug slug of the article (based on the title) + * @returns article favorited article + */ +router.post( + '/articles/:slug/favorite', + auth.required, + async (req: Request, res: Response, next: NextFunction) => { + try { + const article = await favoriteArticle(req.params.slug, req.auth?.user?.id); + res.json({ article }); + } catch (error) { + next(error); + } + }, +); + +/** + * Unfavorite article + * @auth required + * @route {DELETE} /articles/:slug/favorite + * @param slug slug of the article (based on the title) + * @returns article unfavorited article + */ +router.delete( + '/articles/:slug/favorite', + auth.required, + async (req: Request, res: Response, next: NextFunction) => { + try { + const article = await unfavoriteArticle(req.params.slug, req.auth?.user?.id); + res.json({ article }); + } catch (error) { + next(error); + } + }, +); + +export default router; diff --git a/src/app/routes/article/article.mapper.ts b/src/app/routes/article/article.mapper.ts new file mode 100644 index 0000000..8314864 --- /dev/null +++ b/src/app/routes/article/article.mapper.ts @@ -0,0 +1,16 @@ +import authorMapper from './author.mapper'; + +const articleMapper = (article: any, id?: number) => ({ + slug: article.slug, + title: article.title, + description: article.description, + body: article.body, + tagList: article.tagList.map((tag: any) => tag.name), + createdAt: article.createdAt, + updatedAt: article.updatedAt, + favorited: article.favoritedBy.some((item: any) => item.id === id), + favoritesCount: article.favoritedBy.length, + author: authorMapper(article.author, id), +}); + +export default articleMapper; diff --git a/src/app/routes/article/article.model.ts b/src/app/routes/article/article.model.ts new file mode 100644 index 0000000..2971d06 --- /dev/null +++ b/src/app/routes/article/article.model.ts @@ -0,0 +1,10 @@ +import { Comment } from './comment.model'; + +export interface Article { + id: number; + title: string; + slug: string; + description: string; + comments: Comment[]; + favorited: boolean; +} diff --git a/src/app/routes/article/article.service.ts b/src/app/routes/article/article.service.ts new file mode 100644 index 0000000..c8fdc0c --- /dev/null +++ b/src/app/routes/article/article.service.ts @@ -0,0 +1,652 @@ +import slugify from 'slugify'; +import prisma from '../../../prisma/prisma-client'; +import HttpException from '../../models/http-exception.model'; +import profileMapper from '../profile/profile.utils'; +import articleMapper from './article.mapper'; +import { Tag } from '../tag/tag.model'; + +const buildFindAllQuery = (query: any, id: number | undefined) => { + const queries: any = []; + const orAuthorQuery = []; + const andAuthorQuery = []; + + orAuthorQuery.push({ + demo: { + equals: true, + }, + }); + + if (id) { + orAuthorQuery.push({ + id: { + equals: id, + }, + }); + } + + if ('author' in query) { + andAuthorQuery.push({ + username: { + equals: query.author, + }, + }); + } + + const authorQuery = { + author: { + OR: orAuthorQuery, + AND: andAuthorQuery, + }, + }; + + queries.push(authorQuery); + + if ('tag' in query) { + queries.push({ + tagList: { + some: { + name: query.tag, + }, + }, + }); + } + + if ('favorited' in query) { + queries.push({ + favoritedBy: { + some: { + username: { + equals: query.favorited, + }, + }, + }, + }); + } + + return queries; +}; + +export const getArticles = async (query: any, id?: number) => { + const andQueries = buildFindAllQuery(query, id); + const articlesCount = await prisma.article.count({ + where: { + AND: andQueries, + }, + }); + + const articles = await prisma.article.findMany({ + where: { AND: andQueries }, + orderBy: { + createdAt: 'desc', + }, + skip: Number(query.offset) || 0, + take: Number(query.limit) || 10, + include: { + tagList: { + select: { + name: true, + }, + }, + author: { + select: { + username: true, + bio: true, + image: true, + followedBy: true, + }, + }, + favoritedBy: true, + _count: { + select: { + favoritedBy: true, + }, + }, + }, + }); + + return { + articles: articles.map((article: any) => articleMapper(article, id)), + articlesCount, + }; +}; + +export const getFeed = async (offset: number, limit: number, id: number) => { + const articlesCount = await prisma.article.count({ + where: { + author: { + followedBy: { some: { id: id } }, + }, + }, + }); + + const articles = await prisma.article.findMany({ + where: { + author: { + followedBy: { some: { id: id } }, + }, + }, + orderBy: { + createdAt: 'desc', + }, + skip: offset || 0, + take: limit || 10, + include: { + tagList: { + select: { + name: true, + }, + }, + author: { + select: { + username: true, + bio: true, + image: true, + followedBy: true, + }, + }, + favoritedBy: true, + _count: { + select: { + favoritedBy: true, + }, + }, + }, + }); + + return { + articles: articles.map((article: any) => articleMapper(article, id)), + articlesCount, + }; +}; + +export const createArticle = async (article: any, id: number) => { + const { title, description, body, tagList } = article; + const tags = Array.isArray(tagList) ? tagList : []; + + if (!title) { + throw new HttpException(422, { errors: { title: ["can't be blank"] } }); + } + + if (!description) { + throw new HttpException(422, { errors: { description: ["can't be blank"] } }); + } + + if (!body) { + throw new HttpException(422, { errors: { body: ["can't be blank"] } }); + } + + const slug = `${slugify(title)}-${id}`; + + const existingTitle = await prisma.article.findUnique({ + where: { + slug, + }, + select: { + slug: true, + }, + }); + + if (existingTitle) { + throw new HttpException(422, { errors: { title: ['must be unique'] } }); + } + + const { + authorId, + id: articleId, + ...createdArticle + } = await prisma.article.create({ + data: { + title, + description, + body, + slug, + tagList: { + connectOrCreate: tags.map((tag: string) => ({ + create: { name: tag }, + where: { name: tag }, + })), + }, + author: { + connect: { + id: id, + }, + }, + }, + include: { + tagList: { + select: { + name: true, + }, + }, + author: { + select: { + username: true, + bio: true, + image: true, + followedBy: true, + }, + }, + favoritedBy: true, + _count: { + select: { + favoritedBy: true, + }, + }, + }, + }); + + return articleMapper(createdArticle, id); +}; + +export const getArticle = async (slug: string, id?: number) => { + const article = await prisma.article.findUnique({ + where: { + slug, + }, + include: { + tagList: { + select: { + name: true, + }, + }, + author: { + select: { + username: true, + bio: true, + image: true, + followedBy: true, + }, + }, + favoritedBy: true, + _count: { + select: { + favoritedBy: true, + }, + }, + }, + }); + + if (!article) { + throw new HttpException(404, { errors: { article: ['not found'] } }); + } + + return articleMapper(article, id); +}; + +const disconnectArticlesTags = async (slug: string) => { + await prisma.article.update({ + where: { + slug, + }, + data: { + tagList: { + set: [], + }, + }, + }); +}; + +export const updateArticle = async (article: any, slug: string, id: number) => { + let newSlug = null; + + const existingArticle = await await prisma.article.findFirst({ + where: { + slug, + }, + select: { + author: { + select: { + id: true, + username: true, + }, + }, + }, + }); + + if (!existingArticle) { + throw new HttpException(404, {}); + } + + if (existingArticle.author.id !== id) { + throw new HttpException(403, { + message: 'You are not authorized to update this article', + }); + } + + if (article.title) { + newSlug = `${slugify(article.title)}-${id}`; + + if (newSlug !== slug) { + const existingTitle = await prisma.article.findFirst({ + where: { + slug: newSlug, + }, + select: { + slug: true, + }, + }); + + if (existingTitle) { + throw new HttpException(422, { errors: { title: ['must be unique'] } }); + } + } + } + + const tagList = + Array.isArray(article.tagList) && article.tagList?.length + ? article.tagList.map((tag: string) => ({ + create: { name: tag }, + where: { name: tag }, + })) + : []; + + await disconnectArticlesTags(slug); + + const updatedArticle = await prisma.article.update({ + where: { + slug, + }, + data: { + ...(article.title ? { title: article.title } : {}), + ...(article.body ? { body: article.body } : {}), + ...(article.description ? { description: article.description } : {}), + ...(newSlug ? { slug: newSlug } : {}), + updatedAt: new Date(), + tagList: { + connectOrCreate: tagList, + }, + }, + include: { + tagList: { + select: { + name: true, + }, + }, + author: { + select: { + username: true, + bio: true, + image: true, + followedBy: true, + }, + }, + favoritedBy: true, + _count: { + select: { + favoritedBy: true, + }, + }, + }, + }); + + return articleMapper(updatedArticle, id); +}; + +export const deleteArticle = async (slug: string, id: number) => { + const existingArticle = await await prisma.article.findFirst({ + where: { + slug, + }, + select: { + author: { + select: { + id: true, + username: true, + }, + }, + }, + }); + + if (!existingArticle) { + throw new HttpException(404, {}); + } + + if (existingArticle.author.id !== id) { + throw new HttpException(403, { + message: 'You are not authorized to delete this article', + }); + } + await prisma.article.delete({ + where: { + slug, + }, + }); +}; + +export const getCommentsByArticle = async (slug: string, id?: number) => { + const queries = []; + + queries.push({ + author: { + demo: true, + }, + }); + + if (id) { + queries.push({ + author: { + id, + }, + }); + } + + const comments = await prisma.article.findUnique({ + where: { + slug, + }, + include: { + comments: { + where: { + OR: queries, + }, + select: { + id: true, + createdAt: true, + updatedAt: true, + body: true, + author: { + select: { + username: true, + bio: true, + image: true, + followedBy: true, + }, + }, + }, + }, + }, + }); + + const result = comments?.comments.map((comment: any) => ({ + ...comment, + author: { + username: comment.author.username, + bio: comment.author.bio, + image: comment.author.image, + following: comment.author.followedBy.some((follow: any) => follow.id === id), + }, + })); + + return result; +}; + +export const addComment = async (body: string, slug: string, id: number) => { + if (!body) { + throw new HttpException(422, { errors: { body: ["can't be blank"] } }); + } + + const article = await prisma.article.findUnique({ + where: { + slug, + }, + select: { + id: true, + }, + }); + + const comment = await prisma.comment.create({ + data: { + body, + article: { + connect: { + id: article?.id, + }, + }, + author: { + connect: { + id: id, + }, + }, + }, + include: { + author: { + select: { + username: true, + bio: true, + image: true, + followedBy: true, + }, + }, + }, + }); + + return { + id: comment.id, + createdAt: comment.createdAt, + updatedAt: comment.updatedAt, + body: comment.body, + author: { + username: comment.author.username, + bio: comment.author.bio, + image: comment.author.image, + following: comment.author.followedBy.some((follow: any) => follow.id === id), + }, + }; +}; + +export const deleteComment = async (id: number, userId: number) => { + const comment = await prisma.comment.findFirst({ + where: { + id, + author: { + id: userId, + }, + }, + select: { + author: { + select: { + id: true, + username: true, + }, + }, + }, + }); + + if (!comment) { + throw new HttpException(404, {}); + } + + if (comment.author.id !== userId) { + throw new HttpException(403, { + message: 'You are not authorized to delete this comment', + }); + } + + await prisma.comment.delete({ + where: { + id, + }, + }); +}; + +export const favoriteArticle = async (slugPayload: string, id: number) => { + const { _count, ...article } = await prisma.article.update({ + where: { + slug: slugPayload, + }, + data: { + favoritedBy: { + connect: { + id: id, + }, + }, + }, + include: { + tagList: { + select: { + name: true, + }, + }, + author: { + select: { + username: true, + bio: true, + image: true, + followedBy: true, + }, + }, + favoritedBy: true, + _count: { + select: { + favoritedBy: true, + }, + }, + }, + }); + + const result = { + ...article, + author: profileMapper(article.author, id), + tagList: article?.tagList.map((tag: Tag) => tag.name), + favorited: article.favoritedBy.some((favorited: any) => favorited.id === id), + favoritesCount: _count?.favoritedBy, + }; + + return result; +}; + +export const unfavoriteArticle = async (slugPayload: string, id: number) => { + const { _count, ...article } = await prisma.article.update({ + where: { + slug: slugPayload, + }, + data: { + favoritedBy: { + disconnect: { + id: id, + }, + }, + }, + include: { + tagList: { + select: { + name: true, + }, + }, + author: { + select: { + username: true, + bio: true, + image: true, + followedBy: true, + }, + }, + favoritedBy: true, + _count: { + select: { + favoritedBy: true, + }, + }, + }, + }); + + const result = { + ...article, + author: profileMapper(article.author, id), + tagList: article?.tagList.map((tag: Tag) => tag.name), + favorited: article.favoritedBy.some((favorited: any) => favorited.id === id), + favoritesCount: _count?.favoritedBy, + }; + + return result; +}; diff --git a/src/app/routes/article/author.mapper.ts b/src/app/routes/article/author.mapper.ts new file mode 100644 index 0000000..48391a9 --- /dev/null +++ b/src/app/routes/article/author.mapper.ts @@ -0,0 +1,12 @@ +import { User } from '../auth/user.model'; + +const authorMapper = (author: any, id?: number) => ({ + username: author.username, + bio: author.bio, + image: author.image, + following: id + ? author?.followedBy.some((followingUser: Partial) => followingUser.id === id) + : false, +}); + +export default authorMapper; diff --git a/src/app/routes/article/comment.model.ts b/src/app/routes/article/comment.model.ts new file mode 100644 index 0000000..183c5ed --- /dev/null +++ b/src/app/routes/article/comment.model.ts @@ -0,0 +1,9 @@ +import { Article } from './article.model'; + +export interface Comment { + id: number; + createdAt: Date; + updatedAt: Date; + body: string; + article?: Article; +} diff --git a/src/app/routes/auth/auth.controller.ts b/src/app/routes/auth/auth.controller.ts new file mode 100644 index 0000000..c979b39 --- /dev/null +++ b/src/app/routes/auth/auth.controller.ts @@ -0,0 +1,70 @@ +import { NextFunction, Request, Response, Router } from 'express'; +import auth from './auth'; +import { createUser, getCurrentUser, login, updateUser } from './auth.service'; + +const router = Router(); + +/** + * Create an user + * @auth none + * @route {POST} /users + * @bodyparam user User + * @returns user User + */ +router.post('/users', async (req: Request, res: Response, next: NextFunction) => { + try { + const user = await createUser({ ...req.body.user, demo: false }); + res.status(201).json({ user }); + } catch (error) { + next(error); + } +}); + +/** + * Login + * @auth none + * @route {POST} /users/login + * @bodyparam user User + * @returns user User + */ +router.post('/users/login', async (req: Request, res: Response, next: NextFunction) => { + try { + const user = await login(req.body.user); + res.json({ user }); + } catch (error) { + next(error); + } +}); + +/** + * Get current user + * @auth required + * @route {GET} /user + * @returns user User + */ +router.get('/user', auth.required, async (req: Request, res: Response, next: NextFunction) => { + try { + const user = await getCurrentUser(req.auth?.user?.id); + res.json({ user }); + } catch (error) { + next(error); + } +}); + +/** + * Update user + * @auth required + * @route {PUT} /user + * @bodyparam user User + * @returns user User + */ +router.put('/user', auth.required, async (req: Request, res: Response, next: NextFunction) => { + try { + const user = await updateUser(req.body.user, req.auth?.user?.id); + res.json({ user }); + } catch (error) { + next(error); + } +}); + +export default router; diff --git a/src/app/routes/auth/auth.service.ts b/src/app/routes/auth/auth.service.ts new file mode 100644 index 0000000..d09a28d --- /dev/null +++ b/src/app/routes/auth/auth.service.ts @@ -0,0 +1,183 @@ +import * as bcrypt from 'bcryptjs'; +import { RegisterInput } from './register-input.model'; +import prisma from '../../../prisma/prisma-client'; +import HttpException from '../../models/http-exception.model'; +import { RegisteredUser } from './registered-user.model'; +import generateToken from './token.utils'; +import { User } from './user.model'; + +const checkUserUniqueness = async (email: string, username: string) => { + const existingUserByEmail = await prisma.user.findUnique({ + where: { + email, + }, + select: { + id: true, + }, + }); + + const existingUserByUsername = await prisma.user.findUnique({ + where: { + username, + }, + select: { + id: true, + }, + }); + + if (existingUserByEmail || existingUserByUsername) { + throw new HttpException(422, { + errors: { + ...(existingUserByEmail ? { email: ['has already been taken'] } : {}), + ...(existingUserByUsername ? { username: ['has already been taken'] } : {}), + }, + }); + } +}; + +export const createUser = async (input: RegisterInput): Promise => { + const email = input.email?.trim(); + const username = input.username?.trim(); + const password = input.password?.trim(); + const { image, bio, demo } = input; + + if (!email) { + throw new HttpException(422, { errors: { email: ["can't be blank"] } }); + } + + if (!username) { + throw new HttpException(422, { errors: { username: ["can't be blank"] } }); + } + + if (!password) { + throw new HttpException(422, { errors: { password: ["can't be blank"] } }); + } + + await checkUserUniqueness(email, username); + + const hashedPassword = await bcrypt.hash(password, 10); + + const user = await prisma.user.create({ + data: { + username, + email, + password: hashedPassword, + ...(image ? { image } : {}), + ...(bio ? { bio } : {}), + ...(demo ? { demo } : {}), + }, + select: { + id: true, + email: true, + username: true, + bio: true, + image: true, + }, + }); + + return { + ...user, + token: generateToken(user.id), + }; +}; + +export const login = async (userPayload: any) => { + const email = userPayload.email?.trim(); + const password = userPayload.password?.trim(); + + if (!email) { + throw new HttpException(422, { errors: { email: ["can't be blank"] } }); + } + + if (!password) { + throw new HttpException(422, { errors: { password: ["can't be blank"] } }); + } + + const user = await prisma.user.findUnique({ + where: { + email, + }, + select: { + id: true, + email: true, + username: true, + password: true, + bio: true, + image: true, + }, + }); + + if (user) { + const match = await bcrypt.compare(password, user.password); + + if (match) { + return { + email: user.email, + username: user.username, + bio: user.bio, + image: user.image, + token: generateToken(user.id), + }; + } + } + + throw new HttpException(403, { + errors: { + 'email or password': ['is invalid'], + }, + }); +}; + +export const getCurrentUser = async (id: number) => { + const user = (await prisma.user.findUnique({ + where: { + id, + }, + select: { + id: true, + email: true, + username: true, + bio: true, + image: true, + }, + })) as User; + + return { + ...user, + token: generateToken(user.id), + }; +}; + +export const updateUser = async (userPayload: any, id: number) => { + const { email, username, password, image, bio } = userPayload; + let hashedPassword; + + if (password) { + hashedPassword = await bcrypt.hash(password, 10); + } + + const user = await prisma.user.update({ + where: { + id: id, + }, + data: { + ...(email ? { email } : {}), + ...(username ? { username } : {}), + ...(password ? { password: hashedPassword } : {}), + ...(image ? { image } : {}), + ...(bio ? { bio } : {}), + }, + select: { + id: true, + email: true, + username: true, + bio: true, + image: true, + }, + }); + + return { + ...user, + token: generateToken(user.id), + }; +}; diff --git a/src/app/routes/auth/auth.ts b/src/app/routes/auth/auth.ts new file mode 100644 index 0000000..cec6b60 --- /dev/null +++ b/src/app/routes/auth/auth.ts @@ -0,0 +1,28 @@ +import { expressjwt as jwt } from 'express-jwt'; +import * as express from 'express'; + +const getTokenFromHeaders = (req: express.Request): string | null => { + if ( + (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Token') || + (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') + ) { + return req.headers.authorization.split(' ')[1]; + } + return null; +}; + +const auth = { + required: jwt({ + secret: process.env.JWT_SECRET || 'superSecret', + getToken: getTokenFromHeaders, + algorithms: ['HS256'], + }), + optional: jwt({ + secret: process.env.JWT_SECRET || 'superSecret', + credentialsRequired: false, + getToken: getTokenFromHeaders, + algorithms: ['HS256'], + }), +}; + +export default auth; diff --git a/src/app/routes/auth/register-input.model.ts b/src/app/routes/auth/register-input.model.ts new file mode 100644 index 0000000..c1a3179 --- /dev/null +++ b/src/app/routes/auth/register-input.model.ts @@ -0,0 +1,8 @@ +export interface RegisterInput { + email: string; + username: string; + password: string; + image?: string; + bio?: string; + demo?: boolean; +} diff --git a/src/app/routes/auth/registered-user.model.ts b/src/app/routes/auth/registered-user.model.ts new file mode 100644 index 0000000..0cb4836 --- /dev/null +++ b/src/app/routes/auth/registered-user.model.ts @@ -0,0 +1,8 @@ +export interface RegisteredUser { + id: number; + email: string; + username: string; + bio: string | null; + image: string | null; + token: string; +} diff --git a/src/app/routes/auth/token.utils.ts b/src/app/routes/auth/token.utils.ts new file mode 100644 index 0000000..9414075 --- /dev/null +++ b/src/app/routes/auth/token.utils.ts @@ -0,0 +1,8 @@ +import * as jwt from 'jsonwebtoken'; + +const generateToken = (id: number): string => + jwt.sign({ user: { id } }, process.env.JWT_SECRET || 'superSecret', { + expiresIn: '60d', + }); + +export default generateToken; diff --git a/src/app/routes/auth/user-request.d.ts b/src/app/routes/auth/user-request.d.ts new file mode 100644 index 0000000..325d4d5 --- /dev/null +++ b/src/app/routes/auth/user-request.d.ts @@ -0,0 +1,9 @@ +declare namespace Express { + export interface Request { + auth?: { + user?: { + id?: number; + }; + }; + } +} diff --git a/src/app/routes/auth/user.model.ts b/src/app/routes/auth/user.model.ts new file mode 100644 index 0000000..1e035ac --- /dev/null +++ b/src/app/routes/auth/user.model.ts @@ -0,0 +1,17 @@ +import { Article } from '../article/article.model'; +import { Comment } from '../article/comment.model'; + +export interface User { + id: number; + username: string; + email: string; + password: string; + bio: string | null; + image: any | null; + articles: Article[]; + favorites: Article[]; + followedBy: User[]; + following: User[]; + comments: Comment[]; + demo: boolean; +} diff --git a/src/app/routes/profile/profile.controller.ts b/src/app/routes/profile/profile.controller.ts new file mode 100644 index 0000000..152315a --- /dev/null +++ b/src/app/routes/profile/profile.controller.ts @@ -0,0 +1,67 @@ +import { NextFunction, Request, Response, Router } from 'express'; +import auth from '../auth/auth'; +import { followUser, getProfile, unfollowUser } from './profile.service'; + +const router = Router(); + +/** + * Get profile + * @auth optional + * @route {GET} /profiles/:username + * @param username string + * @returns profile + */ +router.get( + '/profiles/:username', + auth.optional, + async (req: Request, res: Response, next: NextFunction) => { + try { + const profile = await getProfile(req.params.username, req.auth?.user?.id); + res.json({ profile }); + } catch (error) { + next(error); + } + }, +); + +/** + * Follow user + * @auth required + * @route {POST} /profiles/:username/follow + * @param username string + * @returns profile + */ +router.post( + '/profiles/:username/follow', + auth.required, + async (req: Request, res: Response, next: NextFunction) => { + try { + const profile = await followUser(req.params?.username, req.auth?.user?.id); + res.json({ profile }); + } catch (error) { + next(error); + } + }, +); + +/** + * Unfollow user + * @auth required + * @route {DELETE} /profiles/:username/follow + * @param username string + * @returns profiles + */ +router.delete( + '/profiles/:username/follow', + auth.required, + async (req: Request, res: Response, next: NextFunction) => { + try { + const profile = await unfollowUser(req.params.username, req.auth?.user?.id); + res.json({ profile }); + } catch (error) { + next(error); + } + }, +); + +export default router; diff --git a/src/app/routes/profile/profile.model.ts b/src/app/routes/profile/profile.model.ts new file mode 100644 index 0000000..3ff457e --- /dev/null +++ b/src/app/routes/profile/profile.model.ts @@ -0,0 +1,6 @@ +export interface Profile { + username: string; + bio: string; + image: string; + following: boolean; +} diff --git a/src/app/routes/profile/profile.service.ts b/src/app/routes/profile/profile.service.ts new file mode 100644 index 0000000..7e5b7f5 --- /dev/null +++ b/src/app/routes/profile/profile.service.ts @@ -0,0 +1,60 @@ +import prisma from '../../../prisma/prisma-client'; +import profileMapper from './profile.utils'; +import HttpException from '../../models/http-exception.model'; + +export const getProfile = async (usernamePayload: string, id?: number) => { + const profile = await prisma.user.findUnique({ + where: { + username: usernamePayload, + }, + include: { + followedBy: true, + }, + }); + + if (!profile) { + throw new HttpException(404, {}); + } + + return profileMapper(profile, id); +}; + +export const followUser = async (usernamePayload: string, id: number) => { + const profile = await prisma.user.update({ + where: { + username: usernamePayload, + }, + data: { + followedBy: { + connect: { + id, + }, + }, + }, + include: { + followedBy: true, + }, + }); + + return profileMapper(profile, id); +}; + +export const unfollowUser = async (usernamePayload: string, id: number) => { + const profile = await prisma.user.update({ + where: { + username: usernamePayload, + }, + data: { + followedBy: { + disconnect: { + id, + }, + }, + }, + include: { + followedBy: true, + }, + }); + + return profileMapper(profile, id); +}; diff --git a/src/app/routes/profile/profile.utils.ts b/src/app/routes/profile/profile.utils.ts new file mode 100644 index 0000000..a835c8a --- /dev/null +++ b/src/app/routes/profile/profile.utils.ts @@ -0,0 +1,13 @@ +import { User } from '../auth/user.model'; +import { Profile } from './profile.model'; + +const profileMapper = (user: any, id: number | undefined): Profile => ({ + username: user.username, + bio: user.bio, + image: user.image, + following: id + ? user?.followedBy.some((followingUser: Partial) => followingUser.id === id) + : false, +}); + +export default profileMapper; diff --git a/src/app/routes/routes.ts b/src/app/routes/routes.ts new file mode 100644 index 0000000..28b1b60 --- /dev/null +++ b/src/app/routes/routes.ts @@ -0,0 +1,13 @@ +import { Router } from 'express'; +import tagsController from './tag/tag.controller'; +import articlesController from './article/article.controller'; +import authController from './auth/auth.controller'; +import profileController from './profile/profile.controller'; + +const api = Router() + .use(tagsController) + .use(articlesController) + .use(profileController) + .use(authController); + +export default Router().use('/api', api); diff --git a/src/app/routes/tag/tag.controller.ts b/src/app/routes/tag/tag.controller.ts new file mode 100644 index 0000000..9958b46 --- /dev/null +++ b/src/app/routes/tag/tag.controller.ts @@ -0,0 +1,22 @@ +import { NextFunction, Request, Response, Router } from 'express'; +import auth from '../auth/auth'; +import getTags from './tag.service'; + +const router = Router(); + +/** + * Get top 10 popular tags + * @auth optional + * @route {GET} /api/tags + * @returns tags list of tag names + */ +router.get('/tags', auth.optional, async (req: Request, res: Response, next: NextFunction) => { + try { + const tags = await getTags(req.auth?.user?.id); + res.json({ tags }); + } catch (error) { + next(error); + } +}); + +export default router; diff --git a/src/app/routes/tag/tag.model.ts b/src/app/routes/tag/tag.model.ts new file mode 100644 index 0000000..b6765b7 --- /dev/null +++ b/src/app/routes/tag/tag.model.ts @@ -0,0 +1,3 @@ +export interface Tag { + name: string; +} diff --git a/src/app/routes/tag/tag.service.ts b/src/app/routes/tag/tag.service.ts new file mode 100644 index 0000000..2a6262f --- /dev/null +++ b/src/app/routes/tag/tag.service.ts @@ -0,0 +1,40 @@ +import prisma from '../../../prisma/prisma-client'; +import { Tag } from './tag.model'; + +const getTags = async (id?: number): Promise => { + const queries = []; + queries.push({ demo: true }); + + if (id) { + queries.push({ + id: { + equals: id, + }, + }); + } + + const tags = await prisma.tag.findMany({ + where: { + articles: { + some: { + author: { + OR: queries, + }, + }, + }, + }, + select: { + name: true, + }, + orderBy: { + articles: { + _count: 'desc', + }, + }, + take: 10, + }); + + return tags.map((tag: Tag) => tag.name); +}; + +export default getTags; diff --git a/src/assets/images/demo-avatar.png b/src/assets/images/demo-avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..0a8cfd685bc795ae4a7acfdcc72838d4b82ceffb GIT binary patch literal 1711 zcmV;g22lBlP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 zVoOIv0RI600RN!9r;`8x00(qQO+^Rh0T~km5HvzP6aWAPvq?ljR7l5dRy&U+M;Sfm ztLpoj$9i_>Vc3;1>jVNzMnX=!0wgCuMC6#5fP|Dkz<)q82^kqO5+ooJgzUtuMPOK& zodxggYi8%(y^rp$`VK+e?t5pT?p1Yl(C2*L`RaS{!ykNTBx%O=GIS>pBvCd1WiLwr zB&{D%S>7Kc$z6)u=tjH7QNUTCJDvgxK$HYfk_0(rUiw-3AXAjDw^7@WWLr&T(?`J12Qvwi*R zEBg<>{rE?}nBTb{@{lHiM#hZ}{nZpkJEN16V^K8H0P9l%5G2tweU$5EGtbTZ&5z&s z!_QoPcJG(7@zb3en;?P_Tjm!|0l~~f_hN-Xpy1G&!$DxYTOFLf_vq^%J-YkbI6JgF zdi>V!bXHCN^EP85jD*DS!8boB5jHcUnHj(;R+HgalDl8LyqHaAAgfT71ce}n4K=#B zeL0;!-}~(B^-rIie4J-?`;#Bve)7FsE#d2cMfNUWJ9Xj7VZ3}bJ)gczN^RZ7qfk|q zAb^la?jMccee%;=FWz~&`!_>4y8PDB?Cn%7=tepr3K0dg!|jDOnOx>vw9AFBCe@gk zFhJ|9E_LX&G%ZXZtxfH8IW-GrHVlJRTTiNS z-84z(wVl0T$mtPvKh?AA~20L#| z?idZ^v&DHr% z!@c8&=coUC_Qm_(`0l70E}NCn09?#2S4|x(ESseScXt=MCb#WN+)#5vL1U8}mtL(F zSuS{!npgF_PK}Y0K(5k?-Pz>_ys_?}MFp+Jh>*b2R4IZ`@^o|OU=RmwZVx7})xNAk zb#ro1S(QDnL4jwp7mH?jw0~<52Z3RCxRX7XQm!6fit5}FOV>s;JDWav`s!J3_Ce_#_5^Ziz_D^o^9Mo-dFuC#hvj=smZ{PUp(avG=tgRV9K$Ij>Tk4U# zSibzn^9O@axfCoId3y10mzO-QQ!}o{ZAi;@b-9|IUObwvrn|%4ZEhNG0DSu8{dqe-+`IMJ+25!241l{!@~+VP%BhHq^y+mHd4Uj3P zK$k`-UY|_+``zPV{Vb6vdvui&zUDB{VO&>pQR^{)SMWO*HXOY-ew9N}D(d$fAiUrb zWNBa^i+-EI4t?pl7S(NZ$%_XYj!qM94%)I`Tccy=#nsfkKED4KJNBrTH(bH!0000b zbVXQnWMOn=I%9HWVRU5xGB7eSEif@HGBs2&IXW;iIx#jaFf}?bFytE)?EnA(C3Hnt zbYx+4WjbwdWNBu305UK#GA%GMEiyG!F*!OgGdeLgEig4YFff%ytWf{}002ovPDHLk FV1hUs8pQwr literal 0 HcmV?d00001 diff --git a/src/assets/images/smiley-cyrus.jpeg b/src/assets/images/smiley-cyrus.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..784a6b9f904a72c7f9712f84748c5f0023e6e9ff GIT binary patch literal 1343 zcma))dpOez7{`A<+gK)<%XnPoG|r>smM$zIwOppBQ#&2E>Xe8_%xx}}Tx#W36tc`U zXBu^Qa>+KficC~vXfaGIHk??9<$88>{^_stJm>R#|9GG0eV_09$M>rcD#ic}ysL*R z0B&LdS^$7z7&rnzl$5?}6X>R3a2N~+@QQM}ghtk&5)Yj2fv;YV=kOHKDAQDh;0Yd-;Ko|%DKTrmtFcmmNX>+?*0|23* z5)`Tof?NK*00E`Vx5`MB?YmvznkW6Ww4<))loL#JFt`iRq#L>QiXj00-Od>(#{6Hb zo0lX^|9jqAwp1^ zMPEwg1=(%HnU5fKq-KbF{GpYwiwLX%q&oJ3EplnNawK?WuFUV(lrAgE8+eO|!bKli z-J7?1(z~t~zg!VO%TEh_EvGb9_Kq^t-9Bb4gZ3!3BgL#<7HuCcEWkF&R;i!qFFVP$S>DpopmIi#jmIwq@QCCtinwU3!-z1^NrantdY9V_fi7yo{a zFsJSu{Aulpla0k4NAgNOMAiFbQ7VIdK3Rd?=wi0~FE;*6cAnU^AZ=AJ$4YUoFp&m1 z!~)^dhKX0IUORKM)7X)RKQpG4;AQ_-HA%~t?0rjcEqN$7$R(InDmfyujCQR+sg{ z-bw`t;S;*jC$3T!N6ReVW(0p7SaJ>O_cp^eTz$vs^I){y69NvKl}xa>`lDu+REwD!w5YMl7|EMp{fqi+4I_%7*EFcOn}PG4SmJYOJ>Cr!pwBo=;5&Toi`NKJIS zPI16yR0#GLx*+lVG#_Jm>(8SLrU^TZk(Zxe7uPsHAW=!?dQiP)u2SzXpSfdrZ4nmj zRsDhLNGvY1q?C>OJyX z&7On^33;j6%-&*v;h0bQM_A785qB|H2M1)Tg;M1& literal 0 HcmV?d00001 diff --git a/src/checkstyle/nohttp-checkstyle-suppressions.xml b/src/checkstyle/nohttp-checkstyle-suppressions.xml new file mode 100644 index 0000000..c8483c7 --- /dev/null +++ b/src/checkstyle/nohttp-checkstyle-suppressions.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..0c2752f --- /dev/null +++ b/src/main.ts @@ -0,0 +1,57 @@ +import express from 'express'; +import cors from 'cors'; +import * as bodyParser from 'body-parser'; +import routes from './app/routes/routes'; +import HttpException from './app/models/http-exception.model'; + +const app = express(); + +/** + * App Configuration + */ + +app.use(cors()); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: true })); +app.use(routes); + +// Serves images +app.use(express.static(__dirname + '/assets')); + +app.get('/', (req: express.Request, res: express.Response) => { + res.json({ status: 'API is running on /api' }); +}); + +/* eslint-disable */ +app.use( + ( + err: Error | HttpException, + req: express.Request, + res: express.Response, + next: express.NextFunction, + ) => { + // @ts-ignore + if (err && err.name === 'UnauthorizedError') { + return res.status(401).json({ + status: 'error', + message: 'missing authorization credentials', + }); + // @ts-ignore + } else if (err && err.errorCode) { + // @ts-ignore + res.status(err.errorCode).json(err.message); + } else if (err) { + res.status(500).json(err.message); + } + }, +); + +/** + * Server activation + */ + +const PORT = process.env.PORT || 3000; + +app.listen(PORT, () => { + console.info(`server up on port ${PORT}`); +}); diff --git a/src/prisma/migrations/20210924225358_initial/migration.sql b/src/prisma/migrations/20210924225358_initial/migration.sql new file mode 100644 index 0000000..1442f53 --- /dev/null +++ b/src/prisma/migrations/20210924225358_initial/migration.sql @@ -0,0 +1,114 @@ +-- CreateTable +CREATE TABLE "Article" ( + "id" SERIAL NOT NULL, + "slug" TEXT NOT NULL, + "title" TEXT NOT NULL, + "description" TEXT NOT NULL, + "body" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "authorId" INTEGER NOT NULL, + + PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "ArticleTags" ( + "articleId" INTEGER NOT NULL, + "tagId" INTEGER NOT NULL, + + PRIMARY KEY ("articleId","tagId") +); + +-- CreateTable +CREATE TABLE "Comment" ( + "id" SERIAL NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "body" TEXT NOT NULL, + "articleId" INTEGER NOT NULL, + "authorId" INTEGER NOT NULL, + + PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Tag" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + + PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "User" ( + "id" SERIAL NOT NULL, + "email" TEXT NOT NULL, + "username" TEXT NOT NULL, + "password" TEXT NOT NULL, + "image" TEXT DEFAULT E'https://realworld-temp-api.herokuapp.com/images/smiley-cyrus.jpeg', + "bio" TEXT, + "demo" BOOLEAN NOT NULL DEFAULT false, + + PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "_UserFavorites" ( + "A" INTEGER NOT NULL, + "B" INTEGER NOT NULL +); + +-- CreateTable +CREATE TABLE "_UserFollows" ( + "A" INTEGER NOT NULL, + "B" INTEGER NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX "Article.slug_unique" ON "Article"("slug"); + +-- CreateIndex +CREATE UNIQUE INDEX "User.email_unique" ON "User"("email"); + +-- CreateIndex +CREATE UNIQUE INDEX "User.username_unique" ON "User"("username"); + +-- CreateIndex +CREATE UNIQUE INDEX "_UserFavorites_AB_unique" ON "_UserFavorites"("A", "B"); + +-- CreateIndex +CREATE INDEX "_UserFavorites_B_index" ON "_UserFavorites"("B"); + +-- CreateIndex +CREATE UNIQUE INDEX "_UserFollows_AB_unique" ON "_UserFollows"("A", "B"); + +-- CreateIndex +CREATE INDEX "_UserFollows_B_index" ON "_UserFollows"("B"); + +-- AddForeignKey +ALTER TABLE "Article" ADD FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ArticleTags" ADD FOREIGN KEY ("articleId") REFERENCES "Article"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "ArticleTags" ADD FOREIGN KEY ("tagId") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Comment" ADD FOREIGN KEY ("articleId") REFERENCES "Article"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Comment" ADD FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_UserFavorites" ADD FOREIGN KEY ("A") REFERENCES "Article"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_UserFavorites" ADD FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_UserFollows" ADD FOREIGN KEY ("A") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_UserFollows" ADD FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/prisma/migrations/20211001143221_implicit_tags/migration.sql b/src/prisma/migrations/20211001143221_implicit_tags/migration.sql new file mode 100644 index 0000000..1bb691d --- /dev/null +++ b/src/prisma/migrations/20211001143221_implicit_tags/migration.sql @@ -0,0 +1,36 @@ +/* + Warnings: + + - You are about to drop the `ArticleTags` table. If the table is not empty, all the data it contains will be lost. + - A unique constraint covering the columns `[name]` on the table `Tag` will be added. If there are existing duplicate values, this will fail. + +*/ +-- DropForeignKey +ALTER TABLE "ArticleTags" DROP CONSTRAINT "ArticleTags_articleId_fkey"; + +-- DropForeignKey +ALTER TABLE "ArticleTags" DROP CONSTRAINT "ArticleTags_tagId_fkey"; + +-- DropTable +DROP TABLE "ArticleTags"; + +-- CreateTable +CREATE TABLE "_ArticleToTag" ( + "A" INTEGER NOT NULL, + "B" INTEGER NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX "_ArticleToTag_AB_unique" ON "_ArticleToTag"("A", "B"); + +-- CreateIndex +CREATE INDEX "_ArticleToTag_B_index" ON "_ArticleToTag"("B"); + +-- CreateIndex +CREATE UNIQUE INDEX "Tag.name_unique" ON "Tag"("name"); + +-- AddForeignKey +ALTER TABLE "_ArticleToTag" ADD FOREIGN KEY ("A") REFERENCES "Article"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_ArticleToTag" ADD FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/prisma/migrations/20211105153605_api_url/migration.sql b/src/prisma/migrations/20211105153605_api_url/migration.sql new file mode 100644 index 0000000..01134b2 --- /dev/null +++ b/src/prisma/migrations/20211105153605_api_url/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "User" ALTER COLUMN "image" SET DEFAULT E'https://api.realworld.io/images/smiley-cyrus.jpeg'; diff --git a/src/prisma/migrations/20211221184529_deprecated_preview/migration.sql b/src/prisma/migrations/20211221184529_deprecated_preview/migration.sql new file mode 100644 index 0000000..74957c4 --- /dev/null +++ b/src/prisma/migrations/20211221184529_deprecated_preview/migration.sql @@ -0,0 +1,11 @@ +-- RenameIndex +ALTER INDEX "Article.slug_unique" RENAME TO "Article_slug_key"; + +-- RenameIndex +ALTER INDEX "Tag.name_unique" RENAME TO "Tag_name_key"; + +-- RenameIndex +ALTER INDEX "User.email_unique" RENAME TO "User_email_key"; + +-- RenameIndex +ALTER INDEX "User.username_unique" RENAME TO "User_username_key"; diff --git a/src/prisma/migrations/migration_lock.toml b/src/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..fbffa92 --- /dev/null +++ b/src/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "postgresql" \ No newline at end of file diff --git a/src/prisma/prisma-client.ts b/src/prisma/prisma-client.ts new file mode 100644 index 0000000..bd0bf1f --- /dev/null +++ b/src/prisma/prisma-client.ts @@ -0,0 +1,23 @@ +import { PrismaClient } from '@prisma/client'; + +declare global { + namespace NodeJS { + interface Global {} + } +} + +// add prisma to the NodeJS global type +interface CustomNodeJsGlobal extends NodeJS.Global { + prisma: PrismaClient; +} + +// Prevent multiple instances of Prisma Client in development +declare const global: CustomNodeJsGlobal; + +const prisma = global.prisma || new PrismaClient(); + +if (process.env.NODE_ENV === 'development') { + global.prisma = prisma; +} + +export default prisma; diff --git a/src/prisma/schema.prisma b/src/prisma/schema.prisma new file mode 100644 index 0000000..3d767b7 --- /dev/null +++ b/src/prisma/schema.prisma @@ -0,0 +1,56 @@ +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" + previewFeatures = [] +} + +model Article { + id Int @id @default(autoincrement()) + slug String @unique + title String + description String + body String + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) + tagList Tag[] + author User @relation("UserArticles", fields: [authorId], onDelete: Cascade, references: [id]) + authorId Int + favoritedBy User[] @relation("UserFavorites") + comments Comment[] +} + +model Comment { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) + body String + article Article @relation(fields: [articleId], references: [id], onDelete: Cascade) + articleId Int + author User @relation(fields: [authorId], references: [id], onDelete: Cascade) + authorId Int +} + +model Tag { + id Int @id @default(autoincrement()) + name String @unique + articles Article[] +} + +model User { + id Int @id @default(autoincrement()) + email String @unique + username String @unique + password String + image String? @default("https://api.realworld.io/images/smiley-cyrus.jpeg") + bio String? + articles Article[] @relation("UserArticles") + favorites Article[] @relation("UserFavorites") + followedBy User[] @relation("UserFollows") + following User[] @relation("UserFollows") + comments Comment[] + demo Boolean @default(false) +} diff --git a/src/prisma/seed.ts b/src/prisma/seed.ts new file mode 100644 index 0000000..c625abd --- /dev/null +++ b/src/prisma/seed.ts @@ -0,0 +1,66 @@ +import { + randEmail, + randFullName, + randLines, + randParagraph, + randPassword, randPhrase, + randWord +} from '@ngneat/falso'; +import { PrismaClient } from '@prisma/client'; +import { RegisteredUser } from '../app/routes/auth/registered-user.model'; +import { createUser } from '../app/routes/auth/auth.service'; +import { addComment, createArticle } from '../app/routes/article/article.service'; + +const prisma = new PrismaClient(); + +export const generateUser = async (): Promise => + createUser({ + username: randFullName(), + email: randEmail(), + password: randPassword(), + image: 'https://api.realworld.io/images/demo-avatar.png', + demo: true, + }); + +export const generateArticle = async (id: number) => + createArticle( + { + title: randPhrase(), + description: randParagraph(), + body: randLines({ length: 10 }).join(' '), + tagList: randWord({ length: 4 }), + }, + id, + ); + +export const generateComment = async (id: number, slug: string) => + addComment(randParagraph(), slug, id); + +const main = async () => { + try { + const users = await Promise.all(Array.from({length: 12}, () => generateUser())); + users?.map(user => user); + + // eslint-disable-next-line no-restricted-syntax + for await (const user of users) { + const articles = await Promise.all(Array.from({length: 12}, () => generateArticle(user.id))); + + // eslint-disable-next-line no-restricted-syntax + for await (const article of articles) { + await Promise.all(users.map(userItem => generateComment(userItem.id, article.slug))); + } + } + } catch (e) { + console.error(e); + + } +}; + +main() + .then(async () => { + await prisma.$disconnect(); + }) + .catch(async () => { + await prisma.$disconnect(); + process.exit(1); + }); diff --git a/src/tests/prisma-mock.ts b/src/tests/prisma-mock.ts new file mode 100644 index 0000000..fb854f1 --- /dev/null +++ b/src/tests/prisma-mock.ts @@ -0,0 +1,17 @@ +import { mockDeep, mockReset, DeepMockProxy } from 'jest-mock-extended'; + +import prisma from '../prisma/prisma-client'; +import { PrismaClient } from '@prisma/client'; + +jest.mock('../prisma/prisma-client', () => ({ + __esModule: true, + default: mockDeep(), +})); + +const prismaMock = prisma as unknown as DeepMockProxy; + +beforeEach(() => { + mockReset(prismaMock); +}); + +export default prismaMock; diff --git a/src/tests/services/article.service.test.ts b/src/tests/services/article.service.test.ts new file mode 100644 index 0000000..4f39562 --- /dev/null +++ b/src/tests/services/article.service.test.ts @@ -0,0 +1,144 @@ +import prismaMock from '../prisma-mock'; +import { + deleteComment, + favoriteArticle, + unfavoriteArticle, +} from '../../app/routes/article/article.service'; + +describe('ArticleService', () => { + describe('deleteComment', () => { + test('should throw an error ', () => { + // Given + const id = 123; + const idUser = 456; + + // When + // @ts-ignore + prismaMock.comment.findFirst.mockResolvedValue(null); + + // Then + expect(deleteComment(id, idUser)).rejects.toThrowError(); + }); + }); + + describe('favoriteArticle', () => { + test('should return the favorited article', async () => { + // Given + const slug = 'How-to-train-your-dragon'; + const username = 'RealWorld'; + + const mockedUserResponse = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: '1234', + bio: null, + image: null, + token: '', + demo: false, + }; + + const mockedArticleResponse = { + id: 123, + slug: 'How-to-train-your-dragon', + title: 'How to train your dragon', + description: '', + body: '', + createdAt: new Date(), + updatedAt: new Date(), + authorId: 456, + tagList: [], + favoritedBy: [], + author: { + username: 'RealWorld', + bio: null, + image: null, + followedBy: [], + }, + }; + + // When + // @ts-ignore + prismaMock.user.findUnique.mockResolvedValue(mockedUserResponse); + // @ts-ignore + prismaMock.article.update.mockResolvedValue(mockedArticleResponse); + + // Then + await expect(favoriteArticle(slug, mockedUserResponse.id)).resolves.toHaveProperty( + 'favoritesCount', + ); + }); + + test('should throw an error if no user is found', async () => { + // Given + const id = 123; + const slug = 'how-to-train-your-dragon'; + const username = 'RealWorld'; + + // When + prismaMock.user.findUnique.mockResolvedValue(null); + + // Then + await expect(favoriteArticle(slug, id)).rejects.toThrowError(); + }); + }); + describe('unfavoriteArticle', () => { + test('should return the unfavorited article', async () => { + // Given + const slug = 'How-to-train-your-dragon'; + const username = 'RealWorld'; + + const mockedUserResponse = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: '1234', + bio: null, + image: null, + token: '', + demo: false, + }; + + const mockedArticleResponse = { + id: 123, + slug: 'How-to-train-your-dragon', + title: 'How to train your dragon', + description: '', + body: '', + createdAt: new Date(), + updatedAt: new Date(), + authorId: 456, + tagList: [], + favoritedBy: [], + author: { + username: 'RealWorld', + bio: null, + image: null, + followedBy: [], + }, + }; + + // When + prismaMock.user.findUnique.mockResolvedValue(mockedUserResponse); + prismaMock.article.update.mockResolvedValue(mockedArticleResponse); + + // Then + await expect(unfavoriteArticle(slug, mockedUserResponse.id)).resolves.toHaveProperty( + 'favoritesCount', + ); + }); + + test('should throw an error if no user is found', async () => { + // Given + const id = 123; + const slug = 'how-to-train-your-dragon'; + const username = 'RealWorld'; + + // When + prismaMock.user.findUnique.mockResolvedValue(null); + + // Then + await expect(unfavoriteArticle(slug, id)).rejects.toThrowError(); + }); + }); +}); diff --git a/src/tests/services/auth.service.test.ts b/src/tests/services/auth.service.test.ts new file mode 100644 index 0000000..35c4d64 --- /dev/null +++ b/src/tests/services/auth.service.test.ts @@ -0,0 +1,254 @@ +import * as bcrypt from 'bcryptjs'; +import { createUser, getCurrentUser, login, updateUser } from '../../app/routes/auth/auth.service'; +import prismaMock from '../prisma-mock'; + +describe('AuthService', () => { + describe('createUser', () => { + test('should create new user ', async () => { + // Given + const user = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: '1234', + }; + + const mockedResponse = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: '1234', + bio: null, + image: null, + token: '', + demo: false, + }; + + // When + // @ts-ignore + prismaMock.user.create.mockResolvedValue(mockedResponse); + + // Then + await expect(createUser(user)).resolves.toHaveProperty('token'); + }); + + test('should throw an error when creating new user with empty username ', async () => { + // Given + const user = { + id: 123, + username: ' ', + email: 'realworld@me', + password: '1234', + }; + + // Then + const error = String({ errors: { username: ["can't be blank"] } }); + await expect(createUser(user)).rejects.toThrow(error); + }); + + test('should throw an error when creating new user with empty email ', async () => { + // Given + const user = { + id: 123, + username: 'RealWorld', + email: ' ', + password: '1234', + }; + + // Then + const error = String({ errors: { email: ["can't be blank"] } }); + await expect(createUser(user)).rejects.toThrow(error); + }); + + test('should throw an error when creating new user with empty password ', async () => { + // Given + const user = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: ' ', + }; + + // Then + const error = String({ errors: { password: ["can't be blank"] } }); + await expect(createUser(user)).rejects.toThrow(error); + }); + + test('should throw an exception when creating a new user with already existing user on same username ', async () => { + // Given + const user = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: '1234', + }; + + const mockedExistingUser = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: '1234', + bio: null, + image: null, + token: '', + demo: false, + }; + + // When + prismaMock.user.findUnique.mockResolvedValue(mockedExistingUser); + + // Then + const error = { email: ['has already been taken'] }.toString(); + await expect(createUser(user)).rejects.toThrow(error); + }); + }); + + describe('login', () => { + test('should return a token', async () => { + // Given + const user = { + email: 'realworld@me', + password: '1234', + }; + + const hashedPassword = await bcrypt.hash(user.password, 10); + + const mockedResponse = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: hashedPassword, + bio: null, + image: null, + token: '', + demo: false, + }; + + // When + prismaMock.user.findUnique.mockResolvedValue(mockedResponse); + + // Then + await expect(login(user)).resolves.toHaveProperty('token'); + }); + + test('should throw an error when the email is empty', async () => { + // Given + const user = { + email: ' ', + password: '1234', + }; + + // Then + const error = String({ errors: { email: ["can't be blank"] } }); + await expect(login(user)).rejects.toThrow(error); + }); + + test('should throw an error when the password is empty', async () => { + // Given + const user = { + email: 'realworld@me', + password: ' ', + }; + + // Then + const error = String({ errors: { password: ["can't be blank"] } }); + await expect(login(user)).rejects.toThrow(error); + }); + + test('should throw an error when no user is found', async () => { + // Given + const user = { + email: 'realworld@me', + password: '1234', + }; + + // When + prismaMock.user.findUnique.mockResolvedValue(null); + + // Then + const error = String({ errors: { 'email or password': ['is invalid'] } }); + await expect(login(user)).rejects.toThrow(error); + }); + + test('should throw an error if the password is wrong', async () => { + // Given + const user = { + email: 'realworld@me', + password: '1234', + }; + + const hashedPassword = await bcrypt.hash('4321', 10); + + const mockedResponse = { + id: 123, + username: 'Gerome', + email: 'realworld@me', + password: hashedPassword, + bio: null, + image: null, + token: '', + demo: false, + }; + + // When + prismaMock.user.findUnique.mockResolvedValue(mockedResponse); + + // Then + const error = String({ errors: { 'email or password': ['is invalid'] } }); + await expect(login(user)).rejects.toThrow(error); + }); + }); + + describe('getCurrentUser', () => { + test('should return a token', async () => { + // Given + const id = 123; + + const mockedResponse = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: '1234', + bio: null, + image: null, + token: '', + demo: false, + }; + + // When + prismaMock.user.findUnique.mockResolvedValue(mockedResponse); + + // Then + await expect(getCurrentUser(id)).resolves.toHaveProperty('token'); + }); + }); + + describe('updateUser', () => { + test('should return a token', async () => { + // Given + const user = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: '1234', + }; + + const mockedResponse = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: '1234', + bio: null, + image: null, + token: '', + demo: false, + }; + + // When + prismaMock.user.update.mockResolvedValue(mockedResponse); + + // Then + await expect(updateUser(user, user.id)).resolves.toHaveProperty('token'); + }); + }); +}); diff --git a/src/tests/services/profile.service.test.ts b/src/tests/services/profile.service.test.ts new file mode 100644 index 0000000..ca86754 --- /dev/null +++ b/src/tests/services/profile.service.test.ts @@ -0,0 +1,145 @@ +import prismaMock from '../prisma-mock'; +import { followUser, getProfile, unfollowUser } from '../../app/routes/profile/profile.service'; + +describe('ProfileService', () => { + describe('getProfile', () => { + test('should return a following property', async () => { + // Given + const username = 'RealWorld'; + const id = 123; + + const mockedResponse = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: '1234', + bio: null, + image: null, + token: '', + demo: false, + followedBy: [], + }; + + // When + // @ts-ignore + prismaMock.user.findUnique.mockResolvedValue(mockedResponse); + + // Then + await expect(getProfile(username, id)).resolves.toHaveProperty('following'); + }); + + test('should throw an error if no user is found', async () => { + // Given + const username = 'RealWorld'; + const id = 123; + + // When + prismaMock.user.findUnique.mockResolvedValue(null); + + // Then + await expect(getProfile(username, id)).rejects.toThrowError(); + }); + }); + + describe('followUser', () => { + test('shoud return a following property', async () => { + // Given + const usernamePayload = 'AnotherUser'; + const id = 123; + + const mockedAuthUser = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: '1234', + bio: null, + image: null, + token: '', + demo: false, + followedBy: [], + }; + + const mockedResponse = { + id: 123, + username: 'AnotherUser', + email: 'another@me', + password: '1234', + bio: null, + image: null, + token: '', + demo: false, + followedBy: [], + }; + + // When + prismaMock.user.findUnique.mockResolvedValue(mockedAuthUser); + prismaMock.user.update.mockResolvedValue(mockedResponse); + + // Then + await expect(followUser(usernamePayload, id)).resolves.toHaveProperty('following'); + }); + + test('shoud throw an error if no user is found', async () => { + // Given + const usernamePayload = 'AnotherUser'; + const id = 123; + + // When + prismaMock.user.findUnique.mockResolvedValue(null); + + // Then + await expect(followUser(usernamePayload, id)).rejects.toThrowError(); + }); + }); + + describe('unfollowUser', () => { + test('shoud return a following property', async () => { + // Given + const usernamePayload = 'AnotherUser'; + const id = 123; + + const mockedAuthUser = { + id: 123, + username: 'RealWorld', + email: 'realworld@me', + password: '1234', + bio: null, + image: null, + token: '', + demo: false, + followedBy: [], + }; + + const mockedResponse = { + id: 123, + username: 'AnotherUser', + email: 'another@me', + password: '1234', + bio: null, + image: null, + token: '', + demo: false, + followedBy: [], + }; + + // When + prismaMock.user.findUnique.mockResolvedValue(mockedAuthUser); + prismaMock.user.update.mockResolvedValue(mockedResponse); + + // Then + await expect(unfollowUser(usernamePayload, id)).resolves.toHaveProperty('following'); + }); + + test('shoud throw an error if no user is found', async () => { + // Given + const usernamePayload = 'AnotherUser'; + const id = 123; + + // When + prismaMock.user.findUnique.mockResolvedValue(null); + + // Then + await expect(unfollowUser(usernamePayload, id)).rejects.toThrowError(); + }); + }); +}); diff --git a/src/tests/services/tag.service.test.ts b/src/tests/services/tag.service.test.ts new file mode 100644 index 0000000..97bc54d --- /dev/null +++ b/src/tests/services/tag.service.test.ts @@ -0,0 +1,6 @@ +describe('TagService', () => { + describe('getTags', () => { + // TODO : prismaMock.tag.groupBy.mockResolvedValue(mockedResponse) doesn't work + test.todo('should return a list of strings'); + }); +}); diff --git a/src/tests/utils/profile.utils.test.ts b/src/tests/utils/profile.utils.test.ts new file mode 100644 index 0000000..8c697bb --- /dev/null +++ b/src/tests/utils/profile.utils.test.ts @@ -0,0 +1,79 @@ +import profileMapper from '../../app/routes/profile/profile.utils'; + +describe('ProfileUtils', () => { + describe('profileMapper', () => { + test('should return a profile', () => { + // Given + const user = { + username: 'RealWorld', + bio: 'My happy life', + image: null, + followedBy: [], + }; + const id = 123; + + // When + const expected = { + username: 'RealWorld', + bio: 'My happy life', + image: null, + following: false, + }; + + // Then + expect(profileMapper(user, id)).toEqual(expected); + }); + + test('should return a profile followed by the user', () => { + // Given + const user = { + username: 'RealWorld', + bio: 'My happy life', + image: null, + followedBy: [ + { + id: 123, + }, + ], + }; + const id = 123; + + // When + const expected = { + username: 'RealWorld', + bio: 'My happy life', + image: null, + following: true, + }; + + // Then + expect(profileMapper(user, id)).toEqual(expected); + }); + + test('should return a profile not followed by the user', () => { + // Given + const user = { + username: 'RealWorld', + bio: 'My happy life', + image: null, + followedBy: [ + { + username: 'NotRealWorld', + }, + ], + }; + const id = 123; + + // When + const expected = { + username: 'RealWorld', + bio: 'My happy life', + image: null, + following: false, + }; + + // Then + expect(profileMapper(user, id)).toEqual(expected); + }); + }); +}); diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..86cdc2b --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist/out-tsc", + "module": "commonjs", + "types": ["node"] + }, + "exclude": [ + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts", + "src/tests/**/*", + ], + "include": [ + "src/**/*.ts" + ] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..9af0f89 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "rootDir": ".", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "importHelpers": true, + "target": "es2015", + "module": "esnext", + "lib": ["es2020", "dom"], + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "baseUrl": "./api", + "paths": {}, + "esModuleInterop": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "exclude": ["node_modules", "tmp"] +} diff --git a/tsconfig.spec.json b/tsconfig.spec.json new file mode 100644 index 0000000..2fa7e96 --- /dev/null +++ b/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +}