diff --git a/.devcontainer/.env b/.devcontainer/.env new file mode 100644 index 000000000..7398e4add --- /dev/null +++ b/.devcontainer/.env @@ -0,0 +1,12 @@ +# DOCS_NEXT +REACT_APP_VERSION=0.1-development +REACT_APP_DOCS_NEXT_HOST=docs-next.example.de +REACT_APP_DOCS_NEXT_ORG=akyriako + +# DOCUSAURUS +REACT_APP_DOCUSAURUS_BASE_URL=/ + +# UMAMI +UMAMI_WEBSITE_ID=00000000-0000-0000-0000-000000000000 +UMAMI_ANALYTICS_DOMAIN=localhost + diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e50f72c61..dbdc906d8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -21,7 +21,8 @@ "yzhang.markdown-all-in-one", "DavidAnson.vscode-markdownlint", "redhat.vscode-yaml", - "TakumiI.markdowntable" + "TakumiI.markdowntable", + "Perkovec.emoji" ] } }, @@ -37,7 +38,11 @@ // "forwardPorts": [], // Use 'postCreateCommand' to run commands after the container is created. - "postCreateCommand": "npm install" + "postCreateCommand": "npm install", + + "runArgs": [ + "--env-file", "${localWorkspaceFolder}/.devcontainer/.env" + ] // Configure tool-specific properties. // "customizations": {}, diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..cf1ef94c1 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +# Admins must approve changes to docs-next repository +/docs/ @opentelekomcloud/ac-content-reviewer diff --git a/.github/workflows/automerge.yaml b/.github/workflows/automerge.yaml new file mode 100644 index 000000000..3146e77b5 --- /dev/null +++ b/.github/workflows/automerge.yaml @@ -0,0 +1,42 @@ +name: automerge + +on: + pull_request: + types: + - labeled + - unlabeled + - synchronize + - opened + - edited + - ready_for_review + - reopened + - unlocked + pull_request_review: + types: + - submitted + check_suite: + types: + - completed + status: {} + +jobs: + automerge: + runs-on: ubuntu-latest + if: > + contains(github.event.pull_request.labels.*.name, 'gate') + environment: github + steps: + - name: Create GitHub App Token + id: app-token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_KEY }} + + - id: automerge + name: automerge + uses: pascalgn/automerge-action@v0.16.3 + env: + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} + MERGE_LABELS: "gate" + MERGE_METHOD: "squash" diff --git a/.github/workflows/build-publish-ephemeral.yaml b/.github/workflows/build-publish-ephemeral.yaml new file mode 100644 index 000000000..3bd31fdb2 --- /dev/null +++ b/.github/workflows/build-publish-ephemeral.yaml @@ -0,0 +1,47 @@ +name: Manage Pull Request Preview Instances + +on: + pull_request: + types: + - opened + - reopened + - synchronize + - closed + +concurrency: preview-${{ github.ref }} + +jobs: + deploy-ephemeral-preview: + name: Deploy or Remove Ephemeral Preview + environment: + name: pull-requests-preview + url: 'https://${{ github.repository_owner }}.github.io${{ vars.DOCUSAURUS_BASE_URL }}pr-${{ github.event.pull_request.number }}' + runs-on: ubuntu-20.04 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Get Commit Hash + id: commit_hash + uses: prompt/actions-commit-hash@v3 + + - name: Install and Build + if: github.event.action != 'closed' + env: + REACT_APP_VERSION: ${{ vars.APP_VERSION }}.PR${{ github.event.pull_request.number }}-${{ github.run_number }}-${{ steps.commit_hash.outputs.short }}-ephemeral + REACT_APP_DOCS_NEXT_HOST: ${{ vars.DOCS_NEXT_HOST }} + REACT_APP_DOCS_NEXT_ORG: ${{ vars.DOCS_NEXT_ORG }} + REACT_APP_DOCUSAURUS_BASE_URL: ${{ vars.DOCUSAURUS_BASE_URL }}pr-${{ github.event.pull_request.number }} + UMAMI_WEBSITE_ID: ${{ vars.UMAMI_WEBSITE_ID }} + UMAMI_ANALYTICS_DOMAIN: ${{ vars.UMAMI_ANALYTICS_DOMAIN }} + UMAMI_DATAHOST_URL: ${{ vars.UMAMI_DATAHOST_URL }} + UMAMI_DATA_DOMAIN: ${{ vars.UMAMI_DATA_DOMAINS }} + run: | + npm install + npm run build + + - name: Deploy preview + uses: rossjrw/pr-preview-action@v1 + with: + source-dir: ./build/ \ No newline at end of file diff --git a/.github/workflows/build-publish-production.yaml b/.github/workflows/build-publish-production.yaml new file mode 100644 index 000000000..cbf818cea --- /dev/null +++ b/.github/workflows/build-publish-production.yaml @@ -0,0 +1,135 @@ +name: Build and Deploy Production Docker Images + +on: + push: + tags: + - "v*.*.*" + workflow_dispatch: + +jobs: + build-stable: + name: Build Production Artifacts + environment: + name: stable + runs-on: ubuntu-latest + outputs: + image_version: ${{ env.IMAGE_SEMVER }} + commit_hash: ${{ steps.export_commit_hash.outputs.commit_hash }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup NodeJS + uses: actions/setup-node@v4 + with: + node-version: 'lts/*' + + - name: Install NodeJS Dependencies + run: npm install + + - name: Get Commit Hash + id: commit_hash + uses: prompt/actions-commit-hash@v3 + + - name: Build Version Tag + id: build_version_tag + run: echo "IMAGE_SEMVER=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV + + - name: Export Commit Hash + id: export_commit_hash + run: echo "commit_hash=${{ steps.commit_hash.outputs.short }}" >> $GITHUB_OUTPUT + + - name: Build Container Image Metadata + id: meta + uses: docker/metadata-action@v5 + with: + # list of Docker images to use as base name for tags + images: | + ${{ vars.REGISTRY }}/${{ vars.REGISTRY_ORG }}/${{ vars.IMG_NAME }} + # generate Docker tags based on the following events/attributes + tags: | + type=semver,pattern=v{{major}}.{{minor}}.{{patch}} + type=raw,value=latest + + + - name: Build App + env: + REACT_APP_VERSION: ${{ env.IMAGE_SEMVER }} + REACT_APP_DOCS_NEXT_HOST: ${{ vars.DOCS_NEXT_HOST }} + REACT_APP_DOCS_NEXT_ORG: ${{ vars.DOCS_NEXT_ORG }} + REACT_APP_DOCUSAURUS_BASE_URL: ${{ vars.DOCUSAURUS_BASE_URL }} + REACT_APP_TYPESENSE_PROTOCOL: ${{ vars.TYPESENSE_PROTOCOL }} + REACT_APP_TYPESENSE_HOST: ${{ vars.TYPESENSE_HOST }} + REACT_APP_TYPESENSE_PORT: ${{ vars.TYPESENSE_PORT }} + REACT_APP_TYPESENSE_API_KEY: ${{ secrets.TYPESENSE_SEARCH_KEY }} + UMAMI_WEBSITE_ID: ${{ vars.UMAMI_WEBSITE_ID }} + UMAMI_ANALYTICS_DOMAIN: ${{ vars.UMAMI_ANALYTICS_DOMAIN }} + UMAMI_DATAHOST_URL: ${{ vars.UMAMI_DATAHOST_URL }} + UMAMI_DATA_DOMAIN: ${{ vars.UMAMI_DATA_DOMAINS }} + run: npm run build + + - name: Login to Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ vars.REGISTRY }} + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Setup Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3.7.1 + + - name: Build and Push (Docker Image) + id: docker_build + uses: docker/build-push-action@v6.9.0 + with: + context: ./ + file: ./Dockerfile + provenance: false + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + annotations: ${{ steps.meta.outputs.annotations }} + + update-helm-charts: + needs: [build-stable] + environment: stable + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + # - name: Create GitHub App Token + # id: app-token + # uses: actions/create-github-app-token@v1 + # with: + # app-id: ${{ secrets.APP_ID }} + # private-key: ${{ secrets.APP_KEY }} + - name: Checkout Charts Repo + uses: actions/checkout@v4 + with: + repository: "${{ vars.DOCS_NEXT_CHARTS_ORG }}/${{ vars.DOCS_NEXT_CHARTS_REPO }}" + token: ${{ secrets.DOCS_NEXT_TOKEN }} + - name: Commit Changes + env: + image: ${{ vars.REGISTRY }}/${{ vars.REGISTRY_ORG }}/${{ vars.IMG_NAME }} + tag: ${{ needs.build-stable.outputs.image_version }} + run: | + git config --global user.name 'otcbot' + git config --global user.email 'otc_ecosystem_squad@t-systems.com' + sed -i 's|^version: .*|version: 0.3.${{github.run_number}}|' ./charts/docusaurus/Chart.yaml + sed -i 's|^appVersion: .*|appVersion: ${{ env.tag }}|' ./charts/docusaurus/Chart.yaml + sed -i 's|^tag: .*|tag: ${{ env.tag }}|' ./charts/docusaurus/values-prod.yaml + sed -i 's|^image: .*|image: ${{ env.image }}|' ./charts/docusaurus/values-prod.yaml + git commit -am "Automatic commit from GitHub Actions triggered by action ${{github.run_number}}" + - name: Create Pull Request + uses: peter-evans/create-pull-request@v7 + env: + remote_pr_branch: 'release/production-${{ needs.build-stable.outputs.image_version }}' + with: + title: ${{ env.remote_pr_branch }} + token: ${{ secrets.DOCS_NEXT_TOKEN }} + branch: ${{ env.remote_pr_branch }} + \ No newline at end of file diff --git a/.github/workflows/build-publish-staging.yaml b/.github/workflows/build-publish-staging.yaml new file mode 100644 index 000000000..6402a4781 --- /dev/null +++ b/.github/workflows/build-publish-staging.yaml @@ -0,0 +1,133 @@ +name: Build and Deploy Staging Docker Images + +on: + push: + branches: + - main + paths-ignore: + - '**/README.md' + - '**/CONTRIBUTING.md' + - '**/CONFIGURATION.md' + - '**/.devcontainer/**' + - "**/.github/workflows/**" + workflow_dispatch: + +jobs: + build-preview: + name: Build Staging Artifacts + environment: + name: preview + runs-on: ubuntu-latest + outputs: + image_version: ${{ steps.build_image_tag.outputs.image_version }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup NodeJS + uses: actions/setup-node@v4 + with: + node-version: 'lts/*' + + - name: Install NodeJS Dependencies + run: npm install + + - name: Get Commit Hash + id: commit_hash + uses: prompt/actions-commit-hash@v3 + + - name: Get Current Date + id: date + run: echo "today=$(date +'%Y%m%d')" >> $GITHUB_OUTPUT + + - name: Build Image Tag + id: build_image_tag + run: echo "image_version=${{ steps.date.outputs.today }}.${{github.run_number}}.0-${{ steps.commit_hash.outputs.short }}" >> $GITHUB_OUTPUT + + - name: Build Container Image Metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ vars.REGISTRY }}/${{ vars.REGISTRY_ORG }}/${{ vars.IMG_NAME }} + tags: | + type=raw,value=${{ steps.build_image_tag.outputs.image_version }} + + - name: Build App + env: + REACT_APP_VERSION: ${{ steps.build_image_tag.outputs.image_version }} + REACT_APP_DOCS_NEXT_HOST: ${{ vars.DOCS_NEXT_HOST }} + REACT_APP_DOCS_NEXT_ORG: ${{ vars.DOCS_NEXT_ORG }} + REACT_APP_DOCUSAURUS_BASE_URL: ${{ vars.DOCUSAURUS_BASE_URL }} + REACT_APP_TYPESENSE_PROTOCOL: ${{ vars.TYPESENSE_PROTOCOL }} + REACT_APP_TYPESENSE_HOST: ${{ vars.TYPESENSE_HOST }} + REACT_APP_TYPESENSE_PORT: ${{ vars.TYPESENSE_PORT }} + REACT_APP_TYPESENSE_API_KEY: ${{ secrets.TYPESENSE_SEARCH_KEY }} + UMAMI_WEBSITE_ID: ${{ vars.UMAMI_WEBSITE_ID }} + UMAMI_ANALYTICS_DOMAIN: ${{ vars.UMAMI_ANALYTICS_DOMAIN }} + UMAMI_DATAHOST_URL: ${{ vars.UMAMI_DATAHOST_URL }} + UMAMI_DATA_DOMAIN: ${{ vars.UMAMI_DATA_DOMAINS }} + run: npm run build + + - name: Login to Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ vars.REGISTRY }} + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Setup Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3.7.1 + + - name: Build and Push (Docker Image) + id: docker_build + uses: docker/build-push-action@v6.9.0 + with: + context: ./ + file: ./Dockerfile + provenance: false + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + annotations: ${{ steps.meta.outputs.annotations }} + + update-helm-charts: + needs: [build-preview] + environment: preview + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + # - name: Create GitHub App Token + # id: app-token + # uses: actions/create-github-app-token@v1 + # with: + # app-id: ${{ secrets.APP_ID }} + # private-key: ${{ secrets.APP_KEY }} + - name: Checkout Charts Repo + uses: actions/checkout@v4 + with: + repository: "${{ vars.DOCS_NEXT_CHARTS_ORG }}/${{ vars.DOCS_NEXT_CHARTS_REPO }}" + token: ${{ secrets.DOCS_NEXT_TOKEN }} + - name: Commit Changes + env: + image: ${{ vars.REGISTRY }}/${{ vars.REGISTRY_ORG }}/${{ vars.IMG_NAME }} + tag: ${{ needs.build-preview.outputs.image_version }} + run: | + git config --global user.name 'otcbot' + git config --global user.email 'otc_ecosystem_squad@t-systems.com' + sed -i 's|^tag: .*|tag: ${{ env.tag }}|' ./charts/docusaurus/values-stg.yaml + sed -i 's|^image: .*|image: ${{ env.image }}|' ./charts/docusaurus/values-stg.yaml + git commit -am "Automatic commit from GitHub Actions triggered by action ${{github.run_number}}" + - name: Create Pull Request + uses: peter-evans/create-pull-request@v7 + env: + remote_pr_branch: 'release/staging-${{ needs.build-preview.outputs.image_version }}' + with: + title: ${{ env.remote_pr_branch }} + token: ${{ secrets.DOCS_NEXT_TOKEN }} + branch: ${{ env.remote_pr_branch }} diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml new file mode 100644 index 000000000..cc096e543 --- /dev/null +++ b/.github/workflows/check.yaml @@ -0,0 +1,23 @@ +name: check + +on: + pull_request: + branches: [ '*' ] + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: 'lts/*' + cache: 'yarn' + + - name: Install dependencies + run: yarn install + + - name: Run typecheck + run: yarn lint diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml deleted file mode 100644 index 25a9f3c0e..000000000 --- a/.github/workflows/release.yaml +++ /dev/null @@ -1,114 +0,0 @@ -on: - push: - branches: - - main - paths-ignore: - - '**/README.md' - - '**/CONTRIBUTING.md' - - '**/.devcontainer/devcontainer.json' - -jobs: - build: - environment: preview - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup NodeJS - uses: actions/setup-node@v2 - with: - node-version: 18 # Use Node.js 18 here - - - name: Install Dependencies - run: npm install - - - name: Build App - env: - REACT_APP_TYPESENSE_PROTOCOL: ${{ vars.TYPESENSE_PROTOCOL }} - REACT_APP_TYPESENSE_HOST: ${{ vars.TYPESENSE_HOST }} - REACT_APP_TYPESENSE_PORT: ${{ vars.TYPESENSE_PORT }} - REACT_APP_TYPESENSE_API_KEY: ${{ secrets.TYPESENSE_SEARCH_KEY }} - run: npm run build - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Setup Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v1 - - - name: Get Commit Hash - id: commit_hash - uses: prompt/actions-commit-hash@v3 - - uses: docker/setup-buildx-action@v3 - - name: Build and Push (Docker Image) - id: docker_build - uses: docker/build-push-action@v2 - with: - context: ./ - file: ./Dockerfile - push: true - tags: | - ${{ secrets.DOCKERHUB_USERNAME }}/${{ vars.IMG_NAME }}:latest - ${{ secrets.DOCKERHUB_USERNAME }}/${{ vars.IMG_NAME }}:${{ vars.APP_VERSION }}.${{github.run_number}}-${{ steps.commit_hash.outputs.short }} - - # - name: Image Digest - # run: echo ${{ steps.docker_build.outputs.digest }} - - update-helm-charts: - needs: [build] - environment: preview - runs-on: ubuntu-latest - - steps: - - name: Get Commit Hash - id: commit_hash - uses: prompt/actions-commit-hash@v3 - - - name: Show Commit Hash Digest - run: echo ${{ steps.commit_hash.outputs.short }} - - - name: Configure Git User as GitHub Actions Bot - run: | - git config --global user.name 'github-actions[bot]' - git config --global user.email 'github-actions[bot]@users.noreply.github.com' - - - name: Checkout - uses: actions/checkout@v4 - with: - repository: "${{ vars.DOCS_NEXT_CHARTS_ORG }}/${{ vars.DOCS_NEXT_CHARTS_REPO }}" - token: ${{ secrets.DOCS_NEXT_CHARTS_TOKEN }} - - - name: Show Contents - run: ls -latr - - - name: Update Charts and Commit Changes - id: update_charts - env: - image: ${{ secrets.DOCKERHUB_USERNAME }}\/${{ vars.IMG_NAME }} - run: | - # docusaurus - sed -i 's/^version: .*/version: ${{ vars.APP_VERSION }}.${{github.run_number}}/' ./charts/docusaurus/Chart.yaml - sed -i 's/^appVersion: .*/appVersion: ${{ vars.APP_VERSION }}.${{github.run_number}}-${{ steps.commit_hash.outputs.short }}/' ./charts/docusaurus/Chart.yaml - sed -i 's/^tag: .*/tag: ${{ vars.APP_VERSION }}.${{github.run_number}}-${{ steps.commit_hash.outputs.short }}/' ./charts/docusaurus/values.yaml - sed -i 's/^image: .*/image: ${{ env.image }}/' ./charts/docusaurus/values.yaml - cat ./charts/docusaurus/Chart.yaml - echo "" - echo "---" - echo "" - cat ./charts/docusaurus/values.yaml - # commit and push - git commit -am "Automatic commit from GitHub Actions triggered by action #${{github.run_number}}" - git remote set-url origin https://${{ secrets.DOCS_NEXT_CHARTS_TOKEN }}@github.com/${{ vars.DOCS_NEXT_CHARTS_ORG }}/${{ vars.DOCS_NEXT_CHARTS_REPO }}.git - git push origin main - - - - - - \ No newline at end of file diff --git a/CONFIGURATION.md b/CONFIGURATION.md new file mode 100644 index 000000000..9c4cd5436 --- /dev/null +++ b/CONFIGURATION.md @@ -0,0 +1,82 @@ +# GitHub Environments Configuration + +You need to configure 4 GitHub environments: + +- **preview**: for staging +- **stable**: for production +- **pull-requests-preview**: for ephemeral deployments for PR reviews +- **gh-pages**: for GitHub pages publishing and deployment + +## GitHub Pages + +Create a new branch, `gh-pages`, and go to *Settings* -> *Pages* of the repository: + +![alt text](static/img/configure_gh_pages.png) + +Choose **Deploy from a branch** as *Source*, and as *Branch* **gh-pages/root**. + +> [!IMPORTANT] +> Do this for **both** repositories, **docs-next** and **docs-next-chart**! + +## Helm Charts Repository Token Configuration (docs-next-charts) + +Go to *Account* -> *Settings* -> *Developer Settings* -> *Personal Access Tokens* -> *Fine-grained tokens* and click *Generate new token*. Create a new token with the name **docs-next-charts-token** and give to it access to the repository: **docs-next-charts**. Assign the following permissions to the token: + +- **Read access to metadata** +- **Read and Write access to actions, code, commit statuses, and workflows** + +![alt text](static/img/cross_repo_commit_token.png) + +> [!IMPORTANT] +>Save the value of the token, you are going to set it afterwards as the value of the secret `DOCS_NEXT_CHARTS_TOKEN`. + +## Code Repository Configuration (docs-next) + +### Workflow Permissions + +Go to *Settings* -> *Actions* -> *General* of the repository and choose **Read and write permissions** as *Workflow Permissions*. Click *Save* to persist changes: + +![alt text](static/img/workflow_permissions.png) + +### Variables + +| Variable | pull-requests-preview | preview | stable | Default/Description | +| :--------------------- | :----------------------------: | :----------------: | :----------------: | :------------------------- | +| APP_VERSION | 1️⃣ | 1️⃣ | 1️⃣ | `0.1` | +| IMG_NAME | ❌ | `docs-next` | `docs-next` | Docker Image Name | +| DOCS_NEXT_ORG | 1️⃣ | 1️⃣ | 1️⃣ | GitHub Org Name | +| DOCS_NEXT_REPO | ❌ | `docs-next` | `docs-next` | GitHub Repo Name | +| DOCS_NEXT_HOST | `$DOCS_NEXT_ORG`.github.io | ✅ | ✅ | Domain name | +| DOCS_NEXT_CHARTS_ORG | ❌ | 1️⃣ | 1️⃣ | GitHub Org Name | +| DOCS_NEXT_CHARTS_REPO | ❌ | `docs-next-charts` | `docs-next-charts` | GitHub Repo Name | +| DOCUSAURUS_BASE_URL | `/docs-next/pr-preview/` | ❌ | ❌ | Docusaurus `baseUrl` | +| TYPESENSE_HOST | ❌ | ✅ | ✅ | Domain name | +| TYPESENSE_PROTOCOL | ❌ | ✅ | ✅ | `https` | +| TYPESENSE_PORT | ❌ | ✅ | ✅ | `443` | +| UMAMI_ANALYTICS_DOMAIN | `analytics.example.de` | ✅ | ✅ | Domain name | +| UMAMI_DATAHOST_URL | `https://analytics.example.de` | ✅ | ✅ | Umami URL | +| UMAMI_DATA_DOMAINS | ✅ | `$DOCS_NEXT_HOST` | `$DOCS_NEXT_HOST` | Umami Allowed CORS Domains | +| UMAMI_WEBSITE_ID | `00000` | ✅ | ✅ | Umami WebSite ID | + +> [!NOTE] +> ✅ : Yes, +> 1️⃣ : Yes but horizontally identical value, +> ❌ : No, +> +> Otherwise use the default value or the one dictated per environment. + +### Secrets + +| Secret | pull-requests-preview | preview | stable | Default/Description | +| :--------------------- | :-------------------: | :-----: | :----: | :--------------------------------- | +| DOCKERHUB_USERNAME | ❌ | ✅ | ✅ | Container Registry User | +| DOCKERHUB_TOKEN | ❌ | ✅ | ✅ | Container Registry Access Token | +| DOCS_NEXT_CHARTS_TOKEN | ❌ | 1️⃣ | 1️⃣ | DOCS_NEXT_CHARTS_REPO Access Token | +| TYPESENSE_API_KEY | ❌ | ✅ | ✅ | TypeSense Admin API Key | +| TYPESENSE_SEARCH_KEY | ❌ | ✅ | ✅ | TypeSense Search API Key | + +> [!NOTE] +> ✅ : Yes, +> 1️⃣ : Yes but horizontally identical value, +> ❌ : No + diff --git a/README.md b/README.md index 771aa29ac..fb17d3614 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ npm run serve ## Deployment You can deploy docs-next in a various infrastructure (as every React/TS application). You can just spin a docker container, or deploy it directly on -an ECS Server or on a CCE Kubernetes Cluster (recommended). Check the architecture and provided Helm Charts for the latter at [Open Telekom Cloud Architecture Center Helm Charts](https://github.com/akyriako/docs-next-charts) repository. +an ECS Server or on a CCE Kubernetes Cluster (recommended). Check the architecture and provided Helm Charts for the latter at [Open Telekom Cloud Architecture Center Helm Charts](https://github.com/opentelekomcloud-infra/docs-next-charts) repository. ### Manual @@ -136,7 +136,7 @@ The repository is already employed with a GitHub Release Workflow that will do t 1. Builds the application for production (`npm run build`) 2. Builds and tags a container image and push the image to a predefined docker hub organization -3. Updates the Helm Charts with new versions and image tags in [Open Telekom Cloud Architecture Center Helm Charts](https://github.com/akyriako/docs-next-charts) +3. Updates the Helm Charts with new versions and image tags in [Open Telekom Cloud Architecture Center Helm Charts](https://github.com/opentelekomcloud-infra/docs-next-charts) ArgoCD (deployed on the same CCE Cluster) will pick up the changes, within its `timeout.reconciliation` value (default is *180s*), and provision the changes without any human intervention. diff --git a/blog/2019-05-28-first-blog-post.md b/blog/2019-05-28-first-blog-post.md deleted file mode 100644 index 02f3f81bd..000000000 --- a/blog/2019-05-28-first-blog-post.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -slug: first-blog-post -title: First Blog Post -authors: - name: Gao Wei - title: Docusaurus Core Team - url: https://github.com/wgao19 - image_url: https://github.com/wgao19.png -tags: [hola, docusaurus] ---- - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/blog/2019-05-29-long-blog-post.md b/blog/2019-05-29-long-blog-post.md deleted file mode 100644 index 26ffb1b1f..000000000 --- a/blog/2019-05-29-long-blog-post.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -slug: long-blog-post -title: Long Blog Post -authors: endi -tags: [hello, docusaurus] ---- - -This is the summary of a very long blog post, - -Use a `` comment to limit blog post size in the list view. - - - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet - -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet diff --git a/blog/2021-08-01-mdx-blog-post.mdx b/blog/2021-08-01-mdx-blog-post.mdx deleted file mode 100644 index c04ebe323..000000000 --- a/blog/2021-08-01-mdx-blog-post.mdx +++ /dev/null @@ -1,20 +0,0 @@ ---- -slug: mdx-blog-post -title: MDX Blog Post -authors: [slorber] -tags: [docusaurus] ---- - -Blog posts support [Docusaurus Markdown features](https://docusaurus.io/docs/markdown-features), such as [MDX](https://mdxjs.com/). - -:::tip - -Use the power of React to create interactive blog posts. - -```js - -``` - - - -::: diff --git a/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg b/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg deleted file mode 100644 index 11bda0928..000000000 Binary files a/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg and /dev/null differ diff --git a/blog/2021-08-26-welcome/index.md b/blog/2021-08-26-welcome/index.md deleted file mode 100644 index 9455168f1..000000000 --- a/blog/2021-08-26-welcome/index.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -slug: welcome -title: Welcome -authors: [slorber, yangshun] -tags: [facebook, hello, docusaurus] ---- - -[Docusaurus blogging features](https://docusaurus.io/docs/blog) are powered by the [blog plugin](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog). - -Simply add Markdown files (or folders) to the `blog` directory. - -Regular blog authors can be added to `authors.yml`. - -The blog post date can be extracted from filenames, such as: - -- `2019-05-30-welcome.md` -- `2019-05-30-welcome/index.md` - -A blog post folder can be convenient to co-locate blog post images: - -![Docusaurus Plushie](./docusaurus-plushie-banner.jpeg) - -The blog supports tags as well! - -**And if you don't want a blog**: just delete this directory, and use `blog: false` in your Docusaurus config. diff --git a/blog/authors.yml b/blog/authors.yml deleted file mode 100644 index bcb299156..000000000 --- a/blog/authors.yml +++ /dev/null @@ -1,17 +0,0 @@ -endi: - name: Endilie Yacop Sucipto - title: Maintainer of Docusaurus - url: https://github.com/endiliey - image_url: https://github.com/endiliey.png - -yangshun: - name: Yangshun Tay - title: Front End Engineer @ Facebook - url: https://github.com/yangshun - image_url: https://github.com/yangshun.png - -slorber: - name: Sébastien Lorber - title: Docusaurus maintainer - url: https://sebastienlorber.com - image_url: https://github.com/slorber.png diff --git a/docs/best-practices/computing/image-management-service/creating-a-linux-Image-using-virtualBox-and-an-iso-file.md b/docs/best-practices/computing/image-management-service/creating-a-linux-Image-using-virtualBox-and-an-iso-file.md deleted file mode 100644 index 0bfcc021f..000000000 --- a/docs/best-practices/computing/image-management-service/creating-a-linux-Image-using-virtualBox-and-an-iso-file.md +++ /dev/null @@ -1,1287 +0,0 @@ ---- -id: creating-a-linux-Image-using-virtualBox-and-an-iso-file -title: Creating a Linux Image Using VirtualBox and an ISO File -tags: [ims, migration] ---- - -# Creating a Linux Image Using VirtualBox and an ISO File - -Introduction ------------- - -#### VirtualBox - -VirtualBox is free, open-source virtualization software. It was first offered by InnoTek GmbH from Germany and re-branded as Oracle VM VirtualBox when InnoTek was acquired by Oracle Corporation. - -For more information about VirtualBox, visit the Oracle official website. Click [here](https://www.virtualbox.org/wiki/Guest_OSes) to see the guest OSs that can work with VirtualBox. - -#### Scenarios - -You can use a 32-bit or 64-bit Linux guest OS provided by VirtualBox to create an image file in VHD format. - -#### Advantages - -You can customize Linux image files. - -#### Tools and Costs - -#### Image Creation Process - -The following figure shows how to use VirtualBox to create an image from an ISO file. - -**Figure 1** Image creation process -![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0200645302.png) - -Step 1: Installing VirtualBox ------------------------------ - -#### Preparations - -The host where VirtualBox is to be installed must meet the following requirements: - -* A 64-bit Windows OS (recommended). -* At least 4 GB of memory and a dual-core processor. For example, the host specifications can be 8U16G. -* At least 20 GB of available disk space. -* Hardware virtualization (Intel VT-x or AMD-V). For how to enable this, see [Host CPU Settings (Hardware Virtualization)](#ims_bp_0017__section1503794314311). - -#### Host CPU Settings (Hardware Virtualization) - -For an Intel host, perform the following operations to enable hardware virtualization: - -![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/note_3.0-en-us.png) - -The operations may differ depending on the CPU type. You can do it as prompted. - -1. During the host startup, press the BIOS key set by the manufacturer to access the BIOS. -2. Choose **Configuration** > **Intel Virtual Technology**, and press **Enter**. -3. Select **Enabled** and press **Enter**. The value of **Intel Virtual Technology** will become **Enabled**. -4. Press **F10** to save the settings and exit. - - **Figure 1** Enabling hardware virtualization - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0107215471.png) - - -#### Procedure - -1. Download the VirtualBox installation package. VirtualBox-5.2.0 is used as an example. - - Download it from [https://www.virtualbox.org/wiki/Downloads](https://www.virtualbox.org/wiki/Downloads). - -2. Decompress the package. Right-click **VirtualBox-5.2.0-118431-Win.exe**, choose **Run as administrator**, and click **Next**. - - **Figure 2** Installing VirtualBox - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0107215473.png) - -3. Select the VirtualBox installation path and click **Next**. - - **Figure 3** Selecting an installation path - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0107215475.png) - -4. Personalize the settings and click **Next**. - - **Figure 4** Personalized settings - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0107215477.png) - -5. Click **Finish**. - - -Step 2: Creating a VM and Installing an OS ------------------------------------------- - -## Creating an Empty VM - -#### Prerequisites - -VirtualBox has been installed. - -#### Procedure - -1. Open VirtualBox and click **New**. In the displayed **Create Virtual Machine** dialog box, enter a VM name, select an OS type and version, and click **Next**. - - Take Ubuntu as an example. The type must be **Linux**. - - Ensure that the selected version is the same as that of the OS you want to install on the VM. - - **Figure 1** Creating a VM - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0268280658.png) - -2. In the **Memory size** dialog box, set a value and click **Next**. - - You can reference the VM specifications or official OS requirements. The minimum value is 256 MB. You can set the memory size to 512 MB as an example. - - **Figure 2** Setting the memory size - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0268284967.png) - -3. In the **Hard disk** dialog box, select **Create a virtual hard disk now** and click **Create**. - - **Figure 3** Creating a virtual hard disk - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0268287010.png) - -4. In the **Hard disk file type** dialog box, select **VHD** and click **Next**. - - **Figure 4** Setting the hard disk file type - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0268287244.png) - -5. In the **Storage on physical hard disk** dialog box, select **Dynamically allocated** and click **Next**. - - **Figure 5** Selecting the disk allocation mode - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0268288436.png) - -6. In the **File location and size** dialog box, set the disk size and storage location. - - For example, you can set the disk size to 20 GB. - - **Figure 6** Setting the disk location and size - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0268290676.png) - -7. Click **Create**. - -## Installing a Linux OS on the VM - -The procedure varies depending on the image file you use. This section uses Ubuntu 20.04 as an example to describe how to install a Linux OS on the VM. - -#### Prerequisites - -You have obtained the ISO image file, for example, **Ubuntu-20.04-server.iso**. - -#### Procedure - -Use the ISO file to install Linux for the empty VM. - -1. In VirtualBox Manager, select the new VM and click **Settings**. - - **Figure 1** Setting the VM - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0268393798.png) - -2. Choose **Storage** > **Empty**, click ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0268393752.png) in the **Attributes** area, and select the ISO image file **Ubuntu-20.04-server.iso**. - - **Figure 2** Selecting the ISO file to be mounted - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0268393846.png) - - **Figure 3** Mounted ISO file - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001457709502.png) - -3. Click **OK**. -4. In VirtualBox Manager, select the new VM and click **Start**. - - **Figure 4** Starting the VM - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0268337032.png) - -5. Install the OS. - 1. Select **English** and press **Enter**. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001514305585.png) - - 2. Select **Continue without updating**. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001464149800.png) - - 3. Retain the default settings for the keyboard. Select **Done** - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001514311097.png) - - 4. Retain the default settings for the installation base. Select **Done**. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001514670405.png) - - 5. Retain the default settings for the network. Select **Done**. - - The installation program will automatically identify the IP address. If the network cannot be found, the installation program can still continue and you can configure the network again after the installation is complete. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001463836772.png) - - 6. Retain the default settings for the proxy. Select **Done**. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001514558429.png) - - 7. Retain the default settings for the software source. Select **Done**. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001463840256.png) - - 8. Retain the default settings for disk partitioning (use an entire disk and set up this disk as an LVM group). Select **Done**. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001514561077.png) - - The file system information will be displayed. Check it and select **Done**. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001463841764.png) - - Confirm the destructive action and select **Continue**. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001514681605.png) - - 9. Configure the server name, username, and password. Select **Done**. - - **Your name**: It is not a username for logging in to the server. You can consider it as server description. - - **Your Server's name**: It is a unique server name on the same network. The name cannot contain uppercase letters. - - **Pick a username**: It is a username for logging in to the server. If you forget it or its password, you will not be allowed to log in to the server. - - **Choose a password**: It is the password for logging in to the server. - - **Confirm your password**: Enter your password again. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001464161876.png) - - 10. Install SSH so that you can remotely connect to the Linux server. - - Select **Install OpenSSH server**. Then, press **Tab** to select **Done**. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001514587325.png) - - 11. Select **Done** to start the OS installation. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001464002560.png) - - 12. After the installation is complete, select **Reboot** to restart the system. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001464031938.png) - - - -Step 3: Configuring the VM --------------------------- - -## Installing Drivers and Changing the Disk Identifiers to the UUID Format - -To ensure that the ECSs created from the image support both Xen and KVM virtualization, install Native Xen and KVM drivers and change the disk identifiers to the UUID format for the VM which is used as the image source. - -This section describes how to perform these operations on a Linux VM that runs Ubuntu 20.04. For other OSs, see [Optimization Process (Linux)](https://support.huaweicloud.com/intl/en-us/usermanual-ims/en-us_topic_0047501133.html). - -#### Install Native Xen and KVM Drivers - -1. Run the following command to open the **modules** file: - - **vi /etc/initramfs-tools/modules** - -2. Press **i** to enter the editing mode and add the native Xen (xen-pv) and KVM (virtio) drivers to the **/etc/initramfs-tools/modules** file (the format depends on the OS requirements). - - `` -[root@CTU10000xxxxx ~]#vi /etc/initramfs-tools/modules -... -# Examples: -# -# raid1 -# sd_mOd -xen-blkfront -xen-netfront -virtio_blk -virtio_scsi -virtio_net -virtio_pci -virtio_ring -virtio -`` - - -3. Press **Esc**, enter **:wq**, and press **Enter** to save the settings and exit the vi editor. -4. Run the following command to generate initrd again: - - **update-initramfs -u** - -5. Run the following commands to check whether native Xen and KVM drivers have been installed: - - **lsinitramfs /boot/initrd.img-\`uname -r\` |grep xen** - - **lsinitramfs /boot/initrd.img-\`uname -r\` |grep virtio** - - `` -[root@ CTU10000xxxxx home]# lsinitramfs /boot/initrd.img-`uname -r` |grep xen -lib/modules/3.5.0-23-generic/kernel/drivers/net/ethernet/qlogic/netxen -lib/modules/3.5.0-23-generic/kernel/drivers/net/ethernet/qlogic/netxen/netxen_nic.ko -lib/modules/3.5.0-23-generic/kernel/drivers/net/xen-netback -lib/modules/3.5.0-23-generic/kernel/drivers/net/xen-netback/xen-netback.ko -lib/modules/3.5.0-23-generic/kernel/drivers/block/xen-blkback -lib/modules/3.5.0-23-generic/kernel/drivers/block/xen-blkback/xen-blkback.ko - -[root@ CTU10000xxxxx home]# lsinitramfs /boot/initrd.img-`uname -r` |grep virtio -lib/modules/3.5.0-23-generic/kernel/drivers/scsi/virtio_scsi.ko -`` - - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/note_3.0-en-us.png) - - If you add built-in drivers to the initrd or initramfs file, the VM will not be affected. This makes it easy to modify the drivers. However, the drivers cannot be shown by running the **lsinitrd** command. You can run the following commands to check whether the drivers are built-in ones in the kernel: - - `` -[root@ CTU10000xxxxx home]# cat /boot/config-`uname -r` | grep CONFIG_VIRTIO | grep y -CONFIG_VIRTIO_BLK=y -CONFIG_VIRTIO_NET=y -CONFIG_VIRTIO=y -CONFIG_VIRTIO_RING=y -CONFIG_VIRTIO_PCI=y -CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y -[root@ CTU10000xxxxx home]# cat /boot/config-`uname -r` | grep CONFIG_XEN | grep y -CONFIG_XEN_BLKDEV_FRONTEND=y -CONFIG_XEN_NETDEV_FRONTEND=y -`` - - - -#### Change the Disk Identifier in the GRUB Configuration File to the UUID Format - -Take Ubuntu 20.04 as an example. Run **blkid** to obtain the UUID of the root partition. Modify the **/boot/grub/grub.cfg** file and use the UUID of the root partition to configure the boot item. If the root partition already uses UUID, no modification is required. The procedure is as follows: - -1. Log in to the newly created VM as user **root**. -2. Run the following command to query all types of mounted file systems and their device UUIDs: - - **blkid** - - The following information is displayed: - - `` -/dev/xvda1: UUID="ec51d860-34bf-4374-ad46-a0c3e337fd34" TYPE="ext3" -/dev/xvda5: UUID="7a44a9ce-9281-4740-b95f-c8de33ae5c11" TYPE="swap" -`` - - - -3. Run the following command to query the **grub.cfg** file: - - **cat /boot/grub/grub.****cfg** - - The following information is displayed: - - `` -......menuentry 'Ubuntu Linux, with Linux 3.13.0-24-generic' --class ubuntu --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.13.0-24-generic-advanced-ec51d860-34bf-4374-ad46-a0c3e337fd34' { -recordfail -load_video -gfxmode $linux_gfx_mode -insmod gzio -insmod part_msdos -insmod ext2 -if [ x$feature_platform_search_hint = xy ]; then -search --no-floppy --fs-uuid --set=root ec51d860-34bf-4374-ad46-a0c3e337fd34 -else -search --no-floppy --fs-uuid --set=root ec51d860-34bf-4374-ad46-a0c3e337fd34 -fi -echo 'Loading Linux 3.13.0-24-generic ...' -linux /boot/vmlinuz-3.13.0-24-generic root=/dev/xvda1 ro -echo 'Loading initial ramdisk ...' -initrd /boot/initrd.img-3.13.0-24-generic -} -`` - - - -4. Check whether the **/boot/grub/grub.cfg** configuration file contains **root=/dev/xvda1** or **root=UUID=ec51d860-34bf-4374-ad46-a0c3e337fd34**. - * If **root=UUID=ec51d860-34bf-4374-ad46-a0c3e337fd34** is contained, the root partition is in the UUID format and no further action is required. - * If **root=/dev/xvda1** is contained, the root partition is represented by a device name. Go to step [5](#ims_bp_0022__en-us_topic_0106036281_lf7085be4afa540f3b52640d8d9157c9a). - -5. Obtain the UUID of the root partition based on **root=/dev/xvda1** and information obtained by running the **blkid** command. -6. Run the following command to open the **grub.cfg** file: - - **vi /boot/grub/grub.cfg** - -7. Press **i** to enter the editing mode. Change the identifier of the root partition to the UUID format. For example, change **root=/dev/xvda1** to **root=UUID=ec51d860-34bf-4374-ad46-a0c3e337fd34**. -8. Press **Esc**, enter **:wq**, and press **Enter** to save the settings and exit the vi editor. -9. Run the following command to verify the change: - - **cat /boot/grub/grub.****cfg** - - The change is successful if information similar to the following is displayed: - - `` -......menuentry 'Ubuntu Linux, with Linux 3.13.0-24-generic' --class ubuntu --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.13.0-24-generic-advanced-ec51d860-34bf-4374-ad46-a0c3e337fd34' { -recordfail -load_video -gfxmode $linux_gfx_mode -insmod gzio -insmod part_msdos -insmod ext2 -if [ x$feature_platform_search_hint = xy ]; then -search --no-floppy --fs-uuid --set=root ec51d860-34bf-4374-ad46-a0c3e337fd34 -else -search --no-floppy --fs-uuid --set=root ec51d860-34bf-4374-ad46-a0c3e337fd34 -fi -echo 'Loading Linux 3.13.0-24-generic ...' -linux /boot/vmlinuz-3.13.0-24-generic root=UUID=ec51d860-34bf-4374-ad46-a0c3e337fd34 ro -echo 'Loading initial ramdisk ...' -initrd /boot/initrd.img-3.13.0-24-generic -} -`` - - - -#### Change the Disk Identifiers in the fstab File to the UUID Format - -Take Ubuntu 20.04 as an example. Run **blkid** to obtain the UUIDs of all partitions. Modify the **/etc/fstab** file and use the partition UUIDs to configure automatic partition mounting. - -1. Run the following command to query all types of mounted file systems and their device UUIDs: - - **blkid** - - The following information is displayed: - - `` -/dev/xvda2: UUID="4eb40294-4c6f-4384-bbb6-b8795bbb1130" TYPE="xfs" -/dev/xvda1: UUID="2de37c6b-2648-43b4-a4f5-40162154e135" TYPE="swap" -`` - - -2. Run the following command to query the **fstab** file: - - **cat /etc/fstab** - - The following information is displayed: - - `` -[root@CTU1000028010 ~]# cat /etc/fstab -/dev/xvda2 / xfs defaults 0 0 -/dev/xvda1 swap swap defaults 0 0 -`` - - -3. Check whether the disk identifiers in the **fstab** file are device names or UUIDs. - * If they are UUIDs, no further action is required. - * If they are device names, go to step [4](#ims_bp_0022__en-us_topic_0106036281_li63646666154817). -4. Run the following command to open the **fstab** file: - - **vi /etc/fstab** - -5. Press **i** to enter the editing mode and change the disk identifiers to the UUID format. -6. Press **Esc**, enter **:wq**, and press **Enter** to save the settings and exit the vi editor. - -## Installing Cloud-Init -#### Scenarios - -To ensure that you can use the user data injection function to inject initial custom information into ECSs created from a private image (such as setting the ECS login password), install Cloud-Init on the ECS used to create the image. - -* You need to download Cloud-Init from its official website. Therefore, you must bind an EIP to the ECS. -* If Cloud-Init is not installed, you cannot configure an ECS. As a result, you can only use the password in the image file to log in to the created ECSs. -* By default, ECSs created from a public image have Cloud-Init installed. You do not need to install or configure Cloud-Init on such ECSs. -* For ECSs created using an external image file, install and configure Cloud-Init by performing the operations in this section. For how to configure Cloud-Init, see [Configuring Cloud-Init](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/ims_bp_0024.html#ims_bp_0024). - -![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/note_3.0-en-us.png) - -Cloud-Init is open-source software. If the installed version has security vulnerabilities, you are advised to upgrade it to the latest version. - -#### Prerequisites - -* An EIP has been bound to the ECS. -* You have logged in to the ECS. -* The IP address obtaining mode of the ECS is DHCP. - -#### Procedure - -1. Check whether Cloud-Init has been installed. - - For details, see [Check Whether Cloud-Init Has Been Installed](#ims_bp_0023__en-us_topic_0030730603_section57525650153449). - -2. Install Cloud-Init. - - You can install Cloud-Init in any of the following ways: [(Recommended) Install Cloud-Init Using the Official Installation Package](#ims_bp_0023__en-us_topic_0030730603_section9013470154018), [Install Cloud-Init Using the Official Source Code Package and pip](#ims_bp_0023__en-us_topic_0030730603_section124220553610), and [Install Cloud-Init Using the Official GitHub Source Code](#ims_bp_0023__en-us_topic_0030730603_section14939636151511). - - -#### Check Whether Cloud-Init Has Been Installed - -Perform the operations provided here to check whether Cloud-Init has been installed. The methods of checking whether Cloud-Init is installed vary depending on the OSs. - -* If you are in a Python 3 environment, run the following command to check whether Cloud-Init is installed (Ubuntu 22.0.4 is used as an example): - - **which cloud-init** - - * If information similar to the following is displayed, Cloud-Init has been installed: - - `` -/usr/bin/cloud-init -`` - - - * If information similar to the following is displayed, Cloud-Init is not installed: - - `` -/usr/bin/which: no cloud-init in (/usr/local/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin) -`` - - -* If you are in a Python 2 environment, run the following command to check whether Cloud-Init is installed (CentOS 6 is used as an example): - - **which cloud-init** - - * If information similar to the following is displayed, Cloud-Init has been installed: - - `` -cloud-init-0.7.5-10.el6.centos.2.x86_64 -`` - - - * If no information is returned, Cloud-Init is not installed. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/note_3.0-en-us.png) - - To confirm Cloud-Init is really not installed, you are advised to run **rpm -qa |grep cloud-init** to check again. If either of **which cloud-init** and **rpm -qa |grep cloud-init** shows that Cloud-Init has been installed, Cloud-Init is installed. - - -If Cloud-Init has been installed, perform the following operations: - -* Check whether to use the SSH certificate in the ECS OS. If the certificate is no longer used, delete it. - * If the certificate is stored in a directory of user **root**, for example, _/$path/$to/$root_**/.ssh/authorized\_keys**, run the following commands: - - **cd /root/.ssh** - - **rm authorized\_keys** - - * If the certificate is not stored in a directory of user **root**, for example, _/$path/$to/$none-root_**/.ssh/authorized\_keys**, run the following commands: - - **cd /home/centos/.ssh** - - **rm authorized\_keys** - -* Run the following command to delete the cache generated by Cloud-Init and ensure that the ECS created from the private image can be logged in by using the certificate: - - **sudo rm -rf /var/lib/cloud/\*** - - -![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/note_3.0-en-us.png) - -Do not restart the ECS after performing the configuration. Otherwise, you need to configure it again. - -#### (Recommended) Install Cloud-Init Using the Official Installation Package - -The method of installing Cloud-Init on an ECS varies depending on the OS. Perform the installation operations as user **root**. - -The following describes how to install Cloud-Init on an ECS running SUSE Linux, CentOS, Fedora, Debian, and Ubuntu. For other OS types, install the required type of Cloud-Init. For example, you need to install coreos-cloudinit on ECSs running CoreOS. - -* SUSE Linux - - Paths for obtaining the Cloud-Init installation package for SUSE Linux - - [https://ftp5.gwdg.de/pub/opensuse/repositories/Cloud:/Tools/](https://ftp5.gwdg.de/pub/opensuse/repositories/Cloud:/Tools) - - [http://download.opensuse.org/repositories/Cloud:/Tools/](http://download.opensuse.org/repositories/Cloud:/Tools/) - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/note_3.0-en-us.png) - - Select the required repo installation package in the provided paths. - - Take SUSE Enterprise Linux Server 12 as an example. Perform the following steps to install Cloud-Init: - - 1. Log in to the ECS used to create a Linux private image. - 2. Run the following command to install the network installation source for SUSE Enterprise Linux Server 12: - - **zypper ar https://ftp5.gwdg.de/pub/opensuse/repositories/Cloud:/Tools/SLE\_12\_SP3/Cloud:Tools.repo** - - 3. Run the following command to update the network installation source: - - **zypper refresh** - - 4. Run the following command to install Cloud-Init: - - **zypper install cloud-init** - - 5. Run the following commands to enable Cloud-Init to automatically start upon system boot: - - * SUSE 11 - - **chkconfig cloud-init-local on; chkconfig cloud-init on; chkconfig cloud-config on; chkconfig cloud-final on** - - **service cloud-init-local status; service cloud-init status; service cloud-config status; service cloud-final status** - - * SUSE 12 and openSUSE 12/13/42 - - **systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service** - - **systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service** - - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/caution_3.0-en-us.png) - - For SUSE and openSUSE, perform the following steps to disable dynamic change of the ECS name: - - 1. Run the following command to open the **dhcp** file using the vi editor: - - **vi** **etc/sysconfig/network/dhcp** - - 2. Change the value of **DHCLIENT\_SET\_HOSTNAME** in the **dhcp** file to **no**. - -* **CentOS** - - [Table 1](#ims_bp_0023__en-us_topic_0030730603_table859383892814) lists the Cloud-Init installation paths for CentOS. Select the required installation package from the following addresses. - - 1. Run the following commands to install Cloud-Init: - - **yum install** _Cloud-Init installation package address_**/epel-release-**_x-y_**.noarch.rpm** - - **yum install cloud-init** - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/note_3.0-en-us.png) - - _Cloud-Init installation package address_ indicates the address of the Cloud-Init epel-release installation package, and _x-y_ indicates the version of the Cloud-Init epel-release required by the current OS. Replace them with the actual values according to [Table 1](#ims_bp_0023__en-us_topic_0030730603_table859383892814). - - * Take CentOS 6 64-bit as an example. If the version is 6.8, the command is as follows: - - **yum install https://archives.fedoraproject.org/pub/archive/epel/6/x86\_64/epel-release-****6-8****.noarch.rpm** - - * Take CentOS 7 64-bit as an example. If the version is 7.14, the command is as follows: - - **yum install https://archives.fedoraproject.org/pub/epel/7/x86\_64/Packages/e/epel-release-****7-14****.noarch.rpm** - - - 2. Run the following commands to enable Cloud-Init to automatically start upon system boot: - - **systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service** - - **systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service** - -* Fedora - - Before installing Cloud-Init, ensure that the network installation source address has been configured for the OS by checking whether the **/etc/yum.repo.d/fedora.repo** file contains the installation source address of the software package. If the file does not contain the address, configure the address by following the instructions on the Fedora official website. - - 1. Run the following command to install Cloud-Init: - - **yum install cloud-init** - - 2. Run the following commands to enable Cloud-Init to automatically start upon system boot: - - **systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service** - - **systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service** - -* Debian and Ubuntu - - Before installing Cloud-Init, ensure that the network installation source address has been configured for the OS by checking whether the **/etc/apt/sources.list** file contains the installation source address of the software package. If the file does not contain the address, configure the address by following the instructions on the Debian or Ubuntu official website. - - 1. Run the following commands to install Cloud-Init: - - **apt-get update** - - **apt-get install** **cloud-init** - - 2. Run the following commands to enable Cloud-Init to automatically start upon system boot: - - **systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service** - - **systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service** - - - **Cloud-Init-23.2.2 is used as an example to describe how to install Cloud-Init on CentOS, Fedora, Ubuntu, Debian, and SUSE.** - - Download the **cloud-init-23.2.2.tar.gz** source code package from [https://launchpad.net/cloud-init/trunk/23.2.2/+download/cloud-init-23.2.2.tar.gz](https://launchpad.net/cloud-init/trunk/23.2.2/+download/cloud-init-23.2.2.tar.gz). - -* **Centos 7/Fedora Server 36** - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/notice_3.0-en-us.png) - - Ensure that Python 3 has been installed. - - 1. Check whether Cloud-Init has been installed. If any command output is displayed, Cloud-Init has been installed. - - `` -cloud-init -v -`` - - - 2. Delete the cache directory of Cloud-Init. - - `` -rm -rf /var/lib/cloud/* -`` - - - 3. Install dependency packages of Cloud-Init. - - `` -yum install python3-pip -y -yum install python3-devel -`` - - - 4. Download the Cloud-Init package. - - `` -wget https://launchpad.net/cloud-init/trunk/23.2.2/+download/cloud-init-23.2.2.tar.gz -`` - - - 5. Decompress the Cloud-Init package. - - `` -tar -zxvf cloud-init-23.2.2.tar.gz -`` - - - 6. Go to the **cloud-init-23.2.2** directory and install dependent libraries: - - `` -cd cloud-init-23.2.2 -pip3 install -r requirements.txt -`` - - - 7. Install Cloud-Init. - - `` -python3 setup.py build -python3 setup.py install --init-system systemd -`` - - - 8. (Optional) Diable Cloud-Init's network configuration capability by modifying the **/etc/cloud/cloud.cfg** file. - - `` -vi /etc/cloud/cloud.cfg -`` - - - Add the following content to the file: - - `` -network: - config: disabled -`` - - - 9. Restart Cloud-Init and check its status. - - `` -systemctl restart cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service -systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service -`` - - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001688060529.png) - - 10. Enable Cloud-Init related services to automatically start upon system boot. - - `` -systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service -`` - - - 11. Check whether Cloud-Init is running properly. - - `` -cloud-init -v -cloud-init init --local -`` - - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001639899816.png) - -* **Ubuntu 22.0.4/Debian 11** - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/notice_3.0-en-us.png) - - Ensure that Python 3 has been installed. - - 1. Check and delete redundant Cloud-Init configuration files. - - `` -rm -rf /var/lib/cloud/* -rm -f /var/log/cloud-init* -`` - - - Delete all files except log-related configuration files from the **/etc/cloud/cloud.cfg.d/** directory. - - 2. Update your package list and check whether Wget is installed. If it is not, install it. - - `` -sudo apt update -sudo apt install wget -`` - - - 3. Install dependency packages. - - `` -apt-get install cloud-guest-utils -y -apt-get install python3-pip -y -apt-get install python3-devel -`` - - - 4. Download the Cloud-Init package. - - `` -wget https://launchpad.net/cloud-init/trunk/23.2.2/+download/cloud-init-23.2.2.tar.gz -`` - - - 5. Decompress the Cloud-Init package. - - `` -tar -zxvf cloud-init-23.2.2.tar.gz -`` - - - 6. Go to the **cloud-init** directory. - - `` -cd cloud-init-23.2.2 -`` - - - 7. Install dependent libraries. - - `` -pip3 install -r requirements.txt -`` - - - 8. Install Cloud-Init. - - `` -python3 setup.py install -`` - - - 9. (Optional) Disable Cloud-Init's network configuration capability. - - You need to do so when the Cloud-Init version is 0.7.9 or later and you want to configure the network. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/note_3.0-en-us.png) - - 1\. Open the **/etc/cloud/cloud.cfg** file. - - `` -vi /etc/cloud/cloud.cfg -`` - - - 2\. Enter **i** and configure **network**. (If there is no such a configuration item, add it.) - - `` -network: - config: disabled -`` - - - 10. Restart Cloud-Init and check its status. - - `` -systemctl restart cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service -systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service -`` - - - 11. Enable Cloud-Init related services to automatically start upon system boot. - - `` -systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service -`` - - - 12. Check whether Cloud-Init is running properly. - - `` -cloud-init -v -cloud-init init --local -`` - - -* **SUSE Enterprise Linux Server 15** - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/notice_3.0-en-us.png) - - Ensure that Python 3 has been installed. - - 1. View existing SUSE repositories. - - `` -zypper lr -`` - - - 2. Delete the SUSE repositories. - - `` -zypper rr No. of repositories listed in 1 -`` - - - 3. Configure a SUSE repository. - - `` -zypper ar https://ftp5.gwdg.de/pub/opensuse/repositories/Cloud:/Tools/SLE_15_SP4/Cloud:Tools.repo -`` - - - 4. Refresh the SUSE repository. - - `` -zypper refresh -`` - - - 5. Install Cloud-Init. - - `` -zypper install cloud-init -`` - - - 6. Run **cloud-init -v**. If error messages similar to the following are displayed, install the dependency packages. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001688251829.png) - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001640131918.png) - - `` -pip install requests pyyaml oauthlib jsonschema jsonpatch jinja2 configobj -`` - - - 7. Check whether Cloud-Init is successfully installed. If the following error message is displayed, configure **datasource\_list** in **/etc/cloud/cloud.cfg**. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001639765024.png) - - `` -datasource_list: [ OpenStack ] -datasource: - OpenStack: - metadata_urls: ['http://169.254.169.254'] - max_wait: 120 - timeout: 5 - apply_network_config: false -`` - - - 8. Modify the configuration file, restart Cloud-Init, and check the Cloud-Init status. - - `` -systemctl restart cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service -systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service -`` - - - 9. Enable Cloud-Init related services to automatically start upon system boot. - - `` -systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service -`` - - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001688204517.png) - - 10. Check whether Cloud-Init is running properly. - - `` -cloud-init -v -cloud-init init --local -`` - - - -#### Install Cloud-Init Using the Official Source Code Package and pip - -The following operations use Cloud-Init 0.7.9 as an example to describe how to install Cloud-Init. - -1. Download the **cloud-init-0.7.9.tar.gz** source code package (version 0.7.9 is recommended) and upload it to the **/home/** directory of the ECS. - - Download **cloud-init-0.7.9.tar.gz** from the following path: - - [https://launchpad.net/cloud-init/trunk/0.7.9/+download/cloud-init-0.7.9.tar.gz](https://launchpad.net/cloud-init/trunk/0.7.9/+download/cloud-init-0.7.9.tar.gz) - -2. Create a **pip.conf** file in the **~/.pip/** directory and edit the following content: - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/note_3.0-en-us.png) - - If the **~/.pip/** directory does not exist, run the **mkdir ~/.pip** command to create it. - - `` -[global] -index-url = https://<$mirror>/simple/ -trusted-host = <$mirror> -`` - - -3. Run the following command to install the downloaded Cloud-Init source code package (select **\--upgrade** as needed during installation): - - **pip install \[--upgrade\] /home/cloud-init-0.7.9.tar.gz** - -4. Run the **cloud-init -v** command. Cloud-Init is installed successfully if the following information is displayed: - - `` -cloud-init 0.7.9 -`` - - -5. Enable Cloud-Init to automatically start upon system boot. - * If the OS uses SysVinit to manage automatic start of services, run the following commands: - - **chkconfig --add cloud-init-local; chkconfig --add cloud-init; chkconfig --add cloud-config; chkconfig --add cloud-final** - - **chkconfig cloud-init-local on; chkconfig cloud-init on; chkconfig cloud-config on; chkconfig cloud-final on** - - **service cloud-init-local status; service cloud-init status; service cloud-config status; service cloud-final status** - - * If the OS uses Systemd to manage automatic start of services, run the following commands: - - **systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service** - - **systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service** - - -![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/caution_3.0-en-us.png) - -If you install Cloud-Init using the official source code package and pip, pay attention to the following: - -1. Add user **syslog** to the **adm** group during the installation. If user **syslog** exists, add it to the **adm** group. For some OSs (such as CentOS and SUSE), user **syslog** may not exist. Run the following commands to create user **syslog** and add it to the **adm** group: - - **useradd syslog** - - **groupadd adm** - - **usermod -g adm syslog** - -2. Change the value of **distro** in **system\_info** in the **/etc/cloud/cloud.cfg** file based on the OS release version, such as **distro: ubuntu**, **distro: sles**, **distro: debian**, and **distro: fedora**. - -#### Install Cloud-Init Using the Official GitHub Source Code - -You can obtain the Cloud-Init source code from GitHub at [https://github.com/canonical/cloud-init/](https://github.com/canonical/cloud-init/) - -1. Run the following commands to download the source code package and copy it to the **/tmp/CLOUD-INIT** folder: - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/note_3.0-en-us.png) - - **wget** **https://github.com/canonical/cloud-init/archive/refs/tags/0.7.6.zip** - - **mkdir /tmp/CLOUD-INIT** - - **cp **cloud-init-0.7.6.zip** /tmp/CLOUD-INIT** - - **cd /tmp/CLOUD-INIT** - -2. Run the following command to decompress the package: - - **unzip **cloud-init-0.7.6.zip**** - -3. Run the following command to enter the **cloud-init-0.7.6** folder: - - **cd **cloud-init**\-0.7.6** - -4. (Optional) If the Cloud-Init version is 18.3 to 22.3, run the following commands: - - **sed -i '/VALID\_DMI\_ASSET\_TAGS =/a\\VALID\_DMI\_ASSET\_TAGS += \["HUAWEICLOUD"\]' cloudinit/sources/DataSourceOpenStack.py** - - **cat cloudinit/sources/DataSourceOpenStack.py | grep VALID\_DMI\_ASSET\_TAGS** - - If the following information is displayed, the execution is successful. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/en-us_image_0000001390619817.png) - -5. Install Cloud-Init. The commands vary depending on the OS type. - - * For CentOS 6.x or SUSE 11.x, run the following commands: - - **python setup.py build** - - **python setup.py install --init-system sysvinit** - - * For CentOS 7.x or SUSE 12.x, run the following commands: - - **python setup.py build** - - **python setup.py install --init-system systemd** - - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/note_3.0-en-us.png) - - Add user **syslog** to the **adm** group during the installation. If user **syslog** exists, add it to the **adm** group. For some OSs (such as CentOS and SUSE), user **syslog** may not exist. Run the following commands to create user **syslog** and add it to the **adm** group: - - **useradd syslog** - - **groupadd adm** - - **usermod -g adm syslog** - -6. Enable Cloud-Init to automatically start upon system boot. - * If the OS uses SysVinit to manage automatic start of services, run the following commands: - - **chkconfig --add cloud-init-local; chkconfig --add cloud-init; chkconfig --add cloud-config; chkconfig --add cloud-final** - - **chkconfig cloud-init-local on; chkconfig cloud-init on; chkconfig cloud-config on; chkconfig cloud-final on** - - **service cloud-init-local status; service cloud-init status; service cloud-config status; service cloud-final status** - - * If the OS uses Systemd to manage automatic start of services, run the following commands: - - **systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service** - - **systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service** - -7. Run the following commands to check whether Cloud-Init has been installed: - - **cloud-init -v** - - **cloud-init init --local** - - Cloud-Init is successfully installed if the following information is displayed: - - `` -cloud-init 0.7.6 -`` - -## (Optional) Installing the One-Click Password Reset Plug-in_Image Management Service - -To ensure that you can reset the password of each ECS created from the image with a few clicks, you are advised to install the one-click password reset plug-in (CloudResetPwdAgent) on the VM which is used as the image source. - -#### Procedure - -1. Download the CloudResetPwdAgent software package. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/note_3.0-en-us.png) - - The one-click password reset plug-in can be automatically updated only if an EIP is bound to the VM. - - You can download the **CloudResetPwdAgent.zip** package from: - - For 32-bit OSs: [http://ap-southeast-1-cloud-reset-pwd.obs.ap-southeast-1.myhuaweicloud.com/linux/32/reset\_pwd\_agent/CloudResetPwdAgent.zip](http://ap-southeast-1-cloud-reset-pwd.obs.ap-southeast-1.myhuaweicloud.com/linux/32/reset_pwd_agent/CloudResetPwdAgent.zip) - - For 64-bit OSs: [http://ap-southeast-1-cloud-reset-pwd.obs.ap-southeast-1.myhuaweicloud.com/linux/64/reset\_pwd\_agent/CloudResetPwdAgent.zip](http://ap-southeast-1-cloud-reset-pwd.obs.ap-southeast-1.myhuaweicloud.com/linux/64/reset_pwd_agent/CloudResetPwdAgent.zip) - -2. Run the following command to decompress **CloudResetPwdAgent.zip**: - - **unzip -o -d** _Decompressed directory_ **CloudResetPwdAgent.zip** - - There is no special requirement for the directory that stores the decompressed **CloudResetPwdAgent.zip**. You can choose a directory as you need. If the directory is **/home/PwdAgent/test**, the command is as follows: - - **unzip -o -d /home/PwdAgent/test CloudResetPwdAgent.zip** - -3. Install the one-click password reset plug-in. - 1. Run the following command to open the **CloudResetPwdAgent.Linux** file: - - **cd CloudResetPwdAgent/CloudResetPwdAgent.Linux** - - 2. Run the following command to add the execute permission for the **setup.sh** file: - - **chmod +x setup.sh** - - 3. Run the following command to install the plug-in: - - **sudo sh setup.sh** - - 4. Run the following command to check whether the installation is successful: - - **service cloudResetPwdAgent status** - - If the status of CloudResetPwdAgent is not **unrecognized service**, the installation is successful. Otherwise, the installation failed. - - ![](https://support.huaweicloud.com/intl/en-us/bestpractice-ims/public_sys-resources/note_3.0-en-us.png) - - If the installation failed, check whether the installation environment meets requirements and install the plug-in again. - -## Configuring NetworkManager - -Linux allows you to use NetworkManager to automatically configure the VM network. You are advised to use NetworkManager for new OS versions. - -Alternatively, you can use the native network management service of the OS. - -#### Red Hat, Oracle, CentOS 6.x, CentOS 7.x, EulerOS 2.x, Fedora 22, or Later - -Install NetworkManager and use it for automatic network configuration. - -1. Run the following command to install NetworkManager: - - **yum install NetworkManager** - -2. Delete **ifcfg-eth1** to **ifcfg-eth11** from the **/etc/sysconfig/network-scripts/** directory and retain only **ifcfg-eth0**. -3. Run the following command to disable the network: - - **service network stop** - -4. Run the following command to disable automatic startup of the network: - - **chkconfig network off** - -5. Run the following commands to restart messagebus and NetworkManager and enable NetworkManager to start automatically at startup: - - **service messagebus restart** - - **service NetworkManager restart** - - **chkconfig NetworkManager on** - - -#### Debian 9.0 or Later - -Install NetworkManager and use it for automatic network configuration. - -1. Run the following command to install NetworkManager: - - **apt-get install network-manager** - -2. Change the value of **managed** in the **/etc/NetworkManager/NetworkManager.conf** file to **true**. -3. Modify **/etc/network/interfaces** and retain only **eth0**. -4. Run the following commands to disable the network, restart messagebus and NetworkManager, and enable NetworkManager to start automatically at startup: - - **service network-manager restart** - - **chkconfig network-manager on** - - **service networking stop** - - **service messagebus restart** - - **service network-manager restart** - - -#### Ubuntu 14 or Later - -Install NetworkManager and use it for automatic network configuration. - -1. Run the following command to install NetworkManager: - - **apt-get install network-manager** - -2. Change the value of **managed** in the **/etc/NetworkManager/NetworkManager.conf** file to **true**. -3. Modify **/etc/network/interfaces** and retain only **eth0**. -4. Run the following command to disable the network: - - **service networking stop** - -5. Run the following command to disable automatic startup of the network: - - **chkconfig network off** - -6. Run the following commands to restart D-Bus and NetworkManager: - - **service dbus restart** - - **service network-manager restar****t** - - -#### SUSE 11 SP3 and openSUSE 13 or Later - -Install NetworkManager and use it for automatic network configuration. - -1. Delete **ifcfg-eth1** to **ifcfg-eth11** from the **/etc/sysconfig/network-scripts/** directory and retain only **ifcfg-eth0**. -2. Run the following command to install NetworkManager: - - **zypper install NetworkManager** - -3. Start YaST, choose **Network Devices** in the navigation pane on the left, and select **Network Settings** in the right pane. In the **Network Setup Method** area of the **Global Options** page, change **Traditional Method with ifup** to **User Controlled with NetworkManager** - - -Step 4: Obtaining the Image File_Image Management Service ---------------------------------------------------------- -Updated on 2022-08-29 GMT+08:00 - -After the VM is configured, perform the following operations to generate and export a Linux image file: - -1. Open VirtualBox, select the VM, choose **Settings** > **Storage**, and select **Linux.vhd**. - - **Linux** is the VM name. - -2. On the right pane, view the image file location. -3. Go to the location to obtain the generated **Linux.vhd** image file. - -Step 5: Registering the Image File as a Private Image ------------------------------------------------------ -Upload the image file to an OBS bucket and register it as a private image. - -#### Constraints - -* Only an unencrypted image file or an image file encrypted using SSE-KMS can be uploaded to an OBS bucket. -* When uploading an image file, you must select an OBS bucket with the storage class of Standard. - -#### Procedure - -1. Use OBS Browser+ to upload the image file. For details, see [OBS Browser+ Best Practices](https://support.huaweicloud.com/intl/en-us/browsertg-obs/obs_03_1006.html). - - For how to download OBS Browser+, see [https://support.huaweicloud.com/intl/en-us/browsertg-obs/obs\_03\_1003.html](https://support.huaweicloud.com/intl/en-us/browsertg-obs/obs_03_1003.html). - -2. Register the external image file as a private image. For details, see [Registering an Image File as a Private Image (Linux)](https://support.huaweicloud.com/intl/en-us/usermanual-ims/ims_01_0211.html). \ No newline at end of file diff --git a/docs/best-practices/computing/image-management-service/creating-a-linux-Image-using-virtualBox-and-an-iso-file.mdx b/docs/best-practices/computing/image-management-service/creating-a-linux-Image-using-virtualBox-and-an-iso-file.mdx new file mode 100644 index 000000000..44d7fb29b --- /dev/null +++ b/docs/best-practices/computing/image-management-service/creating-a-linux-Image-using-virtualBox-and-an-iso-file.mdx @@ -0,0 +1,560 @@ +--- +id: creating-a-linux-Image-using-virtualBox-and-an-iso-file +title: Creating a Linux Image Using VirtualBox and an ISO File +tags: [ims, virtualbox] +--- + +# Creating a Linux Image Using VirtualBox and an ISO File + +[VirtualBox](https://www.virtualbox.org/) is free, open-source virtualization software. It was first offered by InnoTek GmbH from Germany and re-branded as Oracle VM VirtualBox when InnoTek was acquired by Oracle Corporation. + +For more information about VirtualBox, visit the Oracle official website. Click [here](https://www.virtualbox.org/wiki/Guest_OSes) to see the guest OSs that can work with VirtualBox. + +You can use a 32-bit or 64-bit Linux guest OS provided by VirtualBox to create an image file in VHD format. +The following figure shows how to use VirtualBox to create an image from an ISO file. + +![**Figure 1** Image creation process](/img/docs/best-practices/computing/image-management-service/en-us_image_0200645302.png) + +## Installing VirtualBox + +### Prerequisites + +The host where VirtualBox is to be installed must meet the following requirements: + +* A 64-bit Windows OS (recommended). +* At least 4 GB of memory and a dual-core processor. For example, the host specifications can be 8U16G. +* At least 20 GB of available disk space. +* Hardware virtualization (Intel VT-x or AMD-V). For how to enable this, see [Configuring Host BIOS CPU Settings](#configuring-host-bios-cpu-settings). + +:::note +For details about how to install VirtualBox, see the VirtualBox user guide at +[https://www.virtualbox.org/manual/UserManual.html](https://www.virtualbox.org/manual/UserManual.html). +::: + +### Configuring Host BIOS CPU Settings + +For an **Intel host**, perform the following operations to enable hardware virtualization: + +:::warning +The operations **may differ depending on the CPU type**. You can do it as prompted. +::: + +1. During the host startup, press *the BIOS key set by the manufacturer to access the BIOS*. +2. Choose *Configuration* -> *Intel Virtual Technology*, and press *Enter*. +3. Select *Enabled* and press *Enter*. The value of *Intel Virtual Technology* will become *Enabled*. +4. Press *F10* to save the settings and exit. + + **Figure 1** Enabling hardware virtualization + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0107215471.png) + +### Installing VirtualBox Binaries + +1. Download the VirtualBox installation package. VirtualBox-5.2.0 is used as an example. + + Download it from [https://www.virtualbox.org/wiki/Downloads](https://www.virtualbox.org/wiki/Downloads). + +2. Decompress the package. Right-click **VirtualBox-5.2.0-118431-Win.exe**, choose *Run as administrator*, and click *Next*. + + **Figure 2** Installing VirtualBox + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0107215473.png) + +3. Select the VirtualBox installation path and click *Next*. + + **Figure 3** Selecting an installation path + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0107215475.png) + +4. Personalize the settings and click *Next*. + + **Figure 4** Personalized settings + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0107215477.png) + +5. Click *Finish*. + +## Creating a VM and Installing an OS + +### Creating an Empty VM + +1. Open VirtualBox and click *New*. In the displayed *Create Virtual Machine* dialog box, enter a VM name, select an OS type and version, and click *Next*. + + Take Ubuntu as an example. The type must be **Linux**. Ensure that the selected version is the same as that of the OS you want to install on the VM. + + **Figure 1** Creating a VM + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0268280658.png) + +2. In the *Memory size* dialog box, set a value and click *Next*. + + You can reference the VM specifications or official OS requirements. The minimum value is 256 MB. You can set the memory size to 512 MB as an example. + + **Figure 2** Setting the memory size + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0268284967.png) + +3. In the *Hard disk* dialog box, select *Create a virtual hard disk now* and click *Create*. + + **Figure 3** Creating a virtual hard disk + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0268287010.png) + +4. In the *Hard disk file type* dialog box, select *VHD* and click *Next*. + + **Figure 4** Setting the hard disk file type + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0268287244.png) + +5. In the *Storage on physical hard disk* dialog box, select *Dynamically allocated* and click *Next*. + + **Figure 5** Selecting the disk allocation mode + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0268288436.png) + +6. In the *File location and size* dialog box, set the disk size and storage location. + + For example, you can set the disk size to 20 GB. + + **Figure 6** Setting the disk location and size + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0268290676.png) + +7. Click *Create*. + +### Installing a Linux OS on the VM + +The procedure varies depending on the image file you use. This section uses Ubuntu 20.04 as an example to describe how to install a Linux OS on the VM. + +:::note +Make sure you have obtained the ISO image file of your target OS, for example, **Ubuntu-20.04-server.iso**. +::: + +Use the ISO file to install Linux for the empty VM. + +1. In VirtualBox Manager, select the new VM and click *Settings*. + + **Figure 1** Setting the VM + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0268393798.png) + +2. Choose *Storage* -> *Empty*, click ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0268393752.png) in the *Attributes* area, and select the ISO image file **Ubuntu-20.04-server.iso**. + + **Figure 2** Selecting the ISO file to be mounted + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0268393846.png) + + **Figure 3** Mounted ISO file + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001457709502.png) + +3. Click *OK*. +4. In VirtualBox Manager, select the new VM and click *Start*. + + **Figure 4** Starting the VM + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0268337032.png) + +5. Install the OS. + 1. Select *English* and press *Enter*. + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514305585.png) + + 2. Select *Continue without updating*. + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464149800.png) + + 3. Retain the default settings for the keyboard. Select *Done* + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514311097.png) + + 4. Retain the default settings for the installation base. Select *Done*. + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514670405.png) + + 5. Retain the default settings for the network. Select *Done*. + + The installation program will automatically identify the IP address. If the network cannot be found, the installation program can still continue and you can configure the network again after the installation is complete. + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001463836772.png) + + 6. Retain the default settings for the proxy. Select *Done*. + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514558429.png) + + 7. Retain the default settings for the software source. Select *Done*. + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001463840256.png) + + 8. Retain the default settings for disk partitioning (use an entire disk and set up this disk as an LVM group). Select *Done*. + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514561077.png) + + The file system information will be displayed. Check it and select *Done*. + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001463841764.png) + + Confirm the destructive action and select *Continue*. + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514681605.png) + + 9. Configure the server name, username, and password. Select *Done*. + + **Your name**: It is not a username for logging in to the server. You can consider it as server description. + + **Your Server's name**: It is a unique server name on the same network. The name cannot contain uppercase letters. + + **Pick a username**: It is a username for logging in to the server. If you forget it or its password, you will not be allowed to log in to the server. + + **Choose a password**: It is the password for logging in to the server. + + **Confirm your password**: Enter your password again. + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464161876.png) + + 10. Install SSH so that you can remotely connect to the Linux server. + + Select *Install OpenSSH server*. Then, press *TAB* to select *Done*. + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514587325.png) + + 11. Select *Done* to start the OS installation. + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464002560.png) + + 12. After the installation is complete, select *Reboot* to restart the system. + + ![](/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464031938.png) + +## Configuring the VM + +### Installing Drivers and Changing the Disk Identifiers to the UUID Format + +To ensure that the ECSs created from the image support both Xen and KVM virtualization, install Native Xen and KVM drivers and change the disk identifiers to the UUID format for the VM which is used as the image source. + +This section describes how to perform these operations on a Linux VM that runs Ubuntu 20.04. For other OSs, see [Optimization Process (Linux)](https://docs.otc.t-systems.com/image-management-service/umn/managing_private_images/optimizing_a_linux_private_image/optimization_process.html). + +1. Run the following command to open the **modules** file: + + **vi /etc/initramfs-tools/modules** + +2. Press *i* to enter the editing mode and add the native Xen (xen-pv) and KVM (virtio) drivers to the **/etc/initramfs-tools/modules** file (the format depends on the OS requirements). + + ```shell + [root@CTU10000xxxxx ~]#vi /etc/initramfs-tools/modules + ... + # Examples: + # + # raid1 + # sd_mOd + xen-blkfront + xen-netfront + virtio_blk + virtio_scsi + virtio_net + virtio_pci + virtio_ring + virtio + ``` + +3. Press *ESC*, enter **:wq**, and press *Enter* to save the settings and exit the vi editor. +4. Run the following command to generate initrd again: + + ```shell + update-initramfs -u + ``` + +5. Run the following commands to check whether native Xen and KVM drivers have been installed: + + ```shell + lsinitramfs /boot/initrd.img-\`uname -r\` |grep xen + + lsinitramfs /boot/initrd.img-\`uname -r\` |grep virtio + ``` + + ```shell + [root@ CTU10000xxxxx home]# lsinitramfs /boot/initrd.img-`uname -r` |grep xen + lib/modules/3.5.0-23-generic/kernel/drivers/net/ethernet/qlogic/netxen + lib/modules/3.5.0-23-generic/kernel/drivers/net/ethernet/qlogic/netxen/netxen_nic.ko + lib/modules/3.5.0-23-generic/kernel/drivers/net/xen-netback + lib/modules/3.5.0-23-generic/kernel/drivers/net/xen-netback/xen-netback.ko + lib/modules/3.5.0-23-generic/kernel/drivers/block/xen-blkback + lib/modules/3.5.0-23-generic/kernel/drivers/block/xen-blkback/xen-blkback.ko + + [root@ CTU10000xxxxx home]# lsinitramfs /boot/initrd.img-`uname -r` |grep virtio + lib/modules/3.5.0-23-generic/kernel/drivers/scsi/virtio_scsi.ko + ``` + + :::note + If you add built-in drivers to the initrd or initramfs file, the VM will not be affected. This makes it easy to modify the drivers. However, the drivers cannot be shown by running the lsinitrd command. You can run the following commands to check whether the drivers are built-in ones in the kernel: + + ```shell + [root@ CTU10000xxxxx home]# cat /boot/config-`uname -r` | grep CONFIG_VIRTIO | grep y + CONFIG_VIRTIO_BLK=y + CONFIG_VIRTIO_NET=y + CONFIG_VIRTIO=y + CONFIG_VIRTIO_RING=y + CONFIG_VIRTIO_PCI=y + CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y + [root@ CTU10000xxxxx home]# cat /boot/config-`uname -r` | grep CONFIG_XEN | grep y + CONFIG_XEN_BLKDEV_FRONTEND=y + CONFIG_XEN_NETDEV_FRONTEND=y + ``` + ::: + +### Changing the Disk Identifier in the GRUB Configuration File to the UUID Format + +Take Ubuntu 20.04 as an example. Run **blkid** to obtain the UUID of the root partition. Modify the **/boot/grub/grub.cfg** file and use the UUID of the root partition to configure the boot item. If the root partition already uses UUID, no modification is required. The procedure is as follows: + +1. Log in to the newly created VM as user **root**. +2. Run the following command to query all types of mounted file systems and their device UUIDs: + + ```shell + blkid + ``` + + The following information is displayed: + + ```shell + /dev/xvda1: UUID="ec51d860-34bf-4374-ad46-a0c3e337fd34" TYPE="ext3" + /dev/xvda5: UUID="7a44a9ce-9281-4740-b95f-c8de33ae5c11" TYPE="swap" + ``` + +3. Run the following command to query the **grub.cfg** file: + + ```shell + cat /boot/grub/grub.****cfg + ``` + + The following information is displayed: + + ```shell + ......menuentry 'Ubuntu Linux, with Linux 3.13.0-24-generic' --class ubuntu --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.13.0-24-generic-advanced-ec51d860-34bf-4374-ad46-a0c3e337fd34' { + recordfail + load_video + gfxmode $linux_gfx_mode + insmod gzio + insmod part_msdos + insmod ext2 + if [ x$feature_platform_search_hint = xy ]; then + search --no-floppy --fs-uuid --set=root ec51d860-34bf-4374-ad46-a0c3e337fd34 + else + search --no-floppy --fs-uuid --set=root ec51d860-34bf-4374-ad46-a0c3e337fd34 + fi + echo 'Loading Linux 3.13.0-24-generic ...' + linux /boot/vmlinuz-3.13.0-24-generic root=/dev/xvda1 ro + echo 'Loading initial ramdisk ...' + initrd /boot/initrd.img-3.13.0-24-generic + } + ``` + +4. Check whether the **/boot/grub/grub.cfg** configuration file contains **root=/dev/xvda1** or **root=UUID=ec51d860-34bf-4374-ad46-a0c3e337fd34**. + * If **root=UUID=ec51d860-34bf-4374-ad46-a0c3e337fd34** is contained, the root partition is in the UUID format and no further action is required. + * If **root=/dev/xvda1** is contained, the root partition is represented by a device name. Go to step 5. + +5. Obtain the UUID of the root partition based on **root=/dev/xvda1** and information obtained by running the **blkid** command. +6. Run the following command to open the **grub.cfg** file: + + ```shell + vi /boot/grub/grub.cfg + ``` + +7. Press *i* to enter the editing mode. Change the identifier of the root partition to the UUID format. For example, change **root=/dev/xvda1** to **root=UUID=ec51d860-34bf-4374-ad46-a0c3e337fd34**. +8. Press *ESC*, enter **:wq**, and press *Enter* to save the settings and exit the vi editor. +9. Run the following command to verify the change: + + ```shell + cat /boot/grub/grub.cfg + ``` + + The change is successful if information similar to the following is displayed: + + ```shell + ......menuentry 'Ubuntu Linux, with Linux 3.13.0-24-generic' --class ubuntu --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.13.0-24-generic-advanced-ec51d860-34bf-4374-ad46-a0c3e337fd34' { + recordfail + load_video + gfxmode $linux_gfx_mode + insmod gzio + insmod part_msdos + insmod ext2 + if [ x$feature_platform_search_hint = xy ]; then + search --no-floppy --fs-uuid --set=root ec51d860-34bf-4374-ad46-a0c3e337fd34 + else + search --no-floppy --fs-uuid --set=root ec51d860-34bf-4374-ad46-a0c3e337fd34 + fi + echo 'Loading Linux 3.13.0-24-generic ...' + linux /boot/vmlinuz-3.13.0-24-generic root=UUID=ec51d860-34bf-4374-ad46-a0c3e337fd34 ro + echo 'Loading initial ramdisk ...' + initrd /boot/initrd.img-3.13.0-24-generic + } + ``` + +### Changing the Disk Identifiers in the fstab File to the UUID Format + +Take Ubuntu 20.04 as an example. Run **blkid** to obtain the UUIDs of all partitions. Modify the **/etc/fstab** file and use the partition UUIDs to configure automatic partition mounting. + +1. Run the following command to query all types of mounted file systems and their device UUIDs: + + ```shell + blkid + ``` + + The following information is displayed: + + ```shell + /dev/xvda2: UUID="4eb40294-4c6f-4384-bbb6-b8795bbb1130" TYPE="xfs" + /dev/xvda1: UUID="2de37c6b-2648-43b4-a4f5-40162154e135" TYPE="swap" + ``` + +2. Run the following command to query the **fstab** file: + + ```shell + cat /etc/fstab + ``` + + The following information is displayed: + + ```shell + [root@CTU1000028010 ~]# cat /etc/fstab + /dev/xvda2 / xfs defaults 0 0 + /dev/xvda1 swap swap defaults 0 0 + ``` + +3. Check whether the disk identifiers in the **fstab** file are device names or UUIDs. + * If they are UUIDs, no further action is required. + * If they are device names, go to step 4. +4. Run the following command to open the **fstab** file: + + ```shell + vi /etc/fstab + ``` + +5. Press *i* to enter the editing mode and change the disk identifiers to the UUID format. +6. Press *ESC*, enter **:wq**, and press *Enter* to save the settings and exit the vi editor. + +### Installing Cloud-Init + +:::note +For more information on cloud-init check this [link](https://docs.otc.t-systems.com/image-management-service/umn/linux_operations/installing_cloud-init.html). +::: + +### Configuring Cloud-Init + +:::note +For more information on cloud-init check this [link](https://docs.otc.t-systems.com/image-management-service/umn/linux_operations/configuring_cloud-init.html). +::: + +### Configuring NetworkManager + +Linux allows you to use **NetworkManager** to automatically configure the VM network. You are advised to use NetworkManager for new OS versions. + +Alternatively, you can use the native network management service of the OS. + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + + + 1. Run the following command to install NetworkManager: + + ```shell + yum install NetworkManager + ``` + + 2. Delete **ifcfg-eth1** to **ifcfg-eth11** from the **/etc/sysconfig/network-scripts/** directory and retain only **ifcfg-eth0**. + 3. Run the following command to disable the network: + + ```shell + service network stop + ``` + 4. Run the following command to disable automatic startup of the network: + + ```shell + chkconfig network off + ``` + + 5. Run the following commands to restart messagebus and NetworkManager and enable NetworkManager to start automatically at startup: + + ```shell + service messagebus restart + service NetworkManager restart + chkconfig NetworkManager on + ``` + + + Install NetworkManager and use it for automatic network configuration. + 1. Run the following command to install NetworkManager: + + ```shell + apt-get install network-manager + ``` + + 2. Change the value of **managed** in the **/etc/NetworkManager/NetworkManager.conf** file to **true**. + 3. Modify **/etc/network/interfaces** and retain only **eth0**. + 4. Run the following commands to disable the network, restart messagebus and NetworkManager, and enable NetworkManager to start automatically at startup: + + ```shell + service network-manager restart + chkconfig network-manager on + service networking stop + service messagebus restart + service network-manager restart + ``` + + + + Install NetworkManager and use it for automatic network configuration. + + 1. Run the following command to install NetworkManager: + + ```shell + apt-get install network-manager + ``` + + 2. Change the value of **managed** in the **/etc/NetworkManager/NetworkManager.conf** file to **true**. + 3. Modify **/etc/network/interfaces** and retain only **eth0**. + 4. Run the following command to disable the network: + + ```shell + service networking stop + ``` + 5. Run the following command to disable automatic startup of the network: + + ```shell + chkconfig network off + ``` + 6. Run the following commands to restart D-Bus and NetworkManager: + + ```shell + service dbus restart + service network-manager restart + ``` + + + + Install NetworkManager and use it for automatic network configuration. + + 1. Delete **ifcfg-eth1** to **ifcfg-eth11** from the **/etc/sysconfig/network-scripts/** directory and retain only **ifcfg-eth0**. + 2. Run the following command to install NetworkManager: + + ```shell + zypper install NetworkManager + ``` + 3. Start YaST, choose **Network Devices** in the navigation pane on the left, and select **Network Settings** in the right pane. In the **Network Setup Method** area of the **Global Options** page, change **Traditional Method with ifup** to **User Controlled with NetworkManager**. + + + + +## Obtaining the Image File + +After the VM is configured, perform the following operations to generate and export a Linux image file: + +1. Open VirtualBox, select the VM, choose *Settings* -> *Storage*, and select **Linux.vhd**. +2. On the right pane, view the image file location. +3. Go to the location to obtain the generated **Linux.vhd** image file. + +## Registering the Image File as a Private Image + +Upload the image file to an OBS bucket and register it as a private image. + +:::important +* Only an unencrypted image file or an image file encrypted using SSE-KMS can be uploaded to an OBS bucket. +* When uploading an image file, you must select an OBS bucket with the storage class of Standard. +::: + +1. Use OBS Browser+ to upload the image file. For details, see [OBS Browser+ Best Practices](https://docs.otc.t-systems.com/object-storage-service/tool-guide/best_practices/index.html). + + For how to download OBS Browser+, see [https://docs.otc.t-systems.com/object-storage-service/tool-guide/downloading_obs_browser.html](https://docs.otc.t-systems.com/object-storage-service/tool-guide/downloading_obs_browser.html). + +2. Register the external image file as a private image. For details, see [Registering an Image File as a Private Image (Linux)](https://docs.otc.t-systems.com/image-management-service/umn/creating_a_private_image/creating_a_linux_system_disk_image_from_an_external_image_file/registering_an_external_image_file_as_a_private_image.html). diff --git a/docs/best-practices/containers/cloud-container-engine/issue-an-acme-certificate-with-dns01-solver-in-cce.md b/docs/best-practices/containers/cloud-container-engine/issue-an-acme-certificate-with-dns01-solver-in-cce.md new file mode 100644 index 000000000..6ee8866bd --- /dev/null +++ b/docs/best-practices/containers/cloud-container-engine/issue-an-acme-certificate-with-dns01-solver-in-cce.md @@ -0,0 +1,242 @@ +--- +id: issue-an-acme-certificate-with-dns01-solver-in-cce +title: Issue an ACME Certificate with DNS01 Solver in CCE +tags: [cce, acme, lets-encrypt, certificates, cert-manager, dns-solver, cert-manager-webhook-opentelekomcloud] +--- + +# Issue an ACME Certificate with DNS01 Solver in CCE + +A DNS01 challenge is a type of challenge used in the Domain Name System (DNS) to verify ownership of a domain during the process of obtaining an SSL/TLS certificate, often through services like Let's Encrypt. + +When you request a certificate, the Certificate Authority (CA) needs to ensure that you have control over the domain for which you're requesting the certificate. The DNS01 challenge is one of the methods used to prove this control. Here's how it generally works: + +1. **Challenge Issuance**: The CA provides you with a unique token (a random string of characters) that needs to be added to your domain's DNS records. + +2. **DNS Record Addition**: You must create a specific DNS TXT record for your domain that includes the token provided by the CA. This record usually follows a format like `_acme-challenge.example.com` with a value corresponding to the token. + +3. **Verification**: Once you've added the TXT record to your domain's DNS configuration, the CA will query your domain's DNS records to look for the TXT record. If it finds the correct token, it confirms that you control the domain. + +4. **Certificate Issuance**: After successful verification, the CA will issue the SSL/TLS certificate. + +The DNS01 challenge is commonly used because it allows for domain validation without needing to serve files over HTTP, which can be advantageous in certain situations, such as when you don't have a web server configured or when you're managing multiple subdomains. + +One of the tools, that can be employed in the context of Kubernetes, to secure certificates from a Certificate Authority (CA) via the ACME protocol using the the DNS01 challenge, is [cert-manager](https://cert-manager.io). Specifically for Open Telekom Cloud, we can use an additional webhook that acts as an ACME DNS01 solver for Open Telekom Cloud's Domain Name Service, [cert-manager-webhook-opentelekomcloud](https://github.com/akyriako/cert-manager-webhook-opentelekomcloud). + +## Prerequisites + +Only prerequisite is cert-manager. If you don't have it already installed on your CCE Cluster, this can be very easily done using a Helm Chart: + +```shell +helm repo add jetstack https://charts.jetstack.io +helm repo update + +helm install \ + cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --version v1.15.3 \ + --set crds.enabled=true +``` + +## Installing the ACME DNS01 Solver + +**cert-manager-webhook-opentelekomcloud** is an ACME DNS01 solver webhook for Open Telekom Cloud DNS written in Golang, and requires **cert-manager** to be installed first. + +### Acquiring Access/Secret Keys + +In the console, go to *My Credentials* -> *Access Keys* and either pick up an existing pair or create a new one: + +![alt text](<../../../../static/img/docs/best-practices/containers/cloud-container-engine/Screenshot from 2024-09-07 11-33-33.png>) + +Export this pair as environment variables: + +```shell +export OS_ACCESS_KEY={value} +export OS_SECRET_KEY={value} +``` + +### Installing the Helm Chart + +```shell +helm repo add cert-manager-webhook-opentelekomcloud https://akyriako.github.io/cert-manager-webhook-opentelekomcloud/ +helm repo update + +helm upgrade --install \ + acme-dns cert-manager-webhook-opentelekomcloud/cert-manager-webhook-opentelekomcloud \ + --set opentelekomcloud.accessKey=$OS_ACCESS_KEY \ + --set opentelekomcloud.secretKey=$OS_SECRET_KEY \ + --namespace cert-manager +``` + +## Installing Cluster Issuers + +You are going to need one `ClusterIssuer` for the *production* and one for the *staging* Let's Encrypt endpoint. + +:::warning +**cert-manager** has a known bug, that prevents custom webhooks to work with an `Issuer`. For that reason you need to install your issuer as `ClusterIssuer`. +::: + +### For Staging + +Create and deploy the following manifest: + +```yaml title="opentelekomcloud-letsencrypt-staging.yaml" +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: opentelekomcloud-letsencrypt-staging + namespace: cert-manager +spec: + acme: + email: user@company.com + server: https://acme-staging-v02.api.letsencrypt.org/directory + privateKeySecretRef: + name: opentelekomcloud-letsencrypt-staging-tls-key + solvers: + - dns01: + webhook: + groupName: acme.opentelekomcloud.com + solverName: opentelekomcloud + config: + region: "eu-de" + accessKeySecretRef: + name: cert-manager-webhook-opentelekomcloud-creds + key: accessKey + secretKeySecretRef: + name: cert-manager-webhook-opentelekomcloud-creds + key: secretKey +``` + +:::note +Replace placeholder **email** value, `user@company.com`, with the email that will be used for requesting certificates from Let's Encrypt. +::: + +```shell +kubectl apply -f opentelekomcloud-letsencrypt-staging.yaml +``` + +### For Production + +```yaml title="opentelekomcloud-letsencrypt.yaml" +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: opentelekomcloud-letsencrypt + namespace: cert-manager +spec: + acme: + email: user@company.com + server: https://acme-v02.api.letsencrypt.org/directory + privateKeySecretRef: + name: opentelekomcloud-letsencrypt-tls-key + solvers: + - dns01: + webhook: + groupName: acme.opentelekomcloud.com + solverName: opentelekomcloud + config: + region: "eu-de" + accessKeySecretRef: + name: cert-manager-webhook-opentelekomcloud-creds + key: accessKey + secretKeySecretRef: + name: cert-manager-webhook-opentelekomcloud-creds + key: secretKey +``` + +:::note +Replace placeholder **email** value, `user@company.com`, with the email that will be used for requesting certificates from Let's Encrypt. +::: + +```shell +kubectl apply -f opentelekomcloud-letsencrypt.yaml +``` + +## Requesting a Certificate + +Create and deploy the following manifest: + +```yaml title="certificate-subdomain-example-com" +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: certificate-subdomain-example-com +spec: + dnsNames: + - '*.subdomain.example.com' + issuerRef: + kind: ClusterIssuer + name: opentelekomcloud-letsencrypt-staging + secretName: certificate-subdomain-example-com-tls +``` + +:::note +Replace placeholder DNS name `*.subdomain.example.com`, with one that you own and will be used to request a certificate from Let's Encrypt. +::: + +```shell +kubectl apply -f certificate-subdomain-example-com +``` + +:::warning +Using the *staging* endpoint of Let's Encrypt before moving to the *production* endpoint is a best practice. Let's Encrypt imposes rate limits on the number of certificates you can request in a given period to prevent abuse. By testing with the staging environment, you avoid hitting these limits during your development and testing phases. +::: + +## Exposing a workload with Ingress + +Create and deploy the following manifest: + +```yaml title="workload-ingress.yaml" +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: workload-ingress + labels: + app: workload + annotations: + kubernetes.io/elb.class: union + kubernetes.io/elb.id: "{value}" + kubernetes.io/elb.port: 443 +spec: + ingressClassName: cce + tls: + - hosts: + - subdomain.example.com + secretName: certificate-subdomain-example-com-tls + rules: + - host: subdomain.example.com + http: + paths: + - backend: + service: + name: workload-svc + port: + number: 80 + path: / + pathType: ImplementationSpecific +``` + +:::note +You need to have: + +- a *workload* installed in your CCE Cluster (you can experiment with **traefik/whoami**) +- this workload exposed with a `Service`, *workload-svc*, of type `NodePort` +- a Shared Elastic Load Balancer + +::: + +| Parameter | Value | +| ----------------------- | ---------------------------------------------------------------------------- | +| kubernetes.io/elb.class | `union`, if it is a Shared Elastic Load Balancer | +| kubernetes.io/elb.id | Replace placeholder value `{value}` with the ID of the Elastic Load Balancer | +| kubernetes.io/elb.port | 443 | +| ingressClassName | `cce` | +| tls.hosts[0] | Replace placeholder value `subdomain.example.com` with your own | +| tls.secretName | Use the name of the `Secret` that was created from `Certificate` | +| rules.host[0] | Replace placeholder value `subdomain.example.com` with your own | + +```shell +kubectl apply -f workload-ingress.yaml +``` + +If you visit in your browser the address https://subdomain.example.com you will notice that the endpoint is served in HTTPS and is secured by a valid certificate. diff --git a/docs/best-practices/databases/document-database-service/how-do-replica-sets-achieve-high-availability-and-readwrite-splitting.md b/docs/best-practices/databases/document-database-service/how-do-replica-sets-achieve-high-availability-and-readwrite-splitting.md new file mode 100644 index 000000000..7849bcef6 --- /dev/null +++ b/docs/best-practices/databases/document-database-service/how-do-replica-sets-achieve-high-availability-and-readwrite-splitting.md @@ -0,0 +1,84 @@ +--- +id: how-do-replica-sets-achieve-high-availability-and-readwrite-splitting +title: How Do Replica Sets Achieve High Availability and Read/Write Splitting? +tags: [dds, migration, mongodb] +--- + +# How Do Replica Sets Achieve High Availability and Read/Write Splitting? + +DDS replica set instances can store multiple duplicates to ensure data high availability and support the automatic switch of private IP addresses to ensure service high availability. To enhance the read and write performance of your client for connecting to the instance, you can use your client to read different data copies. You need to connect to replica set instances using HA connection addresses. You can also configure read/write splitting. Otherwise, the high availability and high read performance of replica set instances cannot be guaranteed. + +The primary node of a replica set instance is not fixed. If the instance settings are changed, or the primary node fails, or primary and secondary nodes are switched, a new primary node will be elected and the previous one becomes a secondary node. The following figure shows the process of a switchover. + +![**Figure 1** Primary/Secondary switchover](/img/docs/best-practices/databases/document-database-service/en-us_image_0000001166068694.png) + +## Connecting to a Replica Set Instance (HA) + +A DDS replica set consists of the primary, secondary, and hidden nodes. The hidden node is invisible to users. Read/Write splitting and HA can be realized only when you connect to the IP addresses and ports of the primary and secondary nodes of the replica set at the same time (in HA mode). + +The following describes how to use URL and Java to connect to an instance in HA mode. + +### Method 1: Using a URL + +On the *Instances* page, click the instance name. The *Basic Information* page is displayed. Choose *Connections*. Click the *Private Connection* tab and obtain the connection address of the current instance from the *Private HA Connection Address* field. + +![**Figure 2** Obtaining the private HA connection address](/img/docs/best-practices/databases/document-database-service/en-us_image_0000001210912526.png) + +Example: + +```shell +mongodb://rwuser:\*\*\*\*@**_192.168.0.148:8635,192.168.0.96:8635_**/test?authSource=admin&replicaSet=replica +``` + +In the preceding URL, `192.168.0.148:8635` and `192.168.0.96:8635` are the IP addresses and ports of the primary and secondary nodes, respectively. If you use this address, the connection between your client and the instance can be ensured even when a primary/standby switchover occurs. In addition, using multiple IP addresses and port numbers can enhance the read and write performance of the entire database. + +![**Figure 3** Data read and write process ](/img/docs/best-practices/databases/document-database-service/en-us_image_0000001211264689.png) + +### Method 2: Using a Java Driver + +Sample code: + +```java +MongoClientURI connectionString = new MongoClientURI("mongodb://rwuser:****@192.168.0.148:8635,192.168.0.96:8635/test?authSource=admin&replicaSet=replica"); MongoClient client = new MongoClient(connectionString); +MongoDatabase database = client.getDatabase("test"); +MongoCollection collection = database.getCollection("mycoll"); +``` + +| Parameter | Description | +| :----------------------------------- | :---------------------------------------------------------------------------------- | +| rwuser:**** | Username and password for starting authentication | +| 192.168.0.148:8635,192.168.0.96:8635 | IP addresses and ports of the primary and secondary nodes in a replica set instance | +| test | Name of the database to be connected | +| authSource=admin | Database username for authentication | +| replicaSet=replica | Name of the replica set instance type | + +**Table 1**" Parameter description + +## Connecting to a Replica Set Instance + +:::warning +This is not recommended! +::: + +Using the Connection Address: + +```shell +mongodb://rwuser:\*\*\*\*@**_192.168.0.148:8635_**/test?authSource=admin&replicaSet=replica +``` + +In the preceding URL, `192.168.0.148:8635` is the IP address and port number of the current primary node. If a switchover occurs or the primary node is changed, the client fails to connect to the replica set instance because the IP address and port of the newly elected primary node is unknown. As a result, the database service becomes unavailable. In addition, read and write operations can only be performed on a fixed primary node, so the read and write performance cannot be improved by adding nodes. + +![**Figure 4** Data read and write process](/img/docs/best-practices/databases/document-database-service/en-us_image_0000001117852888.png) + +## Read/Write Splitting + +The following HA connection address is used as an example to describe how to connect to a DDS replica set instance: + +```shell +mongodb://rwuser:@192.168.xx.xx:8635,192.168.xx.xx:8635/test? +authSource=admin&replicaSet=replica&readPreference=secondaryPreferred +``` + +The database account is `rwuser`, and the database is `admin`. + +After the DB instance is connected, read requests are preferentially sent to the secondary node to implement read/write splitting. If the relationship between the primary and secondary nodes changes, write operations are automatically switched to the new primary node to ensure high availability of DDS. \ No newline at end of file diff --git a/docs/best-practices/index.md b/docs/best-practices/index.md deleted file mode 100644 index e6db7a5dd..000000000 --- a/docs/best-practices/index.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -id: best-practices -title: Best Practices ---- - -# Best Practices - -Welcome to the Open Telekom Cloud Architecture Center Best Practices. -Here we provide crucial guidelines for optimizing cloud-based solutions with emphasis to architectural principles that -enhance reliability, scalability, and security. Explore our recommended strategies for resource management, such as -efficient utilization of compute and storage resources. Gain insights into designing for high availability and fault tolerance -to ensure robust system performance. This section serves as a valuable resource for architects and developers -to implement cloud solutions that align with industry best practices and maximize the benefits of the public cloud -infrastructure. diff --git a/docs/best-practices/index.mdx b/docs/best-practices/index.mdx new file mode 100644 index 000000000..f08808928 --- /dev/null +++ b/docs/best-practices/index.mdx @@ -0,0 +1,88 @@ +--- +id: best-practices +title: Best Practices +--- + +import BestPractices from '@site/src/components/ServiceCallouts'; +import ApplicationServices from '@site/src/components/ServiceCallouts/ApplicationServices'; +import DataAnalysisServices from '@site/src/components/ServiceCallouts/DataAnalysisServices'; +import ComputingServices from '@site/src/components/ServiceCallouts/ComputingServices'; +import ContainerServices from '@site/src/components/ServiceCallouts/ContainerServices'; +import DatabaseServices from '@site/src/components/ServiceCallouts/DatabaseServices'; +import ManagementServices from '@site/src/components/ServiceCallouts/ManagementServices'; +import NetworkingServices from '@site/src/components/ServiceCallouts/NetworkingServices'; +import SecurityServices from '@site/src/components/ServiceCallouts/SecurityServices'; +import StorageServices from '@site/src/components/ServiceCallouts/StorageServices'; +import clsx from 'clsx'; +import Heading from '@theme/Heading'; +import styles from './styles.module.css'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Best Practices + + Welcome to the Open Telekom Cloud Architecture Center Best Practices. + Here we provide crucial guidelines for optimizing cloud-based solutions with emphasis to architectural principles that + enhance reliability, scalability, and security. Explore our recommended strategies for resource management, such as + efficient utilization of compute and storage resources. Gain insights into designing for high availability and fault tolerance + to ensure robust system performance. This section serves as a valuable resource for architects and developers + to implement cloud solutions that align with industry best practices and maximize the benefits of the public cloud + infrastructure. + + + +
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+
+ + \ No newline at end of file diff --git a/docs/best-practices/networking/virtual-private-network/connecting-multiple-on-premises-branch-networks-through-a-vpn-hub.md b/docs/best-practices/networking/virtual-private-network/connecting-multiple-on-premises-branch-networks-through-a-vpn-hub.md new file mode 100644 index 000000000..bdb26b5ed --- /dev/null +++ b/docs/best-practices/networking/virtual-private-network/connecting-multiple-on-premises-branch-networks-through-a-vpn-hub.md @@ -0,0 +1,317 @@ +--- +id: connecting-multiple-on-premises-branch-networks-through-a-vpn-hub +title: Connecting Multiple On-Premises Branch Networks Through a VPN Hub +tags: [vpn, hybrid, networking] +--- + +# Connecting Multiple On-Premises Branch Networks Through a VPN Hub + +To meet service requirements, enterprise A needs to implement communication between its two on-premises data centers. + +## Solution Design + +[Figure 1](#figure-1) shows the networking where the VPN service is used to connect the two on-premises data centers. + + + +![](/img/docs/best-practices/networking/virtual-private-network/connecting-multiple-on-premises-branch-networks-through-a-vpn-hub/en-us_image_0000001592878805.png) + +**Figure 1**: Networking diagram + +### Advantages + +* A VPN gateway on the cloud can function as a VPN hub to enable communication between on-premises branch sites. This eliminates the need to configure VPN connections between every two sites. +* A VPN gateway provides two IP addresses to establish dual independent VPN connections with each customer gateway. If one VPN connection fails, traffic can be quickly switched to the other VPN connection, ensuring reliability. + +### Limitations and Constraints + +* The local and customer subnets of the VPN gateway cannot be the same. That is, the VPC subnet and the data center subnet to be interconnected cannot be the same. +* The IKE policy, IPsec policy, and PSK of the VPN gateway must be the same as those of the customer gateway. +* The local and remote interface address configurations on the VPN gateway and customer gateway are reversed. +* The security groups associated with ECSs in the VPC permit access from and to the on-premises data center. + +## Planning Networks and Resources + +### Data Plan + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CategoryItemData
VPCSubnet that needs to access the on-premises data centers + • `192.168.0.0/24`
+ • `192.168.1.0/24` +
VPN gatewayInterconnection subnet + This subnet is used for communication between the VPN gateway and VPC. Ensure that the selected interconnection subnet has four or more assignable IP addresses.

+ `192.168.2.0/24` +
HA Mode**Active-active**
EIP + EIPs are automatically generated when you create them. By default, a VPN gateway uses two EIPs. In this example, the EIPs are as follows:

+ • Active EIP: `1.1.1.2`
+ • Active EIP 2: `2.2.2.2` +
VPN connectionTunnel interface address + This address is used by a VPN gateway to establish an IPsec tunnel with a customer gateway. At the two ends of the IPsec tunnel, the configured local and remote tunnel interface addresses must be reversed.

+ VPN connections set up with on-premises data center 1:
+ • VPN connection 1: `169.254.70.1/30`
+ • VPN connection 2: `169.254.71.1/30`

+ VPN connections set up with on-premises data center 2:
+ • VPN connection 3: `169.254.72.1/30`
+ • VPN connection 4: `169.254.73.1/30` +
On-premises data center 1Subnet that needs to access the VPC`172.16.0.0/16`
Customer gateway in on-premises data center 1Public IP address + This public IP address is assigned by a carrier. In this example, the public IP address is:

+ `1.1.1.1` +
Tunnel interface address + • VPN connection 1: `169.254.70.2/30`
+ • VPN connection 2: `169.254.71.2/30` +
On-premises data center 2Subnet that needs to access the VPC`10.10.0.0/16`
Customer gateway in on-premises data center 2Public IP address + This public IP address is assigned by a carrier. In this example, the public IP address is:

+ `2.2.2.1` +
Tunnel interface address + • VPN connection 3: `169.254.72.2/30`
+ • VPN connection 4: `169.254.73.2/30` +
IKE and IPsec policiesPSKTest@123
IKE policy + • Authentication algorithm: `SHA2-256`
+ • Encryption algorithm: `AES-128`
+ • DH algorithm: `Group 15`
+ • Version: `v2`
+ • Lifetime (s): `86400`
+ • Local ID: *IP address*
+ • Peer ID: *IP address* +
IPsec policy + • Authentication algorithm: `SHA2-256`
+ • Encryption algorithm: `AES-128`
+ • PFS: DH `Group15`
+ • Transfer protocol: `ESP`
+ • Lifetime (s): `3600` +
+ +**Table 1**: Data Plan + +## Prerequisites + +* Cloud side + * A VPC has been created. For details about how to create a VPC, see [Creating a VPC](https://docs.otc.t-systems.com/virtual-private-cloud/umn/vpc_and_subnet/vpc/creating_a_vpc.html). + * Security group rules have been configured for the VPC, and ECSs can communicate with other devices on the cloud. For details about how to configure security group rules, see [Security Group Rules](https://docs.otc.t-systems.com/virtual-private-cloud/umn/access_control/security_group/managing_security_group_rules/adding_a_security_group_rule.html). +* Data center side + * IPsec has been configured on the VPN devices in the two on-premises data centers. For details, see [Administrator Guide](https://docs.otc.t-systems.com/virtual-private-network/umn/administrator_guide/index.html). + * The remote subnets of the VPN device in on-premises data center 1 must contain the local subnet of the Open Telekom Cloud VPC and the subnet to be interconnected in on-premises data center 2. The remote subnets of the VPN device in on-premises data center 2 must contain the local subnet of the Open Telekom Cloud VPC and the subnet to be interconnected in on-premises data center 1. + +### Configuration + +Open Telekom Cloud VPNs support static routing mode, BGP routing mode, and policy-based mode. The following uses the static routing mode as an example. + +1. Configure a VPN gateway. + 1. Choose *Virtual Private Network* -> *Enterprise – VPN Gateways*, and click *Create VPN Gateway*. + 2. Set parameters as prompted. + + [Table 1](#table-1) only describes the key parameters for creating a VPN gateway. + + + + **Table 1** Description of VPN gateway parameters + | Parameter | Description | Value | + | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | + | Name | Name of a VPN gateway. | vpngw-001 | + | Network Type | Select **Public network**. | Public network | + | Associate With | Select **VPC**. If the VPN gateway is associated with an enterprise router, select **Enterprise Router**. | VPC | + | VPC | Open Telekom Cloud VPC that the on-premises data centers need to access. | vpc-001(192.168.0.0/16) | + | Local Subnet | VPC subnets that the on-premises data centers need to access. | 192.168.0.0/24,192.168.1.0/24 | + | Interconnection Subnet | This subnet is used for communication between the VPN gateway and VPC. Ensure that the selected interconnection subnet has four or more assignable IP addresses. | 192.168.2.0/24 | + | BGP ASN | BGP AS number. | 64512 | + | HA Mode | Select **Active-active**. | Active-active | + | Active EIP | EIP 1 used by the VPN gateway to access the on-premises data center. | 1.1.1.2 | + | Active EIP 2 | EIP 2 used by the VPN gateway to access the on-premises data center. | 2.2.2.2 | + + +2. Configure customer gateways. + 1. Choose *Virtual Private Network* -> *Enterprise – Customer Gateways*, and click *Create Customer Gateway*. + 2. Set parameters as prompted. + + [Table 2](#table-2) only describes the key parameters for creating a customer gateway. + + + + **Table 2** Description of customer gateway parameters + + | Parameter | Description | Value | + | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | + | Name | Name of a customer gateway. | cgw-fw1 | + | Routing Mode | Select **Static**. | Static | + | Gateway IP Address | IP address used by the customer gateway in on-premises data center 1 to communicate with the Open Telekom Cloud VPN gateway.
Ensure that UDP port 4500 is permitted on the customer gateway device in the on-premises data center. | 1.1.1.1 | + + + + 3. Repeat the preceding operations to configure the customer gateway (2.2.2.1) in on-premises data center 2. +3. Configure VPN connections between the cloud side and on-premises data center 1. + 1. Choose *Virtual Private Network* -> *Enterprise – VPN Connections*, and click *Create VPN Connection*. + 2. Set parameters for VPN connection 1 and click *Submit*. + + [Table 3](#table-3) only describes the key parameters for creating a VPN connection. + + + + **Table 3** Description of VPN connection parameters + + | Parameter | Description | Value | + | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | + | Name | Name of a VPN connection. | vpn-001 | + | VPN Gateway | VPN gateway for which the VPN connection is created. | vpngw-001 | + | Gateway IP Address | Active EIP bound to the VPN gateway. | 1.1.1.2 | + | VPN Type | Select **Static routing**. | Static routing | + | Customer Gateway | Name of a customer gateway. | cgw-fw1 | + | Customer Subnet | Subnet in on-premises data center 1 that needs to access the VPC on Open Telekom Cloud. A customer subnet cannot be included in any local subnet or any subnet of the VPC to which the VPN gateway is attached. Reserved VPC CIDR blocks such as 100.64.0.0/10 and 214.0.0.0/8 cannot be used as customer subnets. | 172.16.0.0/16 | + | Interface IP Address Assignment | Manually specify In this example, select **Manually specify**. Automatically assign | Manually specify | + | Local Tunnel Interface Address | Tunnel interface IP address configured on the VPN gateway. | 169.254.70.1 | + | Customer Tunnel Interface Address | Tunnel interface IP address configured on the customer gateway device. | 169.254.70.2 | + | Link Detection | Whether to enable route reachability detection in multi-link scenarios. When NQA is enabled, ICMP packets are sent for detection and your device needs to respond to these ICMP packets. | **NQA** enabled | + | PSK, Confirm PSK | The value must be the same as the PSK configured on the customer gateway device. | Test@123 | + | Policy Settings | The policy settings must be the same as those on the customer gateway device. | Default | + + + + 3. Create VPN connection 2. + + :::note + For VPN connection 2, you are advised to use the same parameter settings as VPN connection 1, except the parameters listed in the following table. + ::: + + + + **Table 4** Parameter settings for VPN connection 2 + + | Parameter | Description | Value | + | --------------------------------- | ------------------------------------------ | ------------ | + | Name | Name of a VPN connection. | vpn-002 | + | Gateway IP Address | Active EIP 2 bound to the VPN gateway. | 2.2.2.2 | + | Local Tunnel Interface Address | Tunnel IP address of the VPN gateway. | 169.254.71.1 | + | Customer Tunnel Interface Address | Tunnel IP address of the customer gateway. | 169.254.71.2 | + +4. Configure VPN connections between the cloud side and on-premises data center 2. + 1. Choose *Virtual Private Network* -> *Enterprise – VPN Connections*, and click *Create VPN Connection*. + 2. Set parameters for VPN connection 1 as prompted and click *Submit*. + + [Table 5](#table-5) only describes the key parameters for creating a VPN connection. + + + + **Table 5** Description of VPN connection parameters + + | Parameter | Description | Value | + | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | + | Name | Name of a VPN connection. | vpn-003 | + | VPN Gateway | VPN gateway for which the VPN connection is created. | vpngw-001 | + | Gateway IP Address | Active EIP bound to the VPN gateway. | 1.1.1.2 | + | Customer Gateway | Name of a customer gateway. | cgw-fw2 | + | VPN Type | Select **Static routing**. | Static routing | + | Customer Subnet | Subnet in on-premises data center 2 that needs to access the VPC on Open Telekom Cloud. A customer subnet cannot be included in any local subnet or any subnet of the VPC to which the VPN gateway is attached. Reserved VPC CIDR blocks such as 100.64.0.0/10 and 214.0.0.0/8 cannot be used as customer subnets. | 10.10.0.0/16 | + | Interface IP Address Assignment | **Manually specify** In this example, select Manually specify. Automatically assign | Manually specify | + | Local Tunnel Interface Address | Tunnel interface IP address configured on the VPN gateway. | 169.254.72.1 | + | Customer Tunnel Interface Address | Tunnel interface IP address configured on the customer gateway device. | 169.254.72.2 | + | Link Detection | Whether to enable route reachability detection in multi-link scenarios. When NQA is enabled, ICMP packets are sent for detection and your device needs to respond to these ICMP packets. | **NQA** enabled | + | PSK, Confirm PSK | The value must be the same as the PSK configured on the customer gateway device in on-premises data center 2. | Test@123 | + | Policy Settings | The policy settings must be the same as those configured on the customer gateway device in on-premises data center 2. | Default | + + + + 3. Create VPN connection 2. + + :::note + For VPN connection 2, you are advised to use the same parameter settings as VPN connection 1, except the parameters listed in the following table. + ::: + + + + **Table 6** Parameter settings for VPN connection 2 + + | Parameter | Description | Value | + | --------------------------------- | ----------------------------------------------------------------------- | ------------ | + | Name | Name of a VPN connection. | vpn-004 | + | Gateway IP Address | Active EIP 2 bound to the VPN gateway. | 2.2.2.2 | + | Local Tunnel Interface Address | Tunnel IP address of the VPN gateway. | 169.254.73.1 | + | Customer Tunnel Interface Address | Tunnel IP address of the customer gateway in on-premises data center 2. | 169.254.73.2 | + + +5. Configure customer gateway devices in on-premises data centers 1 and 2. + + The configuration procedures may vary according to the type of the customer gateway device. For details, see [Administrator Guide](https://docs.otc.t-systems.com/virtual-private-network/umn/administrator_guide/index.html). + + +### Verification + +* About 5 minutes later, check states of the VPN connections. + + Choose *Virtual Private Network* -> *Enterprise – VPN Connections*. The states of the four VPN connections are all *Normal*. + +* Verify that servers in on-premises data center 1 and servers in on-premises data center 2 can ping each other. + diff --git a/docs/best-practices/storage/object-storage-service/accessing-obs-through-an-nginx-reverse-proxy.md b/docs/best-practices/storage/object-storage-service/accessing-obs-through-an-nginx-reverse-proxy.md index 4e9e5ab55..d6941c790 100644 --- a/docs/best-practices/storage/object-storage-service/accessing-obs-through-an-nginx-reverse-proxy.md +++ b/docs/best-practices/storage/object-storage-service/accessing-obs-through-an-nginx-reverse-proxy.md @@ -6,8 +6,8 @@ tags: [storage, obs, reverse-proxy, nginx] # Accessing OBS Through an NGINX Reverse Proxy -Generally, you can access OBS using a bucket's access domain name [for -example](https://**bucketname**.obs.eu-de.otc.t-systems.com) +Generally, you can access OBS using a bucket's access domain name (for +example, **https://`bucketname`.obs.eu-de.otc.t-systems.com**) provided by OBS or using a user-defined domain name bound to an OBS bucket. @@ -34,11 +34,7 @@ actual domain name or IP address of OBS is hidden. proxy](/img/docs/best-practices/storage/object-storage-service/en-us_image_0273872842.png) ## Prerequisites - -- You have known the region and access domain name of the bucket. For - example, the access domain name of a bucket in the eu-de region is - `nginx-obs.obs.eu-de.otc.t-systems.com`. To obtain the - information, see [Querying Basic Information of a +- You know the region and access domain name of the bucket. For example, the access domain name of a bucket named `nginx-obs` in the **eu-de** region is `nginx-obs.obs.eu-de.otc.t-systems.com`. To obtain the information, see [Querying Basic Information of a Bucket](https://docs.otc.t-systems.com/object-storage-service/umn/obs_browser_operation_guide/managing_buckets/viewing_basic_information_of_a_bucket.html). - You have a Linux ECS **in the same region**. CentOS is used here as an example. For details, see [Creating an @@ -110,9 +106,12 @@ b. Press the *i* key to go to the edit mode and modify the | Parameter | Description | | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | server_name | IP address that provides the reverse proxy service. It is the fixed IP address that is exposed to end users for access. Enter the EIP of the ECS where the NGINX reverse proxy service is deployed. | - | proxy_pass | IP address of the proxied server. Enter the OBS bucket access domain name required in [Prerequisites](#prerequisites). The domain name must start with http:// or https://.

Example: [https://nginx-obs.obs.eu-de.otc.t-systems.com](https://nginx-obs.obs.eu-de.otc.t-systems.com) **Note**: When you use an API, SDK, or obsutil for calling, set this parameter to the region domain name. The following is an example: `obs.eu-de.otc.t-systems.com` | - | proxy_buffering | Whether to enable the proxy buffer. The value can be `on` or `off`. If this parameter is set to on, Nginx stores the response returned by the backend in a buffer and then sends the data to the client. If this parameter is set to off, Nginx sends the response to the client as soon as it receives the data from the backend. Default value: `on`

Example: `proxy_buffering off` | + | proxy_pass | IP address of the proxied server. Enter the OBS bucket access domain name required in [Prerequisites](#prerequisites). The domain name must start with http:// or https://.

Example: [https://nginx-obs.obs.eu-de.otc.t-systems.com](https://nginx-obs.obs.eu-de.otc.t-systems.com)| + | proxy_buffering | Whether to enable the proxy buffer. The value can be `on` or `off`. If this parameter is set to on, Nginx stores the response returned by the backend in a buffer and then sends the data to the client. If this parameter is set to off, Nginx sends the response to the client as soon as it receives the data from the backend. Default value: `on`

Example: `proxy_buffering off` | +:::note +When you use an API, SDK, or obsutil for calling, set **proxy_pass** to the region domain name. The following is an example: `obs.eu-de.otc.t-systems.com`. +::: c. Press the *ESC* key and enter *:wq* to save the configuration and exit. @@ -157,11 +156,107 @@ c. In the navigation pane, choose *Permissions* -> *Bucket d. Click *Create*. -e. Choose a policy configuration method you like. *Visual Editor* - is used here. +e. Choose a policy configuration method you like. *Visual Editor* is used here. + +![*Figure 3* ](/img/docs/best-practices/storage/object-storage-service/policy-visual-editor.png) f. Configure the following parameters. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Table 2 + Bucket policy parameters +
ParameterDescription
Policy NameEnter a policy name.
Policy contentEffectSelect Allow.
Principal +
    +
  • To select All accounts enter *.
  • +
+
Resources +
    +
  • + Method 1: +
      +
    • Select Entire bucket (including the objects in it).
    • +
    +
  • +
  • + Method 2: +
      +
    • Select Current bucket and Specified objects.
    • +
    • Set the resource path to * to indicate all objects in the bucket.
    • +
    +
  • +
+
Actions +
    +
  • Choose Customize.
  • +
  • Select Get* and List*.
  • +
+
Conditions (Optional) +
    +
  • Key: Select SourceIp.
  • +
  • Condition Operator: Select IpAddress
  • +
  • + Value: +
      +
    • +

      If the ECS uses a public DNS, the value is as follows:

      +

      Elastic IP address of the ECS

      +
    • +
    • +

      If the ECS uses a Open Telekom Cloud private DNS, the value is as follows:

      +

      100.64.0.0/10,214.0.0.0/7,Private IP address of the ECS

      +
    • +
    +
  • +
+
+ + +:::note +In conditions you can click **Add** to configure IP addresses (CIDR blocks). +IP addresses in the range starting with **100** or **214** are for ECSs to access OBS through an internal network. +::: + g. Click *Create*. ## Verifying the reverse proxy configuration @@ -172,5 +267,5 @@ configuration is successful. For example, visit `http://**ECS EIP**/otc.jpg`. -![*Figure 3* Using a fixed IP address to access OBS +![*Figure 4* Using a fixed IP address to access OBS resources](/img/docs/best-practices/storage/object-storage-service/en-us_image_0273876194.png) \ No newline at end of file diff --git a/docs/best-practices/styles.module.css b/docs/best-practices/styles.module.css new file mode 100644 index 000000000..2d8f36204 --- /dev/null +++ b/docs/best-practices/styles.module.css @@ -0,0 +1,28 @@ + +.item { + box-shadow: 0 1px 3px gray; + background-color: var(--ifm-background-color); + border-radius: 2rem; + color: black; + overflow: hidden; +} + +html[data-theme='dark'] .item { + box-shadow: 0px 1px 3px var(--ifm-color-primary); + background-color: var(--ifm-background-color); + border-radius: 2rem; + color: white; + overflow: hidden; +} + +.item__inner { + align-items: center; + display: flex; +} +.item__inner div { + padding: 3rem; +} +.item__title span { + display: block; + font-size: 1.25rem; +} \ No newline at end of file diff --git a/docs/blueprints/by-industry/aerospace/_category_.json b/docs/blueprints/by-industry/aerospace/_category_.json new file mode 100644 index 000000000..58f5669b5 --- /dev/null +++ b/docs/blueprints/by-industry/aerospace/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Aerospace", + "link": { + "type": "doc", + "id": "Aerospace" + } +} \ No newline at end of file diff --git a/docs/blueprints/by-industry/aerospace/cloud-satellite-data-mundi-web-services.md b/docs/blueprints/by-industry/aerospace/cloud-satellite-data-mundi-web-services.md new file mode 100644 index 000000000..c3a679130 --- /dev/null +++ b/docs/blueprints/by-industry/aerospace/cloud-satellite-data-mundi-web-services.md @@ -0,0 +1,65 @@ +--- +id: cloud-satellite-data-mundi-web-services +title: "Mundi Web Services: New Business from Space" +tags: [aerospace, by-industry, esa, geoservices] +--- + +# Mundi Web Services: New Business from Space + +The [European Space Agency's](https://www.esa.int/) (ESA) [Copernicus](https://www.esa.int/Applications/Observing_the_Earth/Copernicus) program fulfills the mandate of the European Union to place a series of sentinel earth observation satellites in orbit that transmit about 20 terabytes of images to Earth every day. By now, the previously available satellites have generated several petabytes of data, giving users inside and outside the EU new glimpses from the cosmos. This data is made accessible in a cloud-based manner via Mundi Web Services. The aim is to promote new geo-based business models. + +The EU makes its Earth observation data available free of charge with the intention of creating new business models and applications for mainly European users: from students and software providers, to large corporations and the public sector. + +[Mundi Web Services](#about-mundi-web-services) makes European satellite data accessible for new business models + +## New Geo-Based Business Models + +This brings with it a wealth of new applications in target markets such as agriculture and forestry, energy, environment, climate, insurance, and disaster control. For example, satellite observations can be used to register the use of agricultural land and, as a result, better allocate EU funds, quickly identify environmentally relevant changes, and take action as well as optimize the use of mineral and energy resources. + +Mundi Web Services is a platform on which users can directly use preconfigured geoservices. However, it also offers new geoservice providers the option of offering their services on the market. Mundi Web Services' great strength? All necessary components to implement new geo-based business ideas are already integrated. This includes constantly updated data from the Sentinel satellites as well as historical data from the American Landsat program, geoservice applications, and flexible IT resources from the Open Telekom Cloud. As the computing capacities for the evaluations and the data are on the same technical platform, tedious copying processes are no longer necessary. In addition, Mundi allows specific selection of the data that is relevant for the respective analysis. + +## Benefits for the Customer + +* Complete toolbox for easy launch of new geo-based services +* Simplification of existing processes, e.g. for claims settlement or subsidy allocation +* IT capacities as a complete service +* Usage-dependent costs for IT resources in temporary projects + +## Dynamic IT is Essential for Geoservices + +Access to the data has so far been complex, expensive, and tedious. Users always had to download complete data sets comprising several gigabytes or even terabytes from a central repository before they could start their evaluations. New potential geoservice providers with limited IT resources could not benefit from the data. The Copernicus program is also not yet very well known to the business community or the general public. + +Computing resources are the be-all and end-all for geoservices. To perform further analysis, the original data, usually images at different frequency intervals and on different technical bases (e.g. with optical, thermal or radar sensors), must first be processed - a stage referred to pre-processing. One action in this regard is to normalize images so that they can be compared with one other. In the second stage, the actual processing (which also requires a large amount of computing resources), the data prepared in this way is processed using mathematical models. This creates business-relevant results that can help decision-makers. So far, such statements have been made under the auspices of projects that were set up specifically for the respective application. + +Mundi Web Services makes using earth observation data for business purposes more professional. Geoservices "made in Europe" receive a basis on which they can develop new business models and offer them as web services on the international market. End users are given the opportunity to deploy geoservices as needed. Mundi has the right infrastructure foundation in the form of the Open Telekom Cloud. The resources from the cloud are optimal for temporary high-load calculations and adapt to the desired requirements of users. If a user wants faster results, they can speed up the evaluation with additional capacities. Depending on the speed, customers only pay for the resources that are actually used. + +## The Challenge + +* Provision of a platform for the use of geo-based services +* Integration of services, data, and usage-dependent computing/storage capacities for efficient use of satellite data +* Support of new geo-based business models "made in Europe" +* Optimization of existing processes (e.g. in administrative units) + +## The Aim: Easier Use of Satellite Data + +Mundi Web Services is the answer to these challenges. It simplifies the access and use of satellite data. Mundi Web Services is a consortium led by Atos. T-Systems is another established ICT player on-board; it adds its Open Telekom Cloud and its experience with modern ICT service models into the mix. Experienced providers from the geoservice segment, such as the Italian e-geos, the Austrian EOX, the French Thales Aliena Space, the German GAF, and the German Aerospace Center (DLR), contribute technical expertise and applications. + +## The Solution + +* Mundi Web Services as an integrated platform +* Data and computing capacity over the same infrastructure +* Open Telekom Cloud as a source for scalable IT resources +* Marketplace for geoservices + +## About Mundi Web Services + +[Mundi Web Services](https://mundiwebservices.com/) is a consortium led by Atos. The consortium works on behalf of the European Union and the European Space Agency ESA. The consortium partners are T-Systems, Thales Alenia Space, DLR, e-geos, EOX, GAF AG, Sinergise, and Spacemetric. + +## See Also + +:::info Additional Information + +* Read the whole success story [here](https://www.t-systems.com/de/en/success-stories/cloud-and-infrastructure/cloud-satellite-data-mundi-web-services). +* [Download](https://www.t-systems.com/resource/blob/13730/46910b6a621ed206cec05cf6a04c0011/DL-Flyer-C-Dias-Plattform-ESA-Mundi-t-systems-en-09-2019.pdf) our reference flyer. + +::: diff --git a/docs/blueprints/by-industry/education/index.md b/docs/blueprints/by-industry/aerospace/index.md similarity index 93% rename from docs/blueprints/by-industry/education/index.md rename to docs/blueprints/by-industry/aerospace/index.md index 6933daf72..d51430ebe 100644 --- a/docs/blueprints/by-industry/education/index.md +++ b/docs/blueprints/by-industry/aerospace/index.md @@ -1,9 +1,9 @@ --- -id: Education -title: Education +id: Aerospace +title: Aerospace --- -# Education +# Aerospace The Computing section offers essential insights for optimizing computing resources. Discover guidelines for selecting appropriate instance types, managing virtual machines efficiently, and leveraging auto-scaling capabilities for dynamic diff --git a/docs/blueprints/by-industry/automotive/_category_.json b/docs/blueprints/by-industry/automotive/_category_.json deleted file mode 100644 index 1618e3413..000000000 --- a/docs/blueprints/by-industry/automotive/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "Automotive", - "link": { - "type": "doc", - "id": "Automotive" - } -} \ No newline at end of file diff --git a/docs/blueprints/by-industry/education/_category_.json b/docs/blueprints/by-industry/education/_category_.json deleted file mode 100644 index 3171d6f5e..000000000 --- a/docs/blueprints/by-industry/education/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "Education", - "link": { - "type": "doc", - "id": "Education" - } -} \ No newline at end of file diff --git a/docs/blueprints/by-industry/finance/cloud-euvic.md b/docs/blueprints/by-industry/finance/cloud-euvic.md new file mode 100644 index 000000000..9a4b60bd2 --- /dev/null +++ b/docs/blueprints/by-industry/finance/cloud-euvic.md @@ -0,0 +1,48 @@ +--- +id: cloud-euvic +title: "EUVIC: Cloud-Based Credit Portal for SaarLB" +tags: [finance, by-industry] +--- + +# EUVIC: Cloud-Based Credit Portal for SaarLB + +The software company [EUVIC](#about-euvic-gmbh) has developed a portal which enables business customers' credit requests to be processed interactively and at a considerably faster rate. Since customer data is particularly sensitive, the renowned software company used the Open Telekom Cloud to develop and operate the credit portal. "*T-Systems' servers are located in highly secure, multi-certified data centers in Germany,*" says Daniel Piecha of EUVIC. With the cloud solution, the Landesbank meets the strict regulations of the financial supervisory authority and the European General Data Protection Regulation (GDPR). Only authorized employees of the bank have unencrypted access to the data in the system. In addition, a neutral third party company reviewed the security concept and certified the cloud solution – after a penetration test – as having a very high level of security. + +EUVIC develops customer portal for SaarLB and meets strict security requirements using the Open Telekom Cloud. + +## Benefits for the Customer + +* Server locations for the Open Telekom Cloud in Germany offer IT security and optimum data protection. As a result, the Open Telekom Cloud is widely accepted in the sensitive financial sector +* Demand-based use and payment (pay-per-use principle) +* The solution can be extended by private cloud instances (hybrid solution) +* The company can automatically launch development environments with the Cloud Container Engine (CCE) – including programming tools and scripting languages +* Open cloud base: OpenStack protects against vendor lock-in + +### Bank Relies on Solution from the Ccloud + +Banking and the cloud – for a long time they did not seem to go together. But an increasing number of financial institutions have come to see the cloud as a pioneer for flexibility, agility, and innovation. With a new B2B credit portal from the cloud, Landesbank SaarLB now wants to offer its business customers better service – and at the same time provide optimum protection for customer data. And that's why service provider EUVIC uses the Open Telekom Cloud for the portal. + +### More Agility with the Cloud + +The credit portal was ready for use in just four months. Now EUVIC is gradually expanding the credit portal with additional components. Based on Kubernetes, the Cloud Container Engine (CCE) within the Open Telekom Cloud supports them in this. "A great tool that helps us with the development, testing, operation, and maintenance of the applications," says Daniel Piecha. This enables developers to set up, deploy, cluster, and scale cloud containers automatically, quickly, and easily. + +### Innovative Thanks to OpenStack + +The OpenStack concept of T-Systems' cloud solution has also been well received by EUVIC. Daniel Piecha: "*This concept gives us access to the innovations of the global open source community.*" In addition, the open architecture protects against becoming dependent on a single provider. + +In fact, banks and savings banks prefer to process sensitive data on servers within their own company. But here too, the Open Telekom Cloud performs well – as a hybrid variant. So, EUVIC can also offer its customers hybrid scenarios in the future. The advantage: the private and public instances can be operated on identical hardware and software components. This means that all parts of the solution are fully compatible with one another – and Telekom offers the same support for all configurations. + +## About EUVIC GmbH + +[EUVIC GmbH](http://euvic.de/en/index.html) is an internationally active software development company and is always in demand when sophisticated full-stack software solutions are required. Around 1,800 specialists look after more than a thousand customers in 24 countries at present. The company based in Leverkusen offers special expertise in full-stack software development, cloud-based software solutions, mobile apps, e-commerce, and big data. + + +## See Also + +:::info Additional Information + +* Read the whole success story [here](https://www.t-systems.com/de/en/success-stories/cloud-and-infrastructure/cloud-euvic). +* [Download](https://www.t-systems.com/resource/blob/289024/fbd7957fa9892be51f94181e94475678/DL-Flyer-Sichere-Cloud-fuers-Banking-t-systems-en-10-2020.pdf) our reference flyer. + +::: + diff --git a/docs/blueprints/by-industry/finance/cloud-particulate.md b/docs/blueprints/by-industry/finance/cloud-particulate.md new file mode 100644 index 000000000..0b14ed0ea --- /dev/null +++ b/docs/blueprints/by-industry/finance/cloud-particulate.md @@ -0,0 +1,66 @@ +--- +id: cloud-particulate +title: "Particulate: Donation Platform on Open Telekom Cloud" +tags: [finance, by-industry] +--- + +# Particulate: Donation Platform on Open Telekom Cloud + +Around 5,000 people in the Rhine-Main region are already so-called “Radgeber” or cyclist donors: Together with the start-up [Particulate Solutions](#about-particulate-solutions-gmbh), Deutsche Bahn (DB) has developed the platform, which allows every cyclist participating in the campaign to become a donor. The technology for the platform is based on the Open Telekom Cloud, Telekom's public cloud offering. + +## Digital Donation Currency: Cyclists Collect SocialCoins + +When booking a rental bike via Deutsche Bahn’s Call-a-Bike app, cyclists receive 100 so-called *SocialCoins* – a fictitious donation currency created by the Koblenz-based start-up. Cyclists can distribute the SocialCoins to selected projects via the app with just a few clicks. As soon as the donation target is reached, Deutsche Bahn will transfer the amount to the project. So far, about 12,000 euros have been collected in less than three months. + +### Donation Platforms as a Marketing Tool + +The rental bike donation platform is by no means the start-up’s only project. The three founders, Stefan Pandorf, Stephanie Henn and Stefan Fink, want to combine marketing with social commitment and they plan to do so across many industries. “*We offer companies an effective marketing tool and harness the entrepreneurial potential of donations,*” says Pandorf. “*After all, social engagement and sustainability are becoming more and more important in marketing. Many customers are increasingly choosing a company that is socially engaged when purchasing a product.*” For example, a bank can attract new customers by giving them SocialCoins instead of a certain amount of funds when they open an account. On the bank's platform, the customer can redeem the coins for specific projects, such as a fundraising campaign for new jerseys for a football club or the expansion of a playground. That amount is then paid out by the bank. + +## Data Protection and Data Security as Top Priority + +All data is stored in the secure and inexpensive Object Based Storage (OBS). “*The partnership with Deutsche Telekom is always a winning argument for our customers,*” says Pandorf. “*Deutsche Telekom simply has a good reputation when it comes to data protection and data security. This helps us a lot when it comes to marketing our idea.*” And if questions ever arise about the architecture of the Open Telekom Cloud, the start-up can get in touch with a competent Deutsche Telekom contact person at any time. + +## Customer Benefits + +* The platform is always deliverable, regardless of the number of customers. +* Thanks to auto-scaling, there are always enough IT resources available. +* More than 600 requests per second are possible. +* High data protection and data security are guaranteed. +* Own servers become obsolete. +* Contact persons of the Telekom are always available. + +## Secure Data Storage in the Cloud + + +Many of Particulate's customers come from the energy or financial sector. “*That's why our customers always ask first about data protection and data security,*” says Pandorf. Initially, the Koblenz-based company worked with the German cloud provider ProfitBricks and tested the infrastructure of Amazon Web Services (AWS). But due to the high expectations of customers regarding the secure storage of their data, Particulate looked for another solution that could meet these requirements. “*In addition, we needed a solution that we could scale flexibly, for example, if the number of those accessing the platform suddenly increased sharply,*” says Pandorf. The founders got to know about the Open Telekom Cloud through Deutsche Telekom's TechBoost program. + +There are already plans to expand the platform. Particulate not only wants to extend the project with Deutsche Bahn to the whole of Germany. The start-up also wants to approach other large international companies in the future with a view to developing other donation platforms in the Open Telekom Cloud. + +## The Challenge + +* It was too expensive and inflexible to use its own servers. +* The start-up was therefore looking for a secure, flexibly scalable cloud solution for the white-label platforms. +* An important factor was the secure storage of the data. +* Particular Solutions needed flexible scalability for fluctuating traffic. +* The system should be reliable and stable. + +## The Solution + +* Particulate uses IT capacity from the Open Telekom Cloud as part of the TechBoost program. +* Open Stack provides many ready-made solutions. +* The data storage takes place in the safe and favorable Object Based Storage (OBS). +* As user access increases, the auto-scaling service automatically posts resources. + +## About Particulate Solutions GmbH + +The Koblenz-based start-up [Particulate](https://particulate.de/) and its approximately 30 employees offers companies donation platforms with their own corporate design in order to distribute donations more fairly and transparently. The solution went online in 2012. Corporate Social Responsibility has become an important factor when making a purchase decision. + +## See Also + +:::info Additional Information + +* Read the whole success story [here](https://www.t-systems.com/de/en/success-stories/cloud-and-infrastructure/particulate). +* [Download](https://www.t-systems.com/resource/blob/155260/6cc35e38595813aea929fbf1ea7b92f0/DL-Flyer-Particulate-Solution-GmbH-T-Systems-EN-06-2020.pdf) our reference flyer. + +::: + diff --git a/docs/blueprints/by-industry/government/kirchheim-unter-teck-bundesmessenger.md b/docs/blueprints/by-industry/government/kirchheim-unter-teck-bundesmessenger.md new file mode 100644 index 000000000..9942ed5ed --- /dev/null +++ b/docs/blueprints/by-industry/government/kirchheim-unter-teck-bundesmessenger.md @@ -0,0 +1,47 @@ +--- +id: kirchheim-unter-teck-bundesmessenger +title: Sovereign Digitalization for the City of Kirchheim unter Teck +tags: [government, bundesmessenger, by-industry] +--- + +# Sovereign Digitalization for the City of Kirchheim unter Teck + +The City of [Kirchheim unter Teck](#about-the-city-of-kirchheim-unter-teck) uses the [BundesMessenger](https://docs.bundesmessenger.info/de/start/overview/) from the Open Telekom Cloud. Kirchheim unter Teck has recognized the value of digitalization when it comes to mastering the challenges the city faces. With its strong focus on sovereign IT solutions, T-Systems proved to be the right partner for driving the digitalization of government administration forward in Kirchheim unter Teck. + +## BundesMessenger from Open Telekom Cloud + +### The Challenge + +* Utilize the potential of digitalization for modern, real-time communication in government +* Strict requirements for security +* The solution must be modern and satisfy sovereignty aspects + +### The Solution + +* [BundesMessenger](https://docs.bundesmessenger.info/de/start/overview/) open-source software from [BWI](https://www.bwi.de/) offers secure, encrypted communication (as a device-independent app) +* The software is offered **exclusively** to public institutions (community approach) +* T-Systems provides the BundesMessenger as SaaS from the Open Telekom Cloud +* The SaaS is enriched with managed services (including updates and new releases) +* T-Systems offers additional integration options for using internal IAM systems for user administration + +### Customer Benefits + +* Modern, real-time communication with an enhanced user experience +* Easy availability +* Maximum sovereignty and data security +* Transparent, usage-based costs + +## About the City of Kirchheim unter Teck + +[Kirchheim unter Teck](https://www.kirchheim-teck.de/3134), a county seat in the foothills of the Swabian Mountains, is part of the greater Stuttgart region. The city is home to more than 40,000 residents. It serves as a middle center to the surrounding communities. + + + +## See Also + +:::info Additional Information + +* Read the whole success story [here](https://www.t-systems.com/de/en/success-stories/cloud-and-infrastructure/kirchheim-unter-teck-bundesmessenger-from-the-open-telekom-cloud). +* [Download](https://www.t-systems.com/resource/blob/996990/1d7b18cc88658bdea4e3a96b32fc5a52/DL-Flyer-City-of-Kirchheim-Managed-BundesMessenge-T-Systems-EN-06-2024.pdf) our reference flyer. + +::: diff --git a/docs/blueprints/by-industry/healthcare/brain-plus-german-cloud-for-dementia-therapy-app.md b/docs/blueprints/by-industry/healthcare/brain-plus-german-cloud-for-dementia-therapy-app.md new file mode 100644 index 000000000..52504f6d2 --- /dev/null +++ b/docs/blueprints/by-industry/healthcare/brain-plus-german-cloud-for-dementia-therapy-app.md @@ -0,0 +1,43 @@ +--- +id: brain-plus-german-cloud-for-dementia-therapy-app +title: Open Telekom Cloud for Dementia Therapy App +tags: [healthcare, by-industry] +--- + +# Open Telekom Cloud for Dementia Therapy App + +To meet the strict guidelines for the German digital health market, the team from [Brain+](#about-brain) wanted to provide the backend for its app from a German cloud, and Brain+ chose the Open Telekom Cloud. In addition to that, with a growing focus on the UK market, Open Telekom Cloud can provide a framework allowing the team to scale to the UK and later to the rest of Europe. + + + +## The Challenge + +* Dementia therapy app, released in a first product version in Denmark and Germany +* Laying the foundations for acceptance as a digital health application (DiGA) +* Meeting data security and data protection requirements in the cloud + +## The Solution + +* Transferring the backend to the [Open Telekom Cloud](https://www.t-systems.com/de/en/cloud-services/solutions/public-cloud/open-telekom-cloud) +* Content Management System operated from the Open Telekom Cloud, using relational database service, elastic cloud server, elastic volume storage, caching, and backup +* Full scalability and compliance with regulatory framework conditions + +## Customer Benefits + +* Open Telekom Cloud enables Brain+ to expand into Germany with its offerings and tap into the market potential for dementia +* The platform allows Brain+ to deliver the services they offer in compliance with German regulatory requirements for health apps +* Open Telekom Cloud offers full scalability for further business growth, fully supporting cloud-native technologies and expansion into other markets such as the UK +* Support as an Open Telekom Cloud Circle Partner + +## About Brain+ + +Copenhagen-based scale-up [Brain+](http://www.brain-plus.com/) assists CST therapists with an in-house developed app called [CST-Therapist Companion](https://www.brain-plus.com/cst-therapist-companion-advancing/). The app is based on the latest scientific findings and supports conducting CST sessions by providing materials for exercises (from a content management system) to shorten preparation time and facilitate consistent delivery of the therapy. Furthermore, it organizes the flow of individual sessions. This app gives the therapist a comprehensive tool that manages, facilitates, and optimizes CST-based dementia therapy. + +## See Also + +:::info Additional Information + +* Read the whole success story [here](https://www.t-systems.com/de/en/success-stories/cloud-and-infrastructure/brain-plus-german-cloud-for-dementia-therapy-app). +* [Download](https://www.t-systems.com/resource/blob/700758/24b458b6be64c54cb4d3159ba0280c69/DL-Flyer-Brain-Plus-OTC-T-Systems-EN-03-2024.pdf) our reference flyer. + +::: diff --git a/docs/blueprints/by-industry/healthcare/fuse-ai-open-telekom-cloud.md b/docs/blueprints/by-industry/healthcare/fuse-ai-open-telekom-cloud.md new file mode 100644 index 000000000..27960dbce --- /dev/null +++ b/docs/blueprints/by-industry/healthcare/fuse-ai-open-telekom-cloud.md @@ -0,0 +1,59 @@ +--- +id: fuse-ai-open-telekom-cloud +title: "Fuse-AI: e-Health from the Cloud" +tags: [healthcare, by-industry, artificial-intelligence, ai] +--- + +# Fuse-AI: e-Health from the Cloud + +[Fuse-AI](#about-fuse-ai) is making medical diagnosis easier with artificial intelligence. A second opinion from the Open Telekom Cloud saves radiologists time, improves the quality of their diagnoses and reduces costs. The Hamburg-based entrepreneurs founded their start-up in 2015 and developed artificial intelligence that can detect indications of cancer – such as carcinomas – on MRI scan and assess whether a tumor is benign or malignant. And that doesn’t just save doctors time. “*The biggest advantage is the improved quality of a diagnosis,*” says Maximilian Waschka, one of the four Fuse-AI founders. “*Our algorithm helps radiologists notice abnormalities on thousands of images more reliably.*” The start-up estimates that its e-health solution can save health insurers at least 10 percent of the costs associated with MRI examinations. + +“*In the future, we will help to detect many common illnesses much more quickly, comprehensively, and reliably with the help of the Open Telekom Cloud,*" says Sabrina Reimers-Kipping, PhD biochemist and co-founder of Fuse-AI. “*Not only does this reduce the workload of the doctor and the costs for the healthcare system, it also increases the chances of recovery for the patients. Because the earlier diseases are detected, the better the chance of a recovery.*” + +## Benefits for the Customer + +* Flexibly scalable resources enable the artificial intelligence to do detailed data analysis at any time of the day.  +* Doctors and patients trust the solution thanks to the Open Telekom Cloud, which is known as a secure platform offering the highest levels of data privacy and data protection. +* With Deutsche Telekom as their partner, the founders of the start-up are able to establish a sustainable market foothold more quickly. + +## A Second Opinion Thanks to AI + +Radiologists don’t have an easy job: Each day, they have to analyze several thousand x-rays and other tomographic images. A single MRI (magnetic resonance imagery) scan creates around 2,000 pictures. A diagnosis requires the utmost concentration, from the first to final image. After all, any mistake could have life-threatening consequences. + +The founders of the start-up Fuse-AI want to ease this challenge with their innovative electronic health (e-health for short) solution. They have developed artificial intelligence that helps doctors detect cancer. “*The goal is to give radiologists a computer-assisted second opinion that makes their job easier,*” says Waschka. + +## The Challenge + +* To analyze large amounts of data from MRI scans the founders need flexibly scalable processing resources. +* The young northern German entrepreneurs searched for a provider offering secure, reliable and flexible IT capacity. + +### Cloud-Assisted Diagnosis Help + +The northern German start-up relies on IT resources from the Open Telekom Cloud for its extensive medical analysis. The MRI scans are sent encrypted via the Internet to Deutsche Telekom’s highly secure data centers in the eastern German state of Saxony-Anhalt, where they are then analyzed. The intelligent algorithm notes any abnormalities, adds metadata to the images and then sends it back to the radiologist’s computer system. The doctor can then use the notes and metadata to make a faster and more accurate diagnosis. +The four entrepreneurs submitted their idea to TechBoost, Deutsche Telekom’s program for promising start-ups with software-based business models, and were accepted. Since then, the company has benefited from €100,000 worth of IT resources from the Open Telekom Cloud. “*The Open Telekom Cloud is a wonderful instrument giving us both the flexibility and scalability necessary to realize this kind of solution,*” says Dirk Schäfer, a machine learning expert and co-founder of Fuse-AI. + +### Cloud-Assisted Skin Cancer Diagnosis + +But detecting carcinomas on MRI scans is just the beginning. Fuse-AI is already planning to expand into other solutions. The company’s founders have developed together with dermatologists a so-called digital dermatoscope to make skin cancer detection faster and more accurate. The principle is the same with MRI scans: The dermatoscope photographs the skin’s surface of a patient. An intelligent algorithm in the cloud then analyzes the images and the system alerts the physician to any abnormalities it discovers. + +## The Solution + +* The start-up now has scalable IT resources available all the time from the Open Telekom Cloud. +* The company uses certified, highly secure data centers located in Germany. +* TCDP 1.0 certification attests that the Open Telekom Cloud already conforms to the EU’s General Data Protection Regulation (GDPR). + + ![Infographic](https://www.t-systems.com/resource/image/170888/ratio3x2/1440/960/3b17e291f8a5491c3fa97eba9be7a435/FA23A3FF3A7E664AAA9B62ADB2E073FF/im-ref-fuse-ai-infographic.png "Infographic") + +## About Fuse-AI + +[Fuse-AI](https://fuse-ai.de/) applies big data analytics to medical diagnosis. The Hamburg-based startup was founded in 2015 and developed artificial intelligence that can detect indications of cancer – such as carcinomas – on MRI scan and assess whether a tumor is benign or malignant. And that doesn’t just save doctors time. The start-up’s artificial intelligence analyzes MRI scans, notes possible carcinomas and assesses whether a tumor is benign or malignant – it’s a second medical opinion from the Open Telekom Cloud. That makes a radiologist’s job easier, saves time, improves the quality of a diagnosis and reduces healthcare costs. + + +## See Also + +:::info Additional Information + +* Read the whole success story [here](https://www.t-systems.com/de/en/success-stories/cloud-and-infrastructure/fuse-ai-open-telekom-cloud). +* [Download](https://www.t-systems.com/resource/blob/170894/b87be365511a2bd88d33b32568489572/DL-Flyer-Fuse-AI-T-Systems-EN-06-2020.pdf) our reference flyer. + +::: diff --git a/docs/blueprints/by-industry/index.md b/docs/blueprints/by-industry/index.md index 6ddb50c2e..f74b7dff0 100644 --- a/docs/blueprints/by-industry/index.md +++ b/docs/blueprints/by-industry/index.md @@ -6,10 +6,6 @@ sidebar_position: 3 # By Industry -Welcome to the Open Telekom Cloud Architecture Center Best Practices. -Here we provide crucial guidelines for optimizing cloud-based solutions with emphasis to architectural principles that -enhance reliability, scalability, and security. Explore our recommended strategies for resource management, such as -efficient utilization of compute and storage resources. Gain insights into designing for high availability and fault tolerance -to ensure robust system performance. This section serves as a valuable resource for architects and developers -to implement cloud solutions that align with industry best practices and maximize the benefits of the public cloud -infrastructure. +Here you can find guidance for implementing solutions on Open Telekom Cloud tailored to the specific needs of various sectors. Solutions focus on ensuring data security, real-time analytics, and compliance with industry regulations, while also prioritizing high availability, data protection, and meeting strict regulatory requirements. Architectures are designed to support secure data management, facilitate efficient service delivery, and enable secure information exchange. + +Additionally, the category covers cloud solutions that foster innovation, support research and development, and leverage advanced technologies such as AI. It also provides architectures for scalable content delivery, low-latency streaming, and high-performance workloads, as well as solutions to optimize customer experiences, e-commerce platforms, and inventory management. Architectures for high-capacity networks and scalability are also included to ensure continuity and efficiency. This category provides reference architectures, case studies, and step-by-step guides to help organizations deploy tailored cloud solutions that meet the unique operational and regulatory requirements of their sectors. \ No newline at end of file diff --git a/docs/blueprints/by-industry/innovation/_category_.json b/docs/blueprints/by-industry/innovation/_category_.json new file mode 100644 index 000000000..c813a39c4 --- /dev/null +++ b/docs/blueprints/by-industry/innovation/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Innovation", + "link": { + "type": "doc", + "id": "Innovation" + } +} \ No newline at end of file diff --git a/docs/blueprints/by-industry/automotive/index.md b/docs/blueprints/by-industry/innovation/index.md similarity index 93% rename from docs/blueprints/by-industry/automotive/index.md rename to docs/blueprints/by-industry/innovation/index.md index 2fce1a1ae..29ad8fc5a 100644 --- a/docs/blueprints/by-industry/automotive/index.md +++ b/docs/blueprints/by-industry/innovation/index.md @@ -1,9 +1,9 @@ --- -id: Automotive -title: Automotive +id: Innovation +title: Innovation --- -# Automotive +# Innovation The Computing section offers essential insights for optimizing computing resources. Discover guidelines for selecting appropriate instance types, managing virtual machines efficiently, and leveraging auto-scaling capabilities for dynamic diff --git a/docs/blueprints/by-industry/innovation/xelera-open-telekom-cloud.md b/docs/blueprints/by-industry/innovation/xelera-open-telekom-cloud.md new file mode 100644 index 000000000..a79970239 --- /dev/null +++ b/docs/blueprints/by-industry/innovation/xelera-open-telekom-cloud.md @@ -0,0 +1,52 @@ +--- +id: xelera-open-telekom-cloud +title: "Xelera: Middleware Ignites the Application Turbo" +tags: [innovation, by-industry, fpga] +--- + +# Xelera: Middleware Ignites the Application Turbo + +The founders of Hessian start-up [Xelera](#about-xelera) have developed middleware that greatly accelerates data processing. The best thing: Computing-intensive algorithms are processed in freely programmable circuits, so-called Field Programmable Gate Arrays (FPGAs). These are hardware cards that can be individually programmed depending on the intended use. In this way, they process tasks within a server considerably faster than standard hardware and thus considerably accelerate applications. + +“*However, most companies don’t have the necessary know-how to use FPGAs profitably. Individual configuration also costs a lot of time and money,*” says Xelera founder Dr. Felix Winterstein. The hardware-independent solution from Xelera, on the other hand, is simply booked by companies as a service. There’s no need for specialist knowledge about programming hardware cards. With the Xelera solution, companies can accelerate their processes by up to a factor of 100, depending on the application. + +## The Benefits + +* Spontaneous implementation of individual customer requirements possible at any time +* No in-depth FPGA know-how required on the user side thanks to ready-to-use FPGA middleware from the Open Telekom Cloud +* Up to 100-fold acceleration of applications +* Demand-led FPGA usage, pay-as-you-go + +### FPGA: Freely Programmable Circuits as Accelerators + +What do blockchain, artificial intelligence and self-driving cars have in common? According to Gartner, they are all among the top IT trends of 2019 – and they all require enormous computing capacities. That isn’t just something that has existed since 2019 – even conventional processes in companies require ever more powerful IT resources that can perform computing operations more and more quickly. + +### Big Data Analytics During your Coffee Break + +“*More and more processes are running in real time, whether it's manufacturing, transport, logistics, automotive or services. In addition, there are all the sectors that deal directly with end customers, such as retail,*” says Xelera co-founder Andreas Duffner. That translates into a lot of potential work for the Xelera suite, which shows its strengths in areas such as Edge Computing and IoT applications. For example, the control of industrial robots often results in excessively high latencies. With the help of the Xelera accelerator, these delays can be significantly reduced. + +## The Challenge + +* Growing market demand for extremely powerful IT for a wide variety of applications +* Purchasing own FPGA cards for hardware acceleration extremely expensive and mostly not cost-effective +* Necessity of specialist knowledge for the use of FPGA +* Limited offer of ready-to-use FPGA solutions from the cloud + +### FPGA Flavors on Open Telekom Cloud + +Companies book Xelera's middleware as a service and operate it in their own data center – or in the [Open Telekom Cloud](https://open-telekom-cloud.com/en/products-services/elastic-cloud-server). To make the most of the potential of its middleware as an application accelerator, Xelera relies on the fp1c.2xlarge FPGA flavor and the e2.3xlarge large memory flavor from Deutsche Telekom's [Elastic Cloud Server offering](https://open-telekom-cloud.com/en/products-services/elastic-cloud-server). "*The capacities from the Open Telekom Cloud allow us to set up our accelerator quickly in the cloud and configure it according to the customer's application scenario, for example accelerating standard databases such as SAP,*" says Dr. Felix Winterstein. + +The Open Telekom Cloud was the start-up’s first choice due to its multi-certified and GDPR-compliant data centers in Germany. Xelera relies on Telekom's fast network for the connection and thus obtains the best possible connectivity with very low latencies for business-critical real-time applications. + +With its middleware, the start-up now accelerates processes in a wide range of areas – from market forecasts or risk calculations in the financial sector to real-time analysis of customer behavior in the retail sector and genome analyses in medicine. It’s a solution with great potential that doesn’t interest the start-up’s customers: Xelera recently qualified for [Deutsche Telekom's TechBoost start-up program](https://telekomhilft.telekom.de/t5/TechBoost-EN/ct-p/TechBoost_en). + +## The Solution + +* Xelera middleware with interface to the Open Telekom Cloud +* Use of FPGA flavors from the Elastic Cloud Server offering (fp1c.2xlarge as well as large memory flavor e2.3xlarge) +* Planned use of additional flavors and Object Based Storage (OBS) +* High level of data protection due to multiple certified data centers in Germany + +## About Xelera + +Field Programmable Gate Arrays (FPGAs) are [Xelera](https://xelera.io/)'s main focus: The start-up has developed middleware that shortens application computing times by up to a factor 100 – ideal for real-time analysis or the control of industrial robots. To do so, the Hesse-based company uses resources from the Open Telekom Cloud. diff --git a/docs/blueprints/by-industry/media/ufa-adopts-full-cloud-workflow-in-film-production.md b/docs/blueprints/by-industry/media/ufa-adopts-full-cloud-workflow-in-film-production.md new file mode 100644 index 000000000..bf1861651 --- /dev/null +++ b/docs/blueprints/by-industry/media/ufa-adopts-full-cloud-workflow-in-film-production.md @@ -0,0 +1,59 @@ +--- +id: ufa-adopts-full-cloud-workflow-in-film-productionpp +title: UFA Adopts Full-Cloud Workflow in Film Production +tags: [media, by-industry] +--- + +# UFA Adopts Full-Cloud Workflow in Film Production + +[UFA](#about-ufa-gmbh) opts for the Open Telekom Cloud. Delivery vans commuting by road to transport hard disks will soon be a thing of the past. + +What might at first seem trivial actually has a big impact: because the digitized distribution process not only saves UFA a lot of money, it also protects the environment. Previously, at the end of each day of shooting, courier services and production drivers transported the raw material on hard disks between locations all over Germany and the post-production facilities by road. "*These are tens of thousands of kilometers that we want to eliminate in the future with our new full-cloud workflow. It also increases overall efficiency and production speed,*" says Ernst Feiler, Technology Director at UFA, "*And that’s all without our employees having to change the way they work.*” + +That’s because, after every shoot, the crew plugs the storage media from the film cameras into a network-attached storage (NAS). Previously, the NAS was then picked up by a courier and taken to Potsdam. In the future, however, the NAS systems can simply stay put at locations with suitable connectivity – and transfer the data into the Open Telekom Cloud via the internet. + +## Long-Term Goal: Digitizing the Entire Value Chain + +The film industry is undergoing one of its biggest upheavals since the invention of color television. With more and more people consuming video content on the screens they carry around with them, the value chain is increasingly moving to where the audience is already: the cloud. It’s a development that UFA GmbH is well aware of: The German market leader in film and television production has already been digitizing its value chain for the past 10 years. + +The Potsdam-based company’s next step is to distribute raw material via the cloud. Film material that is shot at different locations during production – such as at outside locations or film studios located far away – is currently still transported to the relevant post-production sites by courier. In the future, some of that data will be automatically transferred directly to the Open Telekom Cloud via the internet. All those involved in the process, such as the editors who turn the material into finished clips, will then have access to it. + +## Lower Costs with Open Telekom Cloud + +Why doesn't UFA send the film material directly to the production headquarters via the internet? Quite simply because the company would then need their own storage capacities, which would not be freely scalable. That would involve having to purchase, store and maintain bulky IT hardware. In the Open Telekom Cloud, on the other hand, UFA will be using low-cost object-based storage (OBS) from now on. The data stored there can be classified at different levels: "cold" for occasional access over a year, "warm" for monthly data access and "standard" for more frequent access. The less frequent the access, the cheaper the storage. + +The full-cloud workflow is currently being tested as part of a proof of concept (PoC). In the long term, Technology Director Feiler plans to move the film production’s entire value chain to the cloud. "*Deutsche Telekom will certainly also be our partner for future cloud projects,*" says Feiler. "*Because we can expect reliable, fast and highly available technology from them. And, what's more, they are competent partners at eye level who reliably meet any legal requirements of the GDPR.*" + +## The Challenge + +* Previously, vans transported film material across Germany between the filming location, headquarters and archive. +* Although this was customary practice in the industry, it was slow and also caused high transport costs. +* For this reason, the entire workflow had to be digitized and automated without changing the employees’ workflow. + +## The Solution + +* A fully automated cloud workflow with S3-compatible object storage in the Open Telekom Cloud. +* Film crews transfer their footage to a network-attached storage (NAS) system. From there it is transferred to the cloud via the internet. +* For that, Deutsche Telekom relies on widely-used standards. This ensures low costs and less complexity compared to individual software and hardware. + +## Customer Benefits + +UFA: “Tens of thousands of kilometers saved thanks to the cloud” + +* Transports between filming locations, headquarters and archive are reduced. This saves time and money. +* Post-production teams have access to raw material from anywhere and can work with it directly. +* Finished video material is automatically archived in the cloud. +* UFA is currently testing the process in a proof of concept (PoC). + +## About UFA GmbH + +[UFA](http://www.ufa.de/) is one of the best-known entertainment brands in the world and market leader in film and television production in Germany. Founded more than 100 years ago, UFA has developed into a comprehensive content specialist providing digital and multimedia content – to all major German broadcasters and other partners. + +## See Also + +:::info Additional Information + +* Read the whole success story [here](https://www.t-systems.com/de/en/success-stories/cloud-and-infrastructure/ufa). +* [Download](https://www.t-systems.com/resource/blob/138216/45bc1b68b95db72e1b9e094872e068e9/DL-Flyer-Success-Story-UFA-T-Systems-en-05-2020.pdf) our reference flyer. + +::: diff --git a/docs/blueprints/by-industry/retail/brodos-open-telekom-cloud.md b/docs/blueprints/by-industry/retail/brodos-open-telekom-cloud.md new file mode 100644 index 000000000..e96973f3e --- /dev/null +++ b/docs/blueprints/by-industry/retail/brodos-open-telekom-cloud.md @@ -0,0 +1,59 @@ +--- +id: brodos-open-telekom-cloud +title: Omnichannel Platform by brodos.net +tags: [retail, omnichannel, by-industry] +--- + +# Omnichannel Platform by brodos.net + +With the help of resources from the Open Telekom Cloud, [brodos.net](#about-brodosnet) is now in a position to meet every customer request spontaneously, because the container-based platform can now be scaled spontaneously in a matter of minutes. According to the company, brodos.net was able to increase the performance of its systems by around 40 percent. The availability of the Open Telekom Cloud is 99.95 percent. + +“*The most important criterion for us, however, is the trust that both we and our customers have in the platform,*” says Managing Director Udo Latino. “*We process sensitive customer data. It is therefore essential for us to use an IT platform that leaves no questions unanswered. With Telekom's public cloud solution, we are on the safe side in every respect.*” + +As a result, brodos.net is now prepared for any growth. The omnichannel platform is increasingly establishing itself on the market. More than 1,000 customers from various industries such as telecommunications, fashion, furniture, bikes and electronics are currently using brodos.net to access the omnichannel platform from the Open Telekom Cloud. “*Next, we will expand our platform to other industries and then, in a second step, to other European markets,*“ says Dingermann. “*With the scalable cloud resources we use, nothing stands in the way of further expansion.*” + +## Customer Benefits + +* 40 percent increase in computing performance +* 99.95 percent availability of cloud resources +* Simple, fast and efficient provision of containers +* Considerable trust of brodos.net customers thanks to the highest level of security +* Scalability creates the necessary basis for conquering new industries and markets + +## The Goal: Attract Customers from All Channels + +What are the three most important technology trends in retail? Artificial intelligence (69 percent), the cloud (34 percent) – and omnichannel (30 percent). This is at least the opinion of IT decision-makers from 90 retail companies in German-speaking countries, who were surveyed on the subject by the EHI Retail Institute at the beginning of 2019. “*In the future it will become increasingly important for companies to address customers on all channels in the right tone, with the right products and the right service,*” says Udo Latino, Managing Director of brodos.net. The company has developed a platform to help local retailers achieve exactly this. + +brodos.net is acutely aware of the growing need for these kinds of solutions: The demand for the platform has recently increased so much that the provider wanted to expand its IT with flexibly scalable resources. + +## The Challenge + +* Delivery of the solution from on-premises IT resources +* Potential for higher growth of the omnichannel platform should be increased +* Looking for a flexible, scalable cloud solution that allows developers to work with docker containers +* Highest standards of data security and data protection due to sensitive customer data + +### More Scope for Growth + +brodos.net initially operated the omnichannel platform exclusively in its own private data center to ensure maximum IT security and data protection. In order to meet the growing demand, brodos.net was looking for a way to be more flexible. “W*e wanted to expand our IT so that it could adapt flexibly and spontaneously to business development at any time without compromising security,*” said Felix Dingermann, Managing Director of Business Development at brodos.net. + +That's why the Bavarian company was looking for a cloud provider that could provide IT resources at the highest level of security and data protection. They found this at Telekom: brodos.net now hosts its omnichannel platform in the Open Telekom Cloud, Telekom's public cloud offering. For this purpose, the company uses virtual machines in the Elastic Cloud Server (ECS) category, the Relational Database Service (RDS), Object Storage Service (OBS) and the Elastic Load Balancer (ELB). For the further development of the platform, the software experts at brodos.net also rely on the container framework of the Open Telekom Cloud – the Cloud Container Engine. “*This is simply a question of convenience and efficiency,*” says Felix Dingermann. “*We could certainly have implemented our own container framework. But that would have taken a lot of effort.*” + +## The Solution + +* Hosting of the omnichannel platform in the Open Telekom Cloud from highly secure German data centers in Biere and Magdeburg +* Use of Elastic Cloud Server (ECS), Relational Database Service (RDS), Object Storage Service (OBS) and Elastic Load Balancer (ELB) +* Developers rely on Cloud Container Engine (CCE) + +## About brodos.net + +[brodos.net](https://brodos.net/omnichannel/) helps local retailers with digitalization: The company offers an omnichannel platform with a solution for every touchpoint – from editable online shops to e-mail marketing tools to digital store shelves. In the future, the company plans to offer its platform not only in German-speaking countries, but throughout Europe. + +## See Also + +:::info Additional Information + +* Read the whole success story [here](https://www.t-systems.com/de/en/success-stories/cloud-and-infrastructure/brodos-open-telekom-cloud). +* [Download](https://www.t-systems.com/resource/blob/148928/807c50e64dcfc1a6d8f81d86818f0892/DL-Flyer-Brodos-T-Systems-EN-05-2020.pdf) our reference flyer. + +::: \ No newline at end of file diff --git a/docs/blueprints/by-industry/telecoms/_category_.json b/docs/blueprints/by-industry/telecoms/_category_.json new file mode 100644 index 000000000..040da3984 --- /dev/null +++ b/docs/blueprints/by-industry/telecoms/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Telecommunications", + "link": { + "type": "doc", + "id": "Telecommunications" + } +} \ No newline at end of file diff --git a/docs/blueprints/by-industry/telecoms/fiber-factory.md b/docs/blueprints/by-industry/telecoms/fiber-factory.md new file mode 100644 index 000000000..cee78e2bf --- /dev/null +++ b/docs/blueprints/by-industry/telecoms/fiber-factory.md @@ -0,0 +1,58 @@ +--- +id: fiber-factory +title: "Fiber-Factory: Accelerated Grid Expansion" +tags: [telecommunications, by-industry] +--- + +# Fiber-Factory: Accelerated Grid Expansion + +More than 33 million households in Germany can access speeds of over 50 MBit/s, thanks to Telekom's fiber optic expansion. This enables people to work from home, streaming, and business line connectivity. Now Telekom is planning to expand the network for up to two million more households each year starting in 2021. This involved extensive construction measures. In order to plan these more efficiently, secure resources from the Open Telekom Cloud are providing support. + +## Benefits for the Customer + +* Faster calculation of potential routes for fiber optic expansion with time savings of up to 75 percent +* Automation of the entire planning process +* Greater transparency around the duration and costs of the expansion +* Nationwide standardized procedure +* Accelerated authorization procedures + +### High Degree of Automation + +Several thousand planners from Fiber Factory, a division of Deutsche Telekom Technik GmbH, are responsible for the planning of up to two million new fiber optic connections nationwide per year. Until now, planning required a lot of time and manual effort, and was therefore prone to errors. Deutsche Telekom Technik GmbH was looking for a highly automated and standardized solution for efficient, cost-effective planning. "*Our ambitious schedule calls for us to bring 15 times more fiber to the home connections online each year than we have in the past. This cannot be achieved without automated processes,*" says Niko Gitzen, Senior Expert at Fiber Factory. + +### AI-Based Process Optimizes Calculation + +In order to position new routes in an optimal fashion, DT Technik GmbH works with a geodata infrastructure (GDI) that incorporates data from cadastres, aerial photographs and images of the expansion area from the T-Surface Car. The customer can flexibly use IT resources from the Open Telekom Cloud for the operation of the GDI, the processing of the large volumes of data and the rapid creation of new expansion plans. "*We operate our geodata infrastructure in Deutsche Telekom's public cloud solution. We prepare and process all the data collected from the T-Surface Cars and link it to other information there. The results form the basis for the planning process of the fiber optic expansion,*" says Tobias Frechen, System Architect at Deutsche Telekom IT GmbH. + +## The Challenge + +* A manual approach and inconsistent planning standards for laying fiber optic networks meant a great deal of effort and high costs +* Geodata infrastructure (GDI) is set to automate planning in conjunction with artificial intelligence (AI) +* Secure storage and ultra-rapid analysis of geodata such as aerial photographs, point clouds from laser scanners and images from digital cameras +* Capacity constraints: storing and processing the large volumes of data in the company's data center would be too cost-intensive + +## The Solution + +* Automation of the planning process using the Open Telekom Cloud +* GDPR-compliant data processing and storage +* Dynamic usage thanks to the pay-as-you-go model + +### Automated Planning Made Easy + +The T-Surface Car collects photos and 3D point clouds of up to 500 gigabytes for each expansion area, which are uploaded to a bucket of the Object Storage Service (OBS) in the Open Telekom Cloud. An artificial neural network (ANN) from Fraunhofer IPM is used to evaluate the survey vehicle's data, and classifies it according to 30 surface and object types. In order to classify them, DT Technik GmbH scales horizontally with twenty GPU VMs in the Open Telekom Cloud. In the process, Fraunhofer IPM has already trained the ANN with over 90,000 photos and it can thus be used as a docker container in the planning process. This enables more efficient use of system resources. + +In addition to the information from the T-Surface Car, the Open Telekom Cloud also contains cadastral data, information about Telekom networks already installed in the expansion area, and images from the European Space Agency's (ESA) Sentinel earth observation satellites. They are used to calculate the exact surface structure of the expansion area. A process that is automated in the Open Telekom Cloud using multiple graphics processing units (GPUs). The resulting two-dimensional images show how and where fiber optic routes can best be laid. + +### Three Times as Fast, Thanks to Open Telekom Cloud + +Planners have been actively working with the cloud solution since 2020. Expansion costs can be calculated much more accurately and quickly with the AI-based process in the Open Telekom Cloud. Automation enables planning times to be reduced by up to 75 percent. New routes are calculated automatically, and the planners can work more quickly, move virtually through the roads themselves using 2D or 3D models and take measurements. For example, whether a sidewalk is wide enough for a power distribution box. "*This site protection has to be approved by the local authorities. For this, a form is automatically created in the GDI,*" says Tobias Frechen. This way, all documents for fiber optic expansion can be made available to the municipalities digitally in the future. + + +## See Also + +:::info Additional Information + +* Read the whole success story [here](https://www.t-systems.com/de/en/success-stories/cloud-and-infrastructure/fiber-factory). +* [Download](https://www.t-systems.com/resource/blob/388280/00f912430705e453e79081c2bc3d5ff1/DL-Flyer-FTTH-Factory-T-Systems-EN-01-2021.pdf) our reference flyer. + +::: diff --git a/docs/blueprints/by-industry/telecoms/index.md b/docs/blueprints/by-industry/telecoms/index.md new file mode 100644 index 000000000..80043aa19 --- /dev/null +++ b/docs/blueprints/by-industry/telecoms/index.md @@ -0,0 +1,13 @@ +--- +id: Telecommunications +title: Telecommunications +--- + +# Telecommunications + +The Computing section offers essential insights for optimizing computing resources. Discover guidelines for selecting +appropriate instance types, managing virtual machines efficiently, and leveraging auto-scaling capabilities for dynamic +workloads. Learn best practices for designing resilient and high-performance computing architectures, ensuring optimal +utilization of resources while maintaining cost-effectiveness. This section serves as a comprehensive guide for architects +and developers to fine-tune their computing strategies, enhancing the overall efficiency and reliability of applications +in the Open Telekom Cloud environment. diff --git a/docs/blueprints/by-use-case/analytics/_category_.json b/docs/blueprints/by-use-case/analytics/_category_.json new file mode 100644 index 000000000..74a5d995f --- /dev/null +++ b/docs/blueprints/by-use-case/analytics/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Analytics", + "link": { + "type": "doc", + "id": "analytics" + } +} \ No newline at end of file diff --git a/docs/blueprints/by-use-case/computing/deploy-clickhouse-cce.md b/docs/blueprints/by-use-case/analytics/deploy-clickhouse-cce.md similarity index 100% rename from docs/blueprints/by-use-case/computing/deploy-clickhouse-cce.md rename to docs/blueprints/by-use-case/analytics/deploy-clickhouse-cce.md diff --git a/docs/blueprints/by-use-case/analytics/index.md b/docs/blueprints/by-use-case/analytics/index.md new file mode 100644 index 000000000..8fa206111 --- /dev/null +++ b/docs/blueprints/by-use-case/analytics/index.md @@ -0,0 +1,8 @@ +--- +id: analytics +title: Analytics +--- + +# Analytics + +In this category, you can find guidance for designing, deploying, and managing scalable analytics solutions on Open Telekom Cloud. Topics include data ingestion, transformation, and storage; real-time and batch processing architectures; tools for data visualization and business intelligence; and leveraging machine learning for predictive analytics. Here are also provided architectural patterns, case studies, and reference implementations to help organizations derive actionable insights from their data while ensuring security, cost-efficiency, and performance. diff --git a/docs/blueprints/by-use-case/analytics/umami/_category_.json b/docs/blueprints/by-use-case/analytics/umami/_category_.json new file mode 100644 index 000000000..ea3fb2cbe --- /dev/null +++ b/docs/blueprints/by-use-case/analytics/umami/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Umami", + "link": { + "type": "doc", + "id": "umami" + } +} \ No newline at end of file diff --git a/docs/blueprints/by-use-case/analytics/umami/deploy-umami-cce.md b/docs/blueprints/by-use-case/analytics/umami/deploy-umami-cce.md new file mode 100644 index 000000000..d0e28f7ac --- /dev/null +++ b/docs/blueprints/by-use-case/analytics/umami/deploy-umami-cce.md @@ -0,0 +1,220 @@ +--- +id: deploy-umami-cce +title: Deploy Umami on CCE +tags: [umami, analytics, cce, postgresql, zalando-postgres-operator] +--- + +# Deploy Umami on CCE + +In this blueprint we are going to set up Umami on Open Telekom Cloud's Cloud Container Engine (CCE), leveraging Kubernetes for scalability and flexibility. For the database backend, we will use the Zalando PostgreSQL Operator to provision and manage a PostgreSQL cluster within the CCE environment. + +## Prerequisites + +We are going to need a CCE Cluster (its provisioning is out of the scope of this blueprint) and the **zalando-postgres-operator**. This operator automates the management of PostgreSQL clusters on Kubernetes, handling tasks like scaling, backups, and failover. It simplifies the deployment and maintenance of a highly available PostgreSQL database within the CCE cluster. Additionally we are going to need an Elastic Load Balancer in order to expose Umami. + +## Installing Zalando Postgres Operator + +We are going to install the operator by using the provided Helm chart: + +```shell +helm repo add postgres-operator-charts https://opensource.zalando.com/postgres-operator/charts/postgres-operator +helm repo update + +helm install postgres-operator postgres-operator-charts/postgres-operator +``` + +## Installing Umami + +### Provisioning a Database + +As we priorly discussed, we are going to use zalando-postgres-operator in order to provision a PostgreSQL Cluster in CCE: + +```yaml title="umami-postgresql.yaml" +apiVersion: acid.zalan.do/v1 +kind: postgresql +metadata: + labels: + application: umami + name: umami-psql +spec: + databases: + umami: umami + numberOfInstances: 1 + postgresql: + version: "16" + parameters: + huge_pages: "false" + preparedDatabases: + umami: + defaultUsers: true + schemas: + data: {} + history: + defaultRoles: true + defaultUsers: false + resources: + limits: + cpu: 500m + memory: 500Mi + requests: + cpu: 10m + memory: 100Mi + teamId: default + users: + admin: + - superuser + - createdb + umami: [] + volume: + size: 1Gi + storageClass: csi-disk +``` + +```shell +kubectl apply -f umami-postgresql.yaml +``` + +### Deploying Umami + +Create the follow manifest: + +```yaml title="umami-web-deployment.yaml" +apiVersion: apps/v1 +kind: Deployment +metadata: + name: umami-web +spec: + replicas: 2 + selector: + matchLabels: + app: umami-web + template: + metadata: + labels: + app: umami-web + spec: + containers: + - name: web + image: ghcr.io/umami-software/umami:postgresql-latest + ports: + - containerPort: 5000 + protocol: TCP + env: + - name: PORT + value: '5000' + - name: DB_DATABASE + value: "umami" + - name: DB_HOST + value: umami-psql.docs-next.svc.cluster.local + - name: DB_PORT + value: '5432' + - name: DB_USERNAME + valueFrom: + secretKeyRef: + name: umami.umami-psql.credentials.postgresql.acid.zalan.do + key: username + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: umami.umami-psql.credentials.postgresql.acid.zalan.do + key: password + - name: DATABASE_URL + value: "postgres://$(DB_USERNAME):$(DB_PASSWORD)@$(DB_HOST):$(DB_PORT)/$(DB_DATABASE)" + imagePullPolicy: IfNotPresent +``` + +```shell +kubectl apply -f umami-web-deployment.yaml +``` + +:::important +A Kubernetes Secret with the name `umami.umami-psql.credentials.postgresql.acid.zalan.do`, containing the credentials of the `umami` database, will be automatically provisioned by the zalando-postgres-operator during the application of manifest **umami-postgresql.yaml**. The environmental variables `DB_USERNAME` & `DB_PASSWORD` are getting their values by referencing this Secret. +::: + +## Creating an Elastic Load Balancer + +Navigate to *Network Console*->*Elastic Load Balancing* and click *Create Elastic Load Balancer*. Choose to create *Shared Load Balancer* and choose *New EIP* so the new ELB is automatically bound to a new elastic IP: + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-32-38.png>) + +:::tip +Write down the ID of the Elastic Load Balancer we are going to need it in the next steps. +::: + +## Exposing Umami + +### Creating a Service + +```yaml title="umami-service.yaml" +apiVersion: v1 +kind: Service +metadata: + name: umami-web +spec: + type: NodePort + ports: + - protocol: TCP + name: umami + port: 5000 + targetPort: 5000 + selector: + app: umami-web +``` + +```shell +kubectl apply -f umami-service.yaml +``` + +:::note +If you are **not** planning to expose the service via an `Ingress` object, change the **type** to `ClusterIP`. +::: + +### Creating an Ingress (optional) + +```yaml title="umami-ingress.yaml" +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: umami-ingress + labels: + app: umami-web + annotations: + kubernetes.io/elb.class: union + kubernetes.io/elb.id: {value} + kubernetes.io/elb.port: 80 +spec: + ingressClassName: cce + rules: + - host: umami.example.com + http: + paths: + - backend: + service: + name: umami-web + port: + number: 5000 + path: / + pathType: ImplementationSpecific +``` + +:::important + +- Replace the placeholder `{value}` of annotation **kubernetes.io/elb.id** with the ID of the Elastic Load Balancer we created before. +- If the Elastic Load Balancer you created was a shared one then the annotation **kubernetes.io/elb.class** should have the value `union`. +- Replace `umami.example.com` in **host**, with the FQDN of yours. + +::: + +```shell +kubectl apply -f umami-ingress.yaml +``` + +## Verification + +Open in a browser the address: `http://ELB_EIP` and you should now land at the logon page of Umami: + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 15-05-13.png>) + +:::warning +Umami uses `admin`/`umami` as default credentials. **Change them immediatelly after you log in!** +::: diff --git a/docs/blueprints/by-use-case/analytics/umami/overview.md b/docs/blueprints/by-use-case/analytics/umami/overview.md new file mode 100644 index 000000000..99b7350a7 --- /dev/null +++ b/docs/blueprints/by-use-case/analytics/umami/overview.md @@ -0,0 +1,21 @@ +--- +id: umami +title: Umami +tags: [umami, analytics, gdpr] +--- + +# Umami + +[Umami](https://umami.is/) is a privacy-focused, open-source web analytics tool designed to provide essential website usage insights without compromising user privacy. It offers core metrics like page views, user behavior, and traffic sources while ensuring compliance with privacy laws by not using cookies or tracking personal data. Lightweight and simple to integrate, Umami delivers real-time data and customizable reporting features, making it a popular alternative to traditional analytics tools. Its emphasis on transparency and user control makes it appealing to businesses prioritizing data privacy and minimalism in web tracking. + +:::danger[important] +Umami is **fully GDPR compliant**. It is designed with privacy in mind, meaning it **does not track personal data**, it **does not use cookies**, and it **does not require user consent under GDPR rules**. Umami collects only anonymized, aggregated data, ensuring that no [personally identifiable information (PII)](https://gdpr.eu/eu-gdpr-personal-data/) is gathered. This makes it an excellent solution for organizations looking to monitor web traffic while staying compliant with strict data protection regulations like GDPR. Additionally, since Umami is self-hosted, businesses have full control over their data, further enhancing privacy and compliance. +::: + +:::tip[See Also] + +- [GDPR.eu: Complete Guide to GDPR Compliance](https://gdpr.eu/) +- [What is considered personal data under the EU GDPR?](https://gdpr.eu/eu-gdpr-personal-data/) +- [Are you ready for the GDPR? GDPR checklist for data controllers](https://gdpr.eu/checklist/) + +::: diff --git a/docs/blueprints/by-use-case/analytics/umami/using-rds-postgresql-to-setup-umami-on-ecs.md b/docs/blueprints/by-use-case/analytics/umami/using-rds-postgresql-to-setup-umami-on-ecs.md new file mode 100644 index 000000000..9b0a77e4f --- /dev/null +++ b/docs/blueprints/by-use-case/analytics/umami/using-rds-postgresql-to-setup-umami-on-ecs.md @@ -0,0 +1,241 @@ +--- +id: using-rds-postgresql-to-setup-umami-on-ecs +title: Using RDS for PostgreSQL to Set Up Umami on ECS +tags: [umami, analytics, ecs, rds, postgresql] +--- + +# Using RDS for PostgreSQL to Set Up Umami on ECS + +In this blueprint we are going to set up Umami on Open Telekom Cloud leveraging an Elastic Cloud Server (ECS), while using Relational Database Service (RDS) for PostgreSQL to manage the database. + +## Prerequisites + +We are going to need, create and configure the following components: + +- a PostgreSQL Instance in RDS: RDS automates database management tasks like backups, patching, and scaling. It simplifies deploying a PostgreSQL instance without needing to manage the infrastructure directly. +- an ECS Server for Umami: The server will be used to run Umami's application layer. You will install and configure Umami on this ECS instance, which will interact with the PostgreSQL database. +- Networking: Set up secure network configurations between your ECS and RDS, ensuring communication between the Umami application and the PostgreSQL instance. +- Deployment: After configuring the ECS and connecting it to the RDS database, you can deploy Umami, connect it to the database, and start monitoring your web traffic. + +## Creating an ECS Server + +Click on the console *Elastic Cloud Server*->*Create ECS* and pick the flavor and operating system that suits your needs. Make sure though, you place it in the same VPC/Subnet that you are planning to install your RDS DB instance. For this blueprint we are going to set up Ubuntu 22.04 on a *s7n.large.4* flavor. Consequently some of the commands that are going to be executed later, will assume you are working on a Ubuntu (or Debian-based) distribution. + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 12-40-41.png>) + +## Creating a PostgreSQL Database + +We are going to create a single, non highly available PostgreSQL v16. In *Relational Database Service* click *Create DB Instance*: + +![Create a Database Wizard Part 1](/img/docs/blueprints/by-use-case/analytics/umami/Screenshot_from_2024-09-09_12-51-39.png) + +Make sure you place the database server in the same VPC/Subnet that the ECS instance lives. Choose the flavor of your liking, provide the **root** password and press *Create Now*. For the time being, we are going to make no changes in the Security Groups; we are going to fix this in the next step. + +![Create a Database Wizard Part 2](/img/docs/blueprints/by-use-case/analytics/umami/Screenshot_from_2024-09-09_12-52-14.png) + +:::note +Picking a single non-HA instance is just for demonstration purposes and **not** suitable for production. While implementing this blueprint adjust instances and replicas according to your needs and volume projections. +::: + +### Installing Cryptographic Functions Plugins + +In *Relational Database Service* click your instance and then navigate to *Plugins*. Search the list for the plugin **pgcrypto**, and install it by click the *Install* link. + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 13-14-30.png>) + +## Establishing Connectivity + +In *Relational Database Service* click your instance and then navigate to *Connectivity & Security* and under *Connection Topology* choose *Private Connection*: + +![Establishing Connectivity](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 13-53-46.png>) + +In this blueprint, we are interested in variant 2, where our database instance (with floating IP `172.16.0.30`) needs to establish two-way communication with the ECS(B) instance, which in our case is the ECS instance that hold the Umami installation. For that matter we need to create two Security Groups, one that will allow inbound connections to port `5432` and will be assigned to our RDS instance and a second one that will allow outbound connections from port `5432` and will be assigned to the ECS instance that our workload will run. + +### Creating Security Group for RDS + +![Adding Inbound Rules for RDS Instances](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-03-16.png>) + +For additional security, make sure you set as **Source** the CIDR of the your Subnet (in this case `172.16.0.0/24`); in that way you prohibit anyone access your database outside your VPC/Subnet. + +Go back to the *Connectivity & Security* panel of your database and replace under *Security Group Rules* -> *Security Group*, the default Security Group with the one we just created: + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-12-28.png>) + +### Creating Security Group for ECS + +#### Creating Outbound Rule for PostgreSQL + +![Adding Outbound Rules for ECS](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-10-01.png>) + +In the same notion, set as **Destination** the CIDR of the your Subnet (in this case `172.16.0.0/24`). + +On our ECS instance, click *Security Groups* -> *Change Security Group*, and add additionally the new Security Group to the list. + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-16-19.png>) + +#### Creating Inbound Rule for SSH + +You are going to need an additionnal inbound rule to allow actors accessing this ECS Server via SSH. Add in the existing Security Group (or create new one for finer granularity of permissions and reusability among more instances) port `22` in the *Inbound Rules* list, and set the value of **Remote End** as `0.0.0.0/24`. + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 12-47-36.png>) + +:::note +How you are going to establish this SSH connection, is entirely up to you. You can use a bastion or an Elastic IP bound to your ECS or a DNAT Rule in a NAT Gateway. Depends on your needs and your assessment. +::: + +#### Creating Inbound Rule for Umami + +## Deploying Umami + +### Creating the Database + +#### Installing the PostgreSQL client tools + +```shell +sudo apt-get update +sudo apt-get -y install postgresql-client-14 +``` + +#### Creating the Umami Database + +```shell +createdb umami --host=172.16.0.30 --username=root +``` + +:::note +You will be asked to provide the root password you've set during the installation. +::: + +#### Creating Roles and Assign Privileges + +Connect to database: + +```shell +psql -h 172.16.0.30 --username=root umami +``` + +Create Role & Privileges and make sure the Cryptographics Functions Plugin is on: + +```SQL +CREATE ROLE umami WITH LOGIN PASSWORD '{value}’; +GRANT ALL PRIVILEGES ON DATABASE umami TO umami; +\c umami +CREATE EXTENSION IF NOT EXISTS pgcrypto; +GRANT ALL PRIVILEGES ON SCHEMA public TO umami; +``` + +:::important +Replace `{value}` with your own password! +::: + +### Installing Docker + +#### Setup Docker's apt repository + +```shell +sudo apt-get update +sudo apt-get install ca-certificates curl +sudo install -m 0755 -d /etc/apt/keyrings +sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc +sudo chmod a+r /etc/apt/keyrings/docker.asc + +echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + +sudo apt-get update +``` + +#### Instal the Docker packages + +```shell +sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin +``` + +#### Post-Installation Steps + +```shell +sudo groupadd docker +sudo usermod -aG docker $USER +newgrp docker +``` + +### Installing Umami as Docker Container + +#### Create an APP_SECRET and export Credentials + +```shell +export APP_SECRET=$(openssl rand 30 | openssl base64 -A) +export PSQL_HOST=172.16.0.30 +export PSQL_ROOT_PASSWORD={value} +``` + +:::note +Replace `PSQL_HOST` and `PSQL_ROOT_PASSWORD` values with your own ones. +::: + +#### Create a Docker Compose file + +```yaml title="docker-compose.yml" +version: '3' +services: + umami: + image: ghcr.io/umami-software/umami:postgresql-latest + ports: + - "3000:3000" + environment: + DATABASE_URL: postgresql://root:${PSQL_ROOT_PASSWORD}@${PSQL_HOST}:5432/umami + DATABASE_TYPE: postgresql + APP_SECRET: ${APP_SECRET} + restart: always + healthcheck: + test: ["CMD-SHELL", "curl http://localhost:3000/api/heartbeat"] + interval: 5s + timeout: 5s + retries: 5 +``` + +```shell +docker compose up -d +``` + +## Exposing Umami + +### Creating an Elastic Load Balancer + +Navigate to *Network Console*->*Elastic Load Balancing* and click *Create Elastic Load Balancer*. Choose to create *Shared Load Balancer* and choose *New EIP* so the new ELB is automatically bound to a new elastic IP: + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-32-38.png>) + +### Creating a Listener + +Choose your Elastic Load Balancer from the console and click *Add Listener*: + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-38-26.png>) + +Configure *Frontend Protocol* as `TCP`, and *Frontend Port* as `80`: + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-38-50.png>) + +Configure a new Routing Policy, supported by a new Backend Server Group and set *Backend Protocol* as `TCP`: + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-39-09.png>) + +Next, you need to add members to the newly created Backend Group. Click *Add Backend Server* and choose the Umami ECS Instance from the list: + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-39-38.png>) + +and set the Backend Port to `3000`: + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-39-50.png>) + +## Verification + +Open in a browser the address: `http://ELB_EIP` and you should now land at the logon page of Umami: + +![alt text](<../../../../../static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 15-05-13.png>) + +:::warning +Umami uses `admin`/`umami` as default credentials. **Change them immediatelly after you log in!** +::: diff --git a/docs/blueprints/by-use-case/computing/index.md b/docs/blueprints/by-use-case/computing/index.md index d40bf7214..f928d443a 100644 --- a/docs/blueprints/by-use-case/computing/index.md +++ b/docs/blueprints/by-use-case/computing/index.md @@ -5,9 +5,4 @@ title: Computing # Computing -The Computing section offers essential insights for optimizing computing resources. Discover guidelines for selecting -appropriate instance types, managing virtual machines efficiently, and leveraging auto-scaling capabilities for dynamic -workloads. Learn best practices for designing resilient and high-performance computing architectures, ensuring optimal -utilization of resources while maintaining cost-effectiveness. This section serves as a comprehensive guide for architects -and developers to fine-tune their computing strategies, enhancing the overall efficiency and reliability of applications -in the Open Telekom Cloud environment. +In this category, you can find guidance for building and managing computing solutions on Open Telekom Cloud. Topics include virtual machines, containerization, serverless computing, and high-performance computing architectures. Here are also provided recommendations for workload optimization, auto-scaling, and cost management, enabling organizations to efficiently handle diverse computing demands while maintaining reliability, security, and scalability. \ No newline at end of file diff --git a/docs/blueprints/by-use-case/devops/ci-devtron-swr-cce.md b/docs/blueprints/by-use-case/devops/ci-devtron-swr-cce.md index 6295eac83..56e3061e6 100644 --- a/docs/blueprints/by-use-case/devops/ci-devtron-swr-cce.md +++ b/docs/blueprints/by-use-case/devops/ci-devtron-swr-cce.md @@ -1,7 +1,7 @@ --- id: ci-devtron-swr-cce title: Build a CI/CD Pipeline with Devtron, SWR and CCE -tags: [devops, ci, cd, ci-cd, devtron, swr, cce] +tags: [devops, ci, cd, cicd, devtron, swr, cce] --- # Build a CI/CD Pipeline with Devtron, SWR and CCE diff --git a/docs/blueprints/by-use-case/devops/crossplane/_category_.json b/docs/blueprints/by-use-case/devops/crossplane/_category_.json deleted file mode 100644 index aeb14756d..000000000 --- a/docs/blueprints/by-use-case/devops/crossplane/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "Crossplane", - "link": { - "type": "doc", - "id": "crossplane" - } -} \ No newline at end of file diff --git a/docs/blueprints/by-use-case/devops/crossplane/overview.md b/docs/blueprints/by-use-case/devops/crossplane/overview.md deleted file mode 100644 index 4a6a2ae25..000000000 --- a/docs/blueprints/by-use-case/devops/crossplane/overview.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -id: crossplane -title: Crossplane -tags: [crossplane, devops, platform-engineering, cce, infrastructure] ---- - -# Crossplane - -[Crossplane](https://www.crossplane.io/) is an open-source Kubernetes add-on that extends Kubernetes' functionality by enabling it to manage infrastructure resources. It allows Kubernetes to serve as a control plane for provisioning and managing infrastructure such as databases, cloud services, and other external systems, similar to how it manages containerized applications. - -## Overview - -### Key Features - -1. **Infrastructure as Code**: Crossplane allows users to define and manage infrastructure using Kubernetes-native declarative configurations (YAML files), promoting consistency and version control. - -2. **Composability**: Crossplane enables users to create reusable infrastructure components, which can be composed into higher-level abstractions. This makes it easier to manage complex infrastructure setups. - -3. **Extensibility**: It supports a wide range of cloud providers (like AWS, GCP, Azure & Open Telekom Cloud) and on-premises environments. Users can extend Crossplane by writing their own custom resource definitions (CRDs) and controllers. - -4. **Seamless Integration**: By integrating with Kubernetes, Crossplane leverages Kubernetes' existing ecosystem, including its API, RBAC, and ecosystem tools, to provide a unified management interface. - -5. **Cross-Provider Portability**: Crossplane abstracts the underlying infrastructure provider details, allowing for easier migration and multi-cloud strategies. It offers a consistent API regardless of the provider. - -### How Crossplane Works - -- **Custom Resource Definitions (CRDs)**: Crossplane defines CRDs for various infrastructure resources (like databases, storage, networking, etc.). These CRDs extend Kubernetes' API to manage non-container resources. - -- **Controllers**: Crossplane controllers watch for changes to these CRDs and take actions to ensure that the current state matches the desired state, provisioning and managing resources as needed. - -- **Providers**: Crossplane uses providers to interact with specific cloud services or infrastructure resources. Providers encapsulate the logic for managing resources on different platforms. - -### Use Cases - -- **Cloud Resource Management**: Provision and manage cloud resources such as databases, virtual machines, and networking components using Kubernetes-native tools. -- **Hybrid Cloud Deployments**: Manage resources across multiple clouds and on-premises environments from a single control plane. -- **DevOps Automation**: Automate the lifecycle management of infrastructure alongside application deployment processes. - -Crossplane essentially brings the principles of Kubernetes orchestration to infrastructure management, enabling a more unified and streamlined approach to handling both application and infrastructure resources within the same ecosystem. - -:::note -You can read more in the official [Crossplane Documentation](https://docs.crossplane.io/v1.16/). -::: - -## Installing Crossplane - -:::note -In order to execute the rest of the blueprint, an existing CCE Cluster is necessary. -::: - -We are going to install Crossplane using the official Helm chart: - -```bash -helm repo add crossplane-stable https://charts.crossplane.io/stable -helm repo update - -helm install crossplane \ ---namespace crossplane-system \ ---create-namespace crossplane-stable/crossplane -``` - -After installing, the Helm chart will create two deployments in the `crossplane-system` namespace to deploy the Crossplane pods: - -```shell -kubectl get deployments -n crossplane-system - -NAME READY UP-TO-DATE AVAILABLE AGE -crossplane 1/1 1 1 8m13s -crossplane-rbac-manager 1/1 1 1 8m13s -``` - -## Installing Open Telekom Cloud Crossplane Provider - -Open Telekom Cloud comes with its own Crossplane provider ([provider-opentelekomcloud](https://github.com/opentelekomcloud/provider-opentelekomcloud)) that is built using [Upjet](https://github.com/crossplane/upjet) code generation tools and exposes XRM-conformant managed resources for the Open Telekom Cloud API. - -Deploy with `kubectl apply -f` the following manifests: - -1. Installing the Provider - - ```yaml title="provider.yaml" - apiVersion: pkg.crossplane.io/v1 - kind: Provider - metadata: - name: provider-opentelekomcloud - spec: - package: xpkg.upbound.io/opentelekomcloud/provider-opentelekomcloud:v0.1.0 - ``` - -2. Installing the Provider Credentials - - Pass the Open Telekom Cloud credentials as a Kubernetes `Secret`: - - ```yaml title="provider-creds.yaml" - apiVersion: v1 - kind: Secret - metadata: - name: provider-opentelekomcloud-creds - namespace: crossplane-system - type: Opaque - stringData: - credentials: | - { - "user_name": "${user_name}", - "password": "${password}", - "auth_url": "https://iam.eu-de.otc.t-systems.com/v3", - "domain_name": "OTC00000000001000XXXXX", - "tenant_name": "${tenant_name}", - "swauth": "false", - "allow_reauth": "true", - "max_retries": "2", - "max_backoff_retries": "6", - "backoff_retry_timeout": "60", - "insecure": "false" - } - ``` - - :::note - Fill in `user_name`, `password`, `domain_name` and `tenant_name` with your organization's values. - ::: - -3. Installing the Provider Configuration - - ```yaml title="provider-config.yaml" - apiVersion: opentelekomcloud.crossplane.io/v1beta1 - kind: ProviderConfig - metadata: - name: default - spec: - credentials: - source: Secret - secretRef: - name: provider-opentelekomcloud-creds - namespace: crossplane-system - key: credentials - ``` - -:::note -After a couple of minutes the `Provider` will deploy the necessary `Pod`s and `CRD`s of the Crossplane Provider for Open Telekom Cloud. -::: diff --git a/docs/blueprints/by-use-case/devops/index.md b/docs/blueprints/by-use-case/devops/index.md index 806edc2fb..818e9b1ea 100644 --- a/docs/blueprints/by-use-case/devops/index.md +++ b/docs/blueprints/by-use-case/devops/index.md @@ -5,9 +5,4 @@ title: DevOps # DevOps -The Computing section offers essential insights for optimizing computing resources. Discover guidelines for selecting -appropriate instance types, managing virtual machines efficiently, and leveraging auto-scaling capabilities for dynamic -workloads. Learn best practices for designing resilient and high-performance computing architectures, ensuring optimal -utilization of resources while maintaining cost-effectiveness. This section serves as a comprehensive guide for architects -and developers to fine-tune their computing strategies, enhancing the overall efficiency and reliability of applications -in the Open Telekom Cloud environment. +In this category, you can find guidance for implementing DevOps methodologies on Open Telekom Cloud. Topics include CI/CD pipelines, infrastructure as code, container orchestration, and monitoring tools. Here are also provided strategies for automating workflows, improving collaboration between development and operations teams, and optimizing deployment processes to achieve faster delivery cycles and maintain high-quality software. diff --git a/docs/blueprints/by-use-case/hybrid/_category_.json b/docs/blueprints/by-use-case/hybrid/_category_.json index ef822871d..112995aa9 100644 --- a/docs/blueprints/by-use-case/hybrid/_category_.json +++ b/docs/blueprints/by-use-case/hybrid/_category_.json @@ -1,7 +1,7 @@ { - "label": "Hybrid", + "label": "Hybrid & MultiCloud", "link": { "type": "doc", - "id": "Hybrid" + "id": "HybridAndMultiCloud" } } \ No newline at end of file diff --git a/docs/blueprints/by-use-case/hybrid/index.md b/docs/blueprints/by-use-case/hybrid/index.md index 3c4107bd8..2cb16e2c3 100644 --- a/docs/blueprints/by-use-case/hybrid/index.md +++ b/docs/blueprints/by-use-case/hybrid/index.md @@ -1,13 +1,8 @@ --- -id: Hybrid -title: Hybrid +id: HybridAndMultiCloud +title: Hybrid & MultiCloud --- -# Hybrid +# Hybrid & MultiCloud -The Computing section offers essential insights for optimizing computing resources. Discover guidelines for selecting -appropriate instance types, managing virtual machines efficiently, and leveraging auto-scaling capabilities for dynamic -workloads. Learn best practices for designing resilient and high-performance computing architectures, ensuring optimal -utilization of resources while maintaining cost-effectiveness. This section serves as a comprehensive guide for architects -and developers to fine-tune their computing strategies, enhancing the overall efficiency and reliability of applications -in the Open Telekom Cloud environment. +In this category, you can find guidance for designing and managing hybrid and multicloud solutions on Open Telekom Cloud. Topics include integration across on-premises, Open Telekom Cloud, and other cloud providers; workload distribution; data synchronization; and cross-cloud governance. Here are also provided architectural patterns, tools, and strategies to help organizations achieve flexibility, scalability, and resilience while maintaining security and compliance across diverse cloud environments. diff --git a/docs/blueprints/by-use-case/index.md b/docs/blueprints/by-use-case/index.md index b296a8b31..af8b52c5d 100644 --- a/docs/blueprints/by-use-case/index.md +++ b/docs/blueprints/by-use-case/index.md @@ -6,10 +6,6 @@ sidebar_position: 2 # By Use Case -Welcome to the Open Telekom Cloud Architecture Center Best Practices. -Here we provide crucial guidelines for optimizing cloud-based solutions with emphasis to architectural principles that -enhance reliability, scalability, and security. Explore our recommended strategies for resource management, such as -efficient utilization of compute and storage resources. Gain insights into designing for high availability and fault tolerance -to ensure robust system performance. This section serves as a valuable resource for architects and developers -to implement cloud solutions that align with industry best practices and maximize the benefits of the public cloud -infrastructure. +Here you can find guidance for implementing solutions on Open Telekom Cloud based on a wide range of use cases. Topics include containerized applications and orchestration with tools like Kubernetes, microservices architectures for building scalable and resilient systems, and DevOps practices for automating workflows and streamlining collaboration between development and operations teams. + +Additional topics cover disaster recovery strategies to ensure business continuity, big data processing for handling large-scale data analysis, AI and machine learning workloads for building intelligent applications, high-performance computing for resource-intensive tasks, serverless architectures for event-driven computing, and automation to optimize resource management and deployment processes. Here are also provided reference architectures, step-by-step guides, and real-world case studies to help organizations efficiently design, deploy, and scale cloud solutions tailored to their unique operational needs and business objectives. diff --git a/docs/blueprints/by-use-case/migration/index.md b/docs/blueprints/by-use-case/migration/index.md index d32ecb53e..d8cfb9ad8 100644 --- a/docs/blueprints/by-use-case/migration/index.md +++ b/docs/blueprints/by-use-case/migration/index.md @@ -5,9 +5,4 @@ title: Migration # Migration -The Computing section offers essential insights for optimizing computing resources. Discover guidelines for selecting -appropriate instance types, managing virtual machines efficiently, and leveraging auto-scaling capabilities for dynamic -workloads. Learn best practices for designing resilient and high-performance computing architectures, ensuring optimal -utilization of resources while maintaining cost-effectiveness. This section serves as a comprehensive guide for architects -and developers to fine-tune their computing strategies, enhancing the overall efficiency and reliability of applications -in the Open Telekom Cloud environment. +In this category, you can find guidance for planning and executing migrations to Open Telekom Cloud. Topics include migration strategies, tools for workload and data transfer, application modernization, and minimizing downtime during transitions. Here are also provided step-by-step approaches, case studies, and recommendations to ensure a smooth migration process while maintaining security, performance, and cost efficiency. diff --git a/docs/blueprints/by-use-case/networking/create-a-public-dns-endpoint-with-externaldns.md b/docs/blueprints/by-use-case/networking/create-a-public-dns-endpoint-with-externaldns.md new file mode 100644 index 000000000..1035a6562 --- /dev/null +++ b/docs/blueprints/by-use-case/networking/create-a-public-dns-endpoint-with-externaldns.md @@ -0,0 +1,150 @@ +--- +id: create-a-public-dns-endpoint-with-externaldns +title: Create a Public DNS Endpoint with ExternalDNS +tags: [cce, networking, dns, cname, externaldns] +--- + +# Create a Public DNS Endpoint with ExternalDNS + +[ExternalDNS](https://github.com/kubernetes-sigs/external-dns) is a Kubernetes component used to manage DNS records for services and applications running in a Kubernetes cluster. It automates the creation, update, and deletion of DNS records based on the state of resources within the cluster. ExternalDNS is typically employed in scenarios where you need to expose services running inside a Kubernetes cluster to the outside world with fully qualified domain names (FQDNs), ensuring they are accessible by external users. + +The most common use cases that ExternalDNS comes to apply are the following: + +1. **Expose Services via Custom DNS Names** + When you want to expose Kubernetes services (e.g., a web application or API) using custom DNS names, ExternalDNS automates the process. Instead of manually creating and updating DNS entries in your DNS provider (like Open Telekom Cloud DNS, AWS Route 53, Google Cloud DNS, or Azure DNS), ExternalDNS dynamically manages these records for you. + + - **Use case**: You deploy an app in Kubernetes, and you want it to be reachable via a domain like `app.example.com`. ExternalDNS can automatically configure the DNS provider to point `app.example.com` to the service's Elastic IP. + +2. **Automating DNS for Load Balancers** + ExternalDNS is often used with Elastic Load Balancers that expose CCE services. For instance, when you create a `LoadBalancer` type service, the Open Telekom Cloud can assign (if not requested otherwise) an Elastic IP. ExternalDNS will create the corresponding DNS record and map the FQDN to that IP address. + + - **Use case**: You have a service with type `LoadBalancer` on CCE, and ExternalDNS creates a Open Telekom Cloud DNS Record that points your desired domain (like `api.example.com`) to the public IP of the Elastic Load Balancer. + +3. **Handling Multi-Cluster or Multi-Region Deployments** + In multi-cluster or multi-region environments, you may want to expose services from multiple clusters under the same DNS domain. ExternalDNS helps manage DNS records across clusters to ensure traffic is routed to the right endpoints. It can help distribute traffic geographically using DNS routing mechanisms like geo-routing or latency-based routing. + + - **Use case**: You have a cross-region application deployed in multiple clusters in both Open Telekom Cloud regions (eu-de & eu-nl for that matter), and you want DNS to automatically direct users to the closest cluster. + +4. **Managing Dynamic or Short-Lived Services** + If your environment frequently scales up and down, with services being created and destroyed dynamically (e.g., in CI/CD pipelines or microservices architectures), ExternalDNS ensures that DNS records are kept up-to-date with these changes. + + - **Use case**: In a microservices architecture, as new versions of services are rolled out or as services are spun up and torn down, ExternalDNS updates DNS records to reflect these dynamic changes. + +5. **Integrating with Ingress Controllers** + When you use an Ingress controller (such as NGINX Ingress, Traefik or CCE) to expose services via HTTP/HTTPS, ExternalDNS can manage the DNS records for the hostnames defined in your Ingress resources. It ensures that DNS is automatically set up to direct traffic to the appropriate Ingress endpoints. + + - **Use case**: You define an Ingress rule to expose `blog.example.com` via an Ingress controller. ExternalDNS automatically creates or updates a DNS record to point to the Ingress endpoint. + +6. **Cloud-Native DNS Management** + In cloud-native environments where automation and scalability are key, ExternalDNS helps reduce manual intervention for DNS management. It integrates with Open Telekom Cloud DNS service to provide cloud-native DNS functionality for Kubernetes workloads. + + - **Use case**: ExternalDNS automatically manages DNS entries for applications, ensuring they remain aligned with the cluster’s state. + +7. **Managing Wildcard DNS Records** + In cases where you need to manage wildcard DNS entries, such as for multi-tenant applications or subdomain-based routing, ExternalDNS can handle the automatic creation and management of wildcard records for your Kubernetes/CCE services. + + - **Use case**: You have a wildcard DNS entry like `*.tenant.example.com`, and you want each tenant to be routed to different backend services based on the subdomain. ExternalDNS helps maintain the necessary DNS records. + +## Prerequisites + +For this blueprint we will assume the existence of one CCE Cluster and a domain that you own and you can configure its DNS behaviour/parameters by your registar. + +## Configuring your registar + +We have to transfer the management of the NS-Records of your domain to the Domain Name Service of Open Telekom +Cloud. Go on the site of your registar and make sure you configure the following: + +- Turn off any Dynamic DNS service for the domain or the subdomains you are going to bind with Open Telekom Cloud DNS. +- Change the NS-Records of your domain or the subdomains to point to:`ns1.open-telekom-cloud.com` **and** `ns2.open-telekom-cloud.com` + +If those two prerequisites are met, then you are ready to configure a new DNS Public Zone and Record Sets for your domain in Open Telekom +Cloud. We do have two mutually exclusive options to do that: + +- Create manually from Open Telekom Cloud Console, a new Public DNS Zone that binds to your domain and an A-Record in that zone that + points to the EIP of the Elastic Load Balancer. +- Automate everything using + [ExternalDNS](https://github.com/kubernetes-sigs/external-dns). + +## Creating a dedicated DNS Service Account + +Go to *IAM management console*, and create a new User that permits +**programmatic access** to Open Telekom Cloud resources: + +![image](/img/docs/blueprints/by-use-case/security/keycloak/SCR-20231212-dfp.png) + +Grant this User the following permissions or add him directly to User +Group `dns-admins` (if it exists, otherwise create it for a more rigid permissions management but that's completely optional) + +![image](/img/docs/blueprints/by-use-case/security/keycloak/SCR-20231212-df8.png) + +## Deploying ExternalDNS on CCE + +We are going to deploy ExternalDNS with Helm as well. First let's lay +down the configuration of the chart: + +```yaml title="overrides.yaml" linenos="" emphasize-lines="11,13-14" +sources: + - crd + - service + - ingress +provider: designate +combineFQDNAnnotation: true +crd: + create: true +logFormat: json +designate: + username: "OTCAC_DNS_ServiceAccount" + password: <> + authUrl: "https://iam.eu-de.otc.t-systems.com:443/v3" + regionName: "eu-de" + userDomainName: "OTCXXXXXXXXXXXXXXXXXXXX" + projectName: "eu-de_XXXXXXXXXXX" +``` + +:::warning +Special attention required here. Although DNS is a global +service, **all** changes have to be applied in Region **eu-de**. +::: + +Install the chart (it will deploy all the necessary resources in an +automatically created namespace called `external-dns`: + +```shell +helm repo add bitnami https://charts.bitnami.com/bitnami +helm repo update + +helm upgrade --install -f overrides.yaml external-dns bitnami/external-dns -n external-dns --create-namespace +``` + +## Verification + +We have now laid all the groundwork in order to automatically provision +a Public DNS Zone and a dedicated A-Record that will bind the Elastic IP of our +Elastic Load Balancer with the FQDN of thesubdomain we configure above. For that matter we need to install +a Custom Resource based on a CRD installed by ExternalDNS that is called `DNSEndpoint`: + +```yaml title="dns-endpoint.yaml" +apiVersion: externaldns.k8s.io/v1alpha1 +kind: DNSEndpoint +metadata: + name: keycloak + namespace: keycloak +spec: + endpoints: + - dnsName: blog.example.com + recordTTL: 300 + recordType: A + targets: + - XXX.XXX.XXX.XXX +``` + +:::note +Replace the placeholder value `XXX.XXX.XXX.XXX` of `targets` with the Elastic IP Address that is +assigned to your Elastic Load Balancer. Additionally, replace the value of `dnsName` with the FQDN of your (sub)domain. +::: + +Wait for a couple of seconds, till the reconciliation loop of the +ExternalDNS controller is done, and if all went well you should now see +the Record Sets of your Public Zone populated with various entries: + +![image](/img/docs/blueprints/by-use-case/security/keycloak/SCR-20231212-dsj.png) \ No newline at end of file diff --git a/docs/blueprints/by-use-case/networking/index.md b/docs/blueprints/by-use-case/networking/index.md index 7533cccd6..c88af8ef4 100644 --- a/docs/blueprints/by-use-case/networking/index.md +++ b/docs/blueprints/by-use-case/networking/index.md @@ -5,9 +5,4 @@ title: Networking # Networking -The Computing section offers essential insights for optimizing computing resources. Discover guidelines for selecting -appropriate instance types, managing virtual machines efficiently, and leveraging auto-scaling capabilities for dynamic -workloads. Learn best practices for designing resilient and high-performance computing architectures, ensuring optimal -utilization of resources while maintaining cost-effectiveness. This section serves as a comprehensive guide for architects -and developers to fine-tune their computing strategies, enhancing the overall efficiency and reliability of applications -in the Open Telekom Cloud environment. +In this category, you can find guidance for designing and managing networking solutions on Open Telekom Cloud. Topics include network architecture, virtual private clouds (VPCs), load balancing, VPNs, and network security. Here are also provided strategies for optimizing network performance, ensuring high availability, and implementing secure and scalable connectivity across different cloud environments. diff --git a/docs/blueprints/by-use-case/observability/index.md b/docs/blueprints/by-use-case/observability/index.md index 71365a9b9..3dd979ba7 100644 --- a/docs/blueprints/by-use-case/observability/index.md +++ b/docs/blueprints/by-use-case/observability/index.md @@ -5,9 +5,4 @@ title: Observability # Observability -The Computing section offers essential insights for optimizing computing resources. Discover guidelines for selecting -appropriate instance types, managing virtual machines efficiently, and leveraging auto-scaling capabilities for dynamic -workloads. Learn best practices for designing resilient and high-performance computing architectures, ensuring optimal -utilization of resources while maintaining cost-effectiveness. This section serves as a comprehensive guide for architects -and developers to fine-tune their computing strategies, enhancing the overall efficiency and reliability of applications -in the Open Telekom Cloud environment. +In this category, you can find guidance for implementing observability solutions on Open Telekom Cloud. Topics include monitoring, logging, tracing, and metrics collection for cloud-native applications and infrastructure. Here are also provided strategies and tools for gaining deep insights into system performance, detecting anomalies, ensuring operational efficiency, and maintaining high availability across environments. diff --git a/docs/blueprints/by-use-case/security/authentik/1_cce-authentik.md b/docs/blueprints/by-use-case/security/authentik/1_cce-authentik.md new file mode 100644 index 000000000..63bb8a1a8 --- /dev/null +++ b/docs/blueprints/by-use-case/security/authentik/1_cce-authentik.md @@ -0,0 +1,100 @@ +--- +id: cce-authentik +title: Deploy Authentik on CCE +tags: [cce, authentik, security, ingress, nginx-ingress] +--- + +# Deploy Authentik on CCE + +This tutorial will guide you through the process of setting up authentik on your CCE Kubernetes environment. + +### Prerequisites + +Before starting the installation, ensure you have the following: + +- A running Kubernetes cluster (CCE) +- Helm installed on your local machine + +### Generating Secure Passwords + +Begin by generating secure passwords for the database and cache. Use one of these commands: + +```shell +pwgen -s 50 1 +``` + +or + +```shell +openssl rand 60 | base64 -w 0 +``` + +### Creating the Values File + +1. Create a file named **values.yaml** in your working directory. +2. Add the following content to the file: + +```yaml title="values.yaml" +authentik: + secret_key: "PleaseGenerateASecureKey" + error_reporting: + enabled: true + postgresql: + password: "ThisIsNotASecurePassword" + +server: + ingress: + ingressClassName: nginx + enabled: true + hosts: + - authentik.test-domain.com + +postgresql: + enabled: true + auth: + password: "ThisIsNotASecurePassword" +redis: + enabled: true +``` + +:::note + +- Replace `PleaseGenerateASecureKey` and `ThisIsNotASecurePassword` with secure passwords you generated earlier. +- Here we are using nginx as ingress controller if you use other ingress controller (like traefik or kong) specify it under path `server.ingress.ingressClassName`. Also replace `authentik.test-domain.com` with the domain name you intend for Authentik. + +::: + +### Installing Authentik Using Helm + +1. Add the authentik Helm repository: + + ```shell + helm repo add authentik https://charts.goauthentik.io + ``` + +2. Update your Helm repositories: + + ```shell + helm repo update + ``` + +3. Install authentik using Helm: + + ```shell + helm upgrade --install authentik authentik/authentik -f values.yaml + ``` + + This command will install authentik or upgrade an existing installation using the values specified in your **values.yaml** file. + +### Accessing Authentik + +Once the installation is complete, you can access authentik by following these steps: + +1. Open your web browser and navigate to `https:///if/flow/initial-setup/`. +2. Set a password for the default `akadmin` user. + +Setting admin password for first time: +![image](/img/docs/blueprints/by-use-case/security/authentik/Screenshot-chpassword-authentik.png "Setting admin password for first time") + +Authentik dashboard: +![image](/img/docs/blueprints/by-use-case/security/authentik/Screenshot-Admin-authentik.png "Authentik dashboard") diff --git a/docs/blueprints/by-use-case/security/authentik/2_identity-federation-github.md b/docs/blueprints/by-use-case/security/authentik/2_identity-federation-github.md new file mode 100644 index 000000000..44d41cbb5 --- /dev/null +++ b/docs/blueprints/by-use-case/security/authentik/2_identity-federation-github.md @@ -0,0 +1,246 @@ +--- +id: identity-federation-github +title: Identity Federation with GitHub +tags: [github, security, github, oauth2, federation] +--- + + +# Identity Federation with GitHub + +Identity Federation with GitHub refers to the process of allowing users to authenticate using their GitHub credentials to access various applications and services. This method leverages GitHub as an identity provider (IdP), enabling single sign-on (SSO) capabilities and simplifying user management across different platforms. + +## How It Works + +1. **User Initiates Login**: When a user attempts to access an application, they are presented with an option to log in using GitHub. +2. **Redirection to GitHub**: The application redirects the user to GitHub's authentication page. +3. **User Authenticates**: The user enters their GitHub credentials (username and password) to log in. +4. **GitHub Issues Token**: Upon successful authentication, GitHub generates an OAuth token and sends it back to the application. +5. **Token Validation**: The application validates the token with GitHub to ensure its authenticity. +6. **Access Granted**: Once validated, the user is granted access to the application based on their GitHub identity and associated permissions. + +## Benefits + +- **Simplified User Management**: Administrators can manage user access through GitHub, reducing the need to maintain separate credentials for each application. +- **Enhanced Security**: By using GitHub's robust authentication mechanisms, applications can benefit from multi-factor authentication (MFA) and other security features. +- **Improved User Experience**: Users can access multiple applications with a single set of credentials, reducing login fatigue and enhancing productivity. +- **Centralized Identity Management**: Organizations can centralize their identity management practices, making it easier to enforce security policies and compliance requirements. + +## Use Cases + +- **Development Environments**: Developers can use their GitHub accounts to access development tools, repositories, and CI/CD pipelines without needing to manage multiple logins. +- **Corporate Applications**: Employees can use their GitHub credentials to access internal corporate applications, streamlining the onboarding process and enhancing security. +- **Open Source Projects**: Open source contributors can authenticate using their GitHub accounts, ensuring a seamless experience across various project management and collaboration tools. + +## Connecting Authentik with GitHub for Federation and Social Login + +This guide will walk you through the process of setting up GitHub as an authentication source in authentik, allowing users to log in using their GitHub credentials. + +### Prerequisites + +Before you begin, make sure you have: + +- An authentik installation +- Access to your GitHub account +- Administrative access to both authentik and GitHub + +:::note Note +Throughout this guide, we'll use the following placeholders: + +- `authentik.test-domain.com` as the FQDN of your authentik installation +- `test-domain.com` as your site's homepage URL +::: + +### Setting up GitHub OAuth App + +1. Go to GitHub Developer Settings: https://github.com/settings/developers +2. Click on *Register a new application* + ![image](/img/docs/blueprints/by-use-case/security/authentik/github-create-oauth-app.png) +3. Fill in the application details: + - *Application Name*: Choose a recognizable name (e.g., "authentik") + - *Homepage URL*: Enter your site's URL (e.g., `www.test-domain.com`) + - *Authorization callback URL*: `https://authentik.test-domain.com/source/oauth/callback/github` + ![image](/img/docs/blueprints/by-use-case/security/authentik/github-New-OAuth-Application.png) +4. Click *Register Application* +5. On the next page, note down the *Client ID* +6. Click *Generate a new client secret* and immediately copy it + +:::warning +You won't be able to see the client secret again, so make sure to save it securely. +::: + +### Configuring Authentik + +1. In authentik, navigate to *Directory -> Federation & Social login* +2. Click *Create -> Github OAuth Source* +3. Fill in the source details: + - *Name*: Choose a name (e.g., "GitHub") + - *Slug*: `github` (or choose a custom slug, but remember to update URLs accordingly) + - *Consumer Key*: Paste the Client ID from GitHub + - *Consumer Secret*: Paste the Client Secret from GitHub + ![image](/img/docs/blueprints/by-use-case/security/authentik/github-idp-configuration.png) + +4. Save the configuration + +:::tip +The *User Matching Mode* in Authentik can be configured to match users based on different identifiers including `email` or `username` + +- **Email Matching**: This mode matches users based on their email address. It is often the most reliable option because email addresses are generally unique and consistent across different platforms. However, you must ensure that users' email addresses are standardized across all identity providers. There is also a risk if users have multiple accounts with different email addresses. Also the admin should make sure that the Email is already validated. + +- **Username Matching**: This mode matches users based on their username. This can be useful in environments where usernames are more consistent or standardized across systems. However, it poses a higher risk of conflicts, especially if users have different usernames on different platforms. It's crucial to ensure that usernames are unique and managed consistently to avoid potential mismatches or user duplication. + +When selecting the matching mode, carefully consider the consistency and uniqueness of either the email or username across the identity providers you plan to integrate. +::: + +Your GitHub OAuth Source in authentik is now set up and ready to use. + +### Adding the GitHub Source to the Login Page + +To make the GitHub login option visible on your authentik login page, you'll need to add it to your login flow. Refer to the [authentik documentation](https://docs.goauthentik.io/docs/sources#add-sources-to-default-login-page) for detailed steps on how to add sources to the default login page. + +### Adding GitHub Users to a Default Group + +To automatically add users who log in via GitHub to a default group in authentik, you can use a post-authentication flow. This process involves creating a group, setting up a policy, and adding the policy to a flow that runs after successful authentication. Here's how to do it: + +#### Step 1: Create a New Group + +1. Go to *Directory -> Groups* +2. Click *Create* +3. Name the group (e.g., "gitHub-users") + ![image](/img/docs/blueprints/by-use-case/security/authentik/create-group.png) +4. Save the group + +#### Step 2: Modifying Enrollment flow + +1. Navigate to *Flows and Stages -> Flows* +2. Under *Enrollment* section select the enrollment flow which is connected to the Github OAuth Source its default name is *default-source-enrollment* +3. Click *Stage Bindings* +4. Click *Edit Stage* of stage which has type of *User Write Stage* +5. Set a default group under *Group* for the newly created users which login using github + ![image](/img/docs/blueprints/by-use-case/security/authentik/configure-groups-enrollment-stage.png) +6. Click *Update* + +#### Step 4: Configure Post-Authentication Flow + +- If you created a new Enrollment flow, make sure it's set as a *Enrollment flow* in your *Github OAuth Source* configuration +- If you're using an existing flow, verify that it runs after successful authentication + +Now, when users log in successfully via GitHub, they will be automatically added to the specified group. This allows you to manage permissions and access control for GitHub users more easily within authentik. + +:::note Note +Remember to test this setup thoroughly in a non-production environment before implementing it in your live system. Ensure that the group assignment works as expected and doesn't interfere with other authentication processes. +::: + +### Checking GitHub Organization Membership + +If you want to restrict access to users who are members of a specific GitHub organization, you can implement a policy in your authentik flows. This feature requires authentik version 2021.12.5 or later. + + +:::danger Security Risk +It is crucial to verify that users belong to a specific GitHub organization before granting them access to your resources. Failing to implement this check can pose a significant security threat to your tenant. + +Without verifying GitHub organization membership, anyone with a GitHub account could potentially log in to your system, which would leave your tenant open to unauthorized access. This effectively makes your application public, which is a severe security concern. + +- **B2C Scenario Exception**: If you are intentionally offering a B2C (Business-to-Consumer) authentication for a SaaS (Software as a Service) scenario, bypassing this check might be acceptable. However, in most cases this should be strictly prohibited to prevent unauthorized access. +::: + + +1. Navigate to *Directory -> Federation and Social login* and edit previously created Github OAuth Source +2. Add the `read:org` scope to your GitHub OAuth Source and save it +3. Then navigate to *Flows and Stages -> Flows -> Enrollment* and click `default-source-enrollment` +4. Go to the *Policy / Group / User Bindings* tab, then *Create and bind Policy* +5. Create a new policy of type *Expression Policy* with the following Python code as *Expression*: + + + ```python + # Ensure flow is only run during oauth logins via Github + if context["source"].provider_type != "github": + return True + + accepted_org = "your_org_name" + + connection = context["goauthentik.io/sources/connection"] + access_token = connection.access_token + github_username = context["oauth_userinfo"] + + orgs_response = requests.get( + "https://api.github.com/user/orgs", + auth=(github_username["login"], access_token), + headers={ + "accept": "application/vnd.github.v3+json" + } + ) + orgs_response.raise_for_status() + orgs = orgs_response.json() + + user_matched = any(org['login'] == accepted_org for org in orgs) + if not user_matched: + ak_message(f"User is not member of {accepted_org}.") + return user_matched + ``` +6. Under *Edit Binding* ensure that the policy is Enabled and *Failure result* is *Don't pass* and save the policy. +7. Go back and edit the `default-source-enrollment` flow, under *Behavior settings* ensure that *Denied action* is set to `MESSAGE` and *Policy engine mode* is set to `all` + +:::tip +For Authentik to successfully check a user's membership in a GitHub organization, the following condition must be met: + +- **OAuth App Configuration**: The *Github OAuth App* used for authentication should either be created by the GitHub organization or explicitly trusted by the organization. If the OAuth App is created by a different user or organization, the GitHub organization must trust the app for Authentik to retrieve and verify the organizations to which the user belongs. + +Ensuring these configurations are in place is essential for the secure and correct functioning of the organization membership verification policy. +::: + +:::info +This part is taken form official [authentik documentation](https://docs.goauthentik.io/docs/sources/github/#checking-for-membership-of-a-github-organisation). +::: + +## IAM Identity Provider Conversion Rules + + +After creating and connecting the Identity provider on your tenant to the authentik if you wish to give users which login with github access to your tenant you can use the following conversion rules. + +:::info +If you haven't created a Identity Provider on your tenant first follow steps described in [Connecting Authentik with IAM for Login](./3_authentik-as-identity-provider-iam.md) and then use the conversion rules given below. +::: + + +Edit the conversion rule of previously created Identity Provider in IAM: + + +Paste the following conversion rule in the *Edit Rule* panel: + +```json +[ + { + "remote": [ + { + "type": "email" + }, + { + "any_one_of": [ + "github-users" + ], + "type": "groups" + } + ], + "local": [ + { + "user": { + "name": "fidp-{0}" + } + }, + { + "group": { + "name": "ecs-admin" + } + } + ] + } +] +``` + +The *remote* part describes the requested *Scopes* (``profile`` or ``email``) of the user. +The *local* part defines the mapping between the remote properties and the local IAM. The user will get a ``name`` +as the value of ``fidp-`` and will automatically belong to the ``ecs-admin`` if it is a member of ``github-users``. + +:::warning +Notice that the *ecs-admin* group is created in advanced so the IAM can find the group locally and it would automatically add all the users which belong to the *github-users* in remote identity provider to this local group. If it cannot match the user to any group the access of the user would be simply denied. +::: \ No newline at end of file diff --git a/docs/blueprints/by-use-case/security/authentik/3_authentik-as-identity-provider-iam.md b/docs/blueprints/by-use-case/security/authentik/3_authentik-as-identity-provider-iam.md new file mode 100644 index 000000000..1603f07bc --- /dev/null +++ b/docs/blueprints/by-use-case/security/authentik/3_authentik-as-identity-provider-iam.md @@ -0,0 +1,153 @@ +--- +id: authentik-as-identity-provider-iam +title: Authentik as an Identity Provider for IAM +tags: [security, oauth2, iam, authentik] +--- +# Authentik as an Identity Provider for IAM + +This guide will walk you through the process of integrating authentik, with Identity and Access Management (IAM) of Open Telekom Cloud using OAuth 2.0. + +## Prerequisites + +Before starting the integration, ensure you have: + +- An authentik installation up and running +- Administrative privileges on both authentik and your IAM system +- Basic understanding of OAuth 2.0 concepts and flows + + +## Configuring Authentik as an OAuth Provider + +1. Log in to your authentik admin panel +2. Navigate to *Applications -> Providers* +3. Create a new OAuth2/OpenID Provider +4. Configure the provider settings: + - Name: Give your provider a descriptive name + - Client type: Public + - Client ID: Auto-generated or specify your own + - Redirect URIs: Enter the callback URL from your IAM: `https://auth.otc.t-systems.com/authui/oidc/post` + - Under Advanced protocol settings -> Scopes: Select the required scopes (e.g., openid, profile, email, groups) + ![image](/img/docs/blueprints/by-use-case/security/authentik/create-oauth.png) +5. Save the provider configuration +6. Note down the Client ID, and Authorization/Token endpoints + +## Configuring IAM + +### Create a new IAM Identity Provider + +1. Log in to your Open Telekom Cloud Console +2. Navigate to *IAM and Identity Providers* under *Management & Deployment* +3. Select *Identity Providers* and click *Create Identity Provider* to create a new identity provider with the following values: + - Name: Give your provider a descriptive name + - Protocol: *OpenID Connect* + - SSO Type: *Virtual User* + - Status: *Enabled* + ![image](/img/docs/blueprints/by-use-case/security/authentik/create-idp-iam.png) + +### Configure the IAM Identity Provider + +Find your newly created provider in Identity Providers list and click *Modify*: + +![image](/img/docs/blueprints/by-use-case/security/authentik/modify-idp-iam.png) + +Set the following values: + +- **Access Type**: *Programmatic access and management console access* +- **Identity Provider URL**: URL of authentik (e.g. `https://test-domain.com/application/o/authentik-iam/`) +- **Client ID**: The id of your client as defined in *Configuring Authentik as an OAuth Provider* +- **Authorization Endpoint**: copy the value from key *authorization_endpoint* of the *OpenID Endpoint Configuration* (e.g. `https://test-domain.com/application/o/authorize/`) +- **Scopes**: Select the required scopes (e.g., openid, profile, email, groups) +- **Response Mode**: `form_post` +- **Signing Key**: Value of the key `jwks_uri` of the *OpenID Endpoint Configuration* JSON output + ![image](/img/docs/blueprints/by-use-case/security/authentik/configure-idp-iam.png) + +:::note +All of the links for your setup can be found under *Overview* page of the *OAuth2/OpenID Provider* in Authentik admin dashboard. +![image](/img/docs/blueprints/by-use-case/security/authentik/authentik-idp-urls.png) +::: + +:::info +For the *Signing Key* you should open link provided under *JWKS URL* and copy the whole json file content to the respective field. +::: + + +## Creating an Application and Connecting the Provider + +To enable users to authenticate, you need to create an application in Authentik and connect it to the provider. Follow these steps: + + +1. In the Authentik web interface, navigate to *Applications* -> *Applications*. +2. Click on *Create*. +3. Fill in the following details: + - **Name**: `Your Application Name` + - **Slug**: `your-application-slug` + - **Provider**: Select the provider you created earlier. + - **Launch URL**: Specify the URI where Authentik should redirect users after authentication. You can find this link under *Programmatic access and management console accesses* of the previously created Identity provider in your tenant. + +![image](/img/docs/blueprints/by-use-case/security/authentik/create-application.png) + +1. Save the application settings. + + + +## Configure the IAM Identity Provider Conversion Rules + +You can use [identity conversion rules](https://docs.otc.t-systems.com/identity-access-management/umn/user_guide/identity_providers/virtual_user_sso_via_openid_connect/step_2_configure_identity_conversion_rules.html) to map the identities of existing users to Open Telekom Cloud and control their access to cloud resources. + +By default federated users are named *FederationUser* in the Open Telekom Cloud platform. These users can only log in to +the cloud platform and they do not have **any** other permissions. You can configure identity conversion rules on the +IAM console to achieve the following: + +- Display enterprise users with different names in the cloud platform. +- Assign permissions to enterprise users to use the cloud platform resources by mapping these users to IAM user groups. + Ensure that you have created the required user groups. + +This can be done by editing the Identity Conversion Rules. Edit the conversion rule of previously created Identity Provider in IAM: + +![image](/img/docs/blueprints/by-use-case/security/authentik/edit-conversion-rules.png) + +Paste the following conversion rule in the *Edit Rule* panel: + +```json +[ + { + "remote": [ + { + "type": "email" + }, + { + "type": "groups" + } + ], + "local": [ + { + "user": { + "name": "fidp-{0}" + } + }, + { + "groups": "{1}" + } + ] + } +] +``` + +The *remote* part describes the requested *Scopes* (``profile`` or ``email``) of the user. +The *local* part defines the mapping between the remote properties and the local IAM. The user will get a ``name`` +as the value of ``fidp-`` and will automatically belong to the groups on your tenant which have the same name as the groups that the user is a member of on authentik. + +:::danger +Administrators must exercise extreme caution when naming groups in Authentik. Group names are critical because conversion rules within the Identity provider automatically assign users to groups based on these names in this configuration. + +If a group is improperly named or if the naming conventions are not strictly followed, users might be incorrectly assigned to sensitive groups. This misconfiguration could grant unauthorized users elevated permissions or access to restricted resources, thereby posing a significant security risk to the tenant. + +Always use clear, descriptive, and unique names for groups that align with your access control policies. Regularly review and audit group names and associated conversion rules to ensure they are correctly configured and do not inadvertently expose the tenant to security vulnerabilities. +::: + +:::info +You can find more detailed info about *Conversion Rules* under: + +- [Configure Identity Conversion Rules](https://docs.otc.t-systems.com/identity-access-management/umn/user_guide/identity_providers/virtual_user_sso_via_openid_connect/step_2_configure_identity_conversion_rules.html) +- [Syntax of Identity Conversion Rules](https://docs.otc.t-systems.com/identity-access-management/umn/user_guide/identity_providers/syntax_of_identity_conversion_rules.html#en-us-topic-0079620340) +::: diff --git a/docs/blueprints/by-use-case/security/authentik/_category_.json b/docs/blueprints/by-use-case/security/authentik/_category_.json new file mode 100644 index 000000000..866a7a442 --- /dev/null +++ b/docs/blueprints/by-use-case/security/authentik/_category_.json @@ -0,0 +1,7 @@ +{ + "label": "Authentik", + "link": { + "type": "doc", + "id": "authentik" + } +} \ No newline at end of file diff --git a/docs/blueprints/by-use-case/security/authentik/overview.md b/docs/blueprints/by-use-case/security/authentik/overview.md new file mode 100644 index 000000000..f457c663f --- /dev/null +++ b/docs/blueprints/by-use-case/security/authentik/overview.md @@ -0,0 +1,55 @@ +--- +id: authentik +title: Authentik +tags: [authentik, security] +--- + +# Authentik + +## Overview + +Authentik is a modern, open-source Identity Provider (IdP) that offers flexible and secure authentication and authorization solutions for organizations of all sizes. It provides a comprehensive suite of identity management features, allowing businesses to centralize user authentication, implement single sign-on (SSO), and manage access to various applications and services. + +## Key Features + +- **Single Sign-On (SSO)**: Enables users to access multiple applications with a single set of credentials. +- **Multi-Factor Authentication (MFA)**: Supports various second-factor methods for enhanced security. +- **User Lifecycle Management**: Facilitates user provisioning, de-provisioning, and self-service capabilities. +- **Access Control**: Provides fine-grained access policies based on user attributes and context. +- **Federation**: Supports identity federation protocols like SAML, OAuth 2.0, and OpenID Connect. +- **Customizable UI**: Offers a flexible, brandable user interface for login and self-service pages. +- **API-first Design**: Enables easy integration and automation with other systems. + +## Use Cases + +1. **Enterprise SSO**: Centralize authentication for all corporate applications. +2. **Customer Identity and Access Management (CIAM)**: Manage customer identities and access to services. +3. **API Security**: Secure APIs using OAuth 2.0 and OpenID Connect. +4. **DevOps and Infrastructure Access**: Control access to development and infrastructure resources. +5. **Compliance and Auditing**: Meet regulatory requirements with comprehensive logging and reporting. + +## Architecture + +Authentik is designed with a modular, microservices-based architecture that ensures scalability and flexibility. The main components include: + +1. **Core Service**: Handles the core logic, user management, and policy decisions. +2. **Web Interface**: Provides the user-facing frontend for authentication and self-service. +3. **API**: Offers a RESTful API for integration and automation. +4. **Outposts**: Edge proxies that can be deployed close to applications for improved performance and offline capabilities. +5. **Providers**: Modules that implement various authentication and federation protocols. +6. **Stages**: Configurable authentication steps that can be combined to create complex flows. +7. **Policies**: Rules that determine access rights and trigger actions based on conditions. + +## Integration + +Authentik integrates with a wide range of systems and protocols, including: + +- LDAP and Active Directory +- SAML 2.0 +- OAuth 2.0 and OpenID Connect +- SCIM for user provisioning +- Various MFA providers (TOTP, WebAuthn, etc.) + +:::warning +While Authentik provides a comprehensive identity management solution, proper configuration and security best practices are essential for maintaining a secure environment. +::: diff --git a/docs/blueprints/by-use-case/security/cce-vault.md b/docs/blueprints/by-use-case/security/cce-vault.md index 0bf986ff4..23d1d8170 100644 --- a/docs/blueprints/by-use-case/security/cce-vault.md +++ b/docs/blueprints/by-use-case/security/cce-vault.md @@ -1,7 +1,7 @@ --- id: cce-vault title: Secrets management with CCE and Hashicorp Vault -tags: [cce, vault, hashicorp, security] +tags: [cce, vault, hashicorp, secrets] --- # Secrets management with CCE and Hashicorp Vault diff --git a/docs/blueprints/by-use-case/security/index.md b/docs/blueprints/by-use-case/security/index.md index 05009c618..f14f7ccab 100644 --- a/docs/blueprints/by-use-case/security/index.md +++ b/docs/blueprints/by-use-case/security/index.md @@ -5,9 +5,4 @@ title: Security # Security -The Computing section offers essential insights for optimizing computing resources. Discover guidelines for selecting -appropriate instance types, managing virtual machines efficiently, and leveraging auto-scaling capabilities for dynamic -workloads. Learn best practices for designing resilient and high-performance computing architectures, ensuring optimal -utilization of resources while maintaining cost-effectiveness. This section serves as a comprehensive guide for architects -and developers to fine-tune their computing strategies, enhancing the overall efficiency and reliability of applications -in the Open Telekom Cloud environment. +In this category, you can find guidance for implementing robust security solutions on Open Telekom Cloud. Topics include identity and access management, data encryption, network security, and compliance frameworks. Here are also provided strategies for safeguarding applications, securing workloads, and ensuring regulatory compliance, all while maintaining a strong security posture across cloud environments. diff --git a/docs/blueprints/by-use-case/security/keycloak/cce-keycloak.md b/docs/blueprints/by-use-case/security/keycloak/cce-keycloak.md index 7d5c85d00..6c097e4f1 100644 --- a/docs/blueprints/by-use-case/security/keycloak/cce-keycloak.md +++ b/docs/blueprints/by-use-case/security/keycloak/cce-keycloak.md @@ -1,7 +1,7 @@ --- id: cce-keycloak title: Deploy Keycloak on CCE -tags: [cce, keycloak, security, rds, postgresql, ingress, nginx-ngress, externaldns, dns] +tags: [cce, keycloak, security, rds, postgresql, ingress, nginx-ingress, externaldns, dns] --- # Deploy Keycloak on CCE @@ -422,74 +422,8 @@ Elastic Load Balancer. #### Creating the Endpoint with ExternalDNS -What is ExternalDNS? Quoting directly from the official repo of the -project: - -*Inspired by Kubernetes DNS, Kubernetes' cluster-internal DNS server, -ExternalDNS makes Kubernetes resources discoverable via public DNS -servers. Like KubeDNS, it retrieves a list of resources (Services, -Ingresses, etc.) from the Kubernetes API to determine a desired list of -DNS records. Unlike KubeDNS, however, it's not a DNS server itself, but -merely configures other DNS providers accordingly---e.g. AWS Route 53 or -Google Cloud DNS.* - -*In a broader sense, ExternalDNS allows you to control DNS records -dynamically via Kubernetes resources in a DNS provider-agnostic way.* - -##### Deploying ExternalDNS on CCE - -We are going to deploy ExternalDNS with Helm as well. First let's lay -down the configuration of the chart: - -```yaml title="overrides.yaml" linenos="" emphasize-lines="11,13-14" -sources: - - crd - - service - - ingress -provider: designate -combineFQDNAnnotation: true -crd: - create: true -logFormat: json -designate: - username: "OTCAC_DNS_ServiceAccount" - password: <> - authUrl: "https://iam.eu-de.otc.t-systems.com:443/v3" - regionName: "eu-de" - userDomainName: "OTCXXXXXXXXXXXXXXXXXXXX" - projectName: "eu-de_XXXXXXXXXXX" -``` - -:::warning -Special attention required at **lines 13,14**. Although DNS is a global -service, **all** changes have to be applied in Region **eu-de**. -::: - -Install the chart (it will deploy all the necessary resources in an -automatically created namespace called `external-dns`: - -```shell -helm repo add bitnami https://charts.bitnami.com/bitnami -helm repo update - -helm upgrade --install -f overrides.yaml external-dns bitnami/external-dns -n external-dns --create-namespace -``` - -##### Creating a dedicated DNS Service Account - -:::note -This is required **only** when ExternalDNS is used. -::: - -Go to IAM management console, and create a new User that permits -programmatic access to Open Telekom Cloud resources: - -![image](/img/docs/blueprints/by-use-case/security/keycloak/SCR-20231212-dfp.png) - -Grant this User the following permissions or add him directly to User -Group `dns-admins` (if it exists) - -![image](/img/docs/blueprints/by-use-case/security/keycloak/SCR-20231212-df8.png) +Alternatively, we can automate the whole process by using ExternalDNS. You can find the necessary steps in blueprint: +[Create a Public DNS Endpoint with ExternalDNS](../../networking/create-a-public-dns-endpoint-with-externaldns.md). ##### Deploying a Keycloak Endpoint diff --git a/docs/blueprints/by-use-case/storage/index.md b/docs/blueprints/by-use-case/storage/index.md index d3a2897ff..f1a538624 100644 --- a/docs/blueprints/by-use-case/storage/index.md +++ b/docs/blueprints/by-use-case/storage/index.md @@ -5,9 +5,4 @@ title: Storage # Storage -The Computing section offers essential insights for optimizing computing resources. Discover guidelines for selecting -appropriate instance types, managing virtual machines efficiently, and leveraging auto-scaling capabilities for dynamic -workloads. Learn best practices for designing resilient and high-performance computing architectures, ensuring optimal -utilization of resources while maintaining cost-effectiveness. This section serves as a comprehensive guide for architects -and developers to fine-tune their computing strategies, enhancing the overall efficiency and reliability of applications -in the Open Telekom Cloud environment. +In this category, you can find guidance for designing and managing storage solutions on Open Telekom Cloud. Topics include block storage, object storage, file storage, and data backup strategies. Here are also provided recommendations for optimizing storage performance, ensuring data durability, and implementing cost-efficient storage architectures that meet the needs of various workloads. diff --git a/docs/blueprints/index.md b/docs/blueprints/index.md index f6fc4bf2e..b22d500b2 100644 --- a/docs/blueprints/index.md +++ b/docs/blueprints/index.md @@ -6,10 +6,6 @@ sidebar_position: 1 # Blueprints -Welcome to the Open Telekom Cloud Architecture Center Best Practices. -Here we provide crucial guidelines for optimizing cloud-based solutions with emphasis to architectural principles that -enhance reliability, scalability, and security. Explore our recommended strategies for resource management, such as -efficient utilization of compute and storage resources. Gain insights into designing for high availability and fault tolerance -to ensure robust system performance. This section serves as a valuable resource for architects and developers -to implement cloud solutions that align with industry best practices and maximize the benefits of the public cloud -infrastructure. +Welcome to the Open Telekom Cloud Architecture Center Best Practices. This section offers comprehensive guidance for designing and implementing cloud solutions tailored to various use cases and industries. Here you can find pre-built architectures and reference models for a wide range of scenarios, such as disaster recovery, big data processing, AI/ML workloads, microservices, DevOps, and automation. These blueprints provide organizations with step-by-step guides, architectural patterns, and real-world case studies, helping them quickly deploy cloud solutions that address specific operational needs and optimize workflows while ensuring scalability, security, and cost-efficiency. + +Additionally, *Blueprints* are organized into two key areas: "Blueprints by Use Cases" and "Blueprints by Industry." The former focuses on general-purpose solutions that address common business and technical challenges, while the latter provides industry-specific architectures that meet the unique regulatory and operational requirements of sectors such as aerospace, finance, government, healthcare, and telecommunications. By leveraging these blueprints, organizations can accelerate their cloud adoption, improve operational efficiency, and ensure their solutions are optimized for performance, security, and compliance across diverse environments. diff --git a/docs/doc1.md b/docs/doc1.md deleted file mode 100644 index 7562e3508..000000000 --- a/docs/doc1.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -id: doc1 -title: doc1 ---- \ No newline at end of file diff --git a/docs/doc2.md b/docs/doc2.md deleted file mode 100644 index 45573c731..000000000 --- a/docs/doc2.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -id: doc2 -title: doc2 ---- \ No newline at end of file diff --git a/docs/doc3.md b/docs/doc3.md deleted file mode 100644 index e33c7e608..000000000 --- a/docs/doc3.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -id: doc3 -title: doc3 ---- \ No newline at end of file diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 4029f6940..a35b6fc70 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -1,23 +1,23 @@ import { themes as prismThemes } from 'prism-react-renderer'; import type { Config } from '@docusaurus/types'; import type * as Preset from '@docusaurus/preset-classic'; +import type { Options as UmamiOptions } from '@dipakparmar/docusaurus-plugin-umami'; const config: Config = { - title: 'Architecture Center - GitOps', + title: 'Architecture Center', tagline: 'Best Practices & Blueprints', favicon: 'img/favicon.ico', // Set the production url of your site here - url: 'http://docs-next.hypelens.de', + url: 'https://' + process.env.REACT_APP_DOCS_NEXT_HOST, // Set the // pathname under which your site is served // For GitHub pages deployment, it is often '//' - baseUrl: '/', + baseUrl: process.env.REACT_APP_DOCUSAURUS_BASE_URL ?? '/', // GitHub pages deployment config. // If you aren't using GitHub pages, you don't need these. - organizationName: 'akyriako', // Usually your GitHub org/user name. + organizationName: process.env.REACT_APP_DOCS_NEXT_ORG, // Usually your GitHub org/user name. projectName: 'docs-next', // Usually your repo name. - deploymentBranch: 'gh-pages', onBrokenLinks: 'throw', onBrokenMarkdownLinks: 'warn', @@ -36,10 +36,11 @@ const config: Config = { { docs: { sidebarPath: './sidebars.ts', - editUrl:'https://github.com/akyriako/docs-next/tree/main/', + editUrl:'https://github.com/opentelekomcloud/docs-next/tree/main/', // showLastUpdateAuthor: true, // showLastUpdateTime: true, - breadcrumbs: true + breadcrumbs: true, + // exclude: ['**/by-industry/**', '**/caf/**', '**/crossplane/**'] }, theme: { @@ -62,6 +63,11 @@ const config: Config = { themeConfig: { // Replace with your project's social card image: 'img/open-telekom-cloud-social-card.png', + colorMode: { + defaultMode: "light", + disableSwitch: false, + respectPrefersColorScheme: true, + }, navbar: { // title: 't', logo: { @@ -102,21 +108,34 @@ const config: Config = { "aria-label": 'Open Telekom Cloud Console', }, { - href: 'https://github.com/opentelekomcloud-blueprints', + href: 'https://github.com/opentelekomcloud/docs-next', position: 'right', className: 'navbar--github-link', "aria-label": 'GitHub', }, - { - href: 'https://discord.gg/zpSRgC9as5', - position: 'right', - className: 'navbar--discord-link', - "aria-label": 'Discord Invite', - }, + // { + // href: 'https://open-telekom-cloud.com', + // position: 'right', + // className: 'navbar--discourse-link', + // "aria-label": 'Discourse OTC', + // }, + // { + // href: 'https://discord.gg/zpSRgC9as5', + // position: 'right', + // className: 'navbar--discord-link', + // "aria-label": 'Discord Invite', + // }, ], }, footer: { style: 'dark', + logo: { + alt: 'Open Telekom Cloud Logo', + src: 'img/telekom-logo.svg', + href: 'https://www.open-telekom-cloud.com', + width: 72, + height: 72, + }, links: [ { title: 'Docs', @@ -125,14 +144,31 @@ const config: Config = { label: 'Help Center', to: 'https://docs.otc.t-systems.com/', }, - { - label: 'Medium', - href: 'https://medium.com', - }, { label: 'Portfolio Roadmap', to: 'https://www.open-telekom-cloud.com/en/products-services/roadmap', }, + { + label: 'Core Services Certifications', + to: 'https://www.open-telekom-cloud.com/en/products-services/core-services/certifications', + }, + ], + }, + { + title: 'Community', + items: [ + { + label: 'Community Forums', + to: 'https://community.open-telekom-cloud.com/', + }, + { + label: 'Webinars', + href: 'https://www.youtube.com/watch?v=U-x2gEy3968&list=PLS60dhorR-hgQ5n5L1boEQh0oVD-_k75p', + }, + // { + // label: 'Medium', + // href: 'https://medium.com', + // }, ], }, { @@ -173,7 +209,7 @@ const config: Config = { }, { label: 'Endpoints', - to: 'https://docs.otc.t-systems.com/additional/endpoints.html', + to: 'https://docs.otc.t-systems.com/regions-and-endpoints/index.html', }, { label: 'Status Dashboard', @@ -181,29 +217,8 @@ const config: Config = { }, ], }, - { - title: 'Community', - items: [ - { - label: 'Community Forums', - to: 'https://community.open-telekom-cloud.com/', - }, - { - label: 'Webinars', - href: 'https://www.youtube.com/watch?v=U-x2gEy3968&list=PLS60dhorR-hgQ5n5L1boEQh0oVD-_k75p', - }, - { - label: 'Discord', - href: 'https://discord.gg/zpSRgC9as5', - }, - // { - // label: 'Twitter', - // href: 'https://x.com/tsystemscom', - // }, - ], - }, ], - copyright: `© T-Systems International GmbH ${new Date().getFullYear()}`, + copyright: `© T-Systems International GmbH ${new Date().getFullYear()} (` + process.env.REACT_APP_VERSION + `)`, }, prism: { theme: prismThemes.oneDark, @@ -240,6 +255,25 @@ const config: Config = { contextualSearch: true, }, } satisfies Preset.ThemeConfig, + + customFields: { + version: `(v` + process.env.REACT_APP_VERSION + `)`, + }, + + plugins: [ + [ + '@dipakparmar/docusaurus-plugin-umami', + { + websiteID: process.env.UMAMI_WEBSITE_ID, // Required + analyticsDomain: process.env.UMAMI_ANALYTICS_DOMAIN, // Required + dataHostURL: process.env.UMAMI_DATAHOST_URL, // Optional + dataAutoTrack: true, // Optional + dataDoNotTrack: true, // Optional + dataCache: true, // Optional + dataDomains: process.env.UMAMI_DATA_DOMAIN, // comma separated list of domains, *Recommended* + } as UmamiOptions, + ], + ], }; export default config; \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..1c7bad2a6 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,17 @@ +import globals from "globals"; +import tseslint from "typescript-eslint"; +import pluginReact from "eslint-plugin-react"; + + +/** @type {import('eslint').Linter.Config[]} */ +export default [ + { + files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"], + languageOptions: { globals: globals.browser }, + }, + { + ignores: [".docusaurus/*"], + }, + ...tseslint.configs.recommended, + pluginReact.configs.flat["jsx-runtime"], +]; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0cd28c43e..8e95bbdb2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "docs-next", "version": "0.0.0", "dependencies": { + "@dipakparmar/docusaurus-plugin-umami": "^2.1.6", "@docusaurus/core": "^3.4.0", "@docusaurus/preset-classic": "^3.4.0", "@mdx-js/react": "^3.0.1", @@ -22,6 +23,10 @@ "@docusaurus/module-type-aliases": "^3.4.0", "@docusaurus/tsconfig": "^3.4.0", "@docusaurus/types": "^3.4.0", + "@typescript-eslint/eslint-plugin": "^8.13.0", + "@typescript-eslint/parser": "^8.13.0", + "eslint": "^9.14.0", + "eslint-plugin-react": "^7.37.2", "typescript": "~5.5.2" }, "engines": { @@ -2091,6 +2096,18 @@ "node": ">=0.1.90" } }, + "node_modules/@dipakparmar/docusaurus-plugin-umami": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@dipakparmar/docusaurus-plugin-umami/-/docusaurus-plugin-umami-2.1.6.tgz", + "integrity": "sha512-jgcDZg/+dOiAip7WTxEm/UyNEewnNLb0Nmdg0hYwwXBNjjdj8RKnMmIrHnO8IBYcsZkgCBcVLLl5VbJ2ns28jw==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.4.0", + "@docusaurus/types": "3.4.0", + "@docusaurus/utils-validation": "3.4.0", + "tslib": "^2.4.0" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -2733,6 +2750,143 @@ "npm": ">= 6.14.0" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "devOptional": true, + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "devOptional": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "devOptional": true, + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", + "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", + "devOptional": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "devOptional": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.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": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "devOptional": 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/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "devOptional": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/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==", + "devOptional": true + }, + "node_modules/@eslint/js": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz", + "integrity": "sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==", + "devOptional": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "devOptional": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz", + "integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==", + "devOptional": true, + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@floating-ui/core": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", @@ -2768,6 +2922,67 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "devOptional": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "devOptional": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "devOptional": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "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==", + "devOptional": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "devOptional": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -3382,9 +3597,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" }, "node_modules/@types/estree-jsx": { "version": "1.0.5", @@ -3659,6 +3874,212 @@ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.13.0.tgz", + "integrity": "sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.13.0", + "@typescript-eslint/type-utils": "8.13.0", + "@typescript-eslint/utils": "8.13.0", + "@typescript-eslint/visitor-keys": "8.13.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.13.0.tgz", + "integrity": "sha512-w0xp+xGg8u/nONcGw1UXAr6cjCPU1w0XVyBs6Zqaj5eLmxkKQAByTdV/uGgNN5tVvN/kKpoQlP2cL7R+ajZZIQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.13.0", + "@typescript-eslint/types": "8.13.0", + "@typescript-eslint/typescript-estree": "8.13.0", + "@typescript-eslint/visitor-keys": "8.13.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.13.0.tgz", + "integrity": "sha512-XsGWww0odcUT0gJoBZ1DeulY1+jkaHUciUq4jKNv4cpInbvvrtDoyBH9rE/n2V29wQJPk8iCH1wipra9BhmiMA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.13.0", + "@typescript-eslint/visitor-keys": "8.13.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.13.0.tgz", + "integrity": "sha512-Rqnn6xXTR316fP4D2pohZenJnp+NwQ1mo7/JM+J1LWZENSLkJI8ID8QNtlvFeb0HnFSK94D6q0cnMX6SbE5/vA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "8.13.0", + "@typescript-eslint/utils": "8.13.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.13.0.tgz", + "integrity": "sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.13.0.tgz", + "integrity": "sha512-v7SCIGmVsRK2Cy/LTLGN22uea6SaUIlpBcO/gnMGT/7zPtxp90bphcGf4fyrCQl3ZtiBKqVTG32hb668oIYy1g==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.13.0", + "@typescript-eslint/visitor-keys": "8.13.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/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/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.13.0.tgz", + "integrity": "sha512-A1EeYOND6Uv250nybnLZapeXpYMl8tkzYUxqmoKAWnI4sei3ihf2XdZVd+vVOmHGcp3t+P7yRrNsyyiXTvShFQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.13.0", + "@typescript-eslint/types": "8.13.0", + "@typescript-eslint/typescript-estree": "8.13.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.13.0.tgz", + "integrity": "sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.13.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -3837,9 +4258,9 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "bin": { "acorn": "bin/acorn" }, @@ -4047,11 +4468,47 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "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-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -4060,24 +4517,118 @@ "node": ">=8" } }, - "node_modules/astring": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", - "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", - "bin": { - "astring": "bin/astring" + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/astring": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", + "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "bin": { + "astring": "bin/astring" + } + }, + "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/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { "node": ">= 4.0.0" } }, @@ -4117,6 +4668,21 @@ "postcss": "^8.1.0" } }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/axios": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", @@ -5386,6 +5952,57 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/debounce": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", @@ -5452,6 +6069,12 @@ "node": ">=4.0.0" } }, + "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==", + "devOptional": true + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -5654,6 +6277,18 @@ "node": ">=6" } }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/docusaurus-theme-search-typesense": { "version": "0.20.0", "resolved": "https://registry.npmjs.org/docusaurus-theme-search-typesense/-/docusaurus-theme-search-typesense-0.20.0.tgz", @@ -5881,6 +6516,66 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", @@ -5900,11 +6595,89 @@ "node": ">= 0.4" } }, + "node_modules/es-iterator-helpers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.0.tgz", + "integrity": "sha512-tpxqxncxnpw3c93u8n3VOzACmRFoVmWJqbWXvX/JfKbkhBw1oslgPrUfeSt2psuqyEJFD6N/9lg5i7bsKpoq+Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.3", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.0.tgz", "integrity": "sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==" }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/escalade": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", @@ -5940,6 +6713,133 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.14.0.tgz", + "integrity": "sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==", + "devOptional": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.7.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.14.0", + "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.0", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz", + "integrity": "sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.1.0", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.0", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react/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/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "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/eslint-plugin-react/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/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -5952,6 +6852,200 @@ "node": ">=8.0.0" } }, + "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==", + "devOptional": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "devOptional": 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/eslint/node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "devOptional": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "devOptional": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "devOptional": true, + "engines": { + "node": ">=4.0" + } + }, + "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==", + "devOptional": 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==", + "devOptional": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/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==", + "devOptional": true + }, + "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==", + "devOptional": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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==", + "devOptional": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "devOptional": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/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==", + "devOptional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "devOptional": true, + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "devOptional": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.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", @@ -5964,6 +7058,27 @@ "node": ">=4" } }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "devOptional": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "devOptional": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -6266,6 +7381,12 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "devOptional": true + }, "node_modules/fast-url-parser": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", @@ -6316,6 +7437,18 @@ "node": ">=0.4.0" } }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "devOptional": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/file-loader": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", @@ -6467,6 +7600,25 @@ "flat": "cli.js" } }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "devOptional": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "devOptional": true + }, "node_modules/follow-redirects": { "version": "1.15.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", @@ -6486,6 +7638,15 @@ } } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/fork-ts-checker-webpack-plugin": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", @@ -6707,6 +7868,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "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", @@ -6749,6 +7937,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/github-slugger": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", @@ -6854,6 +8059,22 @@ "node": ">=4" } }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -6924,6 +8145,12 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "node_modules/gray-matter": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", @@ -6977,6 +8204,15 @@ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -7018,6 +8254,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-yarn": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", @@ -7645,6 +8896,20 @@ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", @@ -7691,11 +8956,54 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "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==" }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -7707,6 +9015,34 @@ "node": ">=8" } }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-ci": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", @@ -7729,6 +9065,36 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-decimal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", @@ -7768,6 +9134,18 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -7776,6 +9154,21 @@ "node": ">=8" } }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -7811,6 +9204,30 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-npm": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", @@ -7830,6 +9247,21 @@ "node": ">=0.12.0" } }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", @@ -7884,6 +9316,22 @@ "@types/estree": "*" } }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", @@ -7900,6 +9348,33 @@ "node": ">=6" } }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -7911,11 +9386,96 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -7953,6 +9513,22 @@ "node": ">=0.10.0" } }, + "node_modules/iterator.prototype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", + "integrity": "sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/jest-util": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", @@ -8059,6 +9635,12 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, + "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==", + "devOptional": true + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -8081,6 +9663,21 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -8136,6 +9733,19 @@ "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==", + "devOptional": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/lilconfig": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", @@ -8202,6 +9812,12 @@ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "devOptional": true + }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -10531,6 +12147,12 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "devOptional": true + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -10647,15 +12269,64 @@ "node": ">= 0.4" } }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -10734,6 +12405,23 @@ "opener": "bin/opener-bin.js" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "devOptional": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/p-cancelable": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", @@ -11084,6 +12772,15 @@ "node": ">=4" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { "version": "8.4.38", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", @@ -11652,6 +13349,15 @@ "postcss": "^8.4.31" } }, + "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==", + "devOptional": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/pretty-error": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", @@ -12195,6 +13901,27 @@ "node": ">=6.0.0" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", + "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.1", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -12224,6 +13951,24 @@ "@babel/runtime": "^7.8.4" } }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", + "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regexpu-core": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", @@ -12663,6 +14408,30 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -12682,6 +14451,23 @@ } ] }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -12974,6 +14760,21 @@ "node": ">= 0.4" } }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -13300,6 +15101,91 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/stringify-entities": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", @@ -13654,11 +15540,35 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/ts-api-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", + "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "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==", + "devOptional": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/type-fest": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", @@ -13701,6 +15611,79 @@ "node": ">= 0.6" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -13809,6 +15792,21 @@ "@babel/runtime": "^7.17.2" } }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -14658,6 +16656,91 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz", + "integrity": "sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/widest-line": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", @@ -14677,6 +16760,15 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", diff --git a/package.json b/package.json index d54ceed9a..783b37223 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,11 @@ "serve": "docusaurus serve --host 0.0.0.0 --port 80", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", - "typecheck": "tsc" + "typecheck": "tsc", + "lint": "eslint" }, "dependencies": { + "@dipakparmar/docusaurus-plugin-umami": "^2.1.6", "@docusaurus/core": "^3.4.0", "@docusaurus/preset-classic": "^3.4.0", "@mdx-js/react": "^3.0.1", @@ -29,7 +31,13 @@ "@docusaurus/module-type-aliases": "^3.4.0", "@docusaurus/tsconfig": "^3.4.0", "@docusaurus/types": "^3.4.0", - "typescript": "~5.5.2" + "@typescript-eslint/eslint-plugin": "^8.13.0", + "@typescript-eslint/parser": "^8.13.0", + "eslint": "^9.14.0", + "eslint-plugin-react": "^7.37.2", + "globals": "^15.12.0", + "typescript": "~5.5.2", + "typescript-eslint": "^8.13.0" }, "browserslist": { "production": [ diff --git a/sidebars.ts b/sidebars.ts index 7ec67f241..af0b7f227 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -226,7 +226,7 @@ const sidebars: SidebarsConfig = { }, { type: 'category', - label: 'FunctionGraph 🔥', + label: 'FunctionGraph', items: [ { type: 'link', @@ -243,6 +243,10 @@ const sidebars: SidebarsConfig = { type: 'doc', id: 'best-practices/computing/image-management-service/migrating-service-data-across-accounts-data-disks', }, + // { + // type: 'doc', + // id: 'best-practices/computing/image-management-service/creating-a-linux-Image-using-virtualBox-and-an-iso-file', + // }, { type: 'doc', id: 'best-practices/computing/image-management-service/creating-a-linux-Image-using-virtualBox-and-an-iso-file', @@ -260,10 +264,25 @@ const sidebars: SidebarsConfig = { type: 'category', label: 'Containers', items: [ + { + type: 'category', + label: 'Application Service Mesh', + items: [ + { + type: 'link', + label: '📚 Go to Help Center', + href: 'https://docs.otc.t-systems.com/application-service-mesh/index.html', + }, + ], + }, { type: 'category', label: 'Cloud Container Engine', items: [ + { + type: 'doc', + id: 'best-practices/containers/cloud-container-engine/issue-an-acme-certificate-with-dns01-solver-in-cce', + }, { type: 'doc', id: 'best-practices/containers/cloud-container-engine/auto-scaling-based-on-elb-monitoring-metrics', @@ -301,6 +320,17 @@ const sidebars: SidebarsConfig = { }, ], }, + { + type: 'category', + label: 'Cloud Container Instance', + items: [ + { + type: 'link', + label: '📚 Go to Help Center', + href: 'https://docs.otc.t-systems.com/cloud-container-instance/index.html', + }, + ], + }, { type: 'category', label: 'Software Repository for Container', @@ -376,6 +406,10 @@ const sidebars: SidebarsConfig = { type: 'doc', id: 'best-practices/databases/document-database-service/from-other-cloud-mongodb-to-dds', }, + { + type: 'doc', + id: 'best-practices/databases/document-database-service/how-do-replica-sets-achieve-high-availability-and-readwrite-splitting', + }, { type: 'link', label: '📚 Go to Help Center', @@ -416,6 +450,17 @@ const sidebars: SidebarsConfig = { }, ], }, + { + type: 'category', + label: 'GeminiDB', + items: [ + { + type: 'link', + label: '📚 Go to Help Center', + href: 'https://docs.otc.t-systems.com/geminidb/index.html', + }, + ], + }, { type: 'category', label: 'Relational Database Service', @@ -446,7 +491,7 @@ const sidebars: SidebarsConfig = { }, { type: 'category', - label: 'Cloud Create 🔥', + label: 'Cloud Create', link: { type: 'doc', id: 'best-practices/management-and-deployment/cloud-create/cloud-create' @@ -516,6 +561,17 @@ const sidebars: SidebarsConfig = { }, ], }, + { + type: 'category', + label: 'Config', + items: [ + { + type: 'link', + label: '📚 Go to Help Center', + href: 'https://docs.otc.t-systems.com/config/index.html', + }, + ], + }, { type: 'category', label: 'Cloud Trace Service', @@ -713,6 +769,10 @@ const sidebars: SidebarsConfig = { type: 'category', label: 'Virtual Private Network', items: [ + { + type: 'doc', + id: 'best-practices/networking/virtual-private-network/connecting-multiple-on-premises-branch-networks-through-a-vpn-hub', + }, { type: 'link', label: '📚 Go to Help Center', diff --git a/src/components/HomepageAskAQuestion/index.tsx b/src/components/HomepageAskAQuestion/index.tsx new file mode 100644 index 000000000..ab7a5b03f --- /dev/null +++ b/src/components/HomepageAskAQuestion/index.tsx @@ -0,0 +1,24 @@ +import clsx from 'clsx'; +import styles from './styles.module.css'; + +export default function HomepageAskAQuestion(): JSX.Element { + return ( +
+
+
+

+ Ask a Technical Question +

+

+ Connect with people sharing the same passion for Open Telekom Cloud. + Discover our exciting upcoming Events and Webinars! +

+ + Join our Community Forum + +
+
+
+ // + ); + } \ No newline at end of file diff --git a/src/components/HomepageAskAQuestion/styles.module.css b/src/components/HomepageAskAQuestion/styles.module.css new file mode 100644 index 000000000..9392b37f0 --- /dev/null +++ b/src/components/HomepageAskAQuestion/styles.module.css @@ -0,0 +1,36 @@ + +.item { + box-shadow: 0 1px 3px gray; + background-color: var(--telekom-color-background-surface); + border-radius: 2rem; + color: black; + overflow: hidden; + height: 100%; +} + +html[data-theme='dark'] .item { + box-shadow: 0px 1px 3px var(--ifm-color-primary); + background-color: var(--telekom-color-background-surface); + border-radius: 2rem; + color: white; + overflow: hidden; + height: 100%; +} + +@media (max-width: 996px) { + .item { + margin-top: 2rem; + } +} + +.item__inner { + align-items: center; + display: flex; +} +.item__inner div { + padding: 3rem; +} +.item__title span { + display: block; + font-size: 1.25rem; +} \ No newline at end of file diff --git a/src/components/HomepageContribute/index.tsx b/src/components/HomepageContribute/index.tsx new file mode 100644 index 000000000..7603b18be --- /dev/null +++ b/src/components/HomepageContribute/index.tsx @@ -0,0 +1,35 @@ +import clsx from 'clsx'; +import styles from './styles.module.css'; + +export default function HomepageContribute(): JSX.Element { + return ( + //
+
+
+
+

Contribute

+

+ Share with our vibrant community all that cool staff you've built with Open Telekom Cloud. +

+ + Join us on GitHub + + {/* + Join us on Medium + */} +
+
+ {/* */} +
+ //
+ ); + } \ No newline at end of file diff --git a/src/components/HomepageContribute/styles.module.css b/src/components/HomepageContribute/styles.module.css new file mode 100644 index 000000000..c21810a6e --- /dev/null +++ b/src/components/HomepageContribute/styles.module.css @@ -0,0 +1,30 @@ + +.item { + box-shadow: 0 1px 3px gray; + background-color: var(--telekom-color-background-surface); + border-radius: 2rem; + color: black; + overflow: hidden; + height: 100%; +} + +html[data-theme='dark'] .item { + box-shadow: 0px 1px 3px var(--ifm-color-primary); + background-color: var(--telekom-color-background-surface); + border-radius: 2rem; + color: white; + overflow: hidden; + height: 100%; +} + +.item__inner { + align-items: center; + display: flex; +} +.item__inner div { + padding: 3rem; +} +.item__title span { + display: block; + font-size: 1.25rem; +} \ No newline at end of file diff --git a/src/components/HomepageFeaturedServices/index.tsx b/src/components/HomepageFeaturedServices/index.tsx new file mode 100644 index 000000000..d87da593e --- /dev/null +++ b/src/components/HomepageFeaturedServices/index.tsx @@ -0,0 +1,47 @@ +import clsx from 'clsx'; +import styles from './styles.module.css'; +import FeaturedServices from '../ServiceCallouts/FeaturedServices'; +import NewServices from '../ServiceCallouts/NewServices'; + +export default function HomepageFeaturedServices(): JSX.Element { + return ( +
+
+
+
+

+ Explore our Featured Services +

+

+ Check out our collection of technical solutions, best practices and cool tips for the most popular services of Open Telekom Cloud. +

+ + Explore our Best Practices + +
+
+ + {/* */} +
+
+

+ What's new? +

+

+ Explore the technical documentation of our brand new services in Help Center. +

+ + Check the Portfolio Roadmap + +
+
+ + +
+
+ ); + } \ No newline at end of file diff --git a/src/components/HomepageFeaturedServices/styles.module.css b/src/components/HomepageFeaturedServices/styles.module.css new file mode 100644 index 000000000..693587131 --- /dev/null +++ b/src/components/HomepageFeaturedServices/styles.module.css @@ -0,0 +1,28 @@ + +.item { + box-shadow: 0 1px 3px gray; + background-color: var(--telekom-color-background-surface); + border-radius: 2rem; + color: black; + overflow: hidden; +} + +html[data-theme='dark'] .item { + box-shadow: 0px 1px 3px var(--ifm-color-primary); + background-color: var(--telekom-color-background-surface); + border-radius: 2rem; + color: white; + overflow: hidden; +} + +.item__inner { + align-items: center; + display: flex; +} +.item__inner div { + padding: 3rem; +} +.item__title span { + display: block; + font-size: 1.25rem; +} \ No newline at end of file diff --git a/src/components/HomepageFeatures/index.tsx b/src/components/HomepageFeatures/index.tsx index de5e76c5c..b3f16504d 100644 --- a/src/components/HomepageFeatures/index.tsx +++ b/src/components/HomepageFeatures/index.tsx @@ -2,16 +2,21 @@ import clsx from 'clsx'; import Heading from '@theme/Heading'; import styles from './styles.module.css'; +import BestPracticesSvg from '@site/static/img/best-practices.svg'; +import BlueprintsSvg from '@site/static/img/blueprints.svg'; +// import CafSvg from '@site/static/img/caf.svg'; + type FeatureItem = { title: string; Svg: React.ComponentType>; description: JSX.Element; + link?: string; }; const FeatureList: FeatureItem[] = [ { title: 'Best Practices', - Svg: require('@site/static/img/best-practices.svg').default, + Svg: BestPracticesSvg, description: ( <> Explore the recommended strategies for resource management, such as @@ -19,10 +24,11 @@ const FeatureList: FeatureItem[] = [ to ensure robust system performance. ), + link: '/docs/best-practices' }, { title: 'Blueprints', - Svg: require('@site/static/img/blueprints.svg').default, + Svg: BlueprintsSvg, description: ( <> Discover tailored out-of-the-box solutions and @@ -30,31 +36,43 @@ const FeatureList: FeatureItem[] = [ application and infrastructure design using Open Telekom Cloud. ), + link: '/docs/blueprints' }, - { - title: 'Cloud Adoption Framework', - Svg: require('@site/static/img/caf.svg').default, - description: ( - <> - The Cloud Adoption Framework provides a structured approach for organizations to transition their business to - Open Telekom Cloud. It covers various stages such as strategy, planning, readiness, migration, governance, and management. - - ), - }, + // { + // title: 'Cloud Adoption Framework', + // Svg: CafSvg, + // description: ( + // <> + // The Cloud Adoption Framework provides a structured approach for organizations to transition their business to + // Open Telekom Cloud. It covers various stages such as strategy, planning, readiness, migration, governance, and management. + // + // ), + // link: '/caf' + // }, ]; -function Feature({title, Svg, description}: FeatureItem) { +function Feature({title, Svg, description, link}: FeatureItem) { return ( -
-
- -
-
- {title} -

{description}

-
+
+ +
+
+ +
+
+ {/*

{title}

*/} + {title} + + {description} + + {/* + Get Started + */} +
+
+
- ); + ); } export default function HomepageFeatures(): JSX.Element { diff --git a/src/components/HomepageNewServices/index.tsx b/src/components/HomepageNewServices/index.tsx new file mode 100644 index 000000000..4b62c673b --- /dev/null +++ b/src/components/HomepageNewServices/index.tsx @@ -0,0 +1,28 @@ +import clsx from 'clsx'; +import styles from './styles.module.css'; +import NewServices from '../ServiceCallouts/NewServices'; + +export default function HomepageNewServices(): JSX.Element { + return ( +
+
+ +
+
+

+ Meet the New Comers +

+

+ Explore the new services added in Open Telekom Cloud portfolio. +

+ + Check the Roadmap Portfolio + +
+
+
+
+ ); + } \ No newline at end of file diff --git a/src/components/HomepageNewServices/styles.module.css b/src/components/HomepageNewServices/styles.module.css new file mode 100644 index 000000000..2d8f36204 --- /dev/null +++ b/src/components/HomepageNewServices/styles.module.css @@ -0,0 +1,28 @@ + +.item { + box-shadow: 0 1px 3px gray; + background-color: var(--ifm-background-color); + border-radius: 2rem; + color: black; + overflow: hidden; +} + +html[data-theme='dark'] .item { + box-shadow: 0px 1px 3px var(--ifm-color-primary); + background-color: var(--ifm-background-color); + border-radius: 2rem; + color: white; + overflow: hidden; +} + +.item__inner { + align-items: center; + display: flex; +} +.item__inner div { + padding: 3rem; +} +.item__title span { + display: block; + font-size: 1.25rem; +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/ApplicationServices/index.tsx b/src/components/ServiceCallouts/ApplicationServices/index.tsx new file mode 100644 index 000000000..11d7062fe --- /dev/null +++ b/src/components/ServiceCallouts/ApplicationServices/index.tsx @@ -0,0 +1,41 @@ +import ServiceCallouts, { Callout } from './../callout'; + +import AomSvg from '@site/static/img/services/aom.svg' +import ApigSvg from '@site/static/img/services/apig.svg' +import DmsSvg from '@site/static/img/services/DMS.svg' +import SmnSvg from '@site/static/img/services/SMN.svg' + + const calloutsList: Callout[] = [ + { + title: "AOM", + text: "Application Operations Management", + link: "/docs/tags/aom", + icon: AomSvg, + }, + { + title: "APIG", + text: "API Gateway", + link: "/docs/tags/apig", + icon: ApigSvg, + }, + { + title: "DMS", + text: "Distributed Message Service", + link: "/docs/tags/dms", + icon: DmsSvg, + }, + { + title: "SMN", + text: "Simple Message Notification", + link: "/docs/tags/smn", + icon: SmnSvg, + }, + ]; + +export default function ApplicationServices(): JSX.Element { + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/ComputingServices/index.tsx b/src/components/ServiceCallouts/ComputingServices/index.tsx new file mode 100644 index 000000000..e998d6765 --- /dev/null +++ b/src/components/ServiceCallouts/ComputingServices/index.tsx @@ -0,0 +1,55 @@ +import ServiceCallouts, { Callout } from './../callout'; + +import AsSvg from '@site/static/img/services/AS.svg' +import BmsSvg from '@site/static/img/services/BMS.svg' +import DhsSvg from '@site/static/img/services/DeH.svg' +import EcsSvg from '@site/static/img/services/ECS.svg' +import FgsSvg from '@site/static/img/services/fg.svg' +import ImsSvg from '@site/static/img/services/IMS.svg' + +const calloutsList: Callout[] = [ + { + title: "AS", + text: "Auto Scaling", + link: "/docs/tags/as", + icon: AsSvg, + }, + { + title: "BMS", + text: "Bare Metal Services", + link: "/docs/tags/bms", + icon: BmsSvg, + }, + { + title: "DHS", + text: "Dedicated Host", + link: "/docs/tags/dhs", + icon: DhsSvg, + }, + { + title: "ECS", + text: "Elastic Cloud Server", + link: "/docs/tags/ecs", + icon: EcsSvg, + }, + { + title: "FGS", + text: "FunctionGraph", + link: "/docs/tags/functiongraph", + icon: FgsSvg, + }, + { + title: "IMS", + text: "Image Management Service", + link: "/docs/tags/ims", + icon: ImsSvg, + }, +]; + +export default function ComputingServices(): JSX.Element { + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/ContainerServices/index.tsx b/src/components/ServiceCallouts/ContainerServices/index.tsx new file mode 100644 index 000000000..fd48ca51a --- /dev/null +++ b/src/components/ServiceCallouts/ContainerServices/index.tsx @@ -0,0 +1,41 @@ +import ServiceCallouts, { Callout } from './../callout'; + +import AsmSvg from '@site/static/img/services/asm.svg' +import CceSvg from '@site/static/img/services/CCE.svg' +import CciSvg from '@site/static/img/services/cci.svg' +import SwrSvg from '@site/static/img/services/swr.svg' + + const calloutsList: Callout[] = [ + { + title: "ASM", + text: "Application Service Mesh", + link: "/docs/tags/asm", + icon: AsmSvg, + }, + { + title: "CCE", + text: "Cloud Container Engine", + link: "/docs/tags/cce", + icon: CceSvg, + }, + { + title: "CCI", + text: "Serverless Container Engine", + link: "/docs/tags/cci", + icon: CciSvg, + }, + { + title: "SWR", + text: "Software Repository for Containers", + link: "/docs/tags/swr", + icon: SwrSvg, + }, + ]; + +export default function ContainerServices(): JSX.Element { + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/DataAnalysisServices/index.tsx b/src/components/ServiceCallouts/DataAnalysisServices/index.tsx new file mode 100644 index 000000000..c55d12abd --- /dev/null +++ b/src/components/ServiceCallouts/DataAnalysisServices/index.tsx @@ -0,0 +1,69 @@ +import ServiceCallouts, { Callout } from './../callout'; + +import CssSvg from '@site/static/img/services/CSS.svg' +import DatarartsSvg from '@site/static/img/services/dataarts_studio.svg' +import DisSvg from '@site/static/img/services/DIS.svg' +import DliSvg from '@site/static/img/services/dli.svg' +import DwsSvg from '@site/static/img/services/DWS.svg' +import ModelartsSvg from '@site/static/img/services/ma.svg' +import MrsSvg from '@site/static/img/services/mapReduce-MRS.svg' +import OcrSvg from '@site/static/img/services/ocr.svg' + + const calloutsList: Callout[] = [ + { + title: "CSS", + text: "Cloud Search Service", + link: "/docs/tags/css", + icon: CssSvg, + }, + { + title: "DataArts Studio", + text: "Data Operations Platform", + link: "/docs/tags/data-arts", + icon: DatarartsSvg, + }, + { + title: "DIS", + text: "Data Ingestion Service", + link: "/docs/tags/dis", + icon: DisSvg, + }, + { + title: "DLI", + text: "Data Lake Insight", + link: "/docs/tags/dli", + icon: DliSvg, + }, + { + title: "DWS", + text: "Data Warehouse Service", + link: "/docs/tags/dws", + icon: DwsSvg, + }, + { + title: "ModelArts", + text: "Development Platform for AI", + link: "/docs/tags/model-arts", + icon: ModelartsSvg, + }, + { + title: "MRS", + text: "MapReduce Service", + link: "/docs/tags/mrs", + icon: MrsSvg, + }, + { + title: "OCR", + text: "Optical Character Recognition", + link: "/docs/tags/ocr", + icon: OcrSvg, + }, + ]; + +export default function DataAnalysisServices(): JSX.Element { + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/DatabaseServices/index.tsx b/src/components/ServiceCallouts/DatabaseServices/index.tsx new file mode 100644 index 000000000..d95304b3a --- /dev/null +++ b/src/components/ServiceCallouts/DatabaseServices/index.tsx @@ -0,0 +1,69 @@ +import ServiceCallouts, { Callout } from './../callout'; + +import DcsSvg from '@site/static/img/services/DCS-redis.svg' +import DdmSvg from '@site/static/img/services/ddm.svg' +import DdsSvg from '@site/static/img/services/DDS.svg' +import DrsSvg from '@site/static/img/services/drs.svg' +import GaussdbmysqlSvg from '@site/static/img/services/gaussdb_mysql.svg' +import GaussdbnosqlSvg from '@site/static/img/services/gaussdb_nosql.svg' +import RdsSvg from '@site/static/img/services/RDS .svg' +import GeminidbSvg from '@site/static/img/services/RDS .svg' + + const calloutsList: Callout[] = [ + { + title: "DCS", + text: "Distributed Cache Service", + link: "/docs/tags/dcs", + icon: DcsSvg + }, + { + title: "DDM", + text: "Distributed Database Middleware", + link: "/docs/tags/ddm", + icon: DdmSvg + }, + { + title: "DDS", + text: "Document Database Service", + link: "/docs/tags/dds", + icon: DdsSvg + }, + { + title: "DRS", + text: "Data Replication Service", + link: "/docs/tags/drs", + icon: DrsSvg + }, + { + title: "GaussDB for MySQL", + text: "Enterprise-Class Distributed Database", + link: "/docs/tags/gaussdb-mysql", + icon: GaussdbmysqlSvg + }, + { + title: "GaussDB NoSQL", + text: "Distributed NoSQL Database Service ", + link: "/docs/tags/model-arts", + icon: GaussdbnosqlSvg + }, + { + title: "GeminiDB", + text: "Distributed, Multi-Model NoSQL Database Service", + link: "/docs/tags/gemini-db", + icon: GeminidbSvg + }, + { + title: "RDS", + text: "Relational Database Service", + link: "/docs/tags/rds", + icon: RdsSvg + }, + ]; + +export default function DatabaseServices(): JSX.Element { + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/FeaturedServices/index.tsx b/src/components/ServiceCallouts/FeaturedServices/index.tsx new file mode 100644 index 000000000..5da61d627 --- /dev/null +++ b/src/components/ServiceCallouts/FeaturedServices/index.tsx @@ -0,0 +1,76 @@ +import ServiceCallouts, { Callout } from '../callout'; + +import VpcSvg from '@site/static/img/services/VPC.svg' +import EcsSvg from '@site/static/img/services/ECS.svg' +import ObsSvg from '@site/static/img/services/OBS.svg' +import IamSvg from '@site/static/img/services/IAM.svg' +import ElbSvg from '@site/static/img/services/ELB.svg' +import DmsSvg from '@site/static/img/services/DMS.svg' +import CceSvg from '@site/static/img/services/CCE.svg' +import SwrSvg from '@site/static/img/services/swr.svg' +import CcSvg from '@site/static/img/services/cc.svg' + + const calloutsList: Callout[] = [ + { + title: "VPC", + text: "Virtual Private Cloud", + link: "/docs/tags/vpc", + icon: VpcSvg + }, + { + title: "ECS", + text: "Elastic Cloud Server", + link: "/docs/tags/ecs", + icon: EcsSvg + }, + { + title: "OBS", + text: "Object Storage Service", + link: "/docs/tags/obs", + icon: ObsSvg + }, + { + title: "IAM", + text: "Identity & Access Management", + link: "/docs/tags/iam", + icon: IamSvg + }, + { + title: "ELB", + text: "Elastic Load Balancing", + link: "/docs/tags/elb", + icon: ElbSvg + }, + { + title: "DMS", + text: "Distributed Message Service", + link: "/docs/tags/dms", + icon: DmsSvg + }, + { + title: "CCE", + text: "Cloud Container Engine", + link: "/docs/tags/cce", + icon: CceSvg + }, + { + title: "SWR", + text: "Software Repository for Containers", + link: "/docs/tags/swr", + icon: SwrSvg + }, + { + title: "Cloud Create", + text: "Multi-Cloud Management Platform", + link: "/docs/tags/cloud-create", + icon: CcSvg + }, + ]; + +export default function FeaturedServices(): JSX.Element { + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/ManagementServices/index.tsx b/src/components/ServiceCallouts/ManagementServices/index.tsx new file mode 100644 index 000000000..93d7d3b40 --- /dev/null +++ b/src/components/ServiceCallouts/ManagementServices/index.tsx @@ -0,0 +1,69 @@ +import ServiceCallouts, { Callout } from './../callout'; + +import ApmSvg from '@site/static/img/services/apm.svg' +import CesSvg from '@site/static/img/services/CES.svg' +import ConfigSvg from '@site/static/img/services/rms.svg' +import CtsSvg from '@site/static/img/services/CTS.svg' +import LtsSvg from '@site/static/img/services/LTS.svg' +import RmsSvg from '@site/static/img/services/rms.svg' +import TmsSvg from '@site/static/img/services/TMS.svg' +import CcSvg from '@site/static/img/services/cc.svg' + + const calloutsList: Callout[] = [ + { + title: "APM", + text: "Application Performance Management", + link: "/docs/tags/apm", + icon: ApmSvg + }, + { + title: "Cloud Create", + text: "Multi-Cloud Management Platform", + link: "/docs/tags/cloud-create", + icon: CcSvg + }, + { + title: "CloudEye", + text: "Multi-Dimensional Monitoring Platform", + link: "/docs/tags/cloudeye", + icon: CesSvg + }, + { + title: "Config", + text: "Continuously Evaluate Resource Configuration", + link: "/docs/tags/config", + icon: ConfigSvg + }, + { + title: "CTS", + text: "Cloud Trace Service", + link: "/docs/tags/cts", + icon: CtsSvg + }, + { + title: "LTS", + text: "Log Tank Service", + link: "/docs/tags/lts", + icon: LtsSvg + }, + { + title: "RMS", + text: "Resource Management Service ", + link: "/docs/tags/rms", + icon: RmsSvg + }, + { + title: "TMS", + text: "Tag Management Service", + link: "/docs/tags/rds", + icon: TmsSvg + }, + ]; + +export default function ManagementServices(): JSX.Element { + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/NetworkingServices/index.tsx b/src/components/ServiceCallouts/NetworkingServices/index.tsx new file mode 100644 index 000000000..0ead41ee4 --- /dev/null +++ b/src/components/ServiceCallouts/NetworkingServices/index.tsx @@ -0,0 +1,90 @@ +import ServiceCallouts, { Callout } from './../callout'; + +import DcSvg from '@site/static/img/services/DC_DirectConnect.svg' +import DnsSvg from '@site/static/img/services/DNS.svg' +import EipSvg from '@site/static/img/services/IP-EIP.svg' +import ElbSvg from '@site/static/img/services/ELB.svg' +import ErSvg from '@site/static/img/services/er.svg' +import NatgwSvg from '@site/static/img/services/nat-nat-gateway.svg' +import PlasSvg from '@site/static/img/services/plas.svg' +import SmgSvg from '@site/static/img/services/smg.svg' +import VpcSvg from '@site/static/img/services/VPC.svg' +import VpcepSvg from '@site/static/img/services/Vpc Endpoint.svg' +import VpnSvg from '@site/static/img/services/VPN.svg' + + const calloutsList: Callout[] = [ + { + title: "Direct Connect", + text: "Dedicated Network Connection", + link: "/docs/tags/direct-connect", + icon: DcSvg + }, + { + title: "DNS", + text: "Domain Name Service", + link: "/docs/tags/dns", + icon: DnsSvg + }, + { + title: "EIP", + text: "Elastic IP", + link: "/docs/tags/eip", + icon: EipSvg + }, + { + title: "ELB", + text: "Elastic Load Balancing", + link: "/docs/tags/elb", + icon: ElbSvg + }, + { + title: "Enterprise Router", + text: "Cloud Router Service", + link: "/docs/tags/enterprise-router", + icon: ErSvg + }, + { + title: "NATGW", + text: "NAT Gateway", + link: "/docs/tags/natgw", + icon: NatgwSvg + }, + { + title: "PLAS", + text: "Private Link Access Service", + link: "/docs/tags/plas", + icon: PlasSvg + }, + { + title: "Secure Mail Gateway", + text: "Anti-Spam & Anti-Junk Outgoing Email Traffic", + link: "/docs/tags/smg", + icon: SmgSvg + }, + { + title: "VPC", + text: "Virtual Private Cloud", + link: "/docs/tags/vpc", + icon: VpcSvg + }, + { + title: "VPCEP", + text: "Virtual Private Cloud Endpoint", + link: "/docs/tags/vpcep", + icon: VpcepSvg + }, + { + title: "VPN", + text: "Virtual Private Network", + link: "/docs/tags/vpn", + icon: VpnSvg + }, + ]; + +export default function NetworkingServices(): JSX.Element { + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/NewServices/index.tsx b/src/components/ServiceCallouts/NewServices/index.tsx new file mode 100644 index 000000000..f5f048a95 --- /dev/null +++ b/src/components/ServiceCallouts/NewServices/index.tsx @@ -0,0 +1,55 @@ +import ServiceCallouts, { Callout } from '../callout'; + +import AsmSvg from '@site/static/img/services/asm.svg' +import CciSvg from '@site/static/img/services/cci.svg' +import ConfigSvg from '@site/static/img/services/rms.svg' +import OcrSvg from '@site/static/img/services/ocr.svg' +import FgSvg from '@site/static/img/services/fg.svg' +import GeminidbSvg from '@site/static/img/services/RDS .svg' + + const calloutsList: Callout[] = [ + { + title: "ASM", + text: "Application Service Mesh (Istio-Based)", + link: "https://docs.otc.t-systems.com/application-service-mesh/index.html", + icon: AsmSvg + }, + { + title: "CCI", + text: "Serverless Container Engine", + link: "https://docs.otc.t-systems.com/cloud-container-instance/index.html", + icon: CciSvg + }, + { + title: "Config", + text: "Continuously Evaluate Resource Configuration", + link: "https://docs.otc.t-systems.com/config/index.html", + icon: ConfigSvg + }, + { + title: "OCR", + text: "Optical Character Recognition", + link: "https://docs.otc.t-systems.com/optical-character-recognition/index.html", + icon: OcrSvg + }, + { + title: "FGS", + text: "FunctionGraph", + link: "https://docs.otc.t-systems.com/function-graph/index.html", + icon: FgSvg + }, + { + title: "GeminiDB", + text: "Distributed, Multi-Model NoSQL Database Service", + link: "https://docs.otc.t-systems.com/geminidb/index.html", + icon: GeminidbSvg + }, + ]; + +export default function NewServices(): JSX.Element { + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/SecurityServices/index.tsx b/src/components/ServiceCallouts/SecurityServices/index.tsx new file mode 100644 index 000000000..46ff47e3f --- /dev/null +++ b/src/components/ServiceCallouts/SecurityServices/index.tsx @@ -0,0 +1,62 @@ +import ServiceCallouts, { Callout } from './../callout'; + +import AntiddosSvg from '@site/static/img/services/Anti-DDoS.svg' +import DbssSvg from '@site/static/img/services/dbss.svg' +import HssSvg from '@site/static/img/services/hss.svg' +import IamSvg from '@site/static/img/services/IAM.svg' +import KmsSvg from '@site/static/img/services/Security-KMS.svg' +import WafSvg from '@site/static/img/services/web-WAF.svg' +import DwafSvg from '@site/static/img/services/web-WAF.svg' + + const calloutsList: Callout[] = [ + { + title: "Anti-DDoS", + text: "Anti-DDoS Traffic Cleaning Service", + link: "/docs/tags/anti-ddos", + icon: AntiddosSvg + }, + { + title: "DDS", + text: "Database Security Service", + link: "/docs/tags/dss", + icon: DbssSvg + }, + { + title: "HSS", + text: "Host Security Service", + link: "/docs/tags/hss", + icon: HssSvg + }, + { + title: "IAM", + text: "Identity & Access Management", + link: "/docs/tags/iam", + icon: IamSvg + }, + { + title: "KMS", + text: "Key Management Service", + link: "/docs/tags/kms", + icon: KmsSvg + }, + { + title: "WAF", + text: "Web Application Firewall", + link: "/docs/tags/waf", + icon: WafSvg + }, + { + title: "Dedicated WAF", + text: "Dedicated Web Application Firewall", + link: "/docs/tags/dedicated-waf", + icon: DwafSvg + }, + ]; + +export default function SecurityServices(): JSX.Element { + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/StorageServices/index.tsx b/src/components/ServiceCallouts/StorageServices/index.tsx new file mode 100644 index 000000000..5769a1e05 --- /dev/null +++ b/src/components/ServiceCallouts/StorageServices/index.tsx @@ -0,0 +1,62 @@ +import ServiceCallouts, { Callout } from './../callout'; + +import CbrSvg from '@site/static/img/services/CBR.svg' +import CsbsSvg from '@site/static/img/services/CSBS.svg' +import EvsSvg from '@site/static/img/services/EVS.svg' +import ObsSvg from '@site/static/img/services/OBS.svg' +import SdrsSvg from '@site/static/img/services/sdrs.svg' +import SfsSvg from '@site/static/img/services/SFS.svg' +import VbsSvg from '@site/static/img/services/VBS.svg' + + const calloutsList: Callout[] = [ + { + title: "CBR", + text: "Cloud Backup & Recovery", + link: "/docs/tags/cbr", + icon: CbrSvg + }, + { + title: "CSBS", + text: "Cloud Server Backup Service", + link: "/docs/tags/csbs", + icon: CsbsSvg + }, + { + title: "EVS", + text: "Elastic Volume Service", + link: "/docs/tags/evs", + icon: EvsSvg + }, + { + title: "OBS", + text: "Object Storage Service", + link: "/docs/tags/obs", + icon: ObsSvg + }, + { + title: "SDRS", + text: "Storage Disaster Recovery Service", + link: "/docs/tags/sdrs", + icon: SdrsSvg + }, + { + title: "SFS", + text: "Scalable File Service", + link: "/docs/tags/sfs", + icon: SfsSvg + }, + { + title: "VBS", + text: "Volume Backup Service", + link: "/docs/tags/vbs", + icon: VbsSvg + }, + ]; + +export default function StorageServices(): JSX.Element { + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/callout.tsx b/src/components/ServiceCallouts/callout.tsx new file mode 100644 index 000000000..c11974754 --- /dev/null +++ b/src/components/ServiceCallouts/callout.tsx @@ -0,0 +1,51 @@ +import clsx from "clsx"; +import styles from "./styles.modules.css"; +import { ComponentType, SVGProps } from 'react'; + +export interface Callout { + title: string; + text?: string; + link: string; + // icon: (props: React.ComponentProps<"svg">) => JSX.Element; + icon: ComponentType>; +} + +function Callout(props: Callout): JSX.Element { + return ( + +
+
+

+

+
+
+ +

+ {props.text} +

+
+
+
+
+ ); +} + +export interface ServiceCalloutsProps { + callouts: Callout[]; +} + +export default function ServiceCallouts({ callouts }: ServiceCalloutsProps): JSX.Element { + return ( +
+
+ {callouts.map((c) => ( +
+ +
+ ))} +
+
+ ); +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/index.tsx b/src/components/ServiceCallouts/index.tsx new file mode 100644 index 000000000..8d3e2676a --- /dev/null +++ b/src/components/ServiceCallouts/index.tsx @@ -0,0 +1,26 @@ +import ServiceCallouts, { Callout } from './callout'; + +import DnsSvg from '@site/static/img/services/DNS.svg' + +const calloutsList: Callout[] = [ + { + title: "ttt", + text: "Application Operations Management", + link: "/docs/best-practices/building-highly-available-web-server-clusters-with-keepalived", + icon: DnsSvg + }, + { + title: "yyy", + text: "Application Operations Management", + link: "/docs/best-practices/building-highly-available-web-server-clusters-with-keepalived", + icon: DnsSvg + }, +]; + +export default function BestPractices(): JSX.Element { + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/components/ServiceCallouts/styles.modules.css b/src/components/ServiceCallouts/styles.modules.css new file mode 100644 index 000000000..8ca9cf28e --- /dev/null +++ b/src/components/ServiceCallouts/styles.modules.css @@ -0,0 +1,70 @@ +/* .hero { +} +.hero__title { + color: var(--ifm-color-primary); + font-size: 3.75rem; + line-height: 1; + letter-spacing: -0.025em; +} +.hero__text { + font-size: 1.25rem; + line-height: 1.75rem; +} */ +/* .card__body { + padding: 0 var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing) !important; + margin-top: -60px 0 0 0; + border-color: blue; +} */ +.callout { + position: relative; + background-color: var(--telekom-color-background-surface-subtle); +} +.callout__title { + align-items: center; + display: flex; + font-weight: normal; + font-size: smaller; + margin-bottom: 0; +} +.callout__icon { + height: 1.25rem; + margin-right: 0.5rem; + width: 1.25rem; +} +.callout__link { + color: inherit; + text-decoration: none; + font-size: small; +} +.callout__link:hover { + color: inherit; + text-decoration: none; +} +.callout__bottom { + background: var(--ifm-color-primary); + height: 0.5rem; + margin-top: 0.5rem; + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + width: 0; +} +.callout:hover .callout__bottom { + width: 100%; +} + +.callout__shadow { + /* box-shadow: 0 1px 2px gray; */ + box-shadow: unset; + background-color: #ebedf0; +} + +html[data-theme='dark'] .callout__shadow { + box-shadow: unset; + background-color: var(--telekom-color-background-surface-subtle); +} + +.video { + box-shadow: 0 2px 6px var(--ifm-background-surface-color-dark); + border-radius: 0.375rem; +} \ No newline at end of file diff --git a/src/css/custom.css b/src/css/custom.css index 552ca9bff..8a0c86db9 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -29,6 +29,14 @@ --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); } */ :root, +html { + display: none; /* Hide until the correct theme is applied */ +} + +html[data-mode] { + display: block; /* Show after the correct theme is set */ +} + html[data-theme='light'] { --ifm-color-primary: #e20074; --ifm-color-primary-dark: #cb0068; @@ -41,11 +49,16 @@ html[data-theme='light'] { --ifm-footer-link-color: black; --ifm-code-font-size: 95%; --ifm-font-family-base: 'TeleNeoWeb'; - --ifm-background-color: #ffffff; - --ifm-background-surface-color: #ffffff; + --ifm-background-color: #fbfbfb; + --ifm-background-surface-color: var(--telekom-color-background-surface); + + /* --background: #ffffff; */ + --telekom-shadow-raised-standard: none; + --telekom-radius-large: 2rem; + --telekom-shadow-raised-hover: 0px 16px 64px 0px hsla(0, 0%, 0%, 0.1), 0px 8px 16px 0px hsla(0, 0%, 0%, 0.1); } -[data-theme='dark'] { +html[data-theme='dark'] { --ifm-color-primary: #ff2796; --ifm-color-primary-dark: #5977f7; --ifm-color-primary-darker: #4768f7; @@ -53,17 +66,23 @@ html[data-theme='light'] { --ifm-color-primary-light: #a1b1fb; --ifm-color-primary-lighter: #b3c0fb; --ifm-color-primary-lightest: #e8ecfe; - --ifm-background-color: #1b1b1d; - --ifm-background-surface-color: #1b1b1d; + --ifm-font-family-base: 'TeleNeoWeb'; + --ifm-background-color: #0e0e0f; + --ifm-background-surface-color: var(--telekom-color-background-surface); + + /* --background: #000000; */ + --telekom-shadow-raised-standard: none; + --telekom-radius-large: 2rem; + --telekom-shadow-raised-hover: 0px 16px 64px 0px #e20074, 0px 8px 16px 0px #e20074; } /* Override system color scheme preference */ -@media (prefers-color-scheme: dark) { +/* @media (prefers-color-scheme: dark) { html[data-theme='light'] { --ifm-background-color: #ffffff; --ifm-background-surface-color: #ffffff; } -} +} */ @media screen and (max-width: 996px) { @@ -91,6 +110,16 @@ html[data-theme='light'] { } } +/* .scale-telekom-feature-card { + --background-footer-minimal: white; + --font-color: black; +} + +html[data-theme='dark'] .scale-telekom-feature-card { + --background-footer-minimal: #1b1b1d; + --font-color: white; +} */ + .scale-telekom-footer { --background-footer-minimal: white; --font-color: black; @@ -99,16 +128,6 @@ html[data-theme='light'] { html[data-theme='dark'] .scale-telekom-footer { --background-footer-minimal: #1b1b1d; --font-color: white; - /* ul { - li { - a { - color: white; - } - } - } - span { - color: white; - } */ } html[data-theme='dark'] .scale-telekom-footer ul li a { @@ -212,12 +231,12 @@ html[data-theme='dark'] .footer__link-item:hover { content: ''; height: 100%; display: block; - background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") + background: url("data:image/svg+xml,%3Csvg viewBox='0 0 25 25' width='25' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat; } html[data-theme='dark'] .navbar--github-link:before { - background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") + background: url("data:image/svg+xml,%3Csvg viewBox='0 0 25 25' width='25' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat; } @@ -250,4 +269,30 @@ html[data-theme='dark'] .footer__link-item:hover { background: url("data:image/svg+xml,%3Csvg viewBox='0 0 1792 1792' width='24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M649 983l-466 466q-10 10-23 10t-23-10l-50-50q-10-10-10-23t10-23l393-393-393-393q-10-10-10-23t10-23l50-50q10-10 23-10t23 10l466 466q10 10 10 23t-10 23zm1079 457v64q0 14-9 23t-23 9h-960q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h960q14 0 23 9t9 23z'/%3E%3C/svg%3E") } + /* Gitlab */ + .navbar--discourse-link { + width: 36px; + height: 36px; + padding: 6px; + margin-right: 6px; + margin-left: 6px; + border-radius: 50%; + transition: background var(--ifm-transition-fast); + } + + .navbar--discourse-link:hover { + background: var(--ifm-color-emphasis-200); + } + + .navbar--discourse-link:before { + content: ''; + height: 100%; + display: block; + background: url("data:image/svg+xml,%3Csvg viewBox='0 36 448 512' width='23' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z'/%3E%3C/svg%3E") + no-repeat; + } + + html[data-theme='dark'] .navbar--discourse-link:before { + background: url("data:image/svg+xml,%3Csvg viewBox='0 36 448 512' width='24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z'/%3E%3C/svg%3E") + } diff --git a/src/pages/index.module.css b/src/pages/index.module.css index 9f71a5da7..d346cc6af 100644 --- a/src/pages/index.module.css +++ b/src/pages/index.module.css @@ -21,3 +21,73 @@ align-items: center; justify-content: center; } + +.callout { + position: relative; +} +.callout__title { + align-items: center; + display: flex; + font-weight: normal; + font-size: smaller; + margin-bottom: 0; +} +.callout__icon { + height: 1.25rem; + margin-right: 0.5rem; + width: 1.25rem; +} +.callout__link { + color: inherit; + text-decoration: none; + font-size: small; +} +.callout__link:hover { + color: inherit; + text-decoration: none; +} +.callout__bottom { + background: var(--ifm-color-primary); + height: 0.5rem; + margin-top: 0.5rem; + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + width: 0; +} +.callout:hover .callout__bottom { + width: 100%; +} + +.video { + box-shadow: 0 2px 6px var(--ifm-background-surface-color-dark); + border-radius: 0.375rem; +} + +.item { + box-shadow: 0 1px 3px gray; + background-color: var(--ifm-background-color); + border-radius: 2rem; + color: black; + overflow: hidden; +} + +html[data-theme='dark'] .item { + box-shadow: 0px 1px 3px var(--ifm-color-primary); + background-color: var(--ifm-background-color); + border-radius: 2rem; + color: white; + overflow: hidden; +} + +.item__inner { + align-items: center; + display: flex; +} +.item__inner div { + padding: 3rem; +} +.item__title span { + display: block; + font-size: 1.25rem; +} \ No newline at end of file diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 880f24f9a..a91563724 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,34 +1,38 @@ import clsx from 'clsx'; -import Link from '@docusaurus/Link'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import Layout from '@theme/Layout'; import HomepageFeatures from '@site/src/components/HomepageFeatures'; -import Heading from '@theme/Heading'; -import {useColorMode, useThemeConfig} from '@docusaurus/theme-common'; +// import Heading from '@theme/Heading'; +// import { useThemeConfig } from '@docusaurus/theme-common'; -import styles from './index.module.css'; +// import styles from './index.module.css'; +import HomepageFeaturedServices from '../components/HomepageFeaturedServices'; +import HomepageAskAQuestion from '../components/HomepageAskAQuestion'; +import HomepageContribute from '../components/HomepageContribute'; -function HomepageHeader() { - const {siteConfig} = useDocusaurusContext(); - const navbarStyle = useThemeConfig().navbar.style; - var buttonVariant = navbarStyle === 'dark' ? "primary" : "secondary-white" - return ( -
-
- - {siteConfig.title} - -

Open Telekom Cloud {siteConfig.tagline}

-
- Get Started! 🚀 -
-
-
- ); -} +// function HomepageHeader() { +// const { siteConfig } = useDocusaurusContext(); +// const navbarStyle = useThemeConfig().navbar.style; +// const buttonVariant = navbarStyle === 'dark' ? "primary" : "secondary-white" +// return ( +//
+//
+// +// {siteConfig.title} +// +//

Open Telekom Cloud {siteConfig.tagline}

+//
+// +// Get Started +// +//
+//
+//
+// ); +// } export default function Home(): JSX.Element { - const {siteConfig} = useDocusaurusContext(); + const { siteConfig } = useDocusaurusContext(); return ( */}
+ + +
+
+
+ +
+
+ +
+
+
+
); diff --git a/src/theme/DocTagDocListPage/index.tsx b/src/theme/DocTagDocListPage/index.tsx new file mode 100644 index 000000000..e0bda86ac --- /dev/null +++ b/src/theme/DocTagDocListPage/index.tsx @@ -0,0 +1,119 @@ +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import { + PageMetadata, + HtmlClassNameProvider, + ThemeClassNames, + usePluralForm, +} from '@docusaurus/theme-common'; +import Translate, {translate} from '@docusaurus/Translate'; +import SearchMetadata from '@theme/SearchMetadata'; +import type {Props} from '@theme/DocTagDocListPage'; +import Unlisted from '@theme/Unlisted'; +import Heading from '@theme/Heading'; +import styles from './styles.module.css'; + +// Very simple pluralization: probably good enough for now +function useNDocsTaggedPlural() { + const {selectMessage} = usePluralForm(); + return (count: number) => + selectMessage( + count, + translate( + { + id: 'theme.docs.tagDocListPageTitle.nDocsTagged', + description: + 'Pluralized label for "{count} docs tagged". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)', + message: 'We found one article tagged|We found {count} articles tagged', + }, + {count}, + ), + ); +} + +function usePageTitle(props: Props): string { + const nDocsTaggedPlural = useNDocsTaggedPlural(); + return translate( + { + id: 'theme.docs.tagDocListPageTitle', + description: 'The title of the page for a docs tag', + message: '{nDocsTagged} with "{tagName}"', + }, + {nDocsTagged: nDocsTaggedPlural(props.tag.count), tagName: props.tag.label}, + ); +} + +function DocItem({doc}: {doc: Props['tag']['items'][number]}): JSX.Element { + return ( +
+
+ {/* */} +
+
+ + {doc.title} + + {doc.description &&

{doc.description}

} +
+
+
+
+ ); +} + +function DocTagDocListPageMetadata({ + title, + tag, +}: Props & {title: string}): JSX.Element { + return ( + <> + + + + ); +} + +function DocTagDocListPageContent({ + tag, + title, +}: Props & {title: string}): JSX.Element { + return ( + +
+
+
+ {tag.unlisted && } +
+ {title} + {tag.description &&

{tag.description}

} + + + View All Tags + + +
+
+ {tag.items.map((doc) => ( + + ))} +
+
+
+
+
+ ); +} + +export default function DocTagDocListPage(props: Props): JSX.Element { + const title = usePageTitle(props); + return ( + <> + + + + ); +} diff --git a/src/theme/DocTagDocListPage/styles.module.css b/src/theme/DocTagDocListPage/styles.module.css new file mode 100644 index 000000000..7316a6ad6 --- /dev/null +++ b/src/theme/DocTagDocListPage/styles.module.css @@ -0,0 +1,28 @@ + +.item { + box-shadow: 0 1px 3px gray; + background-color: var(--ifm-background-color); + border-radius: 0.5rem; + color: black; + overflow: hidden; +} + +html[data-theme='dark'] .item { + box-shadow: 0px 1px 3px var(--ifm-color-primary); + background-color: var(--ifm-background-color); + border-radius: 0.5rem; + color: white; + overflow: hidden; +} + +.item__inner { + align-items: center; + display: flex; +} +.item__inner div { + padding: 1.5rem; +} +.item__title span { + display: block; + font-size: 1.25rem; +} \ No newline at end of file diff --git a/src/theme/Footer/Copyright/index.tsx b/src/theme/Footer/Copyright/index.tsx index d2e99b7f8..88b1442d7 100644 --- a/src/theme/Footer/Copyright/index.tsx +++ b/src/theme/Footer/Copyright/index.tsx @@ -1,41 +1,7 @@ -import React from 'react'; import type { Props } from '@theme/Footer/Copyright'; export default function FooterCopyright({ copyright }: Props): JSX.Element { return ( - //
- //
- // - // - // {copyright} - // - // - // - //
{copyright} ); } diff --git a/src/theme/Footer/Layout/index.tsx b/src/theme/Footer/Layout/index.tsx index b5091c01c..0503e0029 100644 --- a/src/theme/Footer/Layout/index.tsx +++ b/src/theme/Footer/Layout/index.tsx @@ -1,23 +1,27 @@ -import React from 'react'; import clsx from 'clsx'; import type { Props } from '@theme/Footer/Layout'; export default function FooterLayout({ style, links, - logo, copyright, }: Props): JSX.Element { return (
- {links} - {(logo || copyright) && ( -
- {logo &&
{logo} -
} +
+ {/*
+ {(logo || copyright) && ( +
+ {logo &&
{logo} +
} +
+ )} +
*/} +
+ {links}
- )} +
@@ -35,9 +39,12 @@ export default function FooterLayout({
  • Imprint
  • + {/*
  • + v{ "0.1-development" } +
  • */}
    -
    + ); } diff --git a/src/theme/Footer/LinkItem/index.tsx b/src/theme/Footer/LinkItem/index.tsx index 65047723c..20ba6db41 100644 --- a/src/theme/Footer/LinkItem/index.tsx +++ b/src/theme/Footer/LinkItem/index.tsx @@ -1,5 +1,3 @@ -import React from 'react'; - import Link from '@docusaurus/Link'; import useBaseUrl from '@docusaurus/useBaseUrl'; import isInternalUrl from '@docusaurus/isInternalUrl'; diff --git a/src/theme/Footer/Links/MultiColumn/index.tsx b/src/theme/Footer/Links/MultiColumn/index.tsx index f8f7b34f0..24d8688f0 100644 --- a/src/theme/Footer/Links/MultiColumn/index.tsx +++ b/src/theme/Footer/Links/MultiColumn/index.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import LinkItem from '@theme/Footer/LinkItem'; import type {Props} from '@theme/Footer/Links/MultiColumn'; @@ -10,7 +9,7 @@ function ColumnLinkItem({item}: {item: ColumnItemType}) {
  • ) : ( diff --git a/src/theme/Footer/Links/Simple/index.tsx b/src/theme/Footer/Links/Simple/index.tsx index 65744e4e6..cb8da4357 100644 --- a/src/theme/Footer/Links/Simple/index.tsx +++ b/src/theme/Footer/Links/Simple/index.tsx @@ -11,7 +11,7 @@ function SimpleLinkItem({item}: {item: Props['links'][number]}) { ) : ( diff --git a/src/theme/Footer/Links/index.tsx b/src/theme/Footer/Links/index.tsx index d9ec3db74..be1f27776 100644 --- a/src/theme/Footer/Links/index.tsx +++ b/src/theme/Footer/Links/index.tsx @@ -1,5 +1,3 @@ -import React from 'react'; - import {isMultiColumnFooterLinks} from '@docusaurus/theme-common'; import FooterLinksMultiColumn from '@theme/Footer/Links/MultiColumn'; import FooterLinksSimple from '@theme/Footer/Links/Simple'; diff --git a/src/theme/Footer/Logo/index.tsx b/src/theme/Footer/Logo/index.tsx index f778e35cc..ecc4c1e1f 100644 --- a/src/theme/Footer/Logo/index.tsx +++ b/src/theme/Footer/Logo/index.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import clsx from 'clsx'; import Link from '@docusaurus/Link'; import {useBaseUrlUtils} from '@docusaurus/useBaseUrl'; diff --git a/src/theme/Footer/index.tsx b/src/theme/Footer/index.tsx index 1771066d0..b3b530ab7 100644 --- a/src/theme/Footer/index.tsx +++ b/src/theme/Footer/index.tsx @@ -5,20 +5,24 @@ import FooterLinks from '@theme/Footer/Links'; import FooterLogo from '@theme/Footer/Logo'; import FooterCopyright from '@theme/Footer/Copyright'; import FooterLayout from '@theme/Footer/Layout'; +// import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; // get metadata about page function Footer(): JSX.Element | null { + // const context = useDocusaurusContext(); + // const { siteConfig = {} } = context; + const {footer} = useThemeConfig(); if (!footer) { return null; } const {copyright, links, logo, style} = footer; - + // const {version} = siteConfig.customFields["version"]; return ( 0 && } logo={logo && } - copyright={copyright && } + copyright={copyright && } /> ); } diff --git a/src/theme/Navbar/ColorModeToggle/index.tsx b/src/theme/Navbar/ColorModeToggle/index.tsx index b0d400777..53f5337cb 100644 --- a/src/theme/Navbar/ColorModeToggle/index.tsx +++ b/src/theme/Navbar/ColorModeToggle/index.tsx @@ -1,15 +1,36 @@ -import React from 'react'; -import {useColorMode, useThemeConfig} from '@docusaurus/theme-common'; +import {useThemeConfig} from '@docusaurus/theme-common'; import ColorModeToggle from '@theme/ColorModeToggle'; import type {Props} from '@theme/Navbar/ColorModeToggle'; import styles from './styles.module.css'; +import { useColorMode as originalUseColorMode } from '@docusaurus/theme-common'; +import { useEffect } from 'react'; + +// Create a custom hook that extends the original useColorMode for Scale +export function useColorModeWithScale() { + const { colorMode, setColorMode } = originalUseColorMode(); + const toggleScaleColorMode = (newMode) => { + document.documentElement.dataset.mode = newMode + }; + + useEffect(() => { + // On component mount, sync the initial color mode between Docusaurus and Scale + toggleScaleColorMode(colorMode); + }, [colorMode]); + + return { + colorMode, + setColorMode, + toggleScaleColorMode, + }; +} + export default function NavbarColorModeToggle({ className, }: Props): JSX.Element | null { const navbarStyle = useThemeConfig().navbar.style; const disabled = useThemeConfig().colorMode.disableSwitch; - const {colorMode, setColorMode} = useColorMode(); + const {colorMode, setColorMode, toggleScaleColorMode} = useColorModeWithScale(); if (disabled) { return null; @@ -22,7 +43,10 @@ export default function NavbarColorModeToggle({ navbarStyle === 'dark' ? styles.darkNavbarColorModeToggle : undefined } value={colorMode} - onChange={setColorMode} + onChange={(newMode) => { + setColorMode(newMode); + toggleScaleColorMode(newMode); + }} /> ); } diff --git a/src/theme/Navbar/Content/index.tsx b/src/theme/Navbar/Content/index.tsx index f8bf21e1d..a76943209 100644 --- a/src/theme/Navbar/Content/index.tsx +++ b/src/theme/Navbar/Content/index.tsx @@ -1,4 +1,4 @@ -import React, {type ReactNode} from 'react'; +import {type ReactNode} from 'react'; import {useThemeConfig, ErrorCauseBoundary} from '@docusaurus/theme-common'; import { splitNavbarItems, diff --git a/src/theme/Navbar/Layout/index.tsx b/src/theme/Navbar/Layout/index.tsx index e5ef87d0d..16cad75d1 100644 --- a/src/theme/Navbar/Layout/index.tsx +++ b/src/theme/Navbar/Layout/index.tsx @@ -1,4 +1,4 @@ -import React, { type ComponentProps } from 'react'; +import { type ComponentProps } from 'react'; import clsx from 'clsx'; import { useThemeConfig } from '@docusaurus/theme-common'; import { @@ -23,7 +23,7 @@ function NavbarBackdrop(props: ComponentProps<'div'>) { export default function NavbarLayout({ children }: Props): JSX.Element { const { - navbar: { hideOnScroll, style, title }, + navbar: { hideOnScroll, style }, } = useThemeConfig(); const mobileSidebar = useNavbarMobileSidebar(); const { navbarRef, isNavbarVisible } = useHideableNavbar(hideOnScroll); diff --git a/src/theme/Navbar/Logo/index.tsx b/src/theme/Navbar/Logo/index.tsx index 327d7a18b..b76eb1bd0 100644 --- a/src/theme/Navbar/Logo/index.tsx +++ b/src/theme/Navbar/Logo/index.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import Logo from '@theme/Logo'; export default function NavbarLogo(): JSX.Element { diff --git a/src/theme/Navbar/MobileSidebar/Header/index.tsx b/src/theme/Navbar/MobileSidebar/Header/index.tsx index d1f1659bb..d22533865 100644 --- a/src/theme/Navbar/MobileSidebar/Header/index.tsx +++ b/src/theme/Navbar/MobileSidebar/Header/index.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import {useNavbarMobileSidebar} from '@docusaurus/theme-common/internal'; import {translate} from '@docusaurus/Translate'; import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle'; diff --git a/src/theme/Navbar/MobileSidebar/Layout/index.tsx b/src/theme/Navbar/MobileSidebar/Layout/index.tsx index 6107f5105..b48facf39 100644 --- a/src/theme/Navbar/MobileSidebar/Layout/index.tsx +++ b/src/theme/Navbar/MobileSidebar/Layout/index.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import clsx from 'clsx'; import {useNavbarSecondaryMenu} from '@docusaurus/theme-common/internal'; import type {Props} from '@theme/Navbar/MobileSidebar/Layout'; diff --git a/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx b/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx index db30be497..cdbc2af00 100644 --- a/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx +++ b/src/theme/Navbar/MobileSidebar/PrimaryMenu/index.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import {useThemeConfig} from '@docusaurus/theme-common'; import {useNavbarMobileSidebar} from '@docusaurus/theme-common/internal'; import NavbarItem, {type Props as NavbarItemConfig} from '@theme/NavbarItem'; diff --git a/src/theme/Navbar/MobileSidebar/SecondaryMenu/index.tsx b/src/theme/Navbar/MobileSidebar/SecondaryMenu/index.tsx index 757f59673..8cd337d98 100644 --- a/src/theme/Navbar/MobileSidebar/SecondaryMenu/index.tsx +++ b/src/theme/Navbar/MobileSidebar/SecondaryMenu/index.tsx @@ -1,4 +1,4 @@ -import React, {type ComponentProps} from 'react'; +import {type ComponentProps} from 'react'; import {useThemeConfig} from '@docusaurus/theme-common'; import {useNavbarSecondaryMenu} from '@docusaurus/theme-common/internal'; import Translate from '@docusaurus/Translate'; diff --git a/src/theme/Navbar/MobileSidebar/Toggle/index.tsx b/src/theme/Navbar/MobileSidebar/Toggle/index.tsx index 9691f103c..f5ca1e043 100644 --- a/src/theme/Navbar/MobileSidebar/Toggle/index.tsx +++ b/src/theme/Navbar/MobileSidebar/Toggle/index.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import {useNavbarMobileSidebar} from '@docusaurus/theme-common/internal'; import {translate} from '@docusaurus/Translate'; import IconMenu from '@theme/Icon/Menu'; diff --git a/src/theme/Navbar/MobileSidebar/index.tsx b/src/theme/Navbar/MobileSidebar/index.tsx index 484b319b9..710ccb32b 100644 --- a/src/theme/Navbar/MobileSidebar/index.tsx +++ b/src/theme/Navbar/MobileSidebar/index.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { useLockBodyScroll, useNavbarMobileSidebar, diff --git a/src/theme/Navbar/Search/index.tsx b/src/theme/Navbar/Search/index.tsx index 788b3f1cd..83630e010 100644 --- a/src/theme/Navbar/Search/index.tsx +++ b/src/theme/Navbar/Search/index.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import clsx from 'clsx'; import type {Props} from '@theme/Navbar/Search'; diff --git a/src/theme/Navbar/index.tsx b/src/theme/Navbar/index.tsx index a9b61f1ee..146a5c634 100644 --- a/src/theme/Navbar/index.tsx +++ b/src/theme/Navbar/index.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import NavbarLayout from '@theme/Navbar/Layout'; import NavbarContent from '@theme/Navbar/Content'; diff --git a/src/theme/NotFound/Content/index.tsx b/src/theme/NotFound/Content/index.tsx new file mode 100644 index 000000000..d925c2795 --- /dev/null +++ b/src/theme/NotFound/Content/index.tsx @@ -0,0 +1,37 @@ +import clsx from 'clsx'; +import Translate from '@docusaurus/Translate'; +import type {Props} from '@theme/NotFound/Content'; +import Heading from '@theme/Heading'; + +export default function NotFoundContent({className}: Props): JSX.Element { + return ( +
    +
    +
    + + + We are sorry... + + +

    + + We could not find anything related to what you were looking for. + +

    + {/*

    + + Please contact the owner of the site that linked you to the + original URL and let them know their link is broken. + +

    */} +
    +
    +
    + ); +} diff --git a/src/theme/Root.js b/src/theme/Root.js index aac5b08e8..59b6e16c3 100644 --- a/src/theme/Root.js +++ b/src/theme/Root.js @@ -1,4 +1,3 @@ -import React from 'react'; import { defineCustomElements } from '@telekom/scale-components/loader'; import '@telekom/scale-components/dist/scale-components/scale-components.css'; diff --git a/static/img/configure_gh_pages.png b/static/img/configure_gh_pages.png new file mode 100644 index 000000000..411438d57 Binary files /dev/null and b/static/img/configure_gh_pages.png differ diff --git a/static/img/cross_repo_commit_token.png b/static/img/cross_repo_commit_token.png new file mode 100644 index 000000000..10a76e95a Binary files /dev/null and b/static/img/cross_repo_commit_token.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001457709502.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001457709502.png new file mode 100644 index 000000000..69e3ceb60 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001457709502.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001463836772.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001463836772.png new file mode 100644 index 000000000..73e216aff Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001463836772.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001463840256.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001463840256.png new file mode 100644 index 000000000..aa06091aa Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001463840256.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001463841764.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001463841764.png new file mode 100644 index 000000000..247b0e895 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001463841764.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464002560.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464002560.png new file mode 100644 index 000000000..0659dab14 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464002560.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464031938.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464031938.png new file mode 100644 index 000000000..6bfa5a2ec Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464031938.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464149800.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464149800.png new file mode 100644 index 000000000..e18fa76c6 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464149800.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464161876.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464161876.png new file mode 100644 index 000000000..aa27b99d4 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001464161876.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514305585.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514305585.png new file mode 100644 index 000000000..e0128739b Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514305585.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514311097.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514311097.png new file mode 100644 index 000000000..66aede2f3 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514311097.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514558429.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514558429.png new file mode 100644 index 000000000..cfac9f708 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514558429.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514561077.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514561077.png new file mode 100644 index 000000000..1538e64d8 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514561077.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514587325.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514587325.png new file mode 100644 index 000000000..dd7c1bd89 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514587325.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514670405.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514670405.png new file mode 100644 index 000000000..72e493205 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514670405.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514681605.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514681605.png new file mode 100644 index 000000000..30b2bf496 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0000001514681605.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0107215471.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0107215471.png new file mode 100644 index 000000000..1a8c320f2 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0107215471.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0107215473.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0107215473.png new file mode 100644 index 000000000..b3d44158f Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0107215473.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0107215475.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0107215475.png new file mode 100644 index 000000000..abfa2fac0 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0107215475.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0107215477.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0107215477.png new file mode 100644 index 000000000..859e5138d Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0107215477.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0200645302.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0200645302.png new file mode 100644 index 000000000..6a9349928 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0200645302.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268280658.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268280658.png new file mode 100644 index 000000000..50aa580b4 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268280658.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268284967.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268284967.png new file mode 100644 index 000000000..c5b27871d Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268284967.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268287010.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268287010.png new file mode 100644 index 000000000..42c6f4588 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268287010.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268287244.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268287244.png new file mode 100644 index 000000000..84a919aa6 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268287244.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268288436.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268288436.png new file mode 100644 index 000000000..1d8c61aac Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268288436.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268290676.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268290676.png new file mode 100644 index 000000000..c3c3d937b Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268290676.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268337032.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268337032.png new file mode 100644 index 000000000..9e89ac89e Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268337032.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268393752.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268393752.png new file mode 100644 index 000000000..682794e75 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268393752.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268393798.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268393798.png new file mode 100644 index 000000000..70cc2b9fe Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268393798.png differ diff --git a/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268393846.png b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268393846.png new file mode 100644 index 000000000..4c9f796e9 Binary files /dev/null and b/static/img/docs/best-practices/computing/image-management-service/en-us_image_0268393846.png differ diff --git a/static/img/docs/best-practices/containers/cloud-container-engine/Screenshot from 2024-09-07 11-33-33.png b/static/img/docs/best-practices/containers/cloud-container-engine/Screenshot from 2024-09-07 11-33-33.png new file mode 100644 index 000000000..e6875e2a7 Binary files /dev/null and b/static/img/docs/best-practices/containers/cloud-container-engine/Screenshot from 2024-09-07 11-33-33.png differ diff --git a/static/img/docs/best-practices/databases/document-database-service/en-us_image_0000001117852888.png b/static/img/docs/best-practices/databases/document-database-service/en-us_image_0000001117852888.png new file mode 100644 index 000000000..29f20f55c Binary files /dev/null and b/static/img/docs/best-practices/databases/document-database-service/en-us_image_0000001117852888.png differ diff --git a/static/img/docs/best-practices/databases/document-database-service/en-us_image_0000001166068694.png b/static/img/docs/best-practices/databases/document-database-service/en-us_image_0000001166068694.png new file mode 100644 index 000000000..106fc060c Binary files /dev/null and b/static/img/docs/best-practices/databases/document-database-service/en-us_image_0000001166068694.png differ diff --git a/static/img/docs/best-practices/databases/document-database-service/en-us_image_0000001210912526.png b/static/img/docs/best-practices/databases/document-database-service/en-us_image_0000001210912526.png new file mode 100644 index 000000000..afd348839 Binary files /dev/null and b/static/img/docs/best-practices/databases/document-database-service/en-us_image_0000001210912526.png differ diff --git a/static/img/docs/best-practices/databases/document-database-service/en-us_image_0000001211264689.png b/static/img/docs/best-practices/databases/document-database-service/en-us_image_0000001211264689.png new file mode 100644 index 000000000..71ac88a7d Binary files /dev/null and b/static/img/docs/best-practices/databases/document-database-service/en-us_image_0000001211264689.png differ diff --git a/static/img/docs/best-practices/networking/virtual-private-network/connecting-multiple-on-premises-branch-networks-through-a-vpn-hub/en-us_image_0000001592878805.png b/static/img/docs/best-practices/networking/virtual-private-network/connecting-multiple-on-premises-branch-networks-through-a-vpn-hub/en-us_image_0000001592878805.png new file mode 100644 index 000000000..0df4d74c1 Binary files /dev/null and b/static/img/docs/best-practices/networking/virtual-private-network/connecting-multiple-on-premises-branch-networks-through-a-vpn-hub/en-us_image_0000001592878805.png differ diff --git a/static/img/docs/best-practices/storage/object-storage-service/policy-visual-editor.png b/static/img/docs/best-practices/storage/object-storage-service/policy-visual-editor.png new file mode 100644 index 000000000..2cbd28be3 Binary files /dev/null and b/static/img/docs/best-practices/storage/object-storage-service/policy-visual-editor.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 13-53-46.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 13-53-46.png new file mode 100644 index 000000000..9b03ad0e5 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 13-53-46.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-03-16.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-03-16.png new file mode 100644 index 000000000..b81f06fa8 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-03-16.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-10-01.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-10-01.png new file mode 100644 index 000000000..12fc3cc60 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-10-01.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-12-28.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-12-28.png new file mode 100644 index 000000000..a12d7c4a2 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-12-28.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-16-19.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-16-19.png new file mode 100644 index 000000000..ee5dc3cc5 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-09 14-16-19.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 12-40-41.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 12-40-41.png new file mode 100644 index 000000000..855911c4d Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 12-40-41.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 12-47-36.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 12-47-36.png new file mode 100644 index 000000000..b35f53ab4 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 12-47-36.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 13-14-30.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 13-14-30.png new file mode 100644 index 000000000..cc7e34fa2 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 13-14-30.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-32-38.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-32-38.png new file mode 100644 index 000000000..febfc2e74 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-32-38.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-38-26.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-38-26.png new file mode 100644 index 000000000..3e832d7eb Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-38-26.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-38-50.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-38-50.png new file mode 100644 index 000000000..439acacfc Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-38-50.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-39-09.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-39-09.png new file mode 100644 index 000000000..8e062e1de Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-39-09.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-39-38.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-39-38.png new file mode 100644 index 000000000..5ec0dba61 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-39-38.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-39-50.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-39-50.png new file mode 100644 index 000000000..da9aa90cc Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 14-39-50.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 15-05-13.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 15-05-13.png new file mode 100644 index 000000000..dae75d5f0 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot from 2024-09-10 15-05-13.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot_from_2024-09-09_12-51-39.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot_from_2024-09-09_12-51-39.png new file mode 100644 index 000000000..cfc0987d9 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot_from_2024-09-09_12-51-39.png differ diff --git a/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot_from_2024-09-09_12-52-14.png b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot_from_2024-09-09_12-52-14.png new file mode 100644 index 000000000..68304019b Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/analytics/umami/Screenshot_from_2024-09-09_12-52-14.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/Screenshot-Admin-authentik.png b/static/img/docs/blueprints/by-use-case/security/authentik/Screenshot-Admin-authentik.png new file mode 100644 index 000000000..e734fbe75 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/Screenshot-Admin-authentik.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/Screenshot-chpassword-authentik.png b/static/img/docs/blueprints/by-use-case/security/authentik/Screenshot-chpassword-authentik.png new file mode 100644 index 000000000..e442ab8aa Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/Screenshot-chpassword-authentik.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/authentik-idp-urls.png b/static/img/docs/blueprints/by-use-case/security/authentik/authentik-idp-urls.png new file mode 100644 index 000000000..86bb69011 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/authentik-idp-urls.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/configure-groups-enrollment-stage.png b/static/img/docs/blueprints/by-use-case/security/authentik/configure-groups-enrollment-stage.png new file mode 100644 index 000000000..c2debf39c Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/configure-groups-enrollment-stage.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/configure-idp-iam.png b/static/img/docs/blueprints/by-use-case/security/authentik/configure-idp-iam.png new file mode 100644 index 000000000..0c90f3b1d Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/configure-idp-iam.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/create-application.png b/static/img/docs/blueprints/by-use-case/security/authentik/create-application.png new file mode 100644 index 000000000..bbef3e87f Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/create-application.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/create-group.png b/static/img/docs/blueprints/by-use-case/security/authentik/create-group.png new file mode 100644 index 000000000..8efa27dde Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/create-group.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/create-idp-iam.png b/static/img/docs/blueprints/by-use-case/security/authentik/create-idp-iam.png new file mode 100644 index 000000000..d54fe61bb Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/create-idp-iam.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/create-oauth.png b/static/img/docs/blueprints/by-use-case/security/authentik/create-oauth.png new file mode 100644 index 000000000..6a873e120 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/create-oauth.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/edit-conversion-rules.png b/static/img/docs/blueprints/by-use-case/security/authentik/edit-conversion-rules.png new file mode 100644 index 000000000..6a883326b Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/edit-conversion-rules.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/github-New-OAuth-Application.png b/static/img/docs/blueprints/by-use-case/security/authentik/github-New-OAuth-Application.png new file mode 100644 index 000000000..212964904 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/github-New-OAuth-Application.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/github-create-oauth-app.png b/static/img/docs/blueprints/by-use-case/security/authentik/github-create-oauth-app.png new file mode 100644 index 000000000..831efbf76 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/github-create-oauth-app.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/github-idp-configuration.png b/static/img/docs/blueprints/by-use-case/security/authentik/github-idp-configuration.png new file mode 100644 index 000000000..6c1c75088 Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/github-idp-configuration.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/group-scope-mapping.png b/static/img/docs/blueprints/by-use-case/security/authentik/group-scope-mapping.png new file mode 100644 index 000000000..fcd554eba Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/group-scope-mapping.png differ diff --git a/static/img/docs/blueprints/by-use-case/security/authentik/modify-idp-iam.png b/static/img/docs/blueprints/by-use-case/security/authentik/modify-idp-iam.png new file mode 100644 index 000000000..d001c5a5e Binary files /dev/null and b/static/img/docs/blueprints/by-use-case/security/authentik/modify-idp-iam.png differ diff --git a/static/img/factory-inside.svg b/static/img/factory-inside.svg new file mode 100644 index 000000000..0e5699f94 --- /dev/null +++ b/static/img/factory-inside.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/homeoffice.svg b/static/img/homeoffice.svg new file mode 100644 index 000000000..32013c4ba --- /dev/null +++ b/static/img/homeoffice.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/services/AS.svg b/static/img/services/AS.svg new file mode 100644 index 000000000..0934d6368 --- /dev/null +++ b/static/img/services/AS.svg @@ -0,0 +1,24 @@ + + + + + + diff --git a/static/img/services/Anti-DDoS.svg b/static/img/services/Anti-DDoS.svg new file mode 100644 index 000000000..ed292d356 --- /dev/null +++ b/static/img/services/Anti-DDoS.svg @@ -0,0 +1,24 @@ + + + + + + diff --git a/static/img/services/BMS.svg b/static/img/services/BMS.svg new file mode 100644 index 000000000..bd105715c --- /dev/null +++ b/static/img/services/BMS.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + diff --git a/static/img/services/CBR.svg b/static/img/services/CBR.svg new file mode 100644 index 000000000..903f0a04f --- /dev/null +++ b/static/img/services/CBR.svg @@ -0,0 +1 @@ +画板 1 \ No newline at end of file diff --git a/static/img/services/CCE.svg b/static/img/services/CCE.svg new file mode 100644 index 000000000..6e821f427 --- /dev/null +++ b/static/img/services/CCE.svg @@ -0,0 +1,21 @@ + + + + + + + diff --git a/static/img/services/CES.svg b/static/img/services/CES.svg new file mode 100644 index 000000000..5369a3b03 --- /dev/null +++ b/static/img/services/CES.svg @@ -0,0 +1,22 @@ + + + + + + + + + + diff --git a/static/img/services/CSBS.svg b/static/img/services/CSBS.svg new file mode 100644 index 000000000..f9ee732ee --- /dev/null +++ b/static/img/services/CSBS.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + diff --git a/static/img/services/CSS.svg b/static/img/services/CSS.svg new file mode 100644 index 000000000..041cf82df --- /dev/null +++ b/static/img/services/CSS.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/static/img/services/CTS.svg b/static/img/services/CTS.svg new file mode 100644 index 000000000..deea0932f --- /dev/null +++ b/static/img/services/CTS.svg @@ -0,0 +1,26 @@ + + + + + + diff --git a/static/img/services/Computing.svg b/static/img/services/Computing.svg new file mode 100644 index 000000000..92345fe07 --- /dev/null +++ b/static/img/services/Computing.svg @@ -0,0 +1,11 @@ + + + + + diff --git a/static/img/services/DCS-memcached.svg b/static/img/services/DCS-memcached.svg new file mode 100644 index 000000000..bd7bde364 --- /dev/null +++ b/static/img/services/DCS-memcached.svg @@ -0,0 +1,20 @@ + + + + + diff --git a/static/img/services/DCS-redis.svg b/static/img/services/DCS-redis.svg new file mode 100644 index 000000000..32f1354d8 --- /dev/null +++ b/static/img/services/DCS-redis.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/static/img/services/DC_DirectConnect.svg b/static/img/services/DC_DirectConnect.svg new file mode 100644 index 000000000..d5172b705 --- /dev/null +++ b/static/img/services/DC_DirectConnect.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/static/img/services/DDS.svg b/static/img/services/DDS.svg new file mode 100644 index 000000000..0f7833c63 --- /dev/null +++ b/static/img/services/DDS.svg @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/static/img/services/DIS.svg b/static/img/services/DIS.svg new file mode 100644 index 000000000..9105d9b02 --- /dev/null +++ b/static/img/services/DIS.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + diff --git a/static/img/services/DMS.svg b/static/img/services/DMS.svg new file mode 100644 index 000000000..b99ff7709 --- /dev/null +++ b/static/img/services/DMS.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/static/img/services/DNS.svg b/static/img/services/DNS.svg new file mode 100644 index 000000000..777f57745 --- /dev/null +++ b/static/img/services/DNS.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + diff --git a/static/img/services/DWS.svg b/static/img/services/DWS.svg new file mode 100644 index 000000000..33b56a144 --- /dev/null +++ b/static/img/services/DWS.svg @@ -0,0 +1 @@ +数据仓库服务-DWS \ No newline at end of file diff --git a/static/img/services/DeH.svg b/static/img/services/DeH.svg new file mode 100644 index 000000000..84c861542 --- /dev/null +++ b/static/img/services/DeH.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + diff --git a/static/img/services/ECS.svg b/static/img/services/ECS.svg new file mode 100644 index 000000000..fc07b6481 --- /dev/null +++ b/static/img/services/ECS.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + diff --git a/static/img/services/ELB.svg b/static/img/services/ELB.svg new file mode 100644 index 000000000..e40b5e424 --- /dev/null +++ b/static/img/services/ELB.svg @@ -0,0 +1,22 @@ + + + + + + diff --git a/static/img/services/EVS.svg b/static/img/services/EVS.svg new file mode 100644 index 000000000..787ac4c0d --- /dev/null +++ b/static/img/services/EVS.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + diff --git a/static/img/services/IAM.svg b/static/img/services/IAM.svg new file mode 100644 index 000000000..e81823ecd --- /dev/null +++ b/static/img/services/IAM.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + diff --git a/static/img/services/IMS.svg b/static/img/services/IMS.svg new file mode 100644 index 000000000..87a257ea8 --- /dev/null +++ b/static/img/services/IMS.svg @@ -0,0 +1,21 @@ + + + + + + diff --git a/static/img/services/IP-EIP.svg b/static/img/services/IP-EIP.svg new file mode 100644 index 000000000..241fa035f --- /dev/null +++ b/static/img/services/IP-EIP.svg @@ -0,0 +1,14 @@ + + + + + + diff --git a/static/img/services/Kafka.svg b/static/img/services/Kafka.svg new file mode 100644 index 000000000..df1e567d3 --- /dev/null +++ b/static/img/services/Kafka.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/img/services/LTS.svg b/static/img/services/LTS.svg new file mode 100644 index 000000000..c6b384580 --- /dev/null +++ b/static/img/services/LTS.svg @@ -0,0 +1,11 @@ + + + + + diff --git a/static/img/services/Management&Deployment-RTS.svg b/static/img/services/Management&Deployment-RTS.svg new file mode 100644 index 000000000..120a0d9de --- /dev/null +++ b/static/img/services/Management&Deployment-RTS.svg @@ -0,0 +1,24 @@ + + + + + + diff --git a/static/img/services/OBS.svg b/static/img/services/OBS.svg new file mode 100644 index 000000000..944c57cc7 --- /dev/null +++ b/static/img/services/OBS.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/static/img/services/RDS .svg b/static/img/services/RDS .svg new file mode 100644 index 000000000..484051539 --- /dev/null +++ b/static/img/services/RDS .svg @@ -0,0 +1,21 @@ + + + + + + diff --git a/static/img/services/SFS.svg b/static/img/services/SFS.svg new file mode 100644 index 000000000..faf0a3234 --- /dev/null +++ b/static/img/services/SFS.svg @@ -0,0 +1,14 @@ + + + + + + diff --git a/static/img/services/SGW.svg b/static/img/services/SGW.svg new file mode 100644 index 000000000..cdd0d1345 --- /dev/null +++ b/static/img/services/SGW.svg @@ -0,0 +1,32 @@ + + + + + + diff --git a/static/img/services/SMN.svg b/static/img/services/SMN.svg new file mode 100644 index 000000000..a3537c302 --- /dev/null +++ b/static/img/services/SMN.svg @@ -0,0 +1,14 @@ + + + + + + diff --git a/static/img/services/Security-KMS.svg b/static/img/services/Security-KMS.svg new file mode 100644 index 000000000..95b44c831 --- /dev/null +++ b/static/img/services/Security-KMS.svg @@ -0,0 +1,23 @@ + + + + + + diff --git a/static/img/services/TMS.svg b/static/img/services/TMS.svg new file mode 100644 index 000000000..90154302e --- /dev/null +++ b/static/img/services/TMS.svg @@ -0,0 +1,23 @@ + + + + + + diff --git a/static/img/services/VBS.svg b/static/img/services/VBS.svg new file mode 100644 index 000000000..32d5cba4b --- /dev/null +++ b/static/img/services/VBS.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + diff --git a/static/img/services/VPC.svg b/static/img/services/VPC.svg new file mode 100644 index 000000000..221f38a96 --- /dev/null +++ b/static/img/services/VPC.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/static/img/services/VPN.svg b/static/img/services/VPN.svg new file mode 100644 index 000000000..0f19e58dd --- /dev/null +++ b/static/img/services/VPN.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/static/img/services/Vpc Endpoint.svg b/static/img/services/Vpc Endpoint.svg new file mode 100644 index 000000000..2f62a5acf --- /dev/null +++ b/static/img/services/Vpc Endpoint.svg @@ -0,0 +1,16 @@ + + + + +Vpc Endpoint +Created with Sketch. + + diff --git a/static/img/services/ai-Modelarts.svg b/static/img/services/ai-Modelarts.svg new file mode 100644 index 000000000..c7dafef06 --- /dev/null +++ b/static/img/services/ai-Modelarts.svg @@ -0,0 +1 @@ +AI资产 \ No newline at end of file diff --git a/static/img/services/aom.svg b/static/img/services/aom.svg new file mode 100644 index 000000000..2cd52014d --- /dev/null +++ b/static/img/services/aom.svg @@ -0,0 +1,18 @@ + + + + + diff --git a/static/img/services/apig.svg b/static/img/services/apig.svg new file mode 100644 index 000000000..abb686326 --- /dev/null +++ b/static/img/services/apig.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/static/img/services/apm.svg b/static/img/services/apm.svg new file mode 100644 index 000000000..76755ee7e --- /dev/null +++ b/static/img/services/apm.svg @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/static/img/services/asm.svg b/static/img/services/asm.svg new file mode 100644 index 000000000..b8a82617f --- /dev/null +++ b/static/img/services/asm.svg @@ -0,0 +1,46 @@ + + + + + diff --git a/static/img/services/cc.svg b/static/img/services/cc.svg new file mode 100644 index 000000000..897067734 --- /dev/null +++ b/static/img/services/cc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/services/cci.svg b/static/img/services/cci.svg new file mode 100644 index 000000000..e3c241fa5 --- /dev/null +++ b/static/img/services/cci.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/static/img/services/ces (1).svg b/static/img/services/ces (1).svg new file mode 100644 index 000000000..df1bcac8f --- /dev/null +++ b/static/img/services/ces (1).svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/services/dataarts_studio.svg b/static/img/services/dataarts_studio.svg new file mode 100644 index 000000000..b4d57eab6 --- /dev/null +++ b/static/img/services/dataarts_studio.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/static/img/services/dbss.svg b/static/img/services/dbss.svg new file mode 100644 index 000000000..c4a59fe9b --- /dev/null +++ b/static/img/services/dbss.svg @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/static/img/services/ddm.svg b/static/img/services/ddm.svg new file mode 100644 index 000000000..2a553bc55 --- /dev/null +++ b/static/img/services/ddm.svg @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/static/img/services/dli.svg b/static/img/services/dli.svg new file mode 100644 index 000000000..e4383d4dd --- /dev/null +++ b/static/img/services/dli.svg @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/static/img/services/drs.svg b/static/img/services/drs.svg new file mode 100644 index 000000000..9d7c21f47 --- /dev/null +++ b/static/img/services/drs.svg @@ -0,0 +1,9 @@ + + + + + diff --git a/static/img/services/er.svg b/static/img/services/er.svg new file mode 100644 index 000000000..f794ff32a --- /dev/null +++ b/static/img/services/er.svg @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/static/img/services/fg.svg b/static/img/services/fg.svg new file mode 100644 index 000000000..295028dd3 --- /dev/null +++ b/static/img/services/fg.svg @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/static/img/services/gaussdb_mysql.svg b/static/img/services/gaussdb_mysql.svg new file mode 100644 index 000000000..a457c25d4 --- /dev/null +++ b/static/img/services/gaussdb_mysql.svg @@ -0,0 +1 @@ +GaussDB nosql diff --git a/static/img/services/gaussdb_nosql.svg b/static/img/services/gaussdb_nosql.svg new file mode 100644 index 000000000..5459bae25 --- /dev/null +++ b/static/img/services/gaussdb_nosql.svg @@ -0,0 +1,91 @@ + + + + + + + GaussDB nosql + + + + + + + + + + + + + + + + GaussDB nosql + + + + diff --git a/static/img/services/hss.svg b/static/img/services/hss.svg new file mode 100644 index 000000000..e794aca8d --- /dev/null +++ b/static/img/services/hss.svg @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/static/img/services/ma.svg b/static/img/services/ma.svg new file mode 100644 index 000000000..b3d611531 --- /dev/null +++ b/static/img/services/ma.svg @@ -0,0 +1 @@ + diff --git a/static/img/services/mapReduce-MRS.svg b/static/img/services/mapReduce-MRS.svg new file mode 100644 index 000000000..669d6d8d2 --- /dev/null +++ b/static/img/services/mapReduce-MRS.svg @@ -0,0 +1,36 @@ + + + + + + + + + + diff --git a/static/img/services/mysql.svg b/static/img/services/mysql.svg new file mode 100644 index 000000000..07467cacd --- /dev/null +++ b/static/img/services/mysql.svg @@ -0,0 +1,30 @@ + + + + + + diff --git a/static/img/services/nat-nat-gateway.svg b/static/img/services/nat-nat-gateway.svg new file mode 100644 index 000000000..59523356f --- /dev/null +++ b/static/img/services/nat-nat-gateway.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + diff --git a/static/img/services/ocr.svg b/static/img/services/ocr.svg new file mode 100644 index 000000000..1df64a95a --- /dev/null +++ b/static/img/services/ocr.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/services/plas.svg b/static/img/services/plas.svg new file mode 100644 index 000000000..5272eb3b0 --- /dev/null +++ b/static/img/services/plas.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/static/img/services/rms.svg b/static/img/services/rms.svg new file mode 100644 index 000000000..45d4260d9 --- /dev/null +++ b/static/img/services/rms.svg @@ -0,0 +1 @@ + diff --git a/static/img/services/sdrs.svg b/static/img/services/sdrs.svg new file mode 100644 index 000000000..31dc47a82 --- /dev/null +++ b/static/img/services/sdrs.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/img/services/smg.svg b/static/img/services/smg.svg new file mode 100644 index 000000000..5c244d81b --- /dev/null +++ b/static/img/services/smg.svg @@ -0,0 +1,9 @@ + + + + + diff --git a/static/img/services/swr.svg b/static/img/services/swr.svg new file mode 100644 index 000000000..b932b0ca8 --- /dev/null +++ b/static/img/services/swr.svg @@ -0,0 +1,16 @@ + + + + + diff --git a/static/img/services/web-WAF.svg b/static/img/services/web-WAF.svg new file mode 100644 index 000000000..67a0077be --- /dev/null +++ b/static/img/services/web-WAF.svg @@ -0,0 +1,29 @@ + + + + + + diff --git a/static/img/workflow_permissions.png b/static/img/workflow_permissions.png new file mode 100644 index 000000000..318a273e6 Binary files /dev/null and b/static/img/workflow_permissions.png differ diff --git a/yarn.lock b/yarn.lock index 9abf82557..41ef557a8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -103,7 +103,7 @@ "@algolia/requester-common" "4.24.0" "@algolia/transporter" "4.24.0" -"@algolia/client-search@>= 4.9.1 < 6", "@algolia/client-search@4.24.0": +"@algolia/client-search@4.24.0": version "4.24.0" resolved "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz" integrity sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA== @@ -195,7 +195,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz" integrity sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.12.0", "@babel/core@^7.13.0", "@babel/core@^7.21.3", "@babel/core@^7.23.3", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0": +"@babel/core@^7.21.3", "@babel/core@^7.23.3": version "7.24.4" resolved "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz" integrity sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg== @@ -1189,7 +1189,7 @@ core-js-pure "^3.30.2" regenerator-runtime "^0.14.0" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2", "@babel/runtime@^7.22.6", "@babel/runtime@^7.23.2", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.22.6", "@babel/runtime@^7.8.4": version "7.24.4" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz" integrity sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA== @@ -1235,6 +1235,16 @@ resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== +"@dipakparmar/docusaurus-plugin-umami@^2.1.6": + version "2.1.6" + resolved "https://registry.npmjs.org/@dipakparmar/docusaurus-plugin-umami/-/docusaurus-plugin-umami-2.1.6.tgz" + integrity sha512-jgcDZg/+dOiAip7WTxEm/UyNEewnNLb0Nmdg0hYwwXBNjjdj8RKnMmIrHnO8IBYcsZkgCBcVLLl5VbJ2ns28jw== + dependencies: + "@docusaurus/core" "3.4.0" + "@docusaurus/types" "3.4.0" + "@docusaurus/utils-validation" "3.4.0" + tslib "^2.4.0" + "@discoveryjs/json-ext@0.5.7": version "0.5.7" resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz" @@ -1255,7 +1265,7 @@ "@docsearch/css" "3.6.0" algoliasearch "^4.19.1" -"@docusaurus/core@^3.4.0", "@docusaurus/core@3.4.0": +"@docusaurus/core@3.4.0", "@docusaurus/core@^3.4.0": version "3.4.0" resolved "https://registry.npmjs.org/@docusaurus/core/-/core-3.4.0.tgz" integrity sha512-g+0wwmN2UJsBqy2fQRQ6fhXruoEa62JDeEa5d8IdTJlMoaDaEDfHh7WjwGRn4opuTQWpjAwP/fbcgyHKlE+64w== @@ -1377,7 +1387,7 @@ vfile "^6.0.1" webpack "^5.88.1" -"@docusaurus/module-type-aliases@^3.4.0", "@docusaurus/module-type-aliases@3.4.0": +"@docusaurus/module-type-aliases@3.4.0", "@docusaurus/module-type-aliases@^3.4.0": version "3.4.0" resolved "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.4.0.tgz" integrity sha512-A1AyS8WF5Bkjnb8s+guTDuYmUiwJzNrtchebBHpc0gz0PyHJNMaybUlSrmJjHVcGrya0LKI4YcR3lBDQfXRYLw== @@ -1613,7 +1623,7 @@ resolved "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.4.0.tgz" integrity sha512-0qENiJ+TRaeTzcg4olrnh0BQ7eCxTgbYWBnWUeQDc84UYkt/T3pDNnm3SiQkqPb+YQ1qtYFlC0RriAElclo8Dg== -"@docusaurus/types@*", "@docusaurus/types@^3.4.0", "@docusaurus/types@3.4.0": +"@docusaurus/types@3.4.0", "@docusaurus/types@^3.4.0": version "3.4.0" resolved "https://registry.npmjs.org/@docusaurus/types/-/types-3.4.0.tgz" integrity sha512-4jcDO8kXi5Cf9TcyikB/yKmz14f2RZ2qTRerbHAsS+5InE9ZgSLBNLsewtFTcTOXSVcbU3FoGOzcNWAmU1TR0A== @@ -1682,6 +1692,64 @@ dependencies: "@stencil/core" "^2.3.0" +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.1" + resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz" + integrity sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA== + dependencies: + eslint-visitor-keys "^3.4.3" + +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.12.1": + version "4.12.1" + resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz" + integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== + +"@eslint/config-array@^0.18.0": + version "0.18.0" + resolved "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz" + integrity sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw== + dependencies: + "@eslint/object-schema" "^2.1.4" + debug "^4.3.1" + minimatch "^3.1.2" + +"@eslint/core@^0.7.0": + version "0.7.0" + resolved "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz" + integrity sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw== + +"@eslint/eslintrc@^3.1.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz" + integrity sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^10.0.1" + globals "^14.0.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" + +"@eslint/js@9.14.0": + version "9.14.0" + resolved "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz" + integrity sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg== + +"@eslint/object-schema@^2.1.4": + version "2.1.4" + resolved "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz" + integrity sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ== + +"@eslint/plugin-kit@^0.2.0": + version "0.2.2" + resolved "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz" + integrity sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw== + dependencies: + levn "^0.4.1" + "@floating-ui/core@^1.0.0": version "1.6.0" resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz" @@ -1714,6 +1782,34 @@ dependencies: "@hapi/hoek" "^9.0.0" +"@humanfs/core@^0.19.1": + version "0.19.1" + resolved "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz" + integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== + +"@humanfs/node@^0.16.6": + version "0.16.6" + resolved "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz" + integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== + dependencies: + "@humanfs/core" "^0.19.1" + "@humanwhocodes/retry" "^0.3.0" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/retry@^0.3.0": + version "0.3.1" + resolved "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz" + integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== + +"@humanwhocodes/retry@^0.4.0": + version "0.4.1" + resolved "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz" + integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA== + "@jest/schemas@^29.6.3": version "29.6.3" resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz" @@ -1822,7 +1918,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -1961,7 +2057,7 @@ "@svgr/babel-plugin-transform-react-native-svg" "8.1.0" "@svgr/babel-plugin-transform-svg-component" "8.0.0" -"@svgr/core@*", "@svgr/core@8.1.0": +"@svgr/core@8.1.0": version "8.1.0" resolved "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz" integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA== @@ -2110,10 +2206,10 @@ dependencies: "@types/estree" "*" -"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.5": - version "1.0.5" - resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz" - integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== +"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.5", "@types/estree@^1.0.6": + version "1.0.6" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": version "4.19.0" @@ -2193,7 +2289,7 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -2290,7 +2386,7 @@ "@types/history" "^4.7.11" "@types/react" "*" -"@types/react@*", "@types/react@>= 16.8.0 < 19.0.0", "@types/react@>=16": +"@types/react@*": version "18.2.79" resolved "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz" integrity sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w== @@ -2370,12 +2466,93 @@ dependencies: "@types/yargs-parser" "*" +"@typescript-eslint/eslint-plugin@8.13.0", "@typescript-eslint/eslint-plugin@^8.13.0": + version "8.13.0" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.13.0.tgz" + integrity sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg== + dependencies: + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "8.13.0" + "@typescript-eslint/type-utils" "8.13.0" + "@typescript-eslint/utils" "8.13.0" + "@typescript-eslint/visitor-keys" "8.13.0" + graphemer "^1.4.0" + ignore "^5.3.1" + natural-compare "^1.4.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/parser@8.13.0", "@typescript-eslint/parser@^8.13.0": + version "8.13.0" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.13.0.tgz" + integrity sha512-w0xp+xGg8u/nONcGw1UXAr6cjCPU1w0XVyBs6Zqaj5eLmxkKQAByTdV/uGgNN5tVvN/kKpoQlP2cL7R+ajZZIQ== + dependencies: + "@typescript-eslint/scope-manager" "8.13.0" + "@typescript-eslint/types" "8.13.0" + "@typescript-eslint/typescript-estree" "8.13.0" + "@typescript-eslint/visitor-keys" "8.13.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@8.13.0": + version "8.13.0" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.13.0.tgz" + integrity sha512-XsGWww0odcUT0gJoBZ1DeulY1+jkaHUciUq4jKNv4cpInbvvrtDoyBH9rE/n2V29wQJPk8iCH1wipra9BhmiMA== + dependencies: + "@typescript-eslint/types" "8.13.0" + "@typescript-eslint/visitor-keys" "8.13.0" + +"@typescript-eslint/type-utils@8.13.0": + version "8.13.0" + resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.13.0.tgz" + integrity sha512-Rqnn6xXTR316fP4D2pohZenJnp+NwQ1mo7/JM+J1LWZENSLkJI8ID8QNtlvFeb0HnFSK94D6q0cnMX6SbE5/vA== + dependencies: + "@typescript-eslint/typescript-estree" "8.13.0" + "@typescript-eslint/utils" "8.13.0" + debug "^4.3.4" + ts-api-utils "^1.3.0" + +"@typescript-eslint/types@8.13.0": + version "8.13.0" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.13.0.tgz" + integrity sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng== + +"@typescript-eslint/typescript-estree@8.13.0": + version "8.13.0" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.13.0.tgz" + integrity sha512-v7SCIGmVsRK2Cy/LTLGN22uea6SaUIlpBcO/gnMGT/7zPtxp90bphcGf4fyrCQl3ZtiBKqVTG32hb668oIYy1g== + dependencies: + "@typescript-eslint/types" "8.13.0" + "@typescript-eslint/visitor-keys" "8.13.0" + debug "^4.3.4" + fast-glob "^3.3.2" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/utils@8.13.0": + version "8.13.0" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.13.0.tgz" + integrity sha512-A1EeYOND6Uv250nybnLZapeXpYMl8tkzYUxqmoKAWnI4sei3ihf2XdZVd+vVOmHGcp3t+P7yRrNsyyiXTvShFQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "8.13.0" + "@typescript-eslint/types" "8.13.0" + "@typescript-eslint/typescript-estree" "8.13.0" + +"@typescript-eslint/visitor-keys@8.13.0": + version "8.13.0" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.13.0.tgz" + integrity sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw== + dependencies: + "@typescript-eslint/types" "8.13.0" + eslint-visitor-keys "^3.4.3" + "@ungap/structured-clone@^1.0.0": version "1.2.0" resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -"@webassemblyjs/ast@^1.12.1", "@webassemblyjs/ast@1.12.1": +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": version "1.12.1" resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz" integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== @@ -2476,7 +2653,7 @@ "@webassemblyjs/wasm-gen" "1.12.1" "@webassemblyjs/wasm-parser" "1.12.1" -"@webassemblyjs/wasm-parser@^1.12.1", "@webassemblyjs/wasm-parser@1.12.1": +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": version "1.12.1" resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz" integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== @@ -2519,7 +2696,7 @@ acorn-import-assertions@^1.9.0: resolved "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz" integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== -acorn-jsx@^5.0.0: +acorn-jsx@^5.0.0, acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== @@ -2529,10 +2706,10 @@ acorn-walk@^8.0.0: resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz" integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8, acorn@^8.0.0, acorn@^8.0.4, acorn@^8.7.1, acorn@^8.8.2: - version "8.11.3" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" - integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== +acorn@^8.0.0, acorn@^8.0.4, acorn@^8.14.0, acorn@^8.7.1, acorn@^8.8.2: + version "8.14.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== address@^1.0.1, address@^1.1.2: version "1.2.2" @@ -2554,12 +2731,7 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv-keywords@^3.4.1: - version "3.5.2" - resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv-keywords@^3.5.2: +ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== @@ -2571,7 +2743,7 @@ ajv-keywords@^5.1.0: dependencies: fast-deep-equal "^3.1.3" -ajv@^6.12.2, ajv@^6.12.5, ajv@^6.9.1: +ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -2581,7 +2753,7 @@ ajv@^6.12.2, ajv@^6.12.5, ajv@^6.9.1: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.8.2, ajv@^8.9.0: +ajv@^8.0.0, ajv@^8.9.0: version "8.12.0" resolved "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz" integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== @@ -2598,7 +2770,7 @@ algoliasearch-helper@^3.10.0, algoliasearch-helper@^3.13.3: dependencies: "@algolia/events" "^4.0.1" -algoliasearch@^4.18.0, algoliasearch@^4.19.1, "algoliasearch@>= 3.1 < 6", "algoliasearch@>= 4.9.1 < 6": +algoliasearch@^4.18.0, algoliasearch@^4.19.1: version "4.24.0" resolved "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz" integrity sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g== @@ -2685,16 +2857,93 @@ argparse@^2.0.1: resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +array-buffer-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz" + integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg== + dependencies: + call-bind "^1.0.5" + is-array-buffer "^3.0.4" + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== +array-includes@^3.1.6, array-includes@^3.1.8: + version "3.1.8" + resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz" + integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.4" + is-string "^1.0.7" + array-union@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +array.prototype.findlast@^1.2.5: + version "1.2.5" + resolved "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz" + integrity sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-shim-unscopables "^1.0.2" + +array.prototype.flat@^1.3.1: + version "1.3.2" + resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz" + integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.flatmap@^1.3.2: + version "1.3.2" + resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz" + integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.tosorted@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz" + integrity sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.3" + es-errors "^1.3.0" + es-shim-unscopables "^1.0.2" + +arraybuffer.prototype.slice@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz" + integrity sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A== + dependencies: + array-buffer-byte-length "^1.0.1" + call-bind "^1.0.5" + define-properties "^1.2.1" + es-abstract "^1.22.3" + es-errors "^1.2.1" + get-intrinsic "^1.2.3" + is-array-buffer "^3.0.4" + is-shared-array-buffer "^1.0.2" + astring@^1.8.0: version "1.8.6" resolved "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz" @@ -2722,6 +2971,13 @@ autoprefixer@^10.4.14, autoprefixer@^10.4.19: picocolors "^1.0.0" postcss-value-parser "^4.2.0" +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" + axios@^1.6.0: version "1.7.2" resolved "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz" @@ -2862,6 +3118,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" @@ -2869,7 +3132,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^4.22.2, browserslist@^4.23.0, "browserslist@>= 4.21.0": +browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^4.22.2, browserslist@^4.23.0: version "4.23.0" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz" integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== @@ -2912,7 +3175,7 @@ cacheable-request@^10.2.8: normalize-url "^8.0.0" responselike "^3.0.0" -call-bind@^1.0.5, call-bind@^1.0.7: +call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: version "1.0.7" resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz" integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== @@ -3132,16 +3395,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + colord@^2.9.3: version "2.9.3" resolved "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz" @@ -3350,7 +3613,7 @@ cosmiconfig@^8.1.3, cosmiconfig@^8.3.5: parse-json "^5.2.0" path-type "^4.0.0" -cross-spawn@^7.0.3: +cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -3519,32 +3782,52 @@ csstype@^3.0.2: resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== +data-view-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz" + integrity sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz" + integrity sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz" + integrity sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + debounce@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debug@^2.6.0: +debug@2.6.9, debug@^2.6.0: 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" -debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@4: +debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@2.6.9: - 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" - decode-named-character-reference@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz" @@ -3564,6 +3847,11 @@ deep-extend@^0.6.0: resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== +deep-is@^0.1.3: + 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== + deepmerge@^4.2.2, deepmerge@^4.3.1: version "4.3.1" resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" @@ -3595,7 +3883,7 @@ define-lazy-prop@^2.0.0: resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.2.1: +define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -3623,16 +3911,16 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - depd@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + dequal@^2.0.0: version "2.0.3" resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" @@ -3685,6 +3973,13 @@ dns-packet@^5.2.2: dependencies: "@leichtgewicht/ip-codec" "^2.0.1" +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + docusaurus-theme-search-typesense@^0.20.0: version "0.20.0" resolved "https://registry.npmjs.org/docusaurus-theme-search-typesense/-/docusaurus-theme-search-typesense-0.20.0.tgz" @@ -3857,6 +4152,58 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es-abstract@^1.17.5, es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.1, es-abstract@^1.23.2, es-abstract@^1.23.3: + version "1.23.3" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz" + integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== + dependencies: + array-buffer-byte-length "^1.0.1" + arraybuffer.prototype.slice "^1.0.3" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + data-view-buffer "^1.0.1" + data-view-byte-length "^1.0.1" + data-view-byte-offset "^1.0.0" + es-define-property "^1.0.0" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-set-tostringtag "^2.0.3" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.4" + get-symbol-description "^1.0.2" + globalthis "^1.0.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + has-proto "^1.0.3" + has-symbols "^1.0.3" + hasown "^2.0.2" + internal-slot "^1.0.7" + is-array-buffer "^3.0.4" + is-callable "^1.2.7" + is-data-view "^1.0.1" + is-negative-zero "^2.0.3" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.3" + is-string "^1.0.7" + is-typed-array "^1.1.13" + is-weakref "^1.0.2" + object-inspect "^1.13.1" + object-keys "^1.1.1" + object.assign "^4.1.5" + regexp.prototype.flags "^1.5.2" + safe-array-concat "^1.1.2" + safe-regex-test "^1.0.3" + string.prototype.trim "^1.2.9" + string.prototype.trimend "^1.0.8" + string.prototype.trimstart "^1.0.8" + typed-array-buffer "^1.0.2" + typed-array-byte-length "^1.0.1" + typed-array-byte-offset "^1.0.2" + typed-array-length "^1.0.6" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.15" + es-define-property@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz" @@ -3864,16 +4211,69 @@ es-define-property@^1.0.0: dependencies: get-intrinsic "^1.2.4" -es-errors@^1.3.0: +es-errors@^1.2.1, es-errors@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== +es-iterator-helpers@^1.1.0: + version "1.2.0" + resolved "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.0.tgz" + integrity sha512-tpxqxncxnpw3c93u8n3VOzACmRFoVmWJqbWXvX/JfKbkhBw1oslgPrUfeSt2psuqyEJFD6N/9lg5i7bsKpoq+Q== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.3" + es-errors "^1.3.0" + es-set-tostringtag "^2.0.3" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + globalthis "^1.0.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + has-proto "^1.0.3" + has-symbols "^1.0.3" + internal-slot "^1.0.7" + iterator.prototype "^1.1.3" + safe-array-concat "^1.1.2" + es-module-lexer@^1.2.1: version "1.5.0" resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.0.tgz" integrity sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw== +es-object-atoms@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz" + integrity sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw== + dependencies: + es-errors "^1.3.0" + +es-set-tostringtag@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz" + integrity sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ== + dependencies: + get-intrinsic "^1.2.4" + has-tostringtag "^1.0.2" + hasown "^2.0.1" + +es-shim-unscopables@^1.0.0, es-shim-unscopables@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== + dependencies: + hasown "^2.0.0" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + escalade@^3.1.1: version "3.1.2" resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz" @@ -3904,6 +4304,30 @@ escape-string-regexp@^5.0.0: resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz" integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== +eslint-plugin-react@^7.37.2: + version "7.37.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz#cd0935987876ba2900df2f58339f6d92305acc7a" + integrity sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w== + dependencies: + array-includes "^3.1.8" + array.prototype.findlast "^1.2.5" + array.prototype.flatmap "^1.3.2" + array.prototype.tosorted "^1.1.4" + doctrine "^2.1.0" + es-iterator-helpers "^1.1.0" + estraverse "^5.3.0" + hasown "^2.0.2" + jsx-ast-utils "^2.4.1 || ^3.0.0" + minimatch "^3.1.2" + object.entries "^1.1.8" + object.fromentries "^2.0.8" + object.values "^1.2.0" + prop-types "^15.8.1" + resolve "^2.0.0-next.5" + semver "^6.3.1" + string.prototype.matchall "^4.0.11" + string.prototype.repeat "^1.0.0" + eslint-scope@5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" @@ -3912,11 +4336,86 @@ eslint-scope@5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" +eslint-scope@^8.2.0: + version "8.2.0" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz" + integrity sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.4.3: + 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== + +eslint-visitor-keys@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz" + integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== + +eslint@^9.14.0: + version "9.14.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.14.0.tgz#534180a97c00af08bcf2b60b0ebf0c4d6c1b2c95" + integrity sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.12.1" + "@eslint/config-array" "^0.18.0" + "@eslint/core" "^0.7.0" + "@eslint/eslintrc" "^3.1.0" + "@eslint/js" "9.14.0" + "@eslint/plugin-kit" "^0.2.0" + "@humanfs/node" "^0.16.6" + "@humanwhocodes/module-importer" "^1.0.1" + "@humanwhocodes/retry" "^0.4.0" + "@types/estree" "^1.0.6" + "@types/json-schema" "^7.0.15" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + escape-string-regexp "^4.0.0" + eslint-scope "^8.2.0" + eslint-visitor-keys "^4.2.0" + espree "^10.3.0" + esquery "^1.5.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^8.0.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + json-stable-stringify-without-jsonify "^1.0.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + text-table "^0.2.0" + +espree@^10.0.1, espree@^10.3.0: + version "10.3.0" + resolved "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz" + integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== + dependencies: + acorn "^8.14.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^4.2.0" + esprima@^4.0.0: version "4.0.1" resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +esquery@^1.5.0: + version "1.6.0" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== + dependencies: + estraverse "^5.1.0" + esrecurse@^4.3.0: version "4.3.0" resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" @@ -3929,7 +4428,7 @@ estraverse@^4.1.1: resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -estraverse@^5.2.0: +estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: version "5.3.0" resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== @@ -4089,7 +4588,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.11, fast-glob@^3.2.9, fast-glob@^3.3.0: +fast-glob@^3.2.11, fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.2: version "3.3.2" resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -4105,6 +4604,11 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + fast-url-parser@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz" @@ -4140,7 +4644,14 @@ feed@^4.2.2: dependencies: xml-js "^1.6.11" -file-loader@*, file-loader@^6.2.0: +file-entry-cache@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz" + integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== + dependencies: + flat-cache "^4.0.0" + +file-loader@^6.2.0: version "6.2.0" resolved "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz" integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== @@ -4204,16 +4715,36 @@ find-up@^6.3.0: locate-path "^7.1.0" path-exists "^5.0.0" +flat-cache@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz" + integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.4" + flat@^5.0.2: version "5.0.2" resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== +flatted@^3.2.9: + version "3.3.1" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz" + integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== + follow-redirects@^1.0.0, follow-redirects@^1.15.6: version "1.15.6" resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz" integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + fork-ts-checker-webpack-plugin@^6.5.0: version "6.5.3" resolved "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz" @@ -4305,17 +4836,37 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== +function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" + +functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + gensync@^1.0.0-beta.2: 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== -get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: version "1.2.4" resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz" integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== @@ -4336,6 +4887,15 @@ get-stream@^6.0.0, get-stream@^6.0.1: resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-symbol-description@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz" + integrity sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg== + dependencies: + call-bind "^1.0.5" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + github-slugger@^1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz" @@ -4348,7 +4908,7 @@ glob-parent@^5.1.2, glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob-parent@^6.0.1: +glob-parent@^6.0.1, glob-parent@^6.0.2: version "6.0.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== @@ -4400,6 +4960,24 @@ globals@^11.1.0: resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globals@^14.0.0: + version "14.0.0" + resolved "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz" + integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== + +globals@^15.12.0: + version "15.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-15.12.0.tgz#1811872883ad8f41055b61457a130221297de5b5" + integrity sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ== + +globalthis@^1.0.3, globalthis@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz" + integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== + dependencies: + define-properties "^1.2.1" + gopd "^1.0.1" + globby@^11.0.1, globby@^11.0.4, globby@^11.1.0: version "11.1.0" resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" @@ -4447,15 +5025,20 @@ got@^12.1.0: p-cancelable "^3.0.0" responselike "^3.0.0" +graceful-fs@4.2.10: + version "4.2.10" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: 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== -graceful-fs@4.2.10: - version "4.2.10" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== gray-matter@^4.0.3: version "4.0.3" @@ -4479,6 +5062,11 @@ handle-thing@^2.0.0: resolved "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz" integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" @@ -4496,22 +5084,29 @@ has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: dependencies: es-define-property "^1.0.0" -has-proto@^1.0.1: +has-proto@^1.0.1, has-proto@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz" integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== -has-symbols@^1.0.3: +has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + has-yarn@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz" integrity sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA== -hasown@^2.0.0: +hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== @@ -4753,16 +5348,6 @@ http-deceiver@^1.2.7: resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" - integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - http-errors@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" @@ -4774,14 +5359,24 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -http-parser-js@>=0.5.1: - version "0.5.8" - resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz" - integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== - -http-proxy-middleware@^2.0.3: - version "2.0.6" - resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz" +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz" integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== dependencies: "@types/http-proxy" "^1.17.8" @@ -4824,7 +5419,7 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ignore@^5.2.0, ignore@^5.2.4: +ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.1: version "5.3.1" resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz" integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== @@ -4841,7 +5436,7 @@ immer@^9.0.7: resolved "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz" integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== -import-fresh@^3.1.0, import-fresh@^3.3.0: +import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -4877,7 +5472,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@2, inherits@2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -4887,16 +5482,16 @@ inherits@2.0.3: resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== -ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: - version "1.3.8" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - ini@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== +ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: + version "1.3.8" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + inline-style-parser@0.1.1: version "0.1.1" resolved "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz" @@ -4907,6 +5502,15 @@ inline-style-parser@0.2.3: resolved "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.3.tgz" integrity sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g== +internal-slot@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz" + integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== + dependencies: + es-errors "^1.3.0" + hasown "^2.0.0" + side-channel "^1.0.4" + interpret@^1.0.0: version "1.4.0" resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz" @@ -4919,16 +5523,16 @@ invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -ipaddr.js@^2.0.1: - version "2.2.0" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz" - integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== - ipaddr.js@1.9.1: 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== +ipaddr.js@^2.0.1: + version "2.2.0" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz" + integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== + is-alphabetical@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz" @@ -4942,11 +5546,33 @@ is-alphanumerical@^2.0.0: is-alphabetical "^2.0.0" is-decimal "^2.0.0" +is-array-buffer@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz" + integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== +is-async-function@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz" + integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== + dependencies: + has-tostringtag "^1.0.0" + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" @@ -4954,6 +5580,19 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + is-ci@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz" @@ -4968,6 +5607,20 @@ is-core-module@^2.13.0: dependencies: hasown "^2.0.0" +is-data-view@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz" + integrity sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w== + dependencies: + is-typed-array "^1.1.13" + +is-date-object@^1.0.1, is-date-object@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + is-decimal@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz" @@ -4988,12 +5641,26 @@ is-extglob@^2.1.1: resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== +is-finalizationregistry@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz" + integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== + dependencies: + call-bind "^1.0.2" + is-fullwidth-code-point@^3.0.0: 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== -is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: +is-generator-function@^1.0.10: + version "1.0.10" + resolved "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -5013,11 +5680,28 @@ is-installed-globally@^0.4.0: global-dirs "^3.0.0" is-path-inside "^3.0.2" +is-map@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz" + integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== + +is-negative-zero@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz" + integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== + is-npm@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz" integrity sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ== +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + is-number@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" @@ -5067,6 +5751,14 @@ is-reference@^3.0.0: dependencies: "@types/estree" "*" +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz" @@ -5077,16 +5769,69 @@ is-root@^2.1.0: resolved "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz" integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== +is-set@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz" + integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== + +is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz" + integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== + dependencies: + call-bind "^1.0.7" + is-stream@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.13: + version "1.1.13" + resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz" + integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== + dependencies: + which-typed-array "^1.1.14" + is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== +is-weakmap@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz" + integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +is-weakset@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz" + integrity sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ== + dependencies: + call-bind "^1.0.7" + get-intrinsic "^1.2.4" + is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" @@ -5099,16 +5844,21 @@ is-yarn-global@^0.4.0: resolved "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz" integrity sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ== -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - isarray@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" @@ -5119,6 +5869,17 @@ isobject@^3.0.1: resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== +iterator.prototype@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz" + integrity sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ== + dependencies: + define-properties "^1.2.1" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + reflect.getprototypeof "^1.0.4" + set-function-name "^2.0.1" + jest-util@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz" @@ -5216,6 +5977,11 @@ json-schema-traverse@^1.0.0: resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== +json-stable-stringify-without-jsonify@^1.0.1: + 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== + json5@^2.1.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" @@ -5230,7 +5996,17 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -keyv@^4.5.3: +"jsx-ast-utils@^2.4.1 || ^3.0.0": + version "3.3.5" + resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz" + integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== + dependencies: + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + object.assign "^4.1.4" + object.values "^1.1.6" + +keyv@^4.5.3, keyv@^4.5.4: version "4.5.4" resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz" integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== @@ -5267,6 +6043,14 @@ leven@^3.1.0: resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + lilconfig@^3.1.1: version "3.1.2" resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz" @@ -5328,6 +6112,11 @@ lodash.memoize@^4.1.2: resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz" @@ -6074,7 +6863,7 @@ micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: braces "^3.0.2" picomatch "^2.3.1" -"mime-db@>= 1.43.0 < 2": +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== @@ -6084,40 +6873,14 @@ mime-db@~1.33.0: resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz" integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@2.1.18: +mime-types@2.1.18, mime-types@^2.1.12, mime-types@~2.1.17: version "2.1.18" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz" integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== dependencies: mime-db "~1.33.0" -mime-types@^2.1.27: - 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" - -mime-types@^2.1.31: - 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" - -mime-types@~2.1.24: - 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" - -mime-types@~2.1.34: +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -6157,13 +6920,20 @@ minimalistic-assert@^1.0.0: resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@3.1.2: +minimatch@3.1.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0: version "1.2.8" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" @@ -6202,6 +6972,11 @@ nanoid@^3.3.7: resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + negotiator@0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" @@ -6289,7 +7064,7 @@ object-keys@^1.1.1: resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.0: +object.assign@^4.1.0, object.assign@^4.1.4, object.assign@^4.1.5: version "4.1.5" resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz" integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== @@ -6299,6 +7074,34 @@ object.assign@^4.1.0: has-symbols "^1.0.3" object-keys "^1.1.1" +object.entries@^1.1.8: + version "1.1.8" + resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz" + integrity sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + +object.fromentries@^2.0.8: + version "2.0.8" + resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz" + integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + +object.values@^1.1.6, object.values@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz" + integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" @@ -6344,6 +7147,18 @@ opener@^1.5.2: resolved "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz" integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== +optionator@^0.9.3: + version "0.9.4" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.5" + p-cancelable@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz" @@ -6528,13 +7343,6 @@ path-parse@^1.0.7: resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" @@ -6545,6 +7353,13 @@ path-to-regexp@2.2.1: resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz" integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ== +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" @@ -6583,6 +7398,11 @@ pkg-up@^3.1.0: dependencies: find-up "^3.0.0" +possible-typed-array-names@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz" + integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== + postcss-calc@^9.0.1: version "9.0.1" resolved "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz" @@ -6863,7 +7683,7 @@ postcss-zindex@^6.0.2: resolved "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz" integrity sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg== -"postcss@^7.0.0 || ^8.0.1", postcss@^8.0.9, postcss@^8.1.0, postcss@^8.2.2, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.24, postcss@^8.4.26, postcss@^8.4.31, postcss@^8.4.33, postcss@^8.4.38: +postcss@^8.4.21, postcss@^8.4.24, postcss@^8.4.26, postcss@^8.4.33, postcss@^8.4.38: version "8.4.38" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz" integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== @@ -6872,6 +7692,11 @@ postcss-zindex@^6.0.2: picocolors "^1.0.0" source-map-js "^1.2.0" +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + pretty-error@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz" @@ -6911,7 +7736,7 @@ prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -6991,21 +7816,16 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -range-parser@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - range-parser@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz" integrity sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A== +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + raw-body@2.5.2: version "2.5.2" resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz" @@ -7056,7 +7876,7 @@ react-dev-utils@^12.0.1: strip-ansi "^6.0.1" text-table "^0.2.0" -react-dom@*, "react-dom@^16.6.0 || ^17.0.0 || ^18.0.0", react-dom@^18.0.0, react-dom@^18.3.1, "react-dom@>= 16.8.0 < 19.0.0": +react-dom@^18.3.1: version "18.3.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== @@ -7102,7 +7922,7 @@ react-loadable-ssr-addon-v5-slorber@^1.0.1: dependencies: "@babel/runtime" "^7.10.3" -react-loadable@*, "react-loadable@npm:@docusaurus/react-loadable@6.0.0": +"react-loadable@npm:@docusaurus/react-loadable@6.0.0": version "6.0.0" resolved "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz" integrity sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ== @@ -7129,7 +7949,7 @@ react-router-dom@^5.3.4: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-router@^5.3.4, react-router@>=5, react-router@5.3.4: +react-router@5.3.4, react-router@^5.3.4: version "5.3.4" resolved "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz" integrity sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA== @@ -7144,7 +7964,7 @@ react-router@^5.3.4, react-router@>=5, react-router@5.3.4: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react@*, "react@^16.13.1 || ^17.0.0 || ^18.0.0", "react@^16.6.0 || ^17.0.0 || ^18.0.0", react@^18.0.0, react@^18.3.1, "react@>= 16.8.0 < 19.0.0", react@>=15, react@>=16, react@>=16.0.0: +react@^18.3.1: version "18.3.1" resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== @@ -7199,6 +8019,19 @@ recursive-readdir@^2.2.2: dependencies: minimatch "^3.0.5" +reflect.getprototypeof@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz" + integrity sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.1" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + globalthis "^1.0.3" + which-builtin-type "^1.1.3" + regenerate-unicode-properties@^10.1.0: version "10.1.1" resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz" @@ -7223,6 +8056,16 @@ regenerator-transform@^0.15.2: dependencies: "@babel/runtime" "^7.8.4" +regexp.prototype.flags@^1.5.2: + version "1.5.3" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz" + integrity sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-errors "^1.3.0" + set-function-name "^2.0.2" + regexpu-core@^5.3.1: version "5.3.2" resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz" @@ -7401,6 +8244,15 @@ resolve@^1.1.6, resolve@^1.14.2: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^2.0.0-next.5: + version "2.0.0-next.5" + resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz" + integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + responselike@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz" @@ -7447,20 +8299,34 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -safe-buffer@^5.1.0, safe-buffer@>=5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-array-concat@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz" + integrity sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q== + dependencies: + call-bind "^1.0.7" + get-intrinsic "^1.2.4" + has-symbols "^1.0.3" + isarray "^2.0.5" -safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex-test@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz" + integrity sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-regex "^1.1.4" "safer-buffer@>= 2.1.2 < 3": version "2.1.2" @@ -7479,25 +8345,16 @@ scheduler@^0.23.2: dependencies: loose-envify "^1.1.0" -schema-utils@^3.0.0: - version "3.3.0" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" - integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^3.1.1: - version "3.3.0" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" - integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== +schema-utils@2.7.0: + version "2.7.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" -schema-utils@^3.2.0: +schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: version "3.3.0" resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== @@ -7516,20 +8373,6 @@ schema-utils@^4.0.0, schema-utils@^4.0.1: ajv-formats "^2.1.1" ajv-keywords "^5.1.0" -schema-utils@2.7.0: - version "2.7.0" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== - dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" - -"search-insights@>= 1 < 3": - version "2.14.0" - resolved "https://registry.npmjs.org/search-insights/-/search-insights-2.14.0.tgz" - integrity sha512-OLN6MsPMCghDOqlCtsIsYgtsC0pnwVTyT9Mu6A3ewOj1DxvzZF6COrn2g86E/c05xbktB0XN04m/t1Z+n+fTGw== - section-matter@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz" @@ -7563,7 +8406,7 @@ semver@^6.3.1: resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.5.4: +semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.5.4, semver@^7.6.0: version "7.6.0" resolved "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz" integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== @@ -7645,6 +8488,16 @@ set-function-length@^1.2.1: gopd "^1.0.1" has-property-descriptors "^1.0.2" +set-function-name@^2.0.1, set-function-name@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz" + integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.2" + setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" @@ -7693,7 +8546,7 @@ shelljs@^0.8.5: interpret "^1.0.0" rechoir "^0.6.2" -side-channel@^1.0.4: +side-channel@^1.0.4, side-channel@^1.0.6: version "1.0.6" resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz" integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== @@ -7784,7 +8637,7 @@ source-map-support@~0.5.20: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.6.0: +source-map@^0.6.0, source-map@~0.6.0: version "0.6.1" resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== @@ -7794,11 +8647,6 @@ source-map@^0.7.0: resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== -source-map@~0.6.0: - version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - space-separated-tokens@^2.0.0: version "2.0.2" resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz" @@ -7837,16 +8685,16 @@ srcset@^4.0.0: resolved "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz" integrity sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw== -"statuses@>= 1.4.0 < 2": - version "1.5.0" - resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - statuses@2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + std-env@^3.0.1: version "3.7.0" resolved "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz" @@ -7857,30 +8705,7 @@ stencil-inline-svg@^1.0.1: resolved "https://registry.npmjs.org/stencil-inline-svg/-/stencil-inline-svg-1.1.0.tgz" integrity sha512-couT89xzsoycwHOIAgnl3WBpXaVRQ3ZlUBINo7HsT/AtWaFW9cxGlAzsK2JzkzxK7yUuoeIpdH2fNlvuH06DRg== -string_decoder@^1.1.1: - 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== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -string-width@^4.1.0: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.2.0: +string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -7898,6 +8723,74 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" +string.prototype.matchall@^4.0.11: + version "4.0.11" + resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz" + integrity sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-symbols "^1.0.3" + internal-slot "^1.0.7" + regexp.prototype.flags "^1.5.2" + set-function-name "^2.0.2" + side-channel "^1.0.6" + +string.prototype.repeat@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz" + integrity sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string.prototype.trim@^1.2.9: + version "1.2.9" + resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz" + integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.0" + es-object-atoms "^1.0.0" + +string.prototype.trimend@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz" + integrity sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + +string.prototype.trimstart@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz" + integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + +string_decoder@^1.1.1: + 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== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + stringify-entities@^4.0.0: version "4.0.4" resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz" @@ -8098,11 +8991,23 @@ trough@^2.0.0: resolved "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz" integrity sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw== +ts-api-utils@^1.3.0: + version "1.4.0" + resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz" + integrity sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ== + tslib@^2.0.3, tslib@^2.4.0, tslib@^2.6.0: version "2.6.2" resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + type-fest@^1.0.1: version "1.4.0" resolved "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz" @@ -8121,6 +9026,50 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typed-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz" + integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-typed-array "^1.1.13" + +typed-array-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz" + integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw== + dependencies: + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + +typed-array-byte-offset@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz" + integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + +typed-array-length@^1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz" + integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g== + dependencies: + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + possible-typed-array-names "^1.0.0" + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz" @@ -8128,7 +9077,16 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -"typescript@>= 2.7", typescript@>=4.9.5, typescript@~5.5.2: +typescript-eslint@^8.13.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.13.0.tgz#c7d92cc06188176c7d0e3825e10305b9c22fb102" + integrity sha512-vIMpDRJrQd70au2G8w34mPps0ezFSPMEX4pXkTzUkrNbRX+36ais2ksGWN0esZL+ZMaFJEneOBHzCgSqle7DHw== + dependencies: + "@typescript-eslint/eslint-plugin" "8.13.0" + "@typescript-eslint/parser" "8.13.0" + "@typescript-eslint/utils" "8.13.0" + +typescript@~5.5.2: version "5.5.2" resolved "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz" integrity sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew== @@ -8164,6 +9122,16 @@ typesense@^1.7.2: axios "^1.6.0" loglevel "^1.8.1" +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + undici-types@~5.26.4: version "5.26.5" resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" @@ -8275,7 +9243,7 @@ universalify@^2.0.0: resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz" integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== -unpipe@~1.0.0, unpipe@1.0.0: +unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -8483,7 +9451,7 @@ webpack-sources@^3.2.3: resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -"webpack@^4.0.0 || ^5.0.0", "webpack@^4.37.0 || ^5.0.0", webpack@^5.0.0, webpack@^5.1.0, webpack@^5.20.0, webpack@^5.88.1, "webpack@>= 4", "webpack@>=4.41.1 || 5.x", webpack@>=5, "webpack@3 || 4 || 5": +webpack@^5.88.1: version "5.91.0" resolved "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz" integrity sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw== @@ -8523,7 +9491,7 @@ webpackbar@^5.0.2: pretty-time "^1.1.0" std-env "^3.0.1" -websocket-driver@^0.7.4, websocket-driver@>=0.5.1: +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== @@ -8537,6 +9505,56 @@ websocket-extensions@>=0.1.1: resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-builtin-type@^1.1.3: + version "1.1.4" + resolved "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz" + integrity sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w== + dependencies: + function.prototype.name "^1.1.6" + has-tostringtag "^1.0.2" + is-async-function "^2.0.0" + is-date-object "^1.0.5" + is-finalizationregistry "^1.0.2" + is-generator-function "^1.0.10" + is-regex "^1.1.4" + is-weakref "^1.0.2" + isarray "^2.0.5" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.2" + which-typed-array "^1.1.15" + +which-collection@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz" + integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== + dependencies: + is-map "^2.0.3" + is-set "^2.0.3" + is-weakmap "^2.0.2" + is-weakset "^2.0.3" + +which-typed-array@^1.1.14, which-typed-array@^1.1.15: + version "1.1.15" + resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz" + integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.2" + which@^1.3.1: version "1.3.1" resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" @@ -8563,6 +9581,11 @@ wildcard@^2.0.0: resolved "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz" integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz"