diff --git a/.bazelrc b/.bazelrc index 3b5e81ca2..e2e207261 100644 --- a/.bazelrc +++ b/.bazelrc @@ -9,24 +9,16 @@ import %workspace%/envoy.bazelrc # MSAN does not recognize host libc's stat() as initializing the rules_cc runfiles buffer # (@bazel_tools//tools/cpp/runfiles is an alias for @rules_cc//cc/runfiles since Bazel 8). # Scope zero initialization to this helper so proxy and Envoy sources remain fully checked. -build:msan --per_file_copt=external/rules_cc/cc/runfiles/runfiles[.]cc@-ftrivial-auto-var-init=zero - -# Rust crate repinning for repository rules. Inherit CARGO_BAZEL_REPIN from the -# invocation environment so developers can repin explicitly without forcing -# every normal Bazel invocation to recompute the crate index. -common --repo_env=CARGO_BAZEL_REPIN +build:msan --per_file_copt=external/rules_cc[^/]*/cc/runfiles/runfiles[.]cc@-ftrivial-auto-var-init=zero # Retry on transient repository download failures common --experimental_repository_downloader_retries=5 -# Use our own toolchains in all builds. Local builds need this to not pull in external Envoy sysroot -# that only supports glibc 2.31, while for Ubuntu 24.04 builds we need at least 2.38, and actually -# use 2.39. -build --extra_toolchains=//bazel/toolchains:all - -# Use platforms based toolchain resolution -build --incompatible_enable_cc_toolchain_resolution -build --platform_mappings=bazel/platform_mappings +# Build with Envoy's hermetic LLVM toolchain: clang, lld, libc++ and the glibc sysroots are +# downloaded by Bazel and the toolchain is registered by Envoy's MODULE.bazel, so no compiler is +# needed on the host or in the builder image. The target architecture is selected with +# --platforms=//bazel:linux_{x86_64,aarch64}; the hermetic sysroots cover both. +common --repo_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 # envoy.bazelrc always sets -fPIC, tell bazel about it to suppress building both .o and .pic.o # objects from the same C++ sources. diff --git a/.bazelversion b/.bazelversion index df5119ec6..eec6dacbd 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -8.7.0 +8.8.1 diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 71fbdb583..492846ef3 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -13,7 +13,7 @@ 'go.mod', 'go.sum', 'tools/install_bazelisk.sh', - 'WORKSPACE', + 'MODULE.bazel', 'ENVOY_VERSION', ], pinDigests: true, @@ -106,6 +106,7 @@ { matchFileNames: [ 'Dockerfile', + 'Dockerfile.tests', ], matchPackageNames: [ 'docker.io/library/ubuntu', @@ -186,7 +187,7 @@ { customType: 'regex', managerFilePatterns: [ - '/^WORKSPACE$/', + '/^MODULE\\.bazel$/', ], matchStrings: [ '# renovate: datasource=(?.*?) depName=(?.*?)\\s+.+_VERSION = "(?.*)"', diff --git a/.github/workflows/build-envoy-image-ci.yaml b/.github/workflows/build-envoy-image-ci.yaml index 65e889727..4e8e49998 100644 --- a/.github/workflows/build-envoy-image-ci.yaml +++ b/.github/workflows/build-envoy-image-ci.yaml @@ -1,7 +1,8 @@ name: CI Build & Push on: - pull_request_target: - types: [opened, synchronize, reopened] +# pull_request_target: +# types: [opened, synchronize, reopened] + pull_request: {} permissions: # To be able to access the repository with `actions/checkout` @@ -81,89 +82,6 @@ jobs: else echo "Invalid ENVOY_VERSION format: '$VERSION'" && exit 1 fi - echo "BUILDER_DOCKER_HASH=$(git ls-tree --full-tree HEAD -- ./Dockerfile.builder | awk '{ print $3 }')" >> $GITHUB_ENV - - - name: Checking if cilium-envoy-builder image exists - id: cilium-builder-tag-in-repositories - shell: bash - run: | - if docker buildx imagetools inspect quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} &>/dev/null; then - echo exists="true" >> $GITHUB_OUTPUT - else - echo exists="false" >> $GITHUB_OUTPUT - fi - - - name: PR Multi-arch build of Builder image (dev) - uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 - if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' - id: docker_build_builder_ci - with: - provenance: false - context: . - file: ./Dockerfile.builder - platforms: linux/amd64,linux/arm64 - push: false - tags: quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} - outputs: type=oci,dest=${{ runner.temp }}/builder-dev.tar - - # Quay's registry endpoint only accepts credentials or a JWT signed by - # Quay itself, so the GitHub OIDC token cannot be used as the registry - # password directly. Trade it for a short lived robot token first. - # - # Because the job references an environment, the subject of the token is - # repo:cilium@21054566/proxy@155294575:environment:publish-ci-images, the - # immutable form that carries the owner and repository ids. That is the - # identity federated with the robot account on the Quay side, so renaming - # the environment breaks the login. - # - # Quay gives the token one hour and the builds below take hours, so every - # artifact gets its own token once its build finishes. Nothing before the - # first push needs Quay auth: the builder tag lookup and the BUILDER_BASE - # and ARCHIVE_IMAGE pulls all read public repositories. - - name: Get a quay.io robot token via OIDC for the Builder image (dev) - id: token-builder-dev - if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' - env: - ROBOT: ${{ vars.QUAY_ROBOT_CI }} - run: | - oidc_token="$(curl -sSf --retry 3 --retry-all-errors \ - -H "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \ - "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=quay.io" \ - | jq -er '.value')" - echo "::add-mask::${oidc_token}" - - # Pass the credentials on stdin so that the OIDC token is not visible - # in the process list of the runner. - robot_token="$(printf 'user = "%s:%s"\n' "${ROBOT}" "${oidc_token}" \ - | curl -sSf --retry 3 --retry-all-errors -K - \ - "https://quay.io/oauth2/federation/robot/token" \ - | jq -er '.token')" - echo "::add-mask::${robot_token}" - - echo "token=${robot_token}" >> "$GITHUB_OUTPUT" - - - name: Login to quay.io for the Builder image (dev) - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 - if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' - with: - registry: quay.io - username: ${{ vars.QUAY_ROBOT_CI }} - password: ${{ steps.token-builder-dev.outputs.token }} - - - name: PR Push of Builder image (dev) - if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' - run: | - skopeo copy --multi-arch all \ - "oci-archive:${{ runner.temp }}/builder-dev.tar" \ - docker://quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} - rm -f "${{ runner.temp }}/builder-dev.tar" - - - name: CI Builder Image Digest - if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' - shell: bash - run: | - echo "Digests:" - echo "quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }}@${{ steps.docker_build_builder_ci.outputs.digest }}" - name: PR Multi-arch build of cilium-envoy uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 @@ -174,7 +92,6 @@ jobs: file: ./Dockerfile platforms: linux/amd64,linux/arm64 build-args: | - BUILDER_BASE=quay.io/cilium/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} ARCHIVE_IMAGE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ github.base_ref }}-archive-latest BAZEL_BUILD_OPTS=--remote_upload_local_results=false cache-from: type=local,src=/tmp/buildx-cache @@ -183,8 +100,20 @@ jobs: tags: quay.io/${{ github.repository_owner }}/cilium-envoy-dev:${{ github.event.pull_request.head.sha }} outputs: type=oci,dest=${{ runner.temp }}/cilium-envoy-dev.tar - # A token of its own for this push; see the token exchange above. The - # cosign and SBOM steps below write to quay.io with it too. + # Quay's registry endpoint only accepts credentials or a JWT signed by + # Quay itself, so the GitHub OIDC token cannot be used as the registry + # password directly. Trade it for a short lived robot token first. + # + # Because the job references an environment, the subject of the token is + # repo:cilium@21054566/proxy@155294575:environment:publish-ci-images, the + # immutable form that carries the owner and repository ids. That is the + # identity federated with the robot account on the Quay side, so renaming + # the environment breaks the login. + # + # Quay gives the token one hour and the build above takes hours, so the + # token is fetched once the build finishes. Nothing before the push needs + # Quay auth: the ARCHIVE_IMAGE pull reads a public repository. The cosign + # and SBOM steps below write to quay.io with this token too. - name: Get a quay.io robot token via OIDC for cilium-envoy id: token-cilium-envoy-dev env: diff --git a/.github/workflows/build-envoy-images-release-base.yaml b/.github/workflows/build-envoy-images-release-base.yaml index 303cc6b99..4262d3b6b 100644 --- a/.github/workflows/build-envoy-images-release-base.yaml +++ b/.github/workflows/build-envoy-images-release-base.yaml @@ -55,7 +55,6 @@ jobs: echo "${{ github.sha }}" >SOURCE_VERSION echo "ENVOY_MINOR_RELEASE=$(cat ENVOY_VERSION | sed 's/envoy-\([0-9]\+\.[0-9]\+\)\..*/v\1/')" >> $GITHUB_ENV echo "ENVOY_PATCH_RELEASE=$(cat ENVOY_VERSION | sed 's/^envoy-\([0-9]\+\.[0-9]\+\.[0-9]\+$\)/v\1/')" >> $GITHUB_ENV - echo "BUILDER_DOCKER_HASH=$(git ls-tree --full-tree HEAD -- ./Dockerfile.builder | awk '{ print $3 }')" >> $GITHUB_ENV - name: Cache Docker layers uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 @@ -66,13 +65,6 @@ jobs: - name: Clear cache run: rm -rf /tmp/buildx-cache/* - - name: Wait for builder image - uses: ./.github/workflows/wait-for-image - with: - SHA: ${{ env.BUILDER_DOCKER_HASH }} - repo: cilium - images: cilium-envoy-builder - - name: Run integration tests on amd64 & build of test artifact archive uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 id: docker_tests_ci_cache_update @@ -83,7 +75,6 @@ jobs: target: builder-archive platforms: linux/amd64 build-args: | - BUILDER_BASE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ env.BUILDER_DOCKER_HASH }} ARCHIVE_IMAGE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:test-${{ github.ref_name }}-archive-latest COPY_CACHE_EXT=.new BAZEL_BUILD_OPTS=--remote_upload_local_results=false @@ -174,31 +165,22 @@ jobs: echo "${{ github.sha }}" >SOURCE_VERSION echo "ENVOY_MINOR_RELEASE=$(cat ENVOY_VERSION | sed 's/envoy-\([0-9]\+\.[0-9]\+\)\..*/v\1/')" >> $GITHUB_ENV echo "ENVOY_PATCH_RELEASE=$(cat ENVOY_VERSION | sed 's/^envoy-\([0-9]\+\.[0-9]\+\.[0-9]\+$\)/v\1/')" >> $GITHUB_ENV - echo "BUILDER_DOCKER_HASH=$(git ls-tree --full-tree HEAD -- ./Dockerfile.builder | awk '{ print $3 }')" >> $GITHUB_ENV echo "SOURCE_TIMESTAMP=$(git log -1 --pretty=format:"%ct" .)" >> $GITHUB_ENV - - name: Checking if cilium-envoy-builder image exists - id: cilium-builder-tag-in-repositories - shell: bash - run: | - if docker buildx imagetools inspect quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ env.BUILDER_DOCKER_HASH }} &>/dev/null; then - echo exists="true" >> $GITHUB_OUTPUT - else - echo exists="false" >> $GITHUB_OUTPUT - fi - - - name: Multi-arch build of Builder image + - name: Multi-arch build of build artifact archive uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 - if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' - id: docker_build_builder with: - provenance: false context: . - file: ./Dockerfile.builder + file: ./Dockerfile + target: builder-archive platforms: linux/amd64,linux/arm64 + build-args: | + ARCHIVE_IMAGE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ github.ref_name }}-archive-latest + COPY_CACHE_EXT=.new + BAZEL_BUILD_OPTS="--jobs=HOST_CPUS*.75" push: false - tags: quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ env.BUILDER_DOCKER_HASH }} - outputs: type=oci,dest=${{ runner.temp }}/builder.tar + tags: quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ github.ref_name }}-archive-latest + outputs: type=oci,dest=${{ runner.temp }}/archive.tar # Quay's registry endpoint only accepts credentials or a JWT signed by # Quay itself, so the GitHub OIDC token cannot be used as the registry @@ -210,67 +192,10 @@ jobs: # identity federated with the robot account on the Quay side, so renaming # the environment breaks the login. # - # Quay gives the token one hour and the builds below take hours, so every - # artifact gets its own token once its build finishes. Nothing before the - # first push needs Quay auth: the builder tag lookup and the BUILDER_BASE - # and ARCHIVE_IMAGE pulls all read public repositories. - - name: Get a quay.io robot token via OIDC for the Builder image - id: token-builder - if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' - env: - ROBOT: ${{ vars.QUAY_ROBOT_RELEASE }} - run: | - oidc_token="$(curl -sSf --retry 3 --retry-all-errors \ - -H "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" \ - "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=quay.io" \ - | jq -er '.value')" - echo "::add-mask::${oidc_token}" - - # Pass the credentials on stdin so that the OIDC token is not visible - # in the process list of the runner. - robot_token="$(printf 'user = "%s:%s"\n' "${ROBOT}" "${oidc_token}" \ - | curl -sSf --retry 3 --retry-all-errors -K - \ - "https://quay.io/oauth2/federation/robot/token" \ - | jq -er '.token')" - echo "::add-mask::${robot_token}" - - echo "token=${robot_token}" >> "$GITHUB_OUTPUT" - - - name: Login to quay.io for the Builder image - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 - if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' - with: - registry: quay.io - username: ${{ vars.QUAY_ROBOT_RELEASE }} - password: ${{ steps.token-builder.outputs.token }} - - - name: Push of Builder image - if: steps.cilium-builder-tag-in-repositories.outputs.exists == 'false' - run: | - for tag in ${{ env.BUILDER_DOCKER_HASH }} latest; do - skopeo copy --multi-arch all \ - "oci-archive:${{ runner.temp }}/builder.tar" \ - "docker://quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${tag}" - done - rm -f "${{ runner.temp }}/builder.tar" - - - name: Multi-arch build of build artifact archive - uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 - with: - context: . - file: ./Dockerfile - target: builder-archive - platforms: linux/amd64,linux/arm64 - build-args: | - BUILDER_BASE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ env.BUILDER_DOCKER_HASH }} - ARCHIVE_IMAGE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ github.ref_name }}-archive-latest - COPY_CACHE_EXT=.new - BAZEL_BUILD_OPTS="--jobs=HOST_CPUS*.75" - push: false - tags: quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ github.ref_name }}-archive-latest - outputs: type=oci,dest=${{ runner.temp }}/archive.tar - - # A token of its own for this push; see the token exchange above. + # Quay gives the token one hour and the builds in this job take hours, so + # every artifact gets its own token once its build finishes. Nothing before + # the first push needs Quay auth: the ARCHIVE_IMAGE pulls read a public + # repository. - name: Get a quay.io robot token via OIDC for the build artifact archive id: token-archive env: @@ -326,7 +251,6 @@ jobs: file: ./Dockerfile platforms: linux/amd64,linux/arm64 build-args: | - BUILDER_BASE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ env.BUILDER_DOCKER_HASH }} BAZEL_BUILD_OPTS=--remote_upload_local_results=false ARCHIVE_IMAGE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:${{ github.ref_name }}-archive-latest RELEASE_DEBUG=${{ inputs.release_debug && '1' || '' }} diff --git a/.github/workflows/ci-check-format.yaml b/.github/workflows/ci-check-format.yaml index a6fbd50f1..5f0259c9a 100644 --- a/.github/workflows/ci-check-format.yaml +++ b/.github/workflows/ci-check-format.yaml @@ -26,14 +26,6 @@ jobs: - name: Prep for build run: | echo "${{ github.event.pull_request.head.sha }}" >SOURCE_VERSION - echo "BUILDER_DOCKER_HASH=$(git ls-tree --full-tree HEAD -- ./Dockerfile.builder | awk '{ print $3 }')" >> $GITHUB_ENV - - - name: Wait for build image - uses: ./.github/workflows/wait-for-image - with: - SHA: ${{ env.BUILDER_DOCKER_HASH }} - repo: cilium - images: cilium-envoy-builder-dev - name: Check format uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 @@ -45,8 +37,6 @@ jobs: file: ./Dockerfile platforms: linux/amd64 outputs: type=local,dest=check-format-results - build-args: | - BUILDER_BASE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} push: false - name: Check for failure @@ -74,17 +64,9 @@ jobs: - name: Prep for build run: | echo "${{ github.event.pull_request.head.sha }}" >SOURCE_VERSION - echo "BUILDER_DOCKER_HASH=$(git ls-tree --full-tree HEAD -- ./Dockerfile.builder | awk '{ print $3 }')" >> $GITHUB_ENV # git diff filter has everything else than deleted files (those need not be tidied) echo "TIDY_SOURCES=$(git diff --name-only --diff-filter=d HEAD^1 HEAD -- '*.h' '*.cc' | tr '\n' ' ')" >> $GITHUB_ENV - - name: Wait for build image - uses: ./.github/workflows/wait-for-image - with: - SHA: ${{ env.BUILDER_DOCKER_HASH }} - repo: cilium - images: cilium-envoy-builder-dev - - name: Run clang-tidy uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 # skip if nothing changed @@ -98,7 +80,6 @@ jobs: platforms: linux/amd64 outputs: type=local,dest=clang-tidy-results build-args: | - BUILDER_BASE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} TIDY_SOURCES=${{ env.TIDY_SOURCES }} push: false diff --git a/.github/workflows/ci-tests.yaml b/.github/workflows/ci-tests.yaml index 369500cc0..affc3caba 100644 --- a/.github/workflows/ci-tests.yaml +++ b/.github/workflows/ci-tests.yaml @@ -12,9 +12,9 @@ concurrency: cancel-in-progress: true jobs: - proxylib: - timeout-minutes: 360 - name: Run unit tests for proxylib + go-vendoring: + timeout-minutes: 30 + name: Check Go module vendoring runs-on: ubuntu-latest steps: - name: Install Go @@ -31,9 +31,6 @@ jobs: go mod tidy go mod vendor test -z "$(git status --porcelain)" || (echo "please run 'go mod tidy && go mod vendor', and submit your changes"; exit 1) - - name: Run unit tests - run: | - make -C proxylib test tests: timeout-minutes: 360 @@ -59,14 +56,6 @@ jobs: - name: Prep for build run: | echo "${{ github.event.pull_request.head.sha }}" >SOURCE_VERSION - echo "BUILDER_DOCKER_HASH=$(git ls-tree --full-tree HEAD -- ./Dockerfile.builder | awk '{ print $3 }')" >> $GITHUB_ENV - - - name: Wait for build image - uses: ./.github/workflows/wait-for-image - with: - SHA: ${{ env.BUILDER_DOCKER_HASH }} - repo: cilium - images: cilium-envoy-builder-dev - name: Run integration tests on amd64 uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 @@ -77,7 +66,6 @@ jobs: file: ./Dockerfile.tests platforms: linux/amd64 build-args: | - BUILDER_BASE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} ARCHIVE_IMAGE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:test-${{ github.base_ref }}-archive-latest BAZEL_BUILD_OPTS=--remote_upload_local_results=false BAZEL_TEST_OPTS=--jobs=HOST_RAM*.0002 --test_timeout=300 --local_test_jobs=4 --flaky_test_attempts=3 @@ -108,14 +96,6 @@ jobs: - name: Prep for build run: | echo "${{ github.event.pull_request.head.sha }}" >SOURCE_VERSION - echo "BUILDER_DOCKER_HASH=$(git ls-tree --full-tree HEAD -- ./Dockerfile.builder | awk '{ print $3 }')" >> $GITHUB_ENV - - - name: Wait for build image - uses: ./.github/workflows/wait-for-image - with: - SHA: ${{ env.BUILDER_DOCKER_HASH }} - repo: cilium - images: cilium-envoy-builder-dev - name: Run ASAN integration tests on amd64 uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 @@ -126,10 +106,9 @@ jobs: file: ./Dockerfile.tests platforms: linux/amd64 build-args: | - BUILDER_BASE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} ARCHIVE_IMAGE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:test-${{ github.base_ref }}-archive-latest DEBUG=1 - BAZEL_BUILD_OPTS=--remote_upload_local_results=false --config=asan --config=clang-asan + BAZEL_BUILD_OPTS=--remote_upload_local_results=false --config=asan BAZEL_TEST_OPTS=--jobs=HOST_RAM*.0001 --test_timeout=600 --local_test_jobs=2 --flaky_test_attempts=1 --noshow_progress --noshow_loading_progress cache-from: type=local,src=/tmp/buildx-cache push: false @@ -158,14 +137,6 @@ jobs: - name: Prep for build run: | echo "${{ github.event.pull_request.head.sha }}" >SOURCE_VERSION - echo "BUILDER_DOCKER_HASH=$(git ls-tree --full-tree HEAD -- ./Dockerfile.builder | awk '{ print $3 }')" >> $GITHUB_ENV - - - name: Wait for build image - uses: ./.github/workflows/wait-for-image - with: - SHA: ${{ env.BUILDER_DOCKER_HASH }} - repo: cilium - images: cilium-envoy-builder-dev - name: Run MSAN integration tests on amd64 uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 @@ -176,15 +147,10 @@ jobs: file: ./Dockerfile.tests platforms: linux/amd64 build-args: | - BUILDER_BASE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} - PROXYLIB_BUILDER=quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} - PROXYLIB_CC=/usr/lib/llvm-18/bin/clang - PROXYLIB_GO_BUILD_FLAGS=-msan -buildvcs=false - PROXYLIB_GOCACHE=/tmp/go-build ARCHIVE_IMAGE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:test-${{ github.base_ref }}-archive-latest DEBUG=1 BAZEL_BUILD_OPTS=--config=msan --remote_upload_local_results=false - BAZEL_TEST_OPTS=--jobs=HOST_RAM*.00005 --test_timeout=900 --local_test_jobs=1 --notest_keep_going --flaky_test_attempts=1 --noshow_progress --noshow_loading_progress --test_env=MSAN_SYMBOLIZER_PATH=/usr/lib/llvm-18/bin/llvm-symbolizer + BAZEL_TEST_OPTS=--jobs=HOST_RAM*.00005 --test_timeout=900 --local_test_jobs=1 --notest_keep_going --flaky_test_attempts=1 --noshow_progress --noshow_loading_progress cache-from: type=local,src=/tmp/buildx-cache push: false @@ -212,14 +178,6 @@ jobs: - name: Prep for build run: | echo "${{ github.event.pull_request.head.sha }}" >SOURCE_VERSION - echo "BUILDER_DOCKER_HASH=$(git ls-tree --full-tree HEAD -- ./Dockerfile.builder | awk '{ print $3 }')" >> $GITHUB_ENV - - - name: Wait for build image - uses: ./.github/workflows/wait-for-image - with: - SHA: ${{ env.BUILDER_DOCKER_HASH }} - repo: cilium - images: cilium-envoy-builder-dev - name: Run TSAN integration tests on amd64 uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0 @@ -230,15 +188,9 @@ jobs: file: ./Dockerfile.tests platforms: linux/amd64 build-args: | - BUILDER_BASE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} - PROXYLIB_BUILDER=quay.io/${{ github.repository_owner }}/cilium-envoy-builder-dev:${{ env.BUILDER_DOCKER_HASH }} - PROXYLIB_CC=/usr/lib/llvm-18/bin/clang - PROXYLIB_CGO_CFLAGS=-fsanitize=thread - PROXYLIB_GO_BUILD_FLAGS=-installsuffix=tsan -buildvcs=false - PROXYLIB_GOCACHE=/tmp/go-build ARCHIVE_IMAGE=quay.io/${{ github.repository_owner }}/cilium-envoy-builder:test-${{ github.base_ref }}-archive-latest DEBUG=1 BAZEL_BUILD_OPTS=--config=tsan --remote_upload_local_results=false - BAZEL_TEST_OPTS=--jobs=HOST_RAM*.00005 --test_timeout=900 --local_test_jobs=1 --notest_keep_going --flaky_test_attempts=1 --noshow_progress --noshow_loading_progress --test_env=TSAN_OPTIONS=report_atomic_races=0:halt_on_error=1:external_symbolizer_path=/usr/lib/llvm-18/bin/llvm-symbolizer:strip_path_prefix=/proc/self/cwd/ + BAZEL_TEST_OPTS=--jobs=HOST_RAM*.00005 --test_timeout=900 --local_test_jobs=1 --notest_keep_going --flaky_test_attempts=1 --noshow_progress --noshow_loading_progress --test_env=TSAN_OPTIONS=report_atomic_races=0:halt_on_error=1:strip_path_prefix=/proc/self/cwd/ cache-from: type=local,src=/tmp/buildx-cache push: false diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a6897cf06..95e79f1d2 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,20 +38,11 @@ jobs: run: | sudo apt-get update --error-on=any sudo apt-get install --yes \ - libtool libtinfo5 automake autoconf curl unzip - # Note: the llvm/clang version should match the version specifed in: - # - bazel/repository_locations.bzl - # - .github/workflows/codeql-push.yml - # - https://github.com/envoyproxy/envoy-build-tools/blob/main/build_container/build_container_ubuntu.sh#L84 - mkdir -p bin/clang18.1.8 - cd bin/clang18.1.8 - wget -q https://github.com/llvm/llvm-project/releases/download/llvmorg-18.1.8/clang+llvm-18.1.8-x86_64-linux-gnu-ubuntu-18.04.tar.xz - tar -xf clang+llvm-18.1.8-x86_64-linux-gnu-ubuntu-18.04.tar.xz --strip-components 1 + libtool automake autoconf curl unzip - name: Build (for C++) if: matrix.config.language == 'cpp' run: | - bazel/setup_clang.sh bin/clang18.1.8 bazelisk shutdown bazel build \ -c fastbuild \ @@ -59,7 +50,6 @@ jobs: --discard_analysis_cache \ --nouse_action_cache \ --features="-layering_check" \ - --config=clang \ --config=ci \ cilium-envoy diff --git a/.github/workflows/wait-for-image/action.yaml b/.github/workflows/wait-for-image/action.yaml deleted file mode 100644 index 68ff8907a..000000000 --- a/.github/workflows/wait-for-image/action.yaml +++ /dev/null @@ -1,30 +0,0 @@ -name: Wait for images -description: Wait for images -inputs: - SHA: - description: 'inputs.sha' - required: true - default: 'incorrect-sha' - repo: - description: 'Repo for container image' - required: true - default: 'cilium' - images: - description: 'list of images to wait for' - required: false - default: 'cilium-envoy-builder-dev' - -runs: - using: composite - steps: - - name: Wait for images - shell: bash - run: | - images=( ${{ inputs.images }} ) - for image in ${images[@]}; do - until docker manifest inspect quay.io/${{ inputs.repo }}/$image:${{ inputs.SHA }} &> /dev/null - do - echo "Waiting for quay.io/${{ inputs.repo }}/$image:${{ inputs.SHA }} image to become available..." - sleep 45s - done - done diff --git a/.gitignore b/.gitignore index 6e7a14671..0d249e07a 100644 --- a/.gitignore +++ b/.gitignore @@ -38,20 +38,15 @@ __pycache__/ # generated from make targets *.ok -/proxylib/libcilium.so # Istio porting files /envoy_bootstrap*.json # Clang config is platform-specific -/clang.bazelrc # generated for docker builds via make /SOURCE_VERSION -/proxylib/libcilium.so* -/proxylib/_obj* - /BUILD_DEP_HASHES # clangd compilation database diff --git a/BUILD b/BUILD index 5f178671c..da4ad707e 100644 --- a/BUILD +++ b/BUILD @@ -24,7 +24,6 @@ cc_binary( envoy_cc_binary( name = "cilium-envoy", - repository = "@envoy", deps = [ # Cilium filters. "//cilium:health_check_sink_lib", diff --git a/Dockerfile b/Dockerfile index 68690ae45..f84169870 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,3 @@ -# -# BUILDER_BASE is a multi-platform image with all the build tools -# -ARG BUILDER_BASE=quay.io/cilium/cilium-envoy-builder:6.1.0-latest - # # ARCHIVE_IMAGE defaults to the result of the first stage below, # refreshing the build caches from Envoy dependencies before the final @@ -14,16 +9,29 @@ ARG BUILDER_BASE=quay.io/cilium/cilium-envoy-builder:6.1.0-latest # ARG ARCHIVE_IMAGE=builder-fresh -FROM --platform=$BUILDPLATFORM $BUILDER_BASE AS proxylib -WORKDIR /go/src/github.com/cilium/proxy -COPY --chown=1337:1337 . ./ -ARG TARGETARCH -ENV TARGETARCH=$TARGETARCH -RUN --mount=mode=0777,gid=1337,uid=1337,target=/cilium/proxy/.cache,type=cache \ - --mount=mode=0777,gid=1337,uid=1337,target=/go/pkg,type=cache \ - PATH=$PATH:/usr/local/go/bin GOARCH=${TARGETARCH} make -C proxylib all && mv proxylib/libcilium.so /tmp/libcilium.so +# +# Build tools for the stages below. Bazel downloads the LLVM toolchain, the +# sysroots, Python and Go itself, so the host only needs Bazelisk, git and +# make. The downloaded lld links against the host libxml2, and the clang-tidy +# helper scripts run the host python3. +# +FROM --platform=$BUILDPLATFORM docker.io/library/ubuntu:24.04@sha256:534baea6a22c03a63003dbc8dbe78fe34bc0d7e595d9a9dc9834884ff530eb55 AS builder-base +LABEL maintainer="maintainer@cilium.io" +ARG BUILDARCH +RUN apt-get update && \ + apt-get upgrade -y --no-install-recommends && \ + apt-get install -y --no-install-recommends ca-certificates curl git libxml2 make python3 && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +# renovate: datasource=github-releases depName=bazelbuild/bazelisk +ENV BAZELISK_VERSION=v1.29.0 +RUN curl -sfL https://github.com/bazelbuild/bazelisk/releases/download/${BAZELISK_VERSION}/bazelisk-linux-${BUILDARCH} -o /usr/bin/bazel && \ + chmod +x /usr/bin/bazel +RUN groupadd -f -g 1337 cilium && useradd -m -d /cilium/proxy -g cilium -u 1337 cilium +USER 1337:1337 +WORKDIR /cilium/proxy -FROM --platform=$BUILDPLATFORM $BUILDER_BASE AS builder-fresh +FROM builder-base AS builder-fresh LABEL maintainer="maintainer@cilium.io" WORKDIR /cilium/proxy COPY . ./ @@ -53,7 +61,7 @@ FROM $ARCHIVE_IMAGE AS builder-cache # # Persist Bazel disk cache by passing COPY_CACHE=1 # -FROM --platform=$BUILDPLATFORM $BUILDER_BASE AS builder +FROM builder-base AS builder LABEL maintainer="maintainer@cilium.io" WORKDIR /cilium/proxy COPY . ./ @@ -73,10 +81,6 @@ RUN --mount=mode=0777,uid=1337,gid=1337,target=/cilium/proxy/.cache,type=cache,i if [ -n "${COPY_CACHE_EXT}" ]; then PKG_BUILD=1 make BUILD_DEP_HASHES; if [ -f /tmp/bazel-cache/BUILD_DEP_HASHES ] && ! diff BUILD_DEP_HASHES /tmp/bazel-cache/BUILD_DEP_HASHES; then echo "Build dependencies have changed, clearing bazel cache"; rm -rf /tmp/bazel-cache/*; rm -rf /cilium/proxy/.cache/*; fi ; cp BUILD_DEP_HASHES ENVOY_VERSION /tmp/bazel-cache; fi && \ BAZEL_BUILD_OPTS="${BAZEL_BUILD_OPTS} --disk_cache=/tmp/bazel-cache" PKG_BUILD=1 V=$V DEBUG=$DEBUG RELEASE_DEBUG=$RELEASE_DEBUG DESTDIR=/tmp/install make install && \ if [ -n "${COPY_CACHE_EXT}" ]; then cp -ra /tmp/bazel-cache /tmp/bazel-cache${COPY_CACHE_EXT}; ls -la /tmp/bazel-cache${COPY_CACHE_EXT}; fi -# -# Copy proxylib after build to allow install as non-root to succeed -# -COPY --from=proxylib /tmp/libcilium.so /tmp/install/usr/lib/libcilium.so FROM scratch AS empty-builder-archive LABEL maintainer="maintainer@cilium.io" @@ -90,7 +94,7 @@ ARG COPY_CACHE_EXT COPY --from=builder /tmp/bazel-cache${COPY_CACHE_EXT}/ /tmp/bazel-cache/ # Format check -FROM --platform=$BUILDPLATFORM $BUILDER_BASE AS check-format +FROM builder-base AS check-format LABEL maintainer="maintainer@cilium.io" WORKDIR /cilium/proxy COPY --chown=1337:1337 . ./ @@ -108,7 +112,7 @@ FROM scratch AS format COPY --from=check-format /cilium/proxy/format-output.txt / # clang-tidy -FROM --platform=$BUILDPLATFORM $BUILDER_BASE AS run-clang-tidy-fix +FROM builder-base AS run-clang-tidy-fix LABEL maintainer="maintainer@cilium.io" WORKDIR /cilium/proxy COPY --chown=1337:1337 . ./a diff --git a/Dockerfile.builder b/Dockerfile.builder deleted file mode 100644 index b5e9cbe21..000000000 --- a/Dockerfile.builder +++ /dev/null @@ -1,103 +0,0 @@ -# -# Builder dependencies. This takes a long time to build from scratch! -# Also note that if build fails due to C++ internal error or similar, -# it is possible that the image build needs more RAM than available by -# default on non-Linux docker installs. -FROM docker.io/library/ubuntu:24.04@sha256:534baea6a22c03a63003dbc8dbe78fe34bc0d7e595d9a9dc9834884ff530eb55 AS base -LABEL maintainer="maintainer@cilium.io" -ARG TARGETARCH -# Setup TimeZone to prevent tzdata package asking for it interactively -ENV TZ=Etc/UTC - -# renovate: datasource=golang-version depName=go -ENV GO_VERSION=1.26.9 - -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone -RUN apt-get update && \ - apt-get upgrade -y --no-install-recommends && \ - apt-get install -y --no-install-recommends \ - ca-certificates \ - # Multi-arch cross-compilation packages - gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross binutils-aarch64-linux-gnu \ - gcc-x86-64-linux-gnu g++-x86-64-linux-gnu libc6-dev-amd64-cross binutils-x86-64-linux-gnu \ - libc6-dev \ - # Envoy Build dependencies - autoconf automake cmake coreutils curl git libtool make ninja-build patch patchelf libatomic1 \ - python3 python-is-python3 unzip virtualenv wget xz-utils zip && \ - apt-get purge --auto-remove && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* - -# -# Install Clang/LLVM from the official upstream release tarball. -# -# Ubuntu noble only ships clang 18.1.3, and the apt.llvm.org snapshot repo -# serves inconsistent package versions across mirrors (a release-versioned -# libllvm18 paired with a still-snapshot llvm-18-dev), which intermittently -# breaks apt dependency resolution. The upstream release tarball is an -# immutable, checksummed artifact pinned to exactly LLVM_VERSION. It needs the -# libtinfo.so.5 ABI (dropped by noble), provided by the jammy libtinfo5 compat -# package. The toolchain runs on noble but links the host (glibc 2.39) libc, -# so binaries it produces stay compatible with the ubuntu:24.04 runtime image. -# -# LLVM_VERSION must match MIN_CLANG_VERSION in the Makefile; bump both together -# (deliberately, alongside Envoy upgrades) rather than via automated updates. -ENV LLVM_VERSION=18.1.8 -ENV LIBTINFO5_VERSION=6.3-2ubuntu0.1 -ENV UBUNTU_SNAPSHOT=20240501T120000Z -RUN case "$TARGETARCH" in \ - amd64) LLVM_ARCH=x86_64-linux-gnu-ubuntu-18.04 ;; \ - arm64) LLVM_ARCH=aarch64-linux-gnu ;; \ - *) echo "unsupported TARGETARCH: $TARGETARCH" >&2; exit 1 ;; \ - esac && \ - # libtinfo.so.5 compat ABI, required to run the upstream clang on noble - curl -sfL "https://snapshot.ubuntu.com/ubuntu/${UBUNTU_SNAPSHOT}/pool/universe/n/ncurses/libtinfo5_${LIBTINFO5_VERSION}_${TARGETARCH}.deb" -o /tmp/libtinfo5.deb && \ - dpkg -i /tmp/libtinfo5.deb && \ - rm /tmp/libtinfo5.deb && \ - # upstream LLVM toolchain, extracted into the path the bazel toolchain expects - curl -sfL "https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/clang+llvm-${LLVM_VERSION}-${LLVM_ARCH}.tar.xz" -o /tmp/llvm.tar.xz && \ - mkdir -p /usr/lib/llvm-18 && \ - tar -xJf /tmp/llvm.tar.xz -C /usr/lib/llvm-18 --strip-components=1 && \ - rm /tmp/llvm.tar.xz && \ - # The upstream tarball bundles the entire LLVM suite (Flang, MLIR, BOLT, - # clangd, static archives, ...) the Envoy build never uses. Keep only the - # toolchain binaries referenced by //bazel/toolchains plus clang-format and - # clang-tidy, and drop static archives, tooling shared libs and docs. - cd /usr/lib/llvm-18/bin && \ - keep=" clang-18 lld clang-format clang-tidy clang-apply-replacements run-clang-tidy llvm-ar llvm-nm llvm-strip llvm-objcopy llvm-objdump llvm-dwp llvm-cov llvm-config llvm-symbolizer " && \ - for f in $(find . -maxdepth 1 -type f -printf '%f\n'); do case "$keep" in *" $f "*) : ;; *) rm -f "$f" ;; esac; done && \ - cd /usr/lib/llvm-18 && \ - find lib -maxdepth 1 -name '*.a' ! -name 'libc++*.a' ! -name 'libunwind*.a' -delete && \ - rm -f lib/libclang-cpp.so* lib/libclang.so* lib/liblldb.so* lib/libLTO.so* lib/libomptarget* lib/LLVMPolly.so lib/libmlir* lib/liblldbIntel* && \ - rm -rf share libexec && \ - # Create unversioned and -18 suffixed symlinks so tools are on PATH either way - for tool in clang clang++ clang-cpp lld ld.lld clang-format clang-tidy run-clang-tidy clang-apply-replacements \ - llvm-ar llvm-nm llvm-strip llvm-objcopy llvm-objdump llvm-dwp llvm-cov llvm-config llvm-symbolizer; do \ - ln -sf /usr/lib/llvm-18/bin/$tool /usr/bin/$tool && \ - ln -sf /usr/lib/llvm-18/bin/$tool /usr/bin/$tool-18; \ - done && \ - /usr/lib/llvm-18/bin/llvm-symbolizer --version - -# -# Install Bazelisk -# -# renovate: datasource=github-releases depName=bazelbuild/bazelisk -ENV BAZELISK_VERSION=v1.29.0 - -RUN ARCH=$TARGETARCH \ - && curl -sfL https://github.com/bazelbuild/bazelisk/releases/download/${BAZELISK_VERSION}/bazelisk-linux-${ARCH} -o /usr/bin/bazel \ - && chmod +x /usr/bin/bazel -# -# Install Go -# -RUN curl -sfL https://go.dev/dl/go${GO_VERSION}.linux-${TARGETARCH}.tar.gz -o go.tar.gz \ - && tar -C /usr/local -xzf go.tar.gz \ - && rm go.tar.gz \ - && export PATH=$PATH:/usr/local/go/bin \ - && go version -# -# Switch to non-root user for builds -# -RUN groupadd -f -g 1337 cilium && useradd -m -d /cilium/proxy -g cilium -u 1337 cilium -USER 1337:1337 -WORKDIR /cilium/proxy diff --git a/Dockerfile.tests b/Dockerfile.tests index 14953d804..c62c7424f 100644 --- a/Dockerfile.tests +++ b/Dockerfile.tests @@ -1,11 +1,3 @@ -# -# BUILDER_BASE is a multi-platform image with all the build tools -# -ARG BUILDER_BASE=quay.io/cilium/cilium-envoy-builder:6.5.0-latest@sha256:3f98b069a4c4737d8252fdf47f77d9f7e27ef5acb1bec13af3619180d6baee23 - -# Common Builder image used in cilium/cilium -ARG PROXYLIB_BUILDER=quay.io/cilium/cilium-builder:767c4152bb156a879fca4c5b76f445de4b4cdaa9@sha256:26392846fa25ab2607c120ece242d61365724a5f21e85f5733f72221637b70fa - # # ARCHIVE_IMAGE defaults to the result of the first stage below, # refreshing the build caches from Envoy dependencies before the final @@ -17,23 +9,29 @@ ARG PROXYLIB_BUILDER=quay.io/cilium/cilium-builder:767c4152bb156a879fca4c5b76f44 # ARG ARCHIVE_IMAGE=builder-fresh -FROM --platform=$BUILDPLATFORM $PROXYLIB_BUILDER AS proxylib -WORKDIR /go/src/github.com/cilium/proxy -ENV PATH=/usr/local/go/bin:$PATH -ARG TARGETARCH -ARG PROXYLIB_CC=gcc -ARG PROXYLIB_CGO_CFLAGS -ARG PROXYLIB_GO_BUILD_FLAGS -ARG PROXYLIB_GOCACHE -RUN --mount=type=bind,target=/go/src/github.com/cilium/proxy \ - --mount=mode=0777,target=/cilium/proxy/.cache,type=cache \ - --mount=mode=0777,target=/go/pkg,type=cache \ - --mount=mode=0777,uid=1337,gid=1337,target=/tmp/go-build,type=cache \ - if [ -n "${PROXYLIB_GOCACHE}" ]; then export GOCACHE="${PROXYLIB_GOCACHE}"; fi && \ - if [ -n "${PROXYLIB_CGO_CFLAGS}" ]; then export CGO_CFLAGS="${PROXYLIB_CGO_CFLAGS}"; fi && \ - CC="${PROXYLIB_CC}" GOARCH="${TARGETARCH}" GO_BUILD_FLAGS="${PROXYLIB_GO_BUILD_FLAGS}" make -C proxylib TARGET=/tmp/libcilium.so all +# +# Build tools for the stages below. Bazel downloads the LLVM toolchain, the +# sysroots, Python and Go itself, so the host only needs Bazelisk, git and +# make. The downloaded lld links against the host libxml2, and the clang-tidy +# helper scripts run the host python3. +# +FROM --platform=$BUILDPLATFORM docker.io/library/ubuntu:24.04@sha256:534baea6a22c03a63003dbc8dbe78fe34bc0d7e595d9a9dc9834884ff530eb55 AS builder-base +LABEL maintainer="maintainer@cilium.io" +ARG BUILDARCH +RUN apt-get update && \ + apt-get upgrade -y --no-install-recommends && \ + apt-get install -y --no-install-recommends ca-certificates curl git libxml2 make python3 && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +# renovate: datasource=github-releases depName=bazelbuild/bazelisk +ENV BAZELISK_VERSION=v1.29.0 +RUN curl -sfL https://github.com/bazelbuild/bazelisk/releases/download/${BAZELISK_VERSION}/bazelisk-linux-${BUILDARCH} -o /usr/bin/bazel && \ + chmod +x /usr/bin/bazel +RUN groupadd -f -g 1337 cilium && useradd -m -d /cilium/proxy -g cilium -u 1337 cilium +USER 1337:1337 +WORKDIR /cilium/proxy -FROM --platform=$BUILDPLATFORM $BUILDER_BASE AS builder-fresh +FROM builder-base AS builder-fresh LABEL maintainer="maintainer@cilium.io" WORKDIR /cilium/proxy COPY . ./ @@ -48,15 +46,13 @@ ENV TARGETARCH=$TARGETARCH # # Build dependencies # -# Make proxylib available for building the test dependencies by copying it before running the tests -COPY --from=proxylib /tmp/libcilium.so proxylib/libcilium.so RUN BAZEL_BUILD_OPTS="${BAZEL_BUILD_OPTS} --disk_cache=/tmp/bazel-cache" PKG_BUILD=1 V=$V DEBUG=$DEBUG make envoy-test-deps # By default this stage picks up the result of the build above, but ARCHIVE_IMAGE can be # overridden to point to a saved image of an earlier run of that stage. FROM $ARCHIVE_IMAGE AS archive-cache -FROM --platform=$BUILDPLATFORM $BUILDER_BASE AS builder +FROM builder-base AS builder LABEL maintainer="maintainer@cilium.io" WORKDIR /cilium/proxy COPY . ./ @@ -69,8 +65,6 @@ ENV TARGETARCH=$TARGETARCH # Clear runner's cache when building deps RUN --mount=mode=0777,uid=1337,gid=1337,target=/cilium/proxy/.cache,type=cache,id=$TARGETARCH,sharing=private rm -rf /cilium/proxy/.cache/* -# Make proxylib available for building the test dependencies by copying it before running the tests -COPY --from=proxylib /tmp/libcilium.so proxylib/libcilium.so RUN --mount=target=/tmp/bazel-cache,source=/tmp/bazel-cache,from=archive-cache,rw \ if [ -f /tmp/bazel-cache/ENVOY_VERSION ]; then CACHE_ENVOY_VERSION=`cat /tmp/bazel-cache/ENVOY_VERSION`; ENVOY_VERSION=`cat ENVOY_VERSION`; if [ "${CACHE_ENVOY_VERSION}" != "${ENVOY_VERSION}" ]; then echo "Testing Envoy ${ENVOY_VERSION} with bazel archive from different Envoy version (${CACHE_ENVOY_VERSION})"; else echo "Testing Envoy ${ENVOY_VERSION} with bazel cache of the same version"; fi; else echo "Bazel cache has no ENVOY_VERSION, it may be empty."; fi && \ touch /tmp/bazel-cache/permissions-check && \ @@ -78,7 +72,7 @@ RUN --mount=target=/tmp/bazel-cache,source=/tmp/bazel-cache,from=archive-cache,r BAZEL_BUILD_OPTS="${BAZEL_BUILD_OPTS} --disk_cache=/tmp/bazel-cache" PKG_BUILD=1 V=$V DEBUG=$DEBUG make envoy-test-deps && \ if [ -n "${COPY_CACHE_EXT}" ]; then cp -ra /tmp/bazel-cache /tmp/bazel-cache${COPY_CACHE_EXT}; fi -FROM --platform=$BUILDPLATFORM $BUILDER_BASE AS runner +FROM builder-base AS runner LABEL maintainer="maintainer@cilium.io" WORKDIR /cilium/proxy COPY . ./ @@ -92,8 +86,6 @@ ARG NO_CACHE ENV TARGETARCH=$TARGETARCH RUN --mount=mode=0777,uid=1337,gid=1337,target=/cilium/proxy/.cache,type=cache,id=$TARGETARCH,sharing=private if [ -n "$NO_CACHE" ]; then rm -rf /cilium/proxy/.cache/*; fi -# Make proxylib available for the tests by copying it before running the tests -COPY --from=proxylib /tmp/libcilium.so proxylib/libcilium.so RUN --mount=mode=0777,uid=1337,gid=1337,target=/cilium/proxy/.cache,type=cache,id=$TARGETARCH,sharing=private \ --mount=target=/tmp/bazel-cache,source=/tmp/bazel-cache,from=archive-cache,rw \ if [ "$TARGETARCH" != "$BUILDARCH" ]; then \ diff --git a/ENVOY_VERSION b/ENVOY_VERSION index ddfcac064..7726c5ea0 100644 --- a/ENVOY_VERSION +++ b/ENVOY_VERSION @@ -1 +1 @@ -envoy-1.39.3 +envoy-1.40.0 diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 000000000..add1411b0 --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,149 @@ +module(name = "cilium") + +# Envoy GIT commit SHA of release +# +# renovate: datasource=github-releases depName=envoyproxy/envoy digestVersion=v1.39.1 +ENVOY_SHA = "8c1381c08dd9b9a1ed032dc705126f3ff2a43479" + +# Envoy must be the first bazel_dep so that the toolchains it registers (most importantly the +# hermetic LLVM toolchain) take precedence over the ones registered by the other modules below. +bazel_dep(name = "envoy", version = "1.40.0-dev") +bazel_dep(name = "envoy_api", version = "1.40.0-dev") +bazel_dep(name = "abseil-cpp", version = "20260817.0") +bazel_dep(name = "bazel_skylib", version = "1.9.2") +bazel_dep(name = "googleapis", version = "0.0.0-20251003-2193a2bf") +bazel_dep(name = "platforms", version = "1.1.0") +bazel_dep(name = "protobuf", version = "35.1.bcr.envoy") +bazel_dep(name = "protoc-gen-validate", version = "1.3.3.envoy") +bazel_dep(name = "quiche", version = "0.0.0-261006-9e60ac2.envoy") +bazel_dep(name = "re2", version = "2025-11-05.bcr.1") +bazel_dep(name = "rules_cc", version = "0.2.25") +bazel_dep(name = "rules_go", version = "0.63.0") +bazel_dep(name = "rules_python", version = "2.3.3") +bazel_dep(name = "rules_shell", version = "0.8.0") + +# Not used directly, but envoy.bazelrc sets flags on these repositories, which must therefore be +# visible from the main repository. +bazel_dep(name = "boringssl-fips", version = "0.20260929.0.envoy") +bazel_dep(name = "envoy_toolshed", version = "0.5.3.envoy") +bazel_dep(name = "librdkafka", version = "2.15.0") +bazel_dep(name = "proxy-wasm-cpp-host", version = "0.0.0-260704-f2db56a.envoy") +bazel_dep(name = "rules_fuzzing", version = "0.6.0") +bazel_dep(name = "rules_rust", version = "0.74.0.envoy") + +# Used by tools/gen_compilation_database.py. +bazel_dep(name = "bazel-compdb", version = "0.0.0-20220906-4086479.envoy", dev_dependency = True) +bazel_dep(name = "google_benchmark", version = "1.9.5", dev_dependency = True, repo_name = "benchmark") +bazel_dep(name = "googletest", version = "1.18.0.bcr.1", dev_dependency = True) +bazel_dep(name = "tclap", version = "1.2.5.bcr.1", dev_dependency = True) + +#################################################################################### +# Envoy +#################################################################################### + +# Overrides only take effect in the root module, so Envoy (and its in-tree API module) are +# pinned here, and the overrides Envoy's own MODULE.bazel applies are repeated below. +git_override( + module_name = "envoy", + commit = ENVOY_SHA, + patch_strip = 1, + patches = [ + "//patches:0001-network-Add-callback-for-upstream-authorization.patch", + "//patches:0002-listener-add-socket-options.patch", + "//patches:0003-original_dst_cluster-Avoid-multiple-hosts-for-the-sa.patch", + "//patches:0004-thread_local-reset-slot-in-worker-threads-first.patch", + "//patches:0005-http-header-expose-attribute.patch", + "//patches:0006-config-add-grpc-mux-stream-event-callback.patch", + "//patches:0007-network-Allow-write-filters-to-consume-data-after-e.patch", + "//patches:0008-tcp_proxy-Allow-filters-to-wait-for-upstream-close.patch", + ], + remote = "https://github.com/envoyproxy/envoy.git", +) + +git_override( + module_name = "envoy_api", + commit = ENVOY_SHA, + remote = "https://github.com/envoyproxy/envoy.git", + strip_prefix = "api", +) + +# For local development against an Envoy checkout instead of the git repository above, replace +# both git_override()s with: +# +# local_path_override( +# module_name = "envoy", +# path = "/home/tammach/go/src/github.com/envoyproxy/envoy", +# ) +# +# local_path_override( +# module_name = "envoy_api", +# path = "/home/tammach/go/src/github.com/envoyproxy/envoy/api", +# ) + +single_version_override( + module_name = "proxy-wasm-cpp-sdk", + version = "0.0.0-250925-e5256b0.envoy", +) + +single_version_override( + module_name = "boringssl", + version = "0.20260929.0", +) + +single_version_override( + module_name = "openssl", + version = "3.5.7.envoy", +) + +# Build Envoy with the Cilium selection of extensions. +local_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository") + +local_repository( + name = "envoy_build_config", + path = "envoy_build_config", +) + +envoy_build_config_ext = use_extension("@envoy//bazel:extensions.bzl", "envoy_build_config_ext") + +override_repo( + envoy_build_config_ext, + envoy_build_config = "envoy_build_config", +) + +# Envoy declares the QUICHE test platform implementations as a dev dependency, so they are not +# wired up when Envoy is not the root module. The Envoy integration test libraries need them. +quiche_dev = use_extension("@quiche//:extensions.bzl", "quiche", dev_dependency = True) +quiche_dev.deps( + quiche_expect_bug_impl_lib = "@envoy//test/common/quic/platform:quiche_expect_bug_impl_lib", + quiche_test_helpers_impl_lib = "@envoy//test/common/quic/platform:quiche_test_helpers_impl_lib", + quiche_test_impl_lib = "@envoy//test/common/quic/platform:quiche_test_impl_lib", + quiche_test_output_impl_lib = "@envoy//test/common/quic/platform:quiche_test_output_impl_lib", + quiche_thread_impl_lib = "@envoy//test/common/quic/platform:quiche_thread_impl_lib", +) + +#################################################################################### +# Languages/toolchains +#################################################################################### + +# Envoy's ASAN test rules depend on @llvm_toolchain_llvm//:symbolizer by its apparent name. +envoy_llvm_ext = use_extension("@envoy//bazel:extensions.bzl", "envoy_llvm_extension") +use_repo(envoy_llvm_ext, "llvm_toolchain_llvm") + +python = use_extension("@rules_python//python/extensions:python.bzl", "python") +python.toolchain( + is_default = True, + python_version = "3.12", +) + +go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") +go_sdk.download( + name = "go_sdk", + sdks = { + "linux_amd64": ("go1.27.1.linux-amd64.tar.gz", "63d339f0da5ab53635a56f2490a7984dfe12dfcff22ad749f63edaf590168445"), + "linux_arm64": ("go1.27.1.linux-arm64.tar.gz", "3450b45a3f9ee8568792736a5c5e70a1f2e9b36c35a8f74958c03e51d7d92bec"), + }, + version = "1.27.1", +) +use_repo(go_sdk, "go_toolchains") + +register_toolchains("@go_toolchains//:all") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock new file mode 100644 index 000000000..5822323ff --- /dev/null +++ b/MODULE.bazel.lock @@ -0,0 +1,5660 @@ +{ + "lockFileVersion": 28, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20220623.1/MODULE.bazel": "73ae41b6818d423a11fd79d95aedef1258f304448193d4db4ff90e5e7a0f076c", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.0/MODULE.bazel": "98dc378d64c12a4e4741ad3362f87fb737ee6a0886b2d90c3cdbb4d93ea3e0bf", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", + "https://bcr.bazel.build/modules/abseil-cpp/20240722.0.bcr.1/MODULE.bazel": "c0aa5eaefff1121b40208397f229604c717bd2fdf214ff67586d627118e17720", + "https://bcr.bazel.build/modules/abseil-cpp/20240722.0/MODULE.bazel": "88668a07647adbdc14cb3a7cd116fb23c9dda37a90a1681590b6c9d8339a5b84", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", + "https://bcr.bazel.build/modules/abseil-cpp/20250512.0/MODULE.bazel": "c4d02dd22cd87458516655a45512060246ee2a4732f1fbe948a5bd9eb614e626", + "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.0/MODULE.bazel": "c43c16ca2c432566cdb78913964497259903ebe8fb7d9b57b38e9f1425b427b8", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", + "https://bcr.bazel.build/modules/abseil-cpp/20260107.0/MODULE.bazel": "94bdc259eccc59d880d3ae55e35ff1f27a289618a023cb1ed87182e17887b7c3", + "https://bcr.bazel.build/modules/abseil-cpp/20260107.1/MODULE.bazel": "e33b3801443f5fd64465262084534115db76363df13d2168a42bbfacc747be81", + "https://bcr.bazel.build/modules/abseil-cpp/20260526.0/MODULE.bazel": "b4a76a8d70ba08aa0253fd5e374ca5a5fa6b15aba985a7bbe4467c138954830f", + "https://bcr.bazel.build/modules/abseil-cpp/20260817.0/MODULE.bazel": "026d79f94313a7b41e1d133834b802713b2d86faee4acf6008ad1dce5f0c4de3", + "https://bcr.bazel.build/modules/abseil-cpp/20260817.0/source.json": "d25e9948901242071dd567462d04fa13c40bfe27ad8b9a4bbc9cc243e84202cb", + "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a", + "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b", + "https://bcr.bazel.build/modules/antlr4-cpp-runtime/4.13.2.bcr.2/MODULE.bazel": "746535182c0824d4c7367d4e2f4588999adb11fff0f77d5d96a900588e5cab20", + "https://bcr.bazel.build/modules/antlr4-cpp-runtime/4.13.2.bcr.2/source.json": "6cf2fbbd0fd937e132af3229b0febdb36424d4ab6df31fde3c363f49c0289384", + "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", + "https://bcr.bazel.build/modules/apple_support/1.13.0/MODULE.bazel": "7c8cdea7e031b7f9f67f0b497adf6d2c6a2675e9304ca93a9af6ed84eef5a524", + "https://bcr.bazel.build/modules/apple_support/1.14.0/MODULE.bazel": "ff6681d5678559b588b5062313e6314be77d560d546e28833e10d6d1b54d18ee", + "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.17.1/MODULE.bazel": "655c922ab1209978a94ef6ca7d9d43e940cd97d9c172fb55f94d91ac53f8610b", + "https://bcr.bazel.build/modules/apple_support/1.19.0/MODULE.bazel": "195d987152354e9e4cab8f5635b55d39632b1542a8854b2012727d3a7bb02df4", + "https://bcr.bazel.build/modules/apple_support/1.22.1/MODULE.bazel": "90bd1a660590f3ceffbdf524e37483094b29352d85317060b2327fff8f3f4458", + "https://bcr.bazel.build/modules/apple_support/1.23.0/MODULE.bazel": "317d47e3f65b580e7fb4221c160797fda48e32f07d2dfff63d754ef2316dcd25", + "https://bcr.bazel.build/modules/apple_support/1.23.1/MODULE.bazel": "53763fed456a968cf919b3240427cf3a9d5481ec5466abc9d5dc51bc70087442", + "https://bcr.bazel.build/modules/apple_support/1.24.1/MODULE.bazel": "f46e8ddad60aef170ee92b2f3d00ef66c147ceafea68b6877cb45bd91737f5f8", + "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", + "https://bcr.bazel.build/modules/apple_support/2.3.0/MODULE.bazel": "d48f824ae8eeea5f837eb3038cef3615075d996d3e82eb9187192c2820605a81", + "https://bcr.bazel.build/modules/apple_support/2.5.4/MODULE.bazel": "964e9268b37edb64e9a0fa525e5b5e535ba56bf63cadc68375f92e69fcb734f6", + "https://bcr.bazel.build/modules/apple_support/2.8.0/MODULE.bazel": "c45f5176057092afba0be6c48a9ea02101666802f8be536947e099e94757f8ed", + "https://bcr.bazel.build/modules/apple_support/2.8.4/MODULE.bazel": "83ae0682db2a4ea86d20416a9b3bdba7f6c2a81e136b4d210e5986e30436585e", + "https://bcr.bazel.build/modules/apple_support/2.8.4/source.json": "1c9c86472ed56669622b46e2ddfeb36f58e1234cea73d52740f09de58e93ec6e", + "https://bcr.bazel.build/modules/aspect_bazel_lib/1.31.2/MODULE.bazel": "7bee702b4862612f29333590f4b658a5832d433d6f8e4395f090e8f4e85d442f", + "https://bcr.bazel.build/modules/aspect_bazel_lib/1.38.0/MODULE.bazel": "6307fec451ba9962c1c969eb516ebfe1e46528f7fa92e1c9ac8646bef4cdaa3f", + "https://bcr.bazel.build/modules/aspect_bazel_lib/1.40.3/MODULE.bazel": "668e6bcb4d957fc0e284316dba546b705c8d43c857f87119619ee83c4555b859", + "https://bcr.bazel.build/modules/aspect_bazel_lib/1.42.3/MODULE.bazel": "e4529e12d8cd5b828e2b5960d07d3ec032541740d419d7d5b859cabbf5b056f9", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.11.0/MODULE.bazel": "cb1ba9f9999ed0bc08600c221f532c1ddd8d217686b32ba7d45b0713b5131452", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.21.2/MODULE.bazel": "276347663a25b0d5bd6cad869252bea3e160c4d980e764b15f3bae7f80b30624", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.5/MODULE.bazel": "004ba890363d05372a97248c37205ae64b6fa31047629cd2c0895a9d0c7779e8", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.5/source.json": "ac2c3213df8f985785f1d0aeb7f0f73d5324e6e67d593d9b9470fb74a25d4a9b", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.0/MODULE.bazel": "2ee4360a135da51ec06ca49cc4310f5a4c2839118f38ea8417f7f2db56967285", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.7/MODULE.bazel": "491f8681205e31bb57892d67442ce448cda4f472a8e6b3dc062865e29a64f89c", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.9.3/MODULE.bazel": "66baf724dbae7aff4787bf2245cc188d50cb08e07789769730151c0943587c14", + "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.21.0/MODULE.bazel": "77dc393c43ad79398b05865444c5200c6f1aae6765615544f2c7730b5858d533", + "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.21.0/source.json": "062b1d3dba8adcfeb28fe60c185647f5a53ec0487ffe93cf0ae91566596e4b49", + "https://bcr.bazel.build/modules/aspect_rules_js/1.33.1/MODULE.bazel": "db3e7f16e471cf6827059d03af7c21859e7a0d2bc65429a3a11f005d46fc501b", + "https://bcr.bazel.build/modules/aspect_rules_js/1.39.0/MODULE.bazel": "aece421d479e3c31dc3e5f6d49a12acc2700457c03c556650ec7a0ff23fc0d95", + "https://bcr.bazel.build/modules/aspect_rules_js/1.42.0/MODULE.bazel": "f19e6b4a16f77f8cf3728eac1f60dbfd8e043517fd4f4dbf17a75a6c50936d62", + "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5", + "https://bcr.bazel.build/modules/aspect_rules_js/2.3.8/MODULE.bazel": "74bf20a7a6bd5f2be09607fdb4196cfd6f203422ea271752ec2b1afe95426101", + "https://bcr.bazel.build/modules/aspect_rules_js/2.3.8/source.json": "411ec9d79d6f5fe8a083359588c21d01a5b48d88a2cbd334a4c90365015b7836", + "https://bcr.bazel.build/modules/aspect_rules_lint/0.12.0/MODULE.bazel": "e767c5dbfeb254ec03275a7701b5cfde2c4d2873676804bc7cb27ddff3728fed", + "https://bcr.bazel.build/modules/aspect_rules_ts/3.6.0/MODULE.bazel": "d0045b5eabb012be550a609589b3e5e47eba682344b19cfd9365d4d896ed07df", + "https://bcr.bazel.build/modules/aspect_rules_ts/3.6.0/source.json": "5593e3f1cd0dd5147f7748e163307fd5c2e1077913d6945b58739ad8d770a290", + "https://bcr.bazel.build/modules/aws-c-auth-testdata/0.10.4.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/bazel-compdb/0.0.0-20220906-4086479.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/bazel_features/0.1.0/MODULE.bazel": "47011d645b0f949f42ee67f2e8775188a9cf4a0a1528aa2fa4952f2fd00906fd", + "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.13.0/MODULE.bazel": "c14c33c7c3c730612bdbe14ebbb5e61936b6f11322ea95a6e91cd1ba962f94df", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.20.0/MODULE.bazel": "8b85300b9c8594752e0721a37210e34879d23adc219ed9dc8f4104a4a1750920", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", + "https://bcr.bazel.build/modules/bazel_features/1.25.0/MODULE.bazel": "e2e60a10a6da64bbf533f15ca652bf61a033e41c2ed734d79a9a08ba87f68c1a", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.32.0/MODULE.bazel": "095d67022a58cb20f7e20e1aefecfa65257a222c18a938e2914fd257b5f1ccdc", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", + "https://bcr.bazel.build/modules/bazel_features/1.34.0/MODULE.bazel": "e8475ad7c8965542e0c7aac8af68eb48c4af904be3d614b6aa6274c092c2ea1e", + "https://bcr.bazel.build/modules/bazel_features/1.36.0/MODULE.bazel": "596cb62090b039caf1cad1d52a8bc35cf188ca9a4e279a828005e7ee49a1bec3", + "https://bcr.bazel.build/modules/bazel_features/1.38.0/MODULE.bazel": "f9b8a9c890ebd216b4049fd12a31d3c2602e3403c7af636b04fbbd7453edc9c9", + "https://bcr.bazel.build/modules/bazel_features/1.39.0/MODULE.bazel": "28739425c1fc283c91931619749c832b555e60bcd1010b40d8441ce0a5cf726d", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.43.0/MODULE.bazel": "defa2226f06ba20550d6548c3a2ea2a7929634437a52973869c20c225450eb91", + "https://bcr.bazel.build/modules/bazel_features/1.45.0/MODULE.bazel": "7daec6d87ab0703417486d4cb948af0b06f55d4d7c08cbb5978c80e79b538edf", + "https://bcr.bazel.build/modules/bazel_features/1.47.0/MODULE.bazel": "e34df3cb35b1684cfa69923a61ae3803595babd3942cd306a488d51400886b30", + "https://bcr.bazel.build/modules/bazel_features/1.47.1/MODULE.bazel": "e6be691539341681678a68c2076771f6a73fcdc9823c5b6bf280d2e916d1ad80", + "https://bcr.bazel.build/modules/bazel_features/1.50.0/MODULE.bazel": "2083ef9c7a469f520890483ccf8e0189d6e71e2117e7752e15e6554433d5ae3e", + "https://bcr.bazel.build/modules/bazel_features/1.51.0/MODULE.bazel": "8e1310d09db6ee2e4f19f9994e360aca941ddc32083edc8d9bdc19c83c94cee4", + "https://bcr.bazel.build/modules/bazel_features/1.51.0/source.json": "d5af1f1748d2b4ace5f04087030c0a1cfd93f5be6bdf0b5c1beb24ed0fd24955", + "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0-rc.0/MODULE.bazel": "d6e00979a98ac14ada5e31c8794708b41434d461e7e7ca39b59b765e6d233b18", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", + "https://bcr.bazel.build/modules/bazel_lib/3.1.0/MODULE.bazel": "6809765c14e3c766a9b9286c7b0ec56ed87a73326e48fe01749f0c0fdcfe3287", + "https://bcr.bazel.build/modules/bazel_lib/3.2.0/MODULE.bazel": "39b50d94b9be6bda507862254e20c263f9b950e3160112348d10a938be9ce2c2", + "https://bcr.bazel.build/modules/bazel_lib/3.2.2/MODULE.bazel": "e2c890c8a515d6bca9c66d47718aa9e44b458fde64ec7204b8030bf2d349058c", + "https://bcr.bazel.build/modules/bazel_lib/3.2.2/source.json": "9e84e115c20e14652c5c21401ae85ff4daa8702e265b5c0b3bf89353f17aa212", + "https://bcr.bazel.build/modules/bazel_linux_packages/0.4.1/MODULE.bazel": "9bcd612b78aa98db07f01ca7edc3129148aced24d3726884bba1f321031e724d", + "https://bcr.bazel.build/modules/bazel_linux_packages/0.4.1/source.json": "f3bbbf0f046fbc692b5e00f317088c6163b1874213027f1047bf505a1b9c647b", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.0/MODULE.bazel": "2ab127ef8d56a739a99bb2ce00ec4c7d1ecc7977d4370c0ca6efd0d8f03d6d99", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.0/MODULE.bazel": "2fb3fb53675f6adfc1ca5bfbd5cfb655ae350fba4706d924a8ec7e3ba945671c", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.9.0/MODULE.bazel": "72997b29dfd95c3fa0d0c48322d05590418edef451f8db8db5509c57875fb4b7", + "https://bcr.bazel.build/modules/bazel_skylib/1.9.2/MODULE.bazel": "8c51259b0f4481475586dbfede7591e57b75702e637f840f6138eec80c34b270", + "https://bcr.bazel.build/modules/bazel_skylib/1.9.2/source.json": "41cbde7546542dee2f26e3f10bf1c4ac57909943194b7ac48cc5238a01893aa8", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.1/MODULE.bazel": "02a13b77321773b2042e70ee5e4c5e099c8ddee4cf2da9cd420442c36938d4bd", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.4/MODULE.bazel": "460aa12d01231a80cce03c548287b433b321d205b0028ae596728c35e5ee442e", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/MODULE.bazel": "396c1ef53835aafe3d42ce6619080531ee770648303731f16cfaa33fa056bf0c", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/source.json": "abaf8ac9d2ab2f47bda9af4c0c080ff7907378888e1f4bc62a0539dd13ba61e8", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.4/MODULE.bazel": "82494a01018bb7ef06d4a17ec4cd7a758721f10eb8b6c820a818e70d669500db", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/MODULE.bazel": "e76479eae70bd4e8f5f4c2dfc5d03ab971cfb18750246c7b3f3454c5c2ee6629", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/source.json": "9395c4679444bc47bf7e51a710366a4480aa371c6f6bed01868e2fabcf11acec", + "https://bcr.bazel.build/modules/boost.headers/1.89.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/boringssl-fips/0.20260929.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/boringssl-source/0.20260929.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/boringssl/0.20260929.0/MODULE.bazel": "6e1f31b52510f9cb78a6ac24035617a091664ea3b086af5a2d50057e98619e04", + "https://bcr.bazel.build/modules/boringssl/0.20260929.0/source.json": "fac11c1605b2d83da089d954ff10faf1b3db92715de819e032e9265d2a3b2018", + "https://bcr.bazel.build/modules/brotli/1.1.0/MODULE.bazel": "3b5b90488995183419c4b5c9b063a164f6c0bc4d0d6b40550a612a5e860cc0fe", + "https://bcr.bazel.build/modules/brotli/1.2.0-260930-42a2ed4.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/buildifier_prebuilt/10.0.1/MODULE.bazel": "5befcf0b6bf57fdf132ae6f4b19a43a766a78a09d017031edcac38dbac8817e1", + "https://bcr.bazel.build/modules/buildifier_prebuilt/10.1.0/MODULE.bazel": "14a31f06bf9eff863107fe5dfd9ebde3123d8fa57fa9fe3477cff187b67c2972", + "https://bcr.bazel.build/modules/buildifier_prebuilt/10.1.0/source.json": "984c35566e7637562e96e2ae9fa65a34982a76b612bdff8408c46a85e847eea7", + "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84", + "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", + "https://bcr.bazel.build/modules/bzip2/1.0.8/MODULE.bazel": "83ee443b286b0b91566e5ee77e74ba6445895f3135467893871560f9e4ebc159", + "https://bcr.bazel.build/modules/bzip2/1.0.8/source.json": "b64f3a2f973749cf5f6ee32b3d804af56a35a746228a7845ed5daa31c8cc8af1", + "https://bcr.bazel.build/modules/c-ares/1.15.0/MODULE.bazel": "ba0a78360fdc83f02f437a9e7df0532ad1fbaa59b722f6e715c11effebaa0166", + "https://bcr.bazel.build/modules/c-ares/1.16.1/MODULE.bazel": "145c2d47cfc2ada6991f4fbd81ef8b48af576a687b3bf17bd8f617ef59a4fe3c", + "https://bcr.bazel.build/modules/c-ares/1.19.1/MODULE.bazel": "73bca21720772370ff91cc8e88bbbaf14897720c6473e87c1ddc0f848284c313", + "https://bcr.bazel.build/modules/c-ares/1.34.6.bcr.1/MODULE.bazel": "86b9367ece200829ddb943aaec050de621b290a09f8d9055585b159743254a5f", + "https://bcr.bazel.build/modules/c-ares/1.34.6.bcr.1/source.json": "67453e911b15d825c82cf6a39bbdccf1729b473fadd460c3bcae55024c48982e", + "https://bcr.bazel.build/modules/c4core/0.5.0/MODULE.bazel": "6f59de982e2ef2bea13f01b4ec8ac5cde012749063c051d7d927b43abd28543d", + "https://bcr.bazel.build/modules/c4core/0.5.0/source.json": "e01a9fca38b42c874e2860b6bcbb028237c0c2f9bd2deda185f41b10fe633573", + "https://bcr.bazel.build/modules/cel-cpp/0.16.1.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/cel-spec/0.15.0/MODULE.bazel": "e1eed53d233acbdcf024b4b0bc1528116d92c29713251b5154078ab1348cb600", + "https://bcr.bazel.build/modules/cel-spec/0.24.0/MODULE.bazel": "e310c7aff8490ed689ccafd32729b77a660b9547f5a5ba9b20e967011c324b36", + "https://bcr.bazel.build/modules/cel-spec/0.25.1/MODULE.bazel": "72d9f7a9cdf072c659a1afa145d217b42f51fb40ab2dfa348f8e3e6686a3931a", + "https://bcr.bazel.build/modules/cel-spec/0.25.3/MODULE.bazel": "210933f78fabfc789f31febc214fba9888d9e00b165669d3e02838cce97eca37", + "https://bcr.bazel.build/modules/cel-spec/0.25.3/source.json": "24917050fdda1a4e00d6f7f18dd4fb1c0e73f0555afd86b43e28337a2b7cb97e", + "https://bcr.bazel.build/modules/civetweb/1.16.bcr.1/MODULE.bazel": "d4cd273eae3ab919f6ae2eb7da3692e9bc1420346f645916290d4d8688b1bd06", + "https://bcr.bazel.build/modules/civetweb/1.16.bcr.1/source.json": "a2dddab6e51dfbf8480a43a6a5d7272f88cb4cde53a5b6ebcd13ca76b1b68721", + "https://bcr.bazel.build/modules/civetweb/1.16/MODULE.bazel": "46a38f9daeb57392e3827fce7d40926be0c802bd23cdd6bfd3a96c804de42fae", + "https://bcr.bazel.build/modules/cmake_configure_file/0.1.4/MODULE.bazel": "07acee851bb68a1a1dc5d09e7a454a5166fa86341738df49752843b65fb0d275", + "https://bcr.bazel.build/modules/cmake_configure_file/0.1.4/source.json": "78b94a44bdca0c7f7c8a4d446122671e5cadaa74ac4db2bfcc195089bdd751a1", + "https://bcr.bazel.build/modules/colm/0.14.7-211228-2d8ba76.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/cpp-httplib/0.22.0/MODULE.bazel": "ae52a6b756b927694d99fd69328245763106361bfca873eec09194d92349f2a8", + "https://bcr.bazel.build/modules/cpp-httplib/0.22.0/source.json": "949832f5919eb3e3771e0b03a9ce65a20b4bcc36be9bbce7e82435aaab01ea61", + "https://bcr.bazel.build/modules/cpp2sky/0.6.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/curl/8.12.0.bcr.1/MODULE.bazel": "4f44af081ff8e3ae3fe09bf60da815002320fb4d27f0c3013c4057db4beef591", + "https://bcr.bazel.build/modules/curl/8.21.0.bcr.1/MODULE.bazel": "f55df5f829919eddbb235c79fd58e8acb99d4dd38d692588080e9c29dd5076e3", + "https://bcr.bazel.build/modules/curl/8.21.0.bcr.1/source.json": "a29d0712a994f5c42d21b170c016e9880b400fb9170181194796bed7959382de", + "https://bcr.bazel.build/modules/curl/8.4.0/MODULE.bazel": "0bc250aa1cb69590049383df7a9537c809591fcf876c620f5f097c58fdc9bc10", + "https://bcr.bazel.build/modules/curl/8.7.1/MODULE.bazel": "088221c35a2939c555e6e47cb31a81c15f8b59f4daa8009b1e9271a502d33485", + "https://bcr.bazel.build/modules/curl/8.8.0/MODULE.bazel": "7da3b3e79b0b4ee8f8c95d640bc6ad7b430ce66ef6e9c9d2bc29b3b5ef85f6fe", + "https://bcr.bazel.build/modules/cython/3.0.11-1/MODULE.bazel": "868b3f5c956c3657420d2302004c6bb92606bfa47e314bab7f2ba0630c7c966c", + "https://bcr.bazel.build/modules/cython/3.0.11-1/source.json": "da318be900b8ca9c3d1018839d3bebc5a8e1645620d0848fa2c696d4ecf7c296", + "https://bcr.bazel.build/modules/dd-trace-cpp/2.1.1.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/dragonbox/0.0.0-241028-6c7c925.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/elfutils/0.196.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/emsdk/4.0.23.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/envoy_toolshed/0.5.3.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/envoy_toolshed_jq/0.5.3.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/fast_float/8.0.2/MODULE.bazel": "43504664efdfa4c6cf1349626c87135c9b87926325c720458f396eee25568eda", + "https://bcr.bazel.build/modules/fast_float/8.2.4/MODULE.bazel": "38f33a09e0c1f4d91aa68f2434e13d1d1b3e4a1522078204a389bb264c781a73", + "https://bcr.bazel.build/modules/fast_float/8.2.4/source.json": "ce06290cf97317011fe09366b7cfef8d9de3413cdf8f343d95a493865f62e6ec", + "https://bcr.bazel.build/modules/flatbuffers/25.12.19/MODULE.bazel": "fe3a7f7811f43264f68136ad99e64384d70b2a25245e09ab800c4bb83171da25", + "https://bcr.bazel.build/modules/flatbuffers/25.12.19/source.json": "ea0204be7a79de9141cee5fa436e58a14e88b39b5b59227b21efa0394474ebea", + "https://bcr.bazel.build/modules/flatbuffers/25.9.23/MODULE.bazel": "32753ba60bf3bacfe7737c0f3e8e3e55624b19af5d398c485580d57492d145d8", + "https://bcr.bazel.build/modules/fmt/10.0.0/MODULE.bazel": "7116dc51413f0ccde10774ff1be34a94710890d47549694a2feaafaa92f2b23b", + "https://bcr.bazel.build/modules/fmt/12.1.0/MODULE.bazel": "c6b460c936f408b371bf12ccee5ecbd5aed8f6abfb6e8b63fad0c622715fd458", + "https://bcr.bazel.build/modules/fmt/12.2.0/MODULE.bazel": "4dfeae41549da5454feb6ba20ef6313a4121eff976e1696ef622fe296c1652c6", + "https://bcr.bazel.build/modules/fmt/12.2.0/source.json": "783ecf1e5b0d6f5faa61123e92f8f2875fb9cf4df73457885808ce72873cc43c", + "https://bcr.bazel.build/modules/fmt/8.1.1/MODULE.bazel": "0f55e72316f1593d78998e2dc2ddf2d80697c226c43dc66e4bf2e2e9fd99f52d", + "https://bcr.bazel.build/modules/fp16/0.0.0-260704-3d2de18.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/fuzztest/20241028.0/MODULE.bazel": "55ccf828e88fb6ef6aa7fc477f7d0d442c5e740f8c7581294862645069b4a88d", + "https://bcr.bazel.build/modules/fuzztest/20241028.0/source.json": "dc9bc5801d78274b062ee1dc1a27a0e1e63f8bd505cd46cc1e914a62c0f5c274", + "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8", + "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/source.json": "fa7b512dfcb5eafd90ce3959cf42a2a6fe96144ebbb4b3b3928054895f2afac2", + "https://bcr.bazel.build/modules/gazelle/0.27.0/MODULE.bazel": "3446abd608295de6d90b4a8a118ed64a9ce11dcb3dda2dc3290a22056bd20996", + "https://bcr.bazel.build/modules/gazelle/0.30.0/MODULE.bazel": "f888a1effe338491f35f0e0e85003b47bb9d8295ccba73c37e07702d8d31c65b", + "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", + "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", + "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", + "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", + "https://bcr.bazel.build/modules/gazelle/0.37.0/MODULE.bazel": "d1327ba0907d0275ed5103bfbbb13518f6c04955b402213319d0d6c0ce9839d4", + "https://bcr.bazel.build/modules/gazelle/0.39.1/MODULE.bazel": "1fa3fefad240e535066fd0e6950dfccd627d36dc699ee0034645e51dbde3980f", + "https://bcr.bazel.build/modules/gazelle/0.40.0/MODULE.bazel": "42ba5378ebe845fca43989a53186ab436d956db498acde790685fe0e8f9c6146", + "https://bcr.bazel.build/modules/gazelle/0.45.0/MODULE.bazel": "ecd19ebe9f8e024e1ccffb6d997cc893a974bcc581f1ae08f386bdd448b10687", + "https://bcr.bazel.build/modules/gazelle/0.46.0/MODULE.bazel": "3dec215dacf2427df87b524a2c99da387882a18d753f0b1b38675992bd0a99c6", + "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", + "https://bcr.bazel.build/modules/gazelle/0.51.3/MODULE.bazel": "618a729142f66de1e2cb776d026413763be5b80d5e3d29ffb9d3d90c5defde90", + "https://bcr.bazel.build/modules/gazelle/0.54.0/MODULE.bazel": "10620287bdf57c55c2321ed5a387ade11c7187aba444fdec583c9f21c3263f45", + "https://bcr.bazel.build/modules/gazelle/0.54.0/source.json": "6c9639ac87508c7edea37bd9d5380581c96defde056ca26518d201a8816805e4", + "https://bcr.bazel.build/modules/gloop/20260708.rc1/MODULE.bazel": "279ffe031c3e905d6c175ccbc10cf8f7e4418a39eaf2bbc950f385e8adad64e2", + "https://bcr.bazel.build/modules/gloop/20260708.rc1/source.json": "5479fb0b525efab73f527cf0267a55c29123e8e59b8e8c6b693d80d18704b206", + "https://bcr.bazel.build/modules/go-fips/1.27.1.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/google_benchmark/1.8.3/MODULE.bazel": "2349ac3adb7917fdc4378e85fae533015dae3cb583ad1bd5d2c2185106c7c403", + "https://bcr.bazel.build/modules/google_benchmark/1.8.4/MODULE.bazel": "c6d54a11dcf64ee63545f42561eda3fd94c1b5f5ebe1357011de63ae33739d5e", + "https://bcr.bazel.build/modules/google_benchmark/1.8.5/MODULE.bazel": "9ba9b31b984022828a950e3300410977eda2e35df35584c6b0b2d0c2e52766b7", + "https://bcr.bazel.build/modules/google_benchmark/1.9.2/MODULE.bazel": "1d30f717f00d5f18e7d8e55d18573bab80651d75b40e3391af2992cd2568577a", + "https://bcr.bazel.build/modules/google_benchmark/1.9.5/MODULE.bazel": "8a85cfd90b1e45e6e68f1aa2aa9efce3c04add57df732571d7fd54c07e7c5143", + "https://bcr.bazel.build/modules/google_benchmark/1.9.5/source.json": "0bd357fd9db30ee31d5eb4c78b1086ce3d79b4423ce76de19e8a2fa7b2fa2e10", + "https://bcr.bazel.build/modules/googleapis-cc/1.0.0/MODULE.bazel": "cf01757e7590c56140a4b81638ff2b3e7074769e6271720bbf738fcda25b6fc2", + "https://bcr.bazel.build/modules/googleapis-cc/1.0.0/source.json": "ab0e3a2ee9968a8848f59872fbbfa3e1f768597d71d2229e6caa319d357967c7", + "https://bcr.bazel.build/modules/googleapis-go/1.0.0/MODULE.bazel": "0a207a4c49da28c5cc1f7b3aeb23c2f7828c85c14aa8d9db0e30357a8d2250ed", + "https://bcr.bazel.build/modules/googleapis-go/1.0.0/source.json": "ef189be4e7853e1ebc6123fe20b71822bf9896bd1f8eed8f68505c4585f72a48", + "https://bcr.bazel.build/modules/googleapis-grpc-cc/1.0.0/MODULE.bazel": "3553358a9d8d96026c9e28d9fb6c268574950d0be7fa9b4c0aeaf3c37c73f2d3", + "https://bcr.bazel.build/modules/googleapis-grpc-cc/1.0.0/source.json": "fa7b79043b3c82bf74f1f2fa45af289e19b247375868d0752db2c114a1c7366c", + "https://bcr.bazel.build/modules/googleapis-java/1.0.0/MODULE.bazel": "d633989337d069b5a95e6101777319681d7a4af4677e36801f11839d6512095c", + "https://bcr.bazel.build/modules/googleapis-java/1.0.0/source.json": "ee59e2de37e4b531172870ac0296afa38f1ea004105ee21b2793c31a9d0ddccd", + "https://bcr.bazel.build/modules/googleapis-python/1.0.0/MODULE.bazel": "0ccd1614a914fb524b3ac267f9c97f9a5cd5412b027f0176b81a725882ec42ff", + "https://bcr.bazel.build/modules/googleapis-python/1.0.0/source.json": "24364f075ec5e6d5e0cfc5d651bd833b119e0cea1a45d51330c93461e3586e42", + "https://bcr.bazel.build/modules/googleapis-rules-registry/1.0.0/MODULE.bazel": "97c6a4d413b373d4cc97065da3de1b2166e22cbbb5f4cc9f05760bfa83619e24", + "https://bcr.bazel.build/modules/googleapis-rules-registry/1.0.0/source.json": "cf611c836a60e98e2e2ab2de8004f119e9f06878dcf4ea2d95a437b1b7a89fe9", + "https://bcr.bazel.build/modules/googleapis/0.0.0-20240326-1c8d509c5/MODULE.bazel": "a4b7e46393c1cdcc5a00e6f85524467c48c565256b22b5fae20f84ab4a999a68", + "https://bcr.bazel.build/modules/googleapis/0.0.0-20240819-fe8ba054a/MODULE.bazel": "117b7c7be7327ed5d6c482274533f2dbd78631313f607094d4625c28203cacdf", + "https://bcr.bazel.build/modules/googleapis/0.0.0-20241220-5e258e33.bcr.1/MODULE.bazel": "ee6c30f82ecd476e61f019fb1151aaab380ea419958ff274ef2f0efca7969f5c", + "https://bcr.bazel.build/modules/googleapis/0.0.0-20251003-2193a2bf/MODULE.bazel": "cc9e5ed294ed9ebf42cdbbdddd2df29048519e3797004df1e3f369f31ff4f2d4", + "https://bcr.bazel.build/modules/googleapis/0.0.0-20251003-2193a2bf/source.json": "21558a194c519e27262cca9cf031bb166a666a8b7fb89993b700c828f8dc0857", + "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.13.0/MODULE.bazel": "369533f4a302dc7d9ad1cd9a09a9e820a1d9a4011fad2dfa636b5bb225b9a6c7", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", + "https://bcr.bazel.build/modules/googletest/1.16.0/MODULE.bazel": "a175623c69e94fca4ca7acbc12031e637b0c489318cd4805606981d4d7adb34a", + "https://bcr.bazel.build/modules/googletest/1.17.0.bcr.2/MODULE.bazel": "827f54f492a3ce549c940106d73de332c2b30cebd0c20c0bc5d786aba7f116cb", + "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", + "https://bcr.bazel.build/modules/googletest/1.18.0.bcr.1/MODULE.bazel": "b489ffe6790bb6a3544b64c7604cbbea8a5529574cd4697dac227472656cea2b", + "https://bcr.bazel.build/modules/googletest/1.18.0.bcr.1/source.json": "963014628876b76748ab3babb368f53ff4afe6ee327bf9fc1e893e62757b6ac4", + "https://bcr.bazel.build/modules/googletest/1.18.0/MODULE.bazel": "00f855225d5746ca0d59965b09762e278b7259a6dfb7840d1b034ab60e72921e", + "https://bcr.bazel.build/modules/googleurl/0.0.0-221103-dd4080f.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/gperftools/2.18.1/MODULE.bazel": "2bfde64989ae531d9fd9da9c2ccfff1212eafcfcb26b0594b59667d0190b6252", + "https://bcr.bazel.build/modules/gperftools/2.18.1/source.json": "3425124f51a743ab03b3145f55bff4c0d255b5311b4ca54886db79ea461ebedb", + "https://bcr.bazel.build/modules/grpc-httpjson-transcoding/0.0.0-20250507-a6e226f.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/grpc-java/1.62.2/MODULE.bazel": "99b8771e8c7cacb130170fed2a10c9e8fed26334a93e73b42d2953250885a158", + "https://bcr.bazel.build/modules/grpc-java/1.66.0/MODULE.bazel": "86ff26209fac846adb89db11f3714b3dc0090fb2fb81575673cc74880cda4e7e", + "https://bcr.bazel.build/modules/grpc-java/1.69.0/MODULE.bazel": "53887af6a00b3b406d70175d3d07e84ea9362016ff55ea90b9185f0227bfaf98", + "https://bcr.bazel.build/modules/grpc-proto/0.0.0-20240627-ec30f58/MODULE.bazel": "88de79051e668a04726e9ea94a481ec6f1692086735fd6f488ab908b3b909238", + "https://bcr.bazel.build/modules/grpc/1.41.0/MODULE.bazel": "5bcbfc2b274dabea628f0649dc50c90cf36543b1cfc31624832538644ad1aae8", + "https://bcr.bazel.build/modules/grpc/1.56.3.bcr.1/MODULE.bazel": "cd5b1eb276b806ec5ab85032921f24acc51735a69ace781be586880af20ab33f", + "https://bcr.bazel.build/modules/grpc/1.62.1/MODULE.bazel": "2998211594b8a79a6b459c4e797cfa19f0fb8b3be3149760ec7b8c99abfd426f", + "https://bcr.bazel.build/modules/grpc/1.63.1.bcr.1/MODULE.bazel": "d7b9fef03bd175e6825237b521b18a3c29f1ac15f8aa52c8a1a0f3bd8f33d54b", + "https://bcr.bazel.build/modules/grpc/1.66.0.bcr.2/MODULE.bazel": "0fa2b0fd028ce354febf0fe90f1ed8fecfbfc33118cddd95ac0418cc283333a0", + "https://bcr.bazel.build/modules/grpc/1.66.0.bcr.3/MODULE.bazel": "f6047e89faf488f5e3e65cb2594c6f5e86992abec7487163ff6b623526e543b0", + "https://bcr.bazel.build/modules/grpc/1.68.0/MODULE.bazel": "6691126221dbfd615990cc81d0d9705b74937dbc4206fb9921cb0fc7b4fd4c6a", + "https://bcr.bazel.build/modules/grpc/1.69.0/MODULE.bazel": "4e26e05c9e1ef291ccbc96aad8e457b1b8abedbc141623831629da2f8168eef6", + "https://bcr.bazel.build/modules/grpc/1.70.1/MODULE.bazel": "b800cd8e3e7555c1e61cba2e02d3a2fcf0e91f66e800db286d965d3b7a6a721a", + "https://bcr.bazel.build/modules/grpc/1.71.0/MODULE.bazel": "7fcab2c05530373f1a442c362b17740dd0c75b6a2a975eec8f5bf4c70a37928a", + "https://bcr.bazel.build/modules/grpc/1.74.1/MODULE.bazel": "09523be10ba2bfd999683671d0f8f22fb5b20ec77ad89b05ef58ff19a1b65c82", + "https://bcr.bazel.build/modules/grpc/1.80.0/MODULE.bazel": "35ef253a0a31055c8a2495640516224647545b51673b0ccb956b116ee92ef554", + "https://bcr.bazel.build/modules/grpc/1.83.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/hessian2-codec/0.0.0-250114-6f5a647.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/highway/1.2.0/MODULE.bazel": "605dc84b4931a409f16d920409dc38718798754c1afa4c80115a32118d67acb3", + "https://bcr.bazel.build/modules/highway/1.2.0/source.json": "01a2c7e56a1850a28c0026c0adc32e52db44c6a1df142b3f88b2a3747a5bff7d", + "https://bcr.bazel.build/modules/highwayhash/0.0.0-20240305-5ad3bf8/MODULE.bazel": "5c7f29d5bd70feff14b0f65b39584957e18e4a8d555e5a29a4c36019afbb44b9", + "https://bcr.bazel.build/modules/highwayhash/0.0.0-20240305-5ad3bf8/source.json": "211c0937ef5f537da6c3c135d12e60927c71b380642e207e4a02b86d29c55e85", + "https://bcr.bazel.build/modules/hyperscan/5.4.2.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/icu/78.2.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/ipp-crypto/2.2.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/jemalloc/5.3.0-bcr.4/MODULE.bazel": "1b8f4135f785f7277207ff99795a12482d8623f6ce038ec11175900088bceecf", + "https://bcr.bazel.build/modules/jemalloc/5.3.0-bcr.4/source.json": "1ee14acb7c059e13402ce1d5ab9b4a05d05eac89f8d13a0052b8911bf1d0aede", + "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", + "https://bcr.bazel.build/modules/jq.bzl/0.4.0/MODULE.bazel": "a7b39b37589f2b0dad53fd6c1ccaabbdb290330caa920d7ef3e6aad068cd4ab2", + "https://bcr.bazel.build/modules/jq.bzl/0.4.0/source.json": "52ec7530c4618e03f634b30ff719814a68d7d39c235938b7aa2abbfe1eb1c52c", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6.bcr.2/MODULE.bazel": "64f508885f907ac2518039b3d0c5c1703a8f6137d9f5d635067ba93d33c2670a", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6.bcr.2/source.json": "13199fa0a267ca46814e9e6ab313a71890c8f1822e57376fdc23a2d2cd384051", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", + "https://bcr.bazel.build/modules/kafka/3.9.2.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/libbpf/1.7.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/libcircllhist/0.3.2.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/libevent/2.2.2-alpha.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/libmaxminddb/1.12.2/MODULE.bazel": "2387524b4c17ab33285187bb9596ff0a8e1c9ffe938b3ddc9866d6ff791f6bbe", + "https://bcr.bazel.build/modules/libmaxminddb/1.12.2/source.json": "a0463895650ed75a4b73c7834af6dbd4f9083e7b486102933abe83dd12cecb04", + "https://bcr.bazel.build/modules/libpfm/4.11.0.bcr.1/MODULE.bazel": "e5362dadc90aab6724c83a2cc1e67cbed9c89a05d97fb1f90053c8deb1e445c8", + "https://bcr.bazel.build/modules/libpfm/4.11.0.bcr.1/source.json": "0646414d9037f8aad148781dd760bec90b0b25ac12fda5e03f8aadbd6b9c61e6", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/libprotobuf-mutator/1.5.bcr.1/MODULE.bazel": "148dd93e6eb15d32984af052c829cf7a5078911cd620b672fcd8bd4358171611", + "https://bcr.bazel.build/modules/libprotobuf-mutator/1.5.bcr.1/source.json": "14e129dcbff9b660e44bc55fda0d5000c8ee842b8aabd341d081ecd70383ce1c", + "https://bcr.bazel.build/modules/librdkafka/2.15.0/MODULE.bazel": "fb0b967462e8ab4531f38bb78b759eb758a5e120b94b3a16d9724a10547d41ac", + "https://bcr.bazel.build/modules/librdkafka/2.15.0/source.json": "f2b2f7240884946edffb820d9b1d2ad536de5c7f2ea220bfbb0b629e96dee4af", + "https://bcr.bazel.build/modules/libsxg/0.0.0-210708-beaa393.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/libunwind/1.8.3/MODULE.bazel": "ecc153c0d2f661fd730243439b2ca454968f21b7e73ff5f1ff1545b70e87a8a7", + "https://bcr.bazel.build/modules/libunwind/1.8.3/source.json": "8bba6459bed0b337c50f554292d724e2736edf906379556fa56a8a57d5a5299d", + "https://bcr.bazel.build/modules/liburing/2.15.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/luajit/0.0.0-260126-871db2c.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/lz4/1.10.0.bcr.2.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/lz4/1.9.4/MODULE.bazel": "e3d307b1d354d70f6c809167eafecf5d622c3f27e3971ab7273410f429c7f83a", + "https://bcr.bazel.build/modules/m4/1.4.21.bcr.4/MODULE.bazel": "40fef4b9091aea8e97b76a5706b3490b8d731ba008b02a883751ee2abf84daf4", + "https://bcr.bazel.build/modules/m4/1.4.21.bcr.4/source.json": "c4add456cedd43c0c0d1329bd52120f8eedb6191c6d8299448bce1ed81be60a4", + "https://bcr.bazel.build/modules/make/4.4.1.bcr.1/MODULE.bazel": "8ade2c4f2ebfc6389f8192d031d5702e84780069a096761aa2e502089fbb30f2", + "https://bcr.bazel.build/modules/make/4.4.1.bcr.1/source.json": "dfe32147a5bc8ec7e4684e5dc753a1ebcf8084234d60c1e2ef478187727bc3ae", + "https://bcr.bazel.build/modules/mbedtls/3.6.0/MODULE.bazel": "8e380e4698107c5f8766264d4df92e36766248447858db28187151d884995a09", + "https://bcr.bazel.build/modules/mbedtls/3.6.5/MODULE.bazel": "f68edc3db5a01add21c85c2dc2211ecef43a974756656268d8171ad4fb1f30e3", + "https://bcr.bazel.build/modules/mbedtls/3.6.7/MODULE.bazel": "93022414b1cbf149efc1c904a16d6b18b03a73ee0e01518404cceeb780d22a41", + "https://bcr.bazel.build/modules/mbedtls/3.6.7/source.json": "6f805859f925f191394ee7a773a7e76c16bf53ebf011f1bbff5e03834dc3e5af", + "https://bcr.bazel.build/modules/mboworks_bzl/0.5.1/MODULE.bazel": "20c921aded4f4e00a6128dad47a843371c196ba8987474c11c8ba7b9da8c16f1", + "https://bcr.bazel.build/modules/mboworks_bzl/0.5.1/source.json": "3d9086bb203475113a16afb0ca0c9b97fdb37fc6e5a62b604b60ffc2450dc8c5", + "https://bcr.bazel.build/modules/msgpack-c/7.0.0/MODULE.bazel": "265dab2386e30faade04da04efcbd8f6c73a0fff4d6480adc9ed7ebbcb438ab0", + "https://bcr.bazel.build/modules/msgpack-c/7.0.0/source.json": "5602873d1a0c1a995aa9ac09fe09e745a058e082cccaad833cbf2788419bfb3c", + "https://bcr.bazel.build/modules/nghttp2/1.66.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/ninja/1.13.2/MODULE.bazel": "5f28c618cff63811e0d1c4d264afc4eb86b9a660bf1baca38ea385c0dbfe3d26", + "https://bcr.bazel.build/modules/ninja/1.13.2/source.json": "e6d388520a5881ab4f274c5c47a854f5ad401e9aa931da7550992ce15fd4c465", + "https://bcr.bazel.build/modules/nlohmann_json/3.11.3/MODULE.bazel": "87023db2f55fc3a9949c7b08dc711fae4d4be339a80a99d04453c4bb3998eefc", + "https://bcr.bazel.build/modules/nlohmann_json/3.12.0.bcr.1/MODULE.bazel": "a1c8bb07b5b91d971727c635f449d05623ac9608f6fe4f5f04254ea12f08e349", + "https://bcr.bazel.build/modules/nlohmann_json/3.12.0.bcr.2/MODULE.bazel": "5c5596def463aeee17e5a4848a50f02f0cf4a351fc2f0dcc4444f1d87d2d3b08", + "https://bcr.bazel.build/modules/nlohmann_json/3.12.0.bcr.2/source.json": "2b8823c08a9b22f5d516619e437059e449159e7472bffba256cced8ba74643b5", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/numactl/2.0.19/MODULE.bazel": "4905b12bdbd33fa33f16ed1084939eea0d5081ea72b5d42591c32670009ef5c6", + "https://bcr.bazel.build/modules/numactl/2.0.19/source.json": "12874a996a808a6a8afc8f6251ceb95ee3d7f8aad2054f4f3e334076dbe3ea5b", + "https://bcr.bazel.build/modules/ocp-diag-core/0.0.0-230505-e965ac0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/opencensus-cpp/0.0.0-20230502-50eb5de.bcr.2/MODULE.bazel": "cc18734138dd18c912c6ce2a59186db28f85d8058c99c9f21b46ca3e0aba0ebe", + "https://bcr.bazel.build/modules/opencensus-cpp/0.0.0-20230502-50eb5de.bcr.2/source.json": "7c135f9d42bb3b045669c3c6ab3bb3c208e00b46aca4422eea64c29811a5b240", + "https://bcr.bazel.build/modules/opencensus-cpp/0.0.0-20230502-50eb5de/MODULE.bazel": "02201d2921dadb4ec90c4980eca4b2a02904eddcf6fa02f3da7594fb7b0d821c", + "https://bcr.bazel.build/modules/opencensus-proto/0.4.1.bcr.2/MODULE.bazel": "789706a714855f92c5c8cfcf1ef32bbb64dcd3b7c9066756ad7986ec59709d29", + "https://bcr.bazel.build/modules/opencensus-proto/0.4.1.bcr.2/source.json": "aadf3f53e08b72376506b7c4ea3d167010c9efb160d7d6e1e304ed646bac1b36", + "https://bcr.bazel.build/modules/opencensus-proto/0.4.1/MODULE.bazel": "4a2e8b4d0b544002502474d611a5a183aa282251e14f6a01afe841c0c1b10372", + "https://bcr.bazel.build/modules/openssl/3.5.7.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/opentelemetry-cpp/1.14.2/MODULE.bazel": "089a5613c2a159c7dfde098dabfc61e966889c7d6a81a98422a84c51535ed17d", + "https://bcr.bazel.build/modules/opentelemetry-cpp/1.16.0/MODULE.bazel": "b7379a140f538cea3f749179a2d481ed81942cc6f7b05a6113723eb34ac3b3e7", + "https://bcr.bazel.build/modules/opentelemetry-cpp/1.19.0/MODULE.bazel": "3455326c08b28415648a3d60d8e3c811847ebdbe64474f75b25878f25585aea1", + "https://bcr.bazel.build/modules/opentelemetry-cpp/1.29.0/MODULE.bazel": "ac682468786a7767b5f15d3fccba91b38d15798f677e19a5c346da414b01ec3c", + "https://bcr.bazel.build/modules/opentelemetry-cpp/1.29.0/source.json": "5411bfcf3ee1e7b9c65954e001822a893bb7eb253b066aa679dc60de23695e29", + "https://bcr.bazel.build/modules/opentelemetry-proto/1.1.0/MODULE.bazel": "a49f406e99bf05ab43ed4f5b3322fbd33adfd484b6546948929d1316299b68bf", + "https://bcr.bazel.build/modules/opentelemetry-proto/1.3.1/MODULE.bazel": "0141a50e989576ee064c11ce8dd5ec89993525bd9f9a09c5618e4dacc8df9352", + "https://bcr.bazel.build/modules/opentelemetry-proto/1.5.0/MODULE.bazel": "7543d91a53b98e7b5b37c5a0865b93bff12c1ee022b1e322cd236b968894b030", + "https://bcr.bazel.build/modules/opentelemetry-proto/1.8.0/MODULE.bazel": "0db9b378be8c5608058d31a4bad0b2194bbb349f7ac484fdfb5ad315c58b15aa", + "https://bcr.bazel.build/modules/opentelemetry-proto/1.8.0/source.json": "407cd35e6a9ec89e542a575f4107bd637813170e68129c8f7471b341824b23e7", + "https://bcr.bazel.build/modules/opentracing-cpp/1.6.0/MODULE.bazel": "b3925269f63561b8b880ae7cf62ccf81f6ece55b62cd791eda9925147ae116ec", + "https://bcr.bazel.build/modules/opentracing-cpp/1.6.0/source.json": "da1cb1add160f5e5074b7272e9db6fd8f1b3336c15032cd0a653af9d2f484aed", + "https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92", + "https://bcr.bazel.build/modules/package_metadata/0.0.3/MODULE.bazel": "77890552ecea9e284b5424c9de827a58099348763a4359e975c359a83d4faa83", + "https://bcr.bazel.build/modules/package_metadata/0.0.5/MODULE.bazel": "ef4f9439e3270fdd6b9fd4dbc3d2f29d13888e44c529a1b243f7a31dfbc2e8e4", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/MODULE.bazel": "7adb03933fc8401f495800cf4eafcff0edc6da0ff55c7db223ef69d19f689486", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/source.json": "50639625e937b56115012674c797cca7a05a96b4878c87d803c13dc2b31de8a0", + "https://bcr.bazel.build/modules/perfetto/57.2.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/pkgconf/3.0.7/MODULE.bazel": "b40f6bfd17bebe65e7606e978417ec45ed16672cd7b2c5c43f7a55fc91aa4f0c", + "https://bcr.bazel.build/modules/pkgconf/3.0.7/source.json": "d6657631d2ee8ca9abb92f51794ed07c8bf75e75e9f5e8dc8eadbb74b8a11b9b", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", + "https://bcr.bazel.build/modules/platforms/1.1.0/MODULE.bazel": "1c0c09f5bdcf4b3f924720d2478a3711cb39f4977019ca5988685e5b7e18b3d2", + "https://bcr.bazel.build/modules/platforms/1.1.0/source.json": "fcf351c47596c939140ab0d333dfdd08ed1ea6ce33c2fe70c12493a301cf1344", + "https://bcr.bazel.build/modules/prometheus-cpp/1.2.4/MODULE.bazel": "0fbe5dcff66311947a3f6b86ebc6a6d9328e31a28413ca864debc4a043f371e5", + "https://bcr.bazel.build/modules/prometheus-cpp/1.3.0.bcr.1/MODULE.bazel": "116ad46e97c1d2aeb020fe2899a342a7e703574ce7c0faf7e4810f938c974a9a", + "https://bcr.bazel.build/modules/prometheus-cpp/1.3.0.bcr.2/MODULE.bazel": "51570a6677b34eacb44808e9e3e4552a451a184f4a8773f5bb275937955dfb41", + "https://bcr.bazel.build/modules/prometheus-cpp/1.3.0.bcr.2/source.json": "e05ed9ce09a1179566ba841a0915f71563c089a349428abf8adb3d9ebbb81190", + "https://bcr.bazel.build/modules/prometheus-cpp/1.3.0/MODULE.bazel": "ce82e086bbc0b60267e970f6a54b2ca6d0f22d3eb6633e00e2cc2899c700f3d8", + "https://bcr.bazel.build/modules/prometheus-metrics-model/0.6.2.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/proto-converter/0.0.0-20230607-d77ff30/MODULE.bazel": "2f90a76957eb1260f952182aa4b201ba09231822b7b8e3646d12df787e81baac", + "https://bcr.bazel.build/modules/proto-converter/0.0.0-20260912-3850764.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/proto-field-extraction/0.0.0-240710-d5d39f0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/proto-processing/0.0.0-250110-279353c.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a", + "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12", + "https://bcr.bazel.build/modules/protobuf/25.6/MODULE.bazel": "fc0ae073b47c7ede88b825ff79e64f1c058967c7a87a86cdf4abecd9e0516625", + "https://bcr.bazel.build/modules/protobuf/26.0.bcr.1/MODULE.bazel": "8f04d38c2da40a3715ff6bdce4d32c5981e6432557571482d43a62c31a24c2cf", + "https://bcr.bazel.build/modules/protobuf/26.0.bcr.2/MODULE.bazel": "62e0b84ca727bdeb55a6fe1ef180e6b191bbe548a58305ea1426c158067be534", + "https://bcr.bazel.build/modules/protobuf/26.0/MODULE.bazel": "8402da964092af40097f4a205eec2a33fd4a7748dc43632b7d1629bfd9a2b856", + "https://bcr.bazel.build/modules/protobuf/27.0-rc2/MODULE.bazel": "b2b0dbafd57b6bec0ca9b251da02e628c357dab53a097570aa7d79d020f107cf", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", + "https://bcr.bazel.build/modules/protobuf/27.2/MODULE.bazel": "32450b50673882e4c8c3d10a83f3bc82161b213ed2f80d17e38bece8f165c295", + "https://bcr.bazel.build/modules/protobuf/27.5/MODULE.bazel": "1723de82125423bba88590fbbbe7d84792b9de70fa2bd76e9e3d83f9d7f1640b", + "https://bcr.bazel.build/modules/protobuf/28.2/MODULE.bazel": "c0c8e51757df486d0314fa290e174d707bad4a6c2aa5ccb08a4b4abd76a23e90", + "https://bcr.bazel.build/modules/protobuf/28.3/MODULE.bazel": "2b3764bbab2e46703412bd3b859efcf0322638ed015e88432df3bb740507a1e9", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2.bcr.1/MODULE.bazel": "52f4126f63a2f0bbf36b99c2a87648f08467a4eaf92ba726bc7d6a500bbf770c", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", + "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", + "https://bcr.bazel.build/modules/protobuf/29.3/MODULE.bazel": "77480eea5fb5541903e49683f24dc3e09f4a79e0eea247414887bb9fc0066e94", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", + "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", + "https://bcr.bazel.build/modules/protobuf/30.0/MODULE.bazel": "0e736de5d52ad7824113f47e65256a26ee74b689ba859c5447a0663e5a075409", + "https://bcr.bazel.build/modules/protobuf/31.1/MODULE.bazel": "379a389bb330b7b8c1cdf331cc90bf3e13de5614799b3b52cdb7c6f389f6b38e", + "https://bcr.bazel.build/modules/protobuf/32.0/MODULE.bazel": "0741cf24f8e1185286578069060e905ed67d68eef5990bfa3dea3fc1afba14c7", + "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", + "https://bcr.bazel.build/modules/protobuf/33.0/MODULE.bazel": "c5270efb4aad37a2f893536076518793f409ea7df07a06df995d848d1690f21c", + "https://bcr.bazel.build/modules/protobuf/33.2/MODULE.bazel": "e8d408653b855e467ac7f99f2dfae8f073ae421fd4eb9a05b5ade5118d66cc3d", + "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", + "https://bcr.bazel.build/modules/protobuf/34.0.bcr.1/MODULE.bazel": "74e541b0ba877813da786a11707d4e394433c157841d5111a36be0d44b907931", + "https://bcr.bazel.build/modules/protobuf/35.0/MODULE.bazel": "ee97170c013d94c366bbb5fe8a97b0650477cbc00e5e0f6a2c297484bc34d81b", + "https://bcr.bazel.build/modules/protobuf/35.1.bcr.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/protobuf/35.1/MODULE.bazel": "9f25044d646c9c1b1e03b25aa3818bf5250078eabadbd213ea940262dba99471", + "https://bcr.bazel.build/modules/protoc-gen-validate/1.0.4.bcr.2/MODULE.bazel": "c4bd2c850211ff5b7dadf9d2d0496c1c922fdedc303c775b01dfd3b3efc907ed", + "https://bcr.bazel.build/modules/protoc-gen-validate/1.0.4/MODULE.bazel": "b8913c154b16177990f6126d2d2477d187f9ddc568e95ee3e2d50fc65d2c494a", + "https://bcr.bazel.build/modules/protoc-gen-validate/1.2.1.bcr.1/MODULE.bazel": "4bf09676b62fa587ae07e073420a76ec8766dcce7545e5f8c68cfa8e484b5120", + "https://bcr.bazel.build/modules/protoc-gen-validate/1.2.1/MODULE.bazel": "52b51f50533ec4fbd5d613cd093773f979ac2e035d954e02ca11de383f502505", + "https://bcr.bazel.build/modules/protoc-gen-validate/1.3.3.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/proxy-wasm-cpp-host/0.0.0-260704-f2db56a.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/proxy-wasm-cpp-sdk/0.0.0-250925-e5256b0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/proxy-wasm-rust-sdk/0.2.5/MODULE.bazel": "c44116b797e7f37fa3dcd379befe5b29753add6d16d7c6a02af84522960072e7", + "https://bcr.bazel.build/modules/proxy-wasm-rust-sdk/0.2.5/source.json": "a3efa79635a285eb2c9d36e3c69e138881932e03de3e240662eb7bbbd330b675", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1.bzl.1/MODULE.bazel": "1ef2994c097ee88f8f7ae8fbf991aaefb0603b2540fe575eca14943bc9f220a6", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1.bzl.3/MODULE.bazel": "a1b973f5bfa6df193ec17010c461494fae18a2b4477ff3dc8086846ca806683d", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", + "https://bcr.bazel.build/modules/pybind11_bazel/2.13.6/MODULE.bazel": "2d746fda559464b253b2b2e6073cb51643a2ac79009ca02100ebbc44b4548656", + "https://bcr.bazel.build/modules/pybind11_bazel/3.0.0/MODULE.bazel": "a2bfa6020ed603a00d944161c63173c7f109774e99bee0c2cd8dbf24159f8134", + "https://bcr.bazel.build/modules/pybind11_bazel/3.0.0/source.json": "d8f5104d4c21d272bf327ebe44366fb0b4c036cdaa1f5cceb21a408ca4ef2ef8", + "https://bcr.bazel.build/modules/qat-zstd/1.0.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/qatlib/26.02.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/qatzip/2.0.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/quiche/0.0.0-261006-9e60ac2.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/ragel/7.0.4-211228-d4577c9.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/rapidjson/1.1.0.bcr.20241007/MODULE.bazel": "82fbcb2e42f9e0040e76ccc74c06c3e46dfd33c64ca359293f8b84df0e6dff4c", + "https://bcr.bazel.build/modules/rapidjson/1.1.0.bcr.20241007/source.json": "5c42389ad0e21fc06b95ad7c0b730008271624a2fa3292e0eab5f30e15adeee3", + "https://bcr.bazel.build/modules/rapidyaml/0.15.2/MODULE.bazel": "963d4b073bdfd453fe6bc4fb2943046092230dc49a9855d78da602490913491f", + "https://bcr.bazel.build/modules/rapidyaml/0.15.2/source.json": "24770b69b08f79a7737341c5f27ae4b42f7fd7c972f390091e6006eb7408abc6", + "https://bcr.bazel.build/modules/re2/2021-09-01/MODULE.bazel": "bcb6b96f3b071e6fe2d8bed9cc8ada137a105f9d2c5912e91d27528b3d123833", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2024-02-01/MODULE.bazel": "5ed922cb8b6c110e30969695e73bd0d3159576bf17ce8ee2443a7d07bf500551", + "https://bcr.bazel.build/modules/re2/2024-04-01/MODULE.bazel": "eb949379b51784dcc859dfa3655b6e46da179837873ee05aaf7f3b811a7a03ac", + "https://bcr.bazel.build/modules/re2/2024-05-01/MODULE.bazel": "55a3f059538f381107824e7d00df5df6d061ba1fb80e874e4909c0f0549e8f3e", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", + "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", + "https://bcr.bazel.build/modules/re2/2025-08-12.bcr.1/MODULE.bazel": "e09b434b122bfb786a69179f9b325e35cb1856c3f56a7a81dd61609260ed46e1", + "https://bcr.bazel.build/modules/re2/2025-11-05.bcr.1/MODULE.bazel": "3d9d4995833fc0334fc5c88b56a05288dd25d651544cd7b2233bbd6357bbeba0", + "https://bcr.bazel.build/modules/re2/2025-11-05.bcr.1/source.json": "7df1394aabda1c9bc188a302f5d54b1c657924edd04ebc57d2be29dbd7efd141", + "https://bcr.bazel.build/modules/riegeli/0.0.0-20240606-973b6f0/MODULE.bazel": "3e8067b12d3a3bb4bc297b29c66a778af0c1da0cddbfde37d18c077ffc365602", + "https://bcr.bazel.build/modules/riegeli/0.0.0-20240606-973b6f0/source.json": "7383c71350a45496e37b4e55974fb5c9e90ec7397070a4d6fc7c9a00117f95cf", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.6.4/MODULE.bazel": "b4cde12d506dd65d82b2be39761f49f5797303343a3d5b4ee191c0cdf9ef387c", + "https://bcr.bazel.build/modules/rules_android/0.7.1/MODULE.bazel": "a806fc382a774252f228a40e3b11b9fcc6276f8778c7fb33e9f72937c6258363", + "https://bcr.bazel.build/modules/rules_android/0.7.1/source.json": "151440aed3f0f73a00d4ed5cec5d31f63a6fef9b95d8fab1eb1810150fa525f2", + "https://bcr.bazel.build/modules/rules_apple/3.13.0/MODULE.bazel": "b4559a2c6281ca3165275bb36c1f0ac74666632adc5bdb680e366de7ce845f43", + "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", + "https://bcr.bazel.build/modules/rules_apple/3.5.1/MODULE.bazel": "3d1bbf65ad3692003d36d8a29eff54d4e5c1c5f4bfb60f79e28646a924d9101c", + "https://bcr.bazel.build/modules/rules_apple/5.1.0/MODULE.bazel": "57a85577faf7de9f98ecd4d84c3cd9e85f701d8881206ff6f4f31751c8fe4ded", + "https://bcr.bazel.build/modules/rules_apple/5.1.0/source.json": "33eea0f632b6175f9433bdecb36794ab8c831d15cd3bc54e57743b22b3e220c0", + "https://bcr.bazel.build/modules/rules_buf/0.1.1/MODULE.bazel": "6189aec18a4f7caff599ad41b851ab7645d4f1e114aa6431acf9b0666eb92162", + "https://bcr.bazel.build/modules/rules_buf/0.5.4/MODULE.bazel": "735754ce5c8ed7ddf38201b8d937cc8f055dd7218e8a7c0d5b2b539d9cc66e44", + "https://bcr.bazel.build/modules/rules_buf/0.5.4/source.json": "b8a3f87ad9d763749d0c00f6eb9d58119fd1ad6219f604dab49424e93322d65a", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.5/MODULE.bazel": "be41f87587998fe8890cd82ea4e848ed8eb799e053c224f78f3ff7fe1a1d9b74", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", + "https://bcr.bazel.build/modules/rules_cc/0.1.4/MODULE.bazel": "bb03a452a7527ac25a7518fb86a946ef63df860b9657d8323a0c50f8504fb0b9", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", + "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", + "https://bcr.bazel.build/modules/rules_cc/0.2.11/MODULE.bazel": "e94f24f065bf2191dba2dace951814378b66a94bb3bcc48077492fe0508059b5", + "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", + "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", + "https://bcr.bazel.build/modules/rules_cc/0.2.15/MODULE.bazel": "6a0a4a75a57aa6dc888300d848053a58c6b12a29f89d4304e1c41448514ec6e8", + "https://bcr.bazel.build/modules/rules_cc/0.2.16/MODULE.bazel": "9242fa89f950c6ef7702801ab53922e99c69b02310c39fb6e62b2bd30df2a1d4", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", + "https://bcr.bazel.build/modules/rules_cc/0.2.18/MODULE.bazel": "4460ec36adc8f722a6a2a4ac9374cb91f2acebadaa93fc37966129afb3dece87", + "https://bcr.bazel.build/modules/rules_cc/0.2.19/MODULE.bazel": "d5e0f05b63273281a16654eb6b1a8742a75ec153ac8b4f0419949d6e401e46f0", + "https://bcr.bazel.build/modules/rules_cc/0.2.20/MODULE.bazel": "f5c07bce5ddcb99be21a0812ff5aadb439e688b7449c6542152363b2fd859c1a", + "https://bcr.bazel.build/modules/rules_cc/0.2.22/MODULE.bazel": "94df4328edef9e44d38de5e73b037cd348e75e7ae55f4e21bf07878c41a31ebb", + "https://bcr.bazel.build/modules/rules_cc/0.2.25/MODULE.bazel": "4a3d4f3606d3b3190be495dbc497acca552807d1d5540661ef0d1658472882e3", + "https://bcr.bazel.build/modules/rules_cc/0.2.25/source.json": "8df28a9a97b878fe45f0a4f4adf019869dda51a60ee2f6e15a0c79656a25058d", + "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc", + "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", + "https://bcr.bazel.build/modules/rules_cc/0.2.9/MODULE.bazel": "34263f1dca62ea664265438cef714d7db124c03e1ed55ebb4f1dc860164308d1", + "https://bcr.bazel.build/modules/rules_cc_autoconf/0.13.2/MODULE.bazel": "3ec13b93183a28b7088563e0fef1a51835dde06c272a1dabc5900e8bc26b2188", + "https://bcr.bazel.build/modules/rules_cc_autoconf/0.24.0/MODULE.bazel": "332e2a2972ef5d5a537b2dbc23bea7a0d5d97fc5fa82cebe032b1b8d509b06a1", + "https://bcr.bazel.build/modules/rules_cc_autoconf/0.24.0/source.json": "7b729d9f90f03cfd1214a69ddb1f7efd0009d68271ccdbfa7dec9f2dcabaaa55", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.10.1/MODULE.bazel": "b9527010e5fef060af92b6724edb3691970a5b1f76f74b21d39f7d433641be60", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.15.1/MODULE.bazel": "c2c60d26c79fda484acb95cdbec46e89d6b28b4845cb277160ce1e0c8622bb88", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.16.0/MODULE.bazel": "185eee33e2f9ac635ca24261dcab2659b6c890b11d737ec71cc68409b26c8017", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.16.0/source.json": "a22a8da3386e9b042fdfebf9d4e79f4a71d1f088e5b41194cd7b2e51412f41a4", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_fuzzing/0.6.0/MODULE.bazel": "85e11f0640353bd11190db8d8e11162ab7684f382085b81c1bab0702d568f445", + "https://bcr.bazel.build/modules/rules_fuzzing/0.6.0/source.json": "5dda75d267a03611001147cb00874de5c8e7503e1cfbe3c225479dff89bfd111", + "https://bcr.bazel.build/modules/rules_go/0.33.0/MODULE.bazel": "a2b11b64cd24bf94f57454f53288a5dacfe6cb86453eee7761b7637728c1910c", + "https://bcr.bazel.build/modules/rules_go/0.38.1/MODULE.bazel": "fb8e73dd3b6fc4ff9d260ceacd830114891d49904f5bda1c16bc147bcc254f71", + "https://bcr.bazel.build/modules/rules_go/0.39.1/MODULE.bazel": "d34fb2a249403a5f4339c754f1e63dc9e5ad70b47c5e97faee1441fc6636cd61", + "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", + "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", + "https://bcr.bazel.build/modules/rules_go/0.45.1/MODULE.bazel": "6d7884f0edf890024eba8ab31a621faa98714df0ec9d512389519f0edff0281a", + "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", + "https://bcr.bazel.build/modules/rules_go/0.48.0/MODULE.bazel": "d00ebcae0908ee3f5e6d53f68677a303d6d59a77beef879598700049c3980a03", + "https://bcr.bazel.build/modules/rules_go/0.49.0/MODULE.bazel": "61cfc1ba17123356d1b12b6c50f6e0162b2cc7fd6f51753c12471e973a0f72a5", + "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0", + "https://bcr.bazel.build/modules/rules_go/0.51.0-rc2/MODULE.bazel": "edfc3a9cea7bedb0eaaff37b0d7817c1a4bf72b3c615580b0ffcee6c52690fd4", + "https://bcr.bazel.build/modules/rules_go/0.53.0/MODULE.bazel": "a4ed760d3ac0dbc0d7b967631a9a3fd9100d28f7d9fcf214b4df87d4bfff5f9a", + "https://bcr.bazel.build/modules/rules_go/0.59.0/MODULE.bazel": "b7e43e7414a3139a7547d1b4909b29085fbe5182b6c58cbe1ed4c6272815aeae", + "https://bcr.bazel.build/modules/rules_go/0.63.0/MODULE.bazel": "a2079e783a5d2715a90e6e2970ec8ffd717a487ff2aecb5f553e3975c5294a21", + "https://bcr.bazel.build/modules/rules_go/0.63.0/source.json": "5bf37b45c440ac03abad0cbfa8b8b8dd89cc4e82bc8305f468b8436fa58bae78", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.1.0/MODULE.bazel": "324b6478b0343a3ce7a9add8586ad75d24076d6d43d2f622990b9c1cfd8a1b15", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/5.5.0/MODULE.bazel": "486ad1aa15cdc881af632b4b1448b0136c76025a1fe1ad1b65c5899376b83a50", + "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", + "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963", + "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2", + "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/7.6.5/MODULE.bazel": "481164be5e02e4cab6e77a36927683263be56b7e36fef918b458d7a8a1ebadb1", + "https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615", + "https://bcr.bazel.build/modules/rules_java/8.16.1/MODULE.bazel": "0f20b1cecaa8e52f60a8f071e59a20b4e3b9a67f6c56c802ea256f6face692d3", + "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", + "https://bcr.bazel.build/modules/rules_java/8.5.0/MODULE.bazel": "c081eda83625b6d97144f2da9dd5f074ecd56ba10f238257e7a90f56ee8a9c3c", + "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_java/8.6.0/MODULE.bazel": "9c064c434606d75a086f15ade5edb514308cccd1544c2b2a89bbac4310e41c71", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/8.6.3/MODULE.bazel": "e90505b7a931d194245ffcfb6ff4ca8ef9d46b4e830d12e64817752e0198e2ed", + "https://bcr.bazel.build/modules/rules_java/8.9.0/MODULE.bazel": "e17c876cb53dcd817b7b7f0d2985b710610169729e8c371b2221cacdcd3dce4a", + "https://bcr.bazel.build/modules/rules_java/9.3.0/MODULE.bazel": "f657c72d65ac449caae9abf2e68e66c0d36f9416848c4c4903d0b3234229e7f2", + "https://bcr.bazel.build/modules/rules_java/9.9.0/MODULE.bazel": "6b2092957b4849ffcbb84d5c7fe0d5a4582f5e3062bc84d607122ac4ef832e55", + "https://bcr.bazel.build/modules/rules_java/9.9.0/source.json": "9c4e694db18812d19b5c1e279ba9dffc1adc3fcac163896829f374a7c426fe12", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d", + "https://bcr.bazel.build/modules/rules_jvm_external/6.0/MODULE.bazel": "37c93a5a78d32e895d52f86a8d0416176e915daabd029ccb5594db422e87c495", + "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4", + "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", + "https://bcr.bazel.build/modules/rules_jvm_external/6.9/MODULE.bazel": "07c5db05527db7744a54fcffd653e1550d40e0540207a7f7e6d0a4de5bef8274", + "https://bcr.bazel.build/modules/rules_jvm_external/7.1/MODULE.bazel": "e151b1beaa45bfc9e5de4df637d980e27039eb2b1092a95972bf2adbf99ac1a0", + "https://bcr.bazel.build/modules/rules_jvm_external/7.1/source.json": "8cb571a9631c39bf29c1842958542f14bba1c704fe2bcde4fa54679b2a6b3d6f", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/MODULE.bazel": "00d39c5e0fa78cd86193946265bb849e7878c24e44260f9525108428852b315c", + "https://bcr.bazel.build/modules/rules_kotlin/2.3.20/MODULE.bazel": "3443d53d275e14fecfebd0b491f01d06ea3883c04a1b3336e7ae9d5ec9066bef", + "https://bcr.bazel.build/modules/rules_kotlin/2.3.20/source.json": "5a5553cffea43f2c5156c8ad0de4a14ad95413ceb39cd4d08f50e2aea86927e8", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/0.0.8/MODULE.bazel": "5669c6fe49b5134dbf534db681ad3d67a2d49cfc197e4a95f1ca2fd7f3aebe96", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_m4/0.3.1/MODULE.bazel": "dcfb70aa14ba4ab99bcda9605d6fd0c8de4531a74bf854fb76ecd9f93a6f1e7e", + "https://bcr.bazel.build/modules/rules_m4/0.3.1/source.json": "43e9093a7921c709a70395f4af26da7af6e1419c8e9d76726bce1ea9d90557fd", + "https://bcr.bazel.build/modules/rules_nodejs/5.8.2/MODULE.bazel": "6bc03c8f37f69401b888023bf511cb6ee4781433b0cb56236b2e55a21e3a026a", + "https://bcr.bazel.build/modules/rules_nodejs/6.2.0/MODULE.bazel": "ec27907f55eb34705adb4e8257952162a2d4c3ed0f0b3b4c3c1aad1fac7be35e", + "https://bcr.bazel.build/modules/rules_nodejs/6.3.0/MODULE.bazel": "45345e4aba35dd6e4701c1eebf5a4e67af4ed708def9ebcdc6027585b34ee52d", + "https://bcr.bazel.build/modules/rules_nodejs/6.3.2/MODULE.bazel": "42e8d5254b6135f890fecca7c8d7f95a7d27a45f8275b276f66ec337767530ef", + "https://bcr.bazel.build/modules/rules_nodejs/6.3.3/MODULE.bazel": "b66eadebd10f1f1b25f52f95ab5213a57e82c37c3f656fcd9a57ad04d2264ce7", + "https://bcr.bazel.build/modules/rules_nodejs/6.3.3/source.json": "45bd343155bdfed2543f0e39b80ff3f6840efc31975da4b5795797f4c94147ad", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.3.0/MODULE.bazel": "ae0bdefbacc990c91f843206c90cf0f4be620639a5bf22119043599ba86d51a3", + "https://bcr.bazel.build/modules/rules_pkg/1.3.0/source.json": "58ae84c545141762f7c434c0ce78bfb55ef0be08d84863e7f0503fff135fe4e2", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", + "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", + "https://bcr.bazel.build/modules/rules_proto_grpc/5.8.0/MODULE.bazel": "38e2acb9aa480a04c780fa4b11bfaae0fa16e05f85f6d8fc32e044bad683ed86", + "https://bcr.bazel.build/modules/rules_proto_grpc/5.8.0/source.json": "142d5c5dd650d0f817936835738daa7df2256dfb33c247163b600ab28cba31d1", + "https://bcr.bazel.build/modules/rules_proto_grpc_cpp/5.8.0/MODULE.bazel": "7d61151dd22f6df5fc81eda68b0c4a09eb21c9ecb8ccbd2aea1ad772d536e278", + "https://bcr.bazel.build/modules/rules_proto_grpc_cpp/5.8.0/source.json": "d02c9e2c9b3168e06e306fe337e1c5a00e778e7c504fdbf1fbb77c0105c4a234", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.20.0/MODULE.bazel": "bfe14d17f20e3fe900b9588f526f52c967a6f281e47a1d6b988679bd15082286", + "https://bcr.bazel.build/modules/rules_python/0.22.0/MODULE.bazel": "b8057bafa11a9e0f4b08fc3b7cd7bee0dcbccea209ac6fc9a3ff051cd03e19e9", + "https://bcr.bazel.build/modules/rules_python/0.22.1/MODULE.bazel": "26114f0c0b5e93018c0c066d6673f1a2c3737c7e90af95eff30cfee38d0bbac7", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.29.0/MODULE.bazel": "2ac8cd70524b4b9ec49a0b8284c79e4cd86199296f82f6e0d5da3f783d660c82", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.32.2/MODULE.bazel": "01052470fc30b49de91fb8483d26bea6f664500cfad0b078d4605b03e3a83ed4", + "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", + "https://bcr.bazel.build/modules/rules_python/0.34.0/MODULE.bazel": "1d623d026e075b78c9fde483a889cda7996f5da4f36dffb24c246ab30f06513a", + "https://bcr.bazel.build/modules/rules_python/0.35.0/MODULE.bazel": "c3657951764cdcdb5a7370d5e885fad5e8c1583320aad18d46f9f110d2c22755", + "https://bcr.bazel.build/modules/rules_python/0.37.1/MODULE.bazel": "3faeb2d9fa0a81f8980643ee33f212308f4d93eea4b9ce6f36d0b742e71e9500", + "https://bcr.bazel.build/modules/rules_python/0.37.2/MODULE.bazel": "b5ffde91410745750b6c13be1c5dc4555ef5bc50562af4a89fd77807fdde626a", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7", + "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", + "https://bcr.bazel.build/modules/rules_python/1.2.0/MODULE.bazel": "5aeeb48b2a6c19d668b48adf2b8a2b209a6310c230db0ce77450f148a89846e4", + "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", + "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", + "https://bcr.bazel.build/modules/rules_python/1.5.1/MODULE.bazel": "acfe65880942d44a69129d4c5c3122d57baaf3edf58ae5a6bd4edea114906bf5", + "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", + "https://bcr.bazel.build/modules/rules_python/1.6.3/MODULE.bazel": "a7b80c42cb3de5ee2a5fa1abc119684593704fcd2fec83165ebe615dec76574f", + "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", + "https://bcr.bazel.build/modules/rules_python/1.9.0/MODULE.bazel": "afc3a05f29f09f2d3ee95ad99a145250dab41a2b2d8d6f82cc91936b3213282c", + "https://bcr.bazel.build/modules/rules_python/2.0.2/MODULE.bazel": "9d26ecb43f248c2663fb29f3c9b833aa86c31e736096e58c7077f80038f8d32f", + "https://bcr.bazel.build/modules/rules_python/2.3.3/MODULE.bazel": "f6ff81e044aedbcf4ccb915431fea6f506f1262a7f6366f36a6e156ec89b7890", + "https://bcr.bazel.build/modules/rules_python/2.3.3/source.json": "8dbd175f0d158d0a0aa35581584f075b598a00be3a39b04d57e30b3c0ccdd16c", + "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/MODULE.bazel": "d44fec647d0aeb67b9f3b980cf68ba634976f3ae7ccd6c07d790b59b87a4f251", + "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/source.json": "37c10335f2361c337c5c1f34ed36d2da70534c23088062b33a8bdaab68aa9dea", + "https://bcr.bazel.build/modules/rules_rust/0.45.1/MODULE.bazel": "a69d0db3a958fab2c6520961e1b2287afcc8b36690fd31bbc4f6f7391397150d", + "https://bcr.bazel.build/modules/rules_rust/0.51.0/MODULE.bazel": "2b6d1617ac8503bfdcc0e4520c20539d4bba3a691100bee01afe193ceb0310f9", + "https://bcr.bazel.build/modules/rules_rust/0.66.0/MODULE.bazel": "86ef763a582f4739a27029bdcc6c562258ed0ea6f8d58294b049e215ceb251b3", + "https://bcr.bazel.build/modules/rules_rust/0.68.1/MODULE.bazel": "8d3332ef4079673385eb81f8bd68b012decc04ac00c9d5a01a40eff90301732c", + "https://bcr.bazel.build/modules/rules_rust/0.69.0/MODULE.bazel": "4326fec48f2fef0d514de46346f7f77e200c82936dd08b91c9ef039fbdad5c10", + "https://bcr.bazel.build/modules/rules_rust/0.70.0/MODULE.bazel": "5b1407b11c305bc2522e204e7f170faf8399e836e49b6afef9074dfe532e6c3f", + "https://bcr.bazel.build/modules/rules_rust/0.74.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/rules_shell/0.1.2/MODULE.bazel": "66e4ca3ce084b04af0b9ff05ff14cab4e5df7503973818bb91cbc6cda08d32fc", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.4.0/MODULE.bazel": "0f8f11bb3cd11755f0b48c1de0bbcf62b4b34421023aa41a2fc74ef68d9584f0", + "https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", + "https://bcr.bazel.build/modules/rules_shell/0.8.0/MODULE.bazel": "f6a89f1d6a669a26f28fe814503857055d76306b79cfc11d12399af08d0b80ae", + "https://bcr.bazel.build/modules/rules_shell/0.8.0/source.json": "eb53cc815bc503c6683c5fe12d943f98883f81fc22f51403ec8a95610cba4195", + "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", + "https://bcr.bazel.build/modules/rules_swift/1.18.0/MODULE.bazel": "a6aba73625d0dc64c7b4a1e831549b6e375fbddb9d2dde9d80c9de6ec45b24c9", + "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", + "https://bcr.bazel.build/modules/rules_swift/2.5.0/MODULE.bazel": "6d2fec72be0ad2e1fc2eab536cf9d3fb149037c6d2aa678078f3512c06a819e1", + "https://bcr.bazel.build/modules/rules_swift/4.0.1/MODULE.bazel": "24ad295128e648c117a9defc50a994e9fc4790b6e9a6dab64ba3988146eb4736", + "https://bcr.bazel.build/modules/rules_swift/4.0.1/source.json": "77c535c18868a21e3109be7e96acd5cf9811fdee19c1bfcd50909121c643d26c", + "https://bcr.bazel.build/modules/simdutf/8.1.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/skywalking-data-collect-protocol/10.4.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/snappy/1.2.0/MODULE.bazel": "cc7a727b46089c7fdae0ede21b1fd65bdb14d01823da118ef5c48044f40b6b27", + "https://bcr.bazel.build/modules/snappy/1.2.0/source.json": "17f5527e15d30a9d9eebf79ed73b280b56cac44f8c8fea696666d99943f84c33", + "https://bcr.bazel.build/modules/spdlog/1.10.0/MODULE.bazel": "57c572ca15f41f1f577c01aa411ce473fd92c73114fbc75ad72b0be8f7519526", + "https://bcr.bazel.build/modules/spdlog/1.17.0/MODULE.bazel": "5d03b65eb8549f48dc888495c397b4053c8be095ea2e9c776d3c7aaaff3cd0d5", + "https://bcr.bazel.build/modules/spdlog/1.17.0/source.json": "62ba6fc81ead9d2bd05578c92643fa9abfa230c4ac238dbf10e75e3e1aaea4ee", + "https://bcr.bazel.build/modules/sql-parser/0.0.0-260715-52e5ad1.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/stardoc/0.5.0/MODULE.bazel": "f9f1f46ba8d9c3362648eea571c6f9100680efc44913618811b58cc9c02cd678", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.5.4/MODULE.bazel": "6569966df04610b8520957cb8e97cf2e9faac2c0309657c537ab51c16c18a2a4", + "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef", + "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", + "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", + "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", + "https://bcr.bazel.build/modules/su-exec/0.3/MODULE.bazel": "6bb423d69ced425a1cd73940a58b796ab680dcd501436d22cad441781be27711", + "https://bcr.bazel.build/modules/su-exec/0.3/source.json": "25ef2c3fe01ff465eafe06bc16a3c7cbaf836eb92d1dd77c9415bf8059289328", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", + "https://bcr.bazel.build/modules/swift_argument_parser/1.7.0/MODULE.bazel": "40d4e44950e44973dcf8590bcee637591de196b5dbe3696d07eb342b74d53672", + "https://bcr.bazel.build/modules/swift_argument_parser/1.7.0/source.json": "b9b952cba0c748083b9b891e6ac46d347c92d37e8a92ead96d2a54b966bacd87", + "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", + "https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351", + "https://bcr.bazel.build/modules/tar.bzl/0.6.0/MODULE.bazel": "a3584b4edcfafcabd9b0ef9819808f05b372957bbdff41601429d5fd0aac2e7c", + "https://bcr.bazel.build/modules/tar.bzl/0.6.0/source.json": "4a620381df075a16cb3a7ed57bd1d05f7480222394c64a20fa51bdb636fda658", + "https://bcr.bazel.build/modules/tclap/1.2.5.bcr.1/MODULE.bazel": "e79bb0e5f39d04e0b69bf36be65419e4fc595787a4344b1177efa5c149f11313", + "https://bcr.bazel.build/modules/tclap/1.2.5.bcr.1/source.json": "3f51d07ad439a4d8986ecb69699d768397c34050eb8489673fa3e68317e909c8", + "https://bcr.bazel.build/modules/tcmalloc/0.0.0-20250927-12f2552/MODULE.bazel": "b702a6b6806b1041d84918c5098b765b204261647f8cb3e75e0f439106b65ddd", + "https://bcr.bazel.build/modules/tcmalloc/0.0.0-250926-12f2552.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/thrift/0.24.0.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/toml.bzl/0.3.0/MODULE.bazel": "5016e5dd1ad2200e119a4b28b2b3935e276c4b480f2fe3e952bea7eeba88f578", + "https://bcr.bazel.build/modules/toml.bzl/0.4.1/MODULE.bazel": "6bc0b938f03ade8d58c2fca0ad5c3fa12b4764e1e1927ad50b0c860286db2167", + "https://bcr.bazel.build/modules/toml.bzl/0.4.1/source.json": "86a90afd8b43c9b69ad31f5c03998c3adcf4b08175e621addb93e3a38eec538b", + "https://bcr.bazel.build/modules/toolchains_llvm/1.9.1.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/toolchains_protoc/0.5.0/MODULE.bazel": "e649dcd74790d8b186517588c827a777dfa67acfc4cbd733721c4be143ea107f", + "https://bcr.bazel.build/modules/toolchains_protoc/0.5.0/source.json": "9152bf33827a44f796f94f486252fc0128d9efc2413246ebb09a234bb628a846", + "https://bcr.bazel.build/modules/uadk/2.9.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/upb/0.0.0-20211020-160625a/MODULE.bazel": "6cced416be2dc5b9c05efd5b997049ba795e5e4e6fafbe1624f4587767638928", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", + "https://bcr.bazel.build/modules/upb/0.0.0-20230907-e7430e6/MODULE.bazel": "3a7dedadf70346e678dc059dbe44d05cbf3ab17f1ce43a1c7a42edc7cbf93fd9", + "https://bcr.bazel.build/modules/v8/14.6.202.10.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/vectorscan/5.4.11.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/vpp-vcl/26.02-260111-85abefb.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/wamr/2.4.5.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/wasmtime/45.0.2.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/wuffs/0.4.0-alpha.9.envoy/MODULE.bazel": "not found", + "https://bcr.bazel.build/modules/xctestrunner/0.2.16-20260212-4c6f493/MODULE.bazel": "df9d74c77698e7dbc52a65ebdd6de5727044e98121ac309b5d046f2d04121d56", + "https://bcr.bazel.build/modules/xctestrunner/0.2.16-20260212-4c6f493/source.json": "73a5421c8ef51cd455a572dee5bb9415351ab5acbcb65d4efa56a574790bd2f2", + "https://bcr.bazel.build/modules/xds/0.0.0-20240423-555b57e/MODULE.bazel": "cea509976a77e34131411684ef05a1d6ad194dd71a8d5816643bc5b0af16dc0f", + "https://bcr.bazel.build/modules/xds/0.0.0-20251210-ee656c7/MODULE.bazel": "03e1c50b16fc2403de5dd98ff8e2dc0b404865740434b8705c7c0853241f943d", + "https://bcr.bazel.build/modules/xds/0.0.0-20251210-ee656c7/source.json": "69b87f3bff38ba29399c012f3e3fc0f239ac4e5c1ae66ebd9481be6d8461da55", + "https://bcr.bazel.build/modules/xxhash/0.8.3.bcr.1/MODULE.bazel": "d0cf68c7baf489fb8d87e0e62d9637fddb3a66ff93f991af70212707fdec86b0", + "https://bcr.bazel.build/modules/xxhash/0.8.3.bcr.1/source.json": "2b432c0271c0420fbf84af72e27496bb2ea57b4fb68b33a1a40be13565678024", + "https://bcr.bazel.build/modules/xz/5.4.5.bcr.1/MODULE.bazel": "c037f75fa1b7e1ff15fbd15d807a8ce545e9b02f02df0a9777aa9aa7d8b268bb", + "https://bcr.bazel.build/modules/xz/5.4.5.bcr.8/MODULE.bazel": "e48a69bd54053c2ec5fffc2a29fb70122afd3e83ab6c07068f63bc6553fa57cc", + "https://bcr.bazel.build/modules/xz/5.4.5.bcr.8/source.json": "bd7e928ccd63505b44f4784f7bbf12cc11f9ff23bf3ca12ff2c91cd74846099e", + "https://bcr.bazel.build/modules/yaml-cpp/0.9.0.bcr.1/MODULE.bazel": "68fd5f98e762becfc3ee701e77a6fe57d51e367b4c59920b5eecade38546eae7", + "https://bcr.bazel.build/modules/yaml-cpp/0.9.0.bcr.1/source.json": "1e4c3e1716a29c4e6074d95ffafbb579ad7c762fcb9735788b819e7be98fff6a", + "https://bcr.bazel.build/modules/yaml-cpp/0.9.0/MODULE.bazel": "d0841e12e92973d7e4c97557198335788890dafa9487d6dc0f9b852053a6c5c0", + "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", + "https://bcr.bazel.build/modules/yq.bzl/0.4.0/MODULE.bazel": "1e4b142e391b62c95eb637fc0e944c17f3ed5276cdc9d7033df72a2f96a2a457", + "https://bcr.bazel.build/modules/yq.bzl/0.4.0/source.json": "e5a3b94fe7ab720818ac2d8150cb19b009daf48c69a72eaab9a4852efb75331d", + "https://bcr.bazel.build/modules/zipkin-api/1.0.0.bcr.1/MODULE.bazel": "70616960ecd07fb708362e80bc9b2800da523f75487e2a7b256d25ebeaf9daf3", + "https://bcr.bazel.build/modules/zipkin-api/1.0.0.bcr.1/source.json": "a9b9eec6079225cc995802979753ba30c293a4fb1c39ce56f0332e97accf8c70", + "https://bcr.bazel.build/modules/zlib-ng/2.3.3.bcr.2/MODULE.bazel": "86130924115bf8dfc4aba286fb49a2ec8d32430a21771db9ccf5381acf0d10cc", + "https://bcr.bazel.build/modules/zlib-ng/2.3.3.bcr.2/source.json": "7aa4112eb2fbb99757e97cf0b7a4e2bdb3464b2b3cfb351bc807ffcb34bd349f", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", + "https://bcr.bazel.build/modules/zlib/1.2.13/MODULE.bazel": "aa6deb1b83c18ffecd940c4119aff9567cd0a671d7bba756741cb2ef043a29d5", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.1/MODULE.bazel": "6a9fe6e3fc865715a7be9823ce694ceb01e364c35f7a846bf0d2b34762bc066b", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.4/MODULE.bazel": "fc880fa3bd9c5299be64b712fbc60a1978ea9ce0a9f74f6bbd0b61c12db1aee6", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.6/MODULE.bazel": "e937cf0a3772f93ad91f3c7af4f330b76a878bbfee06527ca1a9673b790eb896", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.8/MODULE.bazel": "772c674bb78a0342b8caf32ab5c25085c493ca4ff08398208dcbe4375fe9f776", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198", + "https://bcr.bazel.build/modules/zlib/1.3.2/MODULE.bazel": "7303cb87d80e438f313194fc640e38475a8d337b8c70ff6a0725f55236566a33", + "https://bcr.bazel.build/modules/zlib/1.3.2/source.json": "8f35ed65174ee2ad9630baeccd243cadf482b72d2ab32b57f9d84dc30ab076e0", + "https://bcr.bazel.build/modules/zlib/1.3/MODULE.bazel": "6a9c02f19a24dcedb05572b2381446e27c272cd383aed11d41d99da9e3167a72", + "https://bcr.bazel.build/modules/zstd/1.5.6/MODULE.bazel": "471ebe7d3cdd8c6469390fcf623eb4779ff55fbee0a87f1dc57a1def468b96d4", + "https://bcr.bazel.build/modules/zstd/1.5.7.bcr.2/MODULE.bazel": "d20bf700aacefca7c09840baa4bae9b347ddb31bd9125f4e592998f80b980cd7", + "https://bcr.bazel.build/modules/zstd/1.5.7.bcr.2/source.json": "19cf972e5efc777e24008b90c2d819a4c814d33d1326c62d736ed97544817bf0", + "https://bcr.bazel.build/modules/zstd/1.5.7/MODULE.bazel": "f5780cdbd6f4c5bb985a20f839844316fe48fb5e463056f372dbc37cfabdf450", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/bazel_registry.json": "51bd3a0b193753e419c5d3db38e92fbcb9f7f97fd992ef2e24a0addd7274b37a", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/aws-c-auth-testdata/0.10.4.envoy/MODULE.bazel": "ed40f4181373fb0e277d5511db521f5a77f5558141b5697499a9b22fa1dc96c4", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/aws-c-auth-testdata/0.10.4.envoy/source.json": "20b0d19dc5c1e83f57c1cbc7e54ab0131291cc2220b374b0d222e44a6a0d914e", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/bazel-compdb/0.0.0-20220906-4086479.envoy/MODULE.bazel": "8ea7d294e0ea35bdcfddb8c3597eaa2967a4fa18b0e975ddef9374cd0e926d92", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/bazel-compdb/0.0.0-20220906-4086479.envoy/source.json": "586e9896baf303341171326f8721091d0b9748386e2383c9b60b351d30b60550", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/boost.headers/1.89.0.envoy/MODULE.bazel": "c7205963786fdbe14f5a384ff5a3a04da66ed0cecfee3d3cedecf5be173dcb66", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/boost.headers/1.89.0.envoy/source.json": "86bf1391aea9cd0515c98b1881a630fbe63fa171265e40cf5a77be7c0d680abb", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/boringssl-fips/0.20260929.0.envoy/MODULE.bazel": "6b164fcd628b5e7f75fcc424d46698a4824cea6af1a11678e623490d13d6097e", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/boringssl-fips/0.20260929.0.envoy/source.json": "3af98d27e46461d666e782ef133a2c27233bc388cbcbb17ca231d9aa7af5fb9e", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/boringssl-source/0.20260929.0.envoy/MODULE.bazel": "d80ba9dddc69a8d1900428c2f0b128cd1a41f63f058b4b0bce668357f7ec66a0", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/boringssl-source/0.20260929.0.envoy/source.json": "9c57158c4b3a2b2ac0188c472249d1faacbfcf3fd3fa822a4785836b391fe8b4", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/brotli/1.2.0-260930-42a2ed4.envoy/MODULE.bazel": "dce5f9c0643e0551aaeb0341ed90b994337ae3fbf232b584f2aaeae79ae47800", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/brotli/1.2.0-260930-42a2ed4.envoy/source.json": "c699301760293b6ffa07f1117aa1c1763683aeef33f1e10a061e1db342873860", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/cel-cpp/0.16.1.envoy/MODULE.bazel": "f835ee95427829db17d60fe1349839a759478fe89bb03c3869f39b5d6e56491d", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/cel-cpp/0.16.1.envoy/source.json": "decb295094395a4ef83e0562a82c58487d580e1a89e86cfa575c5705471dbac7", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/colm/0.14.7-211228-2d8ba76.envoy/MODULE.bazel": "3e22f81980923a87210857805bce1714af45b29cc610b040d7f05a85cf594106", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/colm/0.14.7-211228-2d8ba76.envoy/source.json": "84d1244a0a9c2bd7c6c2dd80cbbe174efdc896b2f1de1f4eca10828df5689346", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/cpp2sky/0.6.0.envoy/MODULE.bazel": "4634ce1499a7cd15ba625196eda5ed058cccc37be62c7ea3bf11b978ac49201b", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/cpp2sky/0.6.0.envoy/source.json": "ab2067d20eb1bde1e5beed3fd5cc54b3c91ed6ed162d597078f2e315b147092b", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/dd-trace-cpp/2.1.1.envoy/MODULE.bazel": "53d840ca189cd07b628465d4e7461c0b16458a108c9b1a5088248a16e4cf7074", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/dd-trace-cpp/2.1.1.envoy/source.json": "5542a7bd9a69e1e180fe8655560703f1d287c2a790f97a1bacd56c30f3bc49da", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/dragonbox/0.0.0-241028-6c7c925.envoy/MODULE.bazel": "56dd26c839325bc2c40cc1879c00cab3397cd83fe3cf6ab8ccaf7fd6ad1b890d", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/dragonbox/0.0.0-241028-6c7c925.envoy/source.json": "642addb5bea17b6570a138ccfb4f50f34c810c9e3416748a09e1ac723b01021f", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/elfutils/0.196.envoy/MODULE.bazel": "9625ac2b3d7f9bb696000b284bc7714b5067fa107d74c86d0e6b1414494c6779", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/elfutils/0.196.envoy/source.json": "726cd0015c75134acf6bd28e5360b636aeb7e455ae66c4adebf79e4f55ba5fc8", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/emsdk/4.0.23.envoy/MODULE.bazel": "f764bb57c935c9fb4dc72263dd92c48c50e21367983fb1edf402fb43717752b5", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/emsdk/4.0.23.envoy/source.json": "a87b602d182b5ceb203c858f9ecd88f4702de7b549e3074e22a02f6ac7d68dc0", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/envoy_toolshed/0.5.3.envoy/MODULE.bazel": "ed07f070c24eefddeabf18dc1fbf8e2c44e278b9e3fd664ff45a6b7bb92f9f6b", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/envoy_toolshed/0.5.3.envoy/source.json": "185e9b21127fe42d54b3b44dd10e7881bd6e1fdd690e012c37e34c46f7b43321", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/envoy_toolshed_jq/0.5.3.envoy/MODULE.bazel": "4751a69fa90c783f2cb5027bdf34875d5592c5225ba3695309a1a185e008220e", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/envoy_toolshed_jq/0.5.3.envoy/source.json": "0cdb4559041770664a6456c1ac67db87cbd916343cdee2fc80906aa49c82752b", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/fp16/0.0.0-260704-3d2de18.envoy/MODULE.bazel": "27e5020ea158fdc725eafed3443b6fa9a1555d52505dafcdc3e6ea74d9e112c1", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/fp16/0.0.0-260704-3d2de18.envoy/source.json": "ccc308b4d5afbba59ce93809243da68a5402414bb7f707d2b691df68ab896250", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/go-fips/1.27.1.envoy/MODULE.bazel": "fefcecbef619a02e09a78fa076a2c6433ac2a51b2dcaa8c66305b2c2382c2c45", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/go-fips/1.27.1.envoy/source.json": "fba033c8421e118dade86d72a3b6a082a7834885448a4b2b74aa895911f6d6e3", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/googleurl/0.0.0-221103-dd4080f.envoy/MODULE.bazel": "dc049475e14a1c77a8e306cfaede9208f6df16dfb6b75c22990c19d9113fe6b9", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/googleurl/0.0.0-221103-dd4080f.envoy/source.json": "d8f2befb8dc7e2e891dcbe5d8be118497277dc8ee60cf3ddda087da34fa3b74d", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/grpc-httpjson-transcoding/0.0.0-20250507-a6e226f.envoy/MODULE.bazel": "a68a5f38f92a8665798fa3eb6bd9af9d1c87b7341332874261f5c4ee9eeec469", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/grpc-httpjson-transcoding/0.0.0-20250507-a6e226f.envoy/source.json": "37ef413a76717db2ab97571f4d4380240016f7217bc8078a878faabb12678714", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/grpc/1.83.0.envoy/MODULE.bazel": "71ff92df79911a0975a09c1482791fd3983696383d4652277684e67884ac9d40", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/grpc/1.83.0.envoy/source.json": "39d70fd55602db781fc793f0417b7ecce8f2427e9fdaf6c18938e33acdc4d549", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/hessian2-codec/0.0.0-250114-6f5a647.envoy/MODULE.bazel": "2444f17603d30883fcca2aa40c6379307e1ee28ca716da981d5acd2071fe3ff5", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/hessian2-codec/0.0.0-250114-6f5a647.envoy/source.json": "13edf5f4100d565062fea1478d0a1dc508597cffa949b72bcd9efd2c8cc9f864", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/hyperscan/5.4.2.envoy/MODULE.bazel": "ae14ced374f6066ab5b15745e6a84567be0cf023e417097c836a8d987a604e64", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/hyperscan/5.4.2.envoy/source.json": "f287716046c83cd09084cab3e4407156da445a57544aad4667e48c89da97de3f", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/icu/78.2.envoy/MODULE.bazel": "212dbe6e711c09d51ffc12744373cf7dd3d1cc3f84133bff8a47d83d08f00e71", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/icu/78.2.envoy/source.json": "b6233eecf893f48f303597ca4b46959638de5237828df860bf51f58664540567", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/ipp-crypto/2.2.0.envoy/MODULE.bazel": "4aae1eb5b5e974ddd3e2e86b0259f4e3b4d9e346d8044065a9cd82c4b09e5803", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/ipp-crypto/2.2.0.envoy/source.json": "a815528d2e6d2eb0a1dbc4cf80f3505ad4bcd717bd69e9fd6bf4d48b8e73af30", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/kafka/3.9.2.envoy/MODULE.bazel": "6073e3999d462408a541d0d2a997685f24023a4d574b84fa91c06a1ecf447ccc", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/kafka/3.9.2.envoy/source.json": "df37e7c4a0c424b81b1e312590987f8c300487d1b3562d3e4a54b93f927a03b7", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/libbpf/1.7.0.envoy/MODULE.bazel": "647c18b4c73396cb5e0d2c18d57e1d6f6a70eddee36c0b7cac28aab41890549a", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/libbpf/1.7.0.envoy/source.json": "8ad9808a975020be4a0a29f565df60ef70ecf2b510b2da727578989da334785d", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/libcircllhist/0.3.2.envoy/MODULE.bazel": "093e50ec67a5615229453870c477310985f6feaf282d6a2dbb4ed7059be0085d", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/libcircllhist/0.3.2.envoy/source.json": "51fe6317d2bcc64f396a662d6c57ed8312e2dd8c1e650f95171f08d18f8b4fb7", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/libevent/2.2.2-alpha.envoy/MODULE.bazel": "c48ae76869f4b3eb10706706342071f946991e7813086658ebcb57dedf8f06e8", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/libevent/2.2.2-alpha.envoy/source.json": "9fb08bed4313e04cdf4ae7fbc410e1e13fd3df9c1c9a563570ecb9df32c43031", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/libsxg/0.0.0-210708-beaa393.envoy/MODULE.bazel": "d393e5f349421c439a1f028ce9c89b0dfa1f9037aa8a1b40879eb1075e620439", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/libsxg/0.0.0-210708-beaa393.envoy/source.json": "b9dea2bcae23c5fef915493a6b78aa6a64741ed8cba59054f3f2f3c621f60721", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/liburing/2.15.envoy/MODULE.bazel": "8b912bfd4df468e56e35bb3bfc148fac83e8a5fb22e52328f131731c381a300b", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/liburing/2.15.envoy/source.json": "1003378e3b9e1bb2a0f5edfa3c6e8c106814d0adb69e6b40a89c4fd45557df8a", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/luajit/0.0.0-260126-871db2c.envoy/MODULE.bazel": "0b7a728ac0272b81346c907fd52f4dce689feeb4a4ee99328681f07d55331d1c", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/luajit/0.0.0-260126-871db2c.envoy/source.json": "98c71438265293c5010b7f68c54d3e2ea8bd9b1dc265ad7f96c4b76679b416d5", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/lz4/1.10.0.bcr.2.envoy/MODULE.bazel": "4f4b9441deab58bca7298a594d350404bcd829816f75ce544df25b4e4980a23e", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/lz4/1.10.0.bcr.2.envoy/source.json": "086bfe449856214da347cf8498a17a4b880481b3dc06903c04849c460baa36c8", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/nghttp2/1.66.0.envoy/MODULE.bazel": "49c64a0d1d580d72ba543506540bafa9ebcac9fc9899d1d6b83a0c701f3085b1", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/nghttp2/1.66.0.envoy/source.json": "9aeae96b83a7d38913a127bce69d80fbe16503b7c35c09cfa73cce5ba6eb007c", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/ocp-diag-core/0.0.0-230505-e965ac0.envoy/MODULE.bazel": "e946ff0e3eec7f94a76189c47f8aefb086b753ae012c7455eb6d5a7d7d52d340", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/ocp-diag-core/0.0.0-230505-e965ac0.envoy/source.json": "bfec9a281eaea5ccdc59af0d9ac808abb5d567286c55bccf34810d4a8993e2de", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/openssl/3.5.7.envoy/MODULE.bazel": "3d5416cfc1931483924fdf1c6f4e7c5489d24f0cf2d600bc63701e962fc86c67", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/openssl/3.5.7.envoy/source.json": "4d2b33594d83e4db4e4d0b559f28cb4bfeb934ad77682e24049ec6c2d17de303", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/perfetto/57.2.envoy/MODULE.bazel": "5df6589649d07db7a587cbe64363825a0fa01f0c83f6282c4142cff7fa8259b2", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/perfetto/57.2.envoy/source.json": "f823054d455b84c3c5fd40462b4fdb9c06f15bdc918846ce5ba06b16498e28b3", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/prometheus-metrics-model/0.6.2.envoy/MODULE.bazel": "40e1b9b9db52c3238fcc3e85c08ef35eb9157783e620009ed01eeed7631a9f67", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/prometheus-metrics-model/0.6.2.envoy/source.json": "0943a090f19491879321638e307bf6bea1459659fb8de4d85ff7e1eb153f12c9", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/proto-converter/0.0.0-20260912-3850764.envoy/MODULE.bazel": "4eb07ebfdecce30b188524dcd5e217df5ac8dd0ca6a6b8daec625bcab84ff16b", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/proto-converter/0.0.0-20260912-3850764.envoy/source.json": "c3c5f3e0a26f30883a27ef45c4d911e8c14534ccbdc962f861d6d37a2dcafb28", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/proto-field-extraction/0.0.0-240710-d5d39f0.envoy/MODULE.bazel": "d99a43759299070160315edafc6808433e9ca6a0b427afcbdb7fa33d4e518185", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/proto-field-extraction/0.0.0-240710-d5d39f0.envoy/source.json": "701548f6ec18a892525214ee77cc88ce55a25368caaecff4e948cdff904cb15d", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/proto-processing/0.0.0-250110-279353c.envoy/MODULE.bazel": "04aa144a38236501db9ae2ccfd4b7719760cadadbbd4b31189003565c57cce37", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/proto-processing/0.0.0-250110-279353c.envoy/source.json": "8be438fea43b7b4c99f0784d1f1dbfbf7038d07ba1d29dfca6cfa378d1ecfb3b", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/protobuf/35.1.bcr.envoy/MODULE.bazel": "97206075bc75d7aa4c3d580f488ad19de0f374f192c9e93da9e071b4780d1f23", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/protobuf/35.1.bcr.envoy/source.json": "1e41359b39620019d80e22316fb8762780330dfbae99ea32e0dd98f3db233e56", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/protoc-gen-validate/1.3.3.envoy/MODULE.bazel": "48db25694ec054d0bf9039ce2d51d292daf67b8ff8fc3c4071b43a807f313b41", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/protoc-gen-validate/1.3.3.envoy/source.json": "1c2acb99b8b3e7c57b5d43d06a71e65be1ba5f62ff327e126699ebad6defc018", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/proxy-wasm-cpp-host/0.0.0-260704-f2db56a.envoy/MODULE.bazel": "5ec13aeb03c5c148f1d340127d5f225c5094bc80a152b4c7c90708c529d57722", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/proxy-wasm-cpp-host/0.0.0-260704-f2db56a.envoy/source.json": "39721bf8eee5b6543a959c5a7271524d9b42b6f5618875a10064ba257ed747bf", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/proxy-wasm-cpp-sdk/0.0.0-250925-e5256b0.envoy/MODULE.bazel": "dfc7349d5177a6d63cceac9710e2b00b4ea069973235031c45eb0e8c6a466fd7", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/proxy-wasm-cpp-sdk/0.0.0-250925-e5256b0.envoy/source.json": "59ba8d0658f8da92d73259baf75e419dc23c25fa4909357a3ba784806ebfcf8a", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/qat-zstd/1.0.0.envoy/MODULE.bazel": "9c46bd2cd0752e70de76ce0c1c36811b14448a4dbbc3ff8b0f4f95c343bbb6c4", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/qat-zstd/1.0.0.envoy/source.json": "7aaf3a82884e4e603f76568ca98009fb4769fdd5f66c430054f47b4d82820c16", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/qatlib/26.02.0.envoy/MODULE.bazel": "45e6093e2bd42ef8128bd93a168028a9d2926ce223a43694650359997a046f5f", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/qatlib/26.02.0.envoy/source.json": "c80a93b73f5ede0135ee815ef8af2298c6b0c97d6c776ce323f05a627c245a52", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/qatzip/2.0.0.envoy/MODULE.bazel": "91a13182a0dcba4e582954ef45f2a3fc8132ef74a760fee29746528465d49680", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/qatzip/2.0.0.envoy/source.json": "126a045e6b16e69fa9ba0e6c58a15fd716921b85c36eea30f76149eeed981c82", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/quiche/0.0.0-261006-9e60ac2.envoy/MODULE.bazel": "80964ef537c45786617df5c0ce2e6bed4cbc36f7a0bef6f4ead41fb9abfaaa0a", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/quiche/0.0.0-261006-9e60ac2.envoy/source.json": "ac80d790475f7422eb990efa88b9ab8d7f8f3d3def40d40d112dfa61e05b19c3", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/ragel/7.0.4-211228-d4577c9.envoy/MODULE.bazel": "7635a32860d8fccdf13449fb1ff52137a96d0c03f73b9030483d2a0ad1b6953b", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/ragel/7.0.4-211228-d4577c9.envoy/source.json": "489ee8af503223d444a2b324f750f22a445da60c4f24cd445f5f208dc1aaf2ae", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/rules_rust/0.74.0.envoy/MODULE.bazel": "f53417a525a4d4468c791ed782e2134b8e72d1815c51b2d7b847bc265279f57a", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/rules_rust/0.74.0.envoy/source.json": "e0887f4021cd7972dc569db2b07e6b5ee572bee38809283801f769ec07194d04", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/simdutf/8.1.0.envoy/MODULE.bazel": "d7288f3bd5168bc92aff3591e5f7a3a58277bddcc7fc70fa125f39ac9445f4b7", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/simdutf/8.1.0.envoy/source.json": "81ba7a2c64438dbc4ee978b0fbdffdf2e8e5ff51c1bcbea6b78e1eed466ee3f6", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/skywalking-data-collect-protocol/10.4.0.envoy/MODULE.bazel": "a30a9b06eb67f4b6e48846859c64102740fd76d1fafa2590e9985eeadf0d5bad", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/skywalking-data-collect-protocol/10.4.0.envoy/source.json": "7e7a4138fd7c763dfd71c890f4505aed8f693ff13fcc082515ebb3f759093b0b", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/sql-parser/0.0.0-260715-52e5ad1.envoy/MODULE.bazel": "4eb416b09ac2d3a879e10e1c73fad68c9cc91000386dbe6ec6155fde426cb392", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/sql-parser/0.0.0-260715-52e5ad1.envoy/source.json": "21d2ce08202181862bffefb4a2eb3536dd00ef80c60d794e7d3d4f1337486641", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/tcmalloc/0.0.0-250926-12f2552.envoy/MODULE.bazel": "33724f956ea9ba4995cc87c535a688863acc7d84c44efdb768c34341f75baf50", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/tcmalloc/0.0.0-250926-12f2552.envoy/source.json": "287cfe3beeed272463e8ea4113904d18e3a03b08d1cf3d2348c854fef7164e8d", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/thrift/0.24.0.envoy/MODULE.bazel": "1327eb19f1ee2ddf00bf193ca501d0b49728b107cfd2d80b344df3c2987b11c0", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/thrift/0.24.0.envoy/source.json": "e6cbe9c327a1ac64be264c13f563557467855170eb1e9efd9db5bcfdccf1d483", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/toolchains_llvm/1.9.1.envoy/MODULE.bazel": "a80b6b1ccd6a9e3166723874d6b37a9acc5b84252e332ffb468ade7ff135cd90", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/toolchains_llvm/1.9.1.envoy/source.json": "550817e1f0123e06c59a9cd4814809bd57a0bcf1705bd4ac1e56e90d1952c2f4", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/uadk/2.9.envoy/MODULE.bazel": "de2055688d0c64d1c467d43895e643fd7875a82a53c8461e76908f57598dc34a", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/uadk/2.9.envoy/source.json": "4fbeff6b0573126f5ce1931abd68a8361ce3d86c0b3888d92e2d63d0b0c00f42", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/v8/14.6.202.10.envoy/MODULE.bazel": "57fa395049458e9768b26e4789236ee620bd177414bf979cf583887f06c71749", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/v8/14.6.202.10.envoy/source.json": "eb0a534601513683071d65daa8f27fb100832177f88c9e37821a46ed5942aa0d", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/vectorscan/5.4.11.envoy/MODULE.bazel": "321bf3eac6795ea32dc1814e7016a72f9c8df01aa50a135a952de24efa39acf2", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/vectorscan/5.4.11.envoy/source.json": "cf9fd240073fd187326f57f516a3791b70ee0314cfc4cf17ffa13568a804bdcd", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/vpp-vcl/26.02-260111-85abefb.envoy/MODULE.bazel": "9e76627b1f3cdf4da23386693f9333baaa5078e566495b02994ae2620baf8094", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/vpp-vcl/26.02-260111-85abefb.envoy/source.json": "a4d00de623af10ab9af46799667aadd8fd07d2a4028a3123ebeb959519e820cf", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/wamr/2.4.5.envoy/MODULE.bazel": "1d46e497d61465f6045ce9fa03c67a4e7a53ba9e451bbea4d3d0822f18a17d33", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/wamr/2.4.5.envoy/source.json": "dedc6d874500bff067e8a574e806b2a2da575b5d7f03103b3d215854e62057f8", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/wasmtime/45.0.2.envoy/MODULE.bazel": "049737b70b559b996eb68f95e38ff92ef50d629545ddafa1aa4d62b3c1a73225", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/wasmtime/45.0.2.envoy/source.json": "5fcd6845a0a934f095ccf68298e8f7466b8d8276923221e4488a33077fd6ff69", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/wuffs/0.4.0-alpha.9.envoy/MODULE.bazel": "e46699ee4851ddd18a50012b34c662f2390f014394cb17b8e07337cbc4033eb2", + "https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304/modules/wuffs/0.4.0-alpha.9.envoy/source.json": "b215401a4bd5bb7c4af8b37940209e955e905cd41f3beaffffb00424eec8afcc" + }, + "selectedYankedVersions": {}, + "moduleExtensions": { + "@@aspect_rules_esbuild+//esbuild:extensions.bzl%esbuild": { + "general": { + "bzlTransitiveDigest": "zHTxEUJi37HHbuoiJkToNOdzMWPcyGFW+RzKIesV/Gg=", + "usagesDigest": "sj4kz7yaVclWMuWhUhSLq0bVH7+HrkWyMdODMeA7Zhw=", + "recordedInputs": [ + "REPO_MAPPING:aspect_bazel_lib+,bazel_lib bazel_lib+", + "REPO_MAPPING:aspect_bazel_lib+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:aspect_bazel_lib+,bazel_tools bazel_tools", + "REPO_MAPPING:aspect_bazel_lib+,tar.bzl tar.bzl+", + "REPO_MAPPING:aspect_rules_esbuild+,aspect_rules_js aspect_rules_js+", + "REPO_MAPPING:aspect_rules_esbuild+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:aspect_rules_js+,aspect_bazel_lib aspect_bazel_lib+", + "REPO_MAPPING:aspect_rules_js+,aspect_rules_js aspect_rules_js+", + "REPO_MAPPING:aspect_rules_js+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:aspect_rules_js+,bazel_tools bazel_tools", + "REPO_MAPPING:bazel_lib+,bazel_lib bazel_lib+", + "REPO_MAPPING:bazel_lib+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:bazel_lib+,bazel_tools bazel_tools", + "REPO_MAPPING:tar.bzl+,aspect_bazel_lib aspect_bazel_lib+", + "REPO_MAPPING:tar.bzl+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:tar.bzl+,tar.bzl tar.bzl+" + ], + "generatedRepoSpecs": { + "esbuild_darwin-x64": { + "repoRuleId": "@@aspect_rules_esbuild+//esbuild:repositories.bzl%esbuild_repositories", + "attributes": { + "esbuild_version": "0.19.9", + "platform": "darwin-x64" + } + }, + "esbuild_darwin-arm64": { + "repoRuleId": "@@aspect_rules_esbuild+//esbuild:repositories.bzl%esbuild_repositories", + "attributes": { + "esbuild_version": "0.19.9", + "platform": "darwin-arm64" + } + }, + "esbuild_linux-x64": { + "repoRuleId": "@@aspect_rules_esbuild+//esbuild:repositories.bzl%esbuild_repositories", + "attributes": { + "esbuild_version": "0.19.9", + "platform": "linux-x64" + } + }, + "esbuild_linux-arm64": { + "repoRuleId": "@@aspect_rules_esbuild+//esbuild:repositories.bzl%esbuild_repositories", + "attributes": { + "esbuild_version": "0.19.9", + "platform": "linux-arm64" + } + }, + "esbuild_win32-x64": { + "repoRuleId": "@@aspect_rules_esbuild+//esbuild:repositories.bzl%esbuild_repositories", + "attributes": { + "esbuild_version": "0.19.9", + "platform": "win32-x64" + } + }, + "esbuild_toolchains": { + "repoRuleId": "@@aspect_rules_esbuild+//esbuild/private:toolchains_repo.bzl%toolchains_repo", + "attributes": { + "esbuild_version": "0.19.9", + "user_repository_name": "esbuild" + } + }, + "npm__esbuild_0.19.9": { + "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_rule", + "attributes": { + "package": "esbuild", + "version": "0.19.9", + "root_package": "", + "link_workspace": "", + "link_packages": {}, + "integrity": "sha512-U9CHtKSy+EpPsEBa+/A2gMs/h3ylBC0H0KSqIg7tpztHerLi6nrrcoUJAkNCEPumx8yJ+Byic4BVwHgRbN0TBg==", + "url": "", + "commit": "", + "patch_args": [ + "-p0" + ], + "patches": [], + "custom_postinstall": "", + "npm_auth": "", + "npm_auth_basic": "", + "npm_auth_username": "", + "npm_auth_password": "", + "lifecycle_hooks": [], + "extra_build_content": "", + "generate_bzl_library_targets": false, + "extract_full_archive": false, + "exclude_package_contents": [], + "system_tar": "auto" + } + }, + "npm__esbuild_0.19.9__links": { + "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_links", + "attributes": { + "package": "esbuild", + "version": "0.19.9", + "dev": false, + "root_package": "", + "link_packages": {}, + "deps": {}, + "transitive_closure": {}, + "lifecycle_build_target": false, + "lifecycle_hooks_env": [], + "lifecycle_hooks_execution_requirements": [ + "no-sandbox" + ], + "lifecycle_hooks_use_default_shell_env": false, + "bins": {}, + "package_visibility": [ + "//visibility:public" + ], + "replace_package": "", + "exclude_package_contents": [] + } + } + } + } + }, + "@@aspect_rules_js+//npm:extensions.bzl%pnpm": { + "general": { + "bzlTransitiveDigest": "/slnDINvvdAoi1Ff/19o9L3ApmLO3ZZMd1vJRM2siZo=", + "usagesDigest": "kbjSw2REjlSC0HtTZDf2p+l/dmiMt3NHLoiWEXYAoQI=", + "recordedInputs": [ + "REPO_MAPPING:aspect_bazel_lib+,bazel_lib bazel_lib+", + "REPO_MAPPING:aspect_bazel_lib+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:aspect_bazel_lib+,bazel_tools bazel_tools", + "REPO_MAPPING:aspect_bazel_lib+,tar.bzl tar.bzl+", + "REPO_MAPPING:aspect_rules_js+,aspect_bazel_lib aspect_bazel_lib+", + "REPO_MAPPING:aspect_rules_js+,aspect_rules_js aspect_rules_js+", + "REPO_MAPPING:aspect_rules_js+,bazel_features bazel_features+", + "REPO_MAPPING:aspect_rules_js+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:aspect_rules_js+,bazel_tools bazel_tools", + "REPO_MAPPING:bazel_features+,bazel_features_globals bazel_features++version_extension+bazel_features_globals", + "REPO_MAPPING:bazel_features+,bazel_features_version bazel_features++version_extension+bazel_features_version", + "REPO_MAPPING:bazel_lib+,bazel_lib bazel_lib+", + "REPO_MAPPING:bazel_lib+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:bazel_lib+,bazel_tools bazel_tools", + "REPO_MAPPING:tar.bzl+,aspect_bazel_lib aspect_bazel_lib+", + "REPO_MAPPING:tar.bzl+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:tar.bzl+,tar.bzl tar.bzl+" + ], + "generatedRepoSpecs": { + "pnpm": { + "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_rule", + "attributes": { + "package": "pnpm", + "version": "8.6.7", + "root_package": "", + "link_workspace": "", + "link_packages": {}, + "integrity": "sha512-vRIWpD/L4phf9Bk2o/O2TDR8fFoJnpYrp2TKqTIZF/qZ2/rgL3qKXzHofHgbXsinwMoSEigz28sqk3pQ+yMEQQ==", + "url": "", + "commit": "", + "patch_args": [ + "-p0" + ], + "patches": [], + "custom_postinstall": "", + "npm_auth": "", + "npm_auth_basic": "", + "npm_auth_username": "", + "npm_auth_password": "", + "lifecycle_hooks": [], + "extra_build_content": "load(\"@aspect_rules_js//js:defs.bzl\", \"js_binary\")\njs_binary(name = \"pnpm\", data = glob([\"package/**\"]), entry_point = \"package/dist/pnpm.cjs\", visibility = [\"//visibility:public\"])", + "generate_bzl_library_targets": false, + "extract_full_archive": true, + "exclude_package_contents": [], + "system_tar": "auto" + } + }, + "pnpm__links": { + "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_links", + "attributes": { + "package": "pnpm", + "version": "8.6.7", + "dev": false, + "root_package": "", + "link_packages": {}, + "deps": {}, + "transitive_closure": {}, + "lifecycle_build_target": false, + "lifecycle_hooks_env": [], + "lifecycle_hooks_execution_requirements": [ + "no-sandbox" + ], + "lifecycle_hooks_use_default_shell_env": false, + "bins": {}, + "package_visibility": [ + "//visibility:public" + ], + "replace_package": "", + "exclude_package_contents": [] + } + } + } + } + }, + "@@emsdk+//:emscripten_cache.bzl%emscripten_cache": { + "general": { + "bzlTransitiveDigest": "uqDvXmpTNqW4+ie/Fk+xC3TrFrKvL+9hNtoP51Kt2oo=", + "usagesDigest": "DiK4MwwPwWtYLSt+yREBFYKvCLbm0Cqdn0INE2VZjKM=", + "recordedInputs": [], + "generatedRepoSpecs": { + "emscripten_cache": { + "repoRuleId": "@@emsdk+//:emscripten_cache.bzl%_emscripten_cache_repository", + "attributes": { + "configuration": [], + "targets": [] + } + } + } + } + }, + "@@emsdk+//:emscripten_deps.bzl%emscripten_deps": { + "general": { + "bzlTransitiveDigest": "Q84yui7XG9DiK2HKzzr0oMDg3dpKQ5qZGvK9htQjy9Y=", + "usagesDigest": "yRGSmWwksrOI68EzUU8kC0L5tJnr2E2AVst3Nt5BY1s=", + "recordedInputs": [ + "REPO_MAPPING:bazel_tools,rules_cc rules_cc+", + "REPO_MAPPING:emsdk+,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "emscripten_bin_linux": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\npackage(default_visibility = ['//visibility:public'])\n\nfilegroup(\n name = \"all\",\n srcs = glob([\"**\"]),\n)\n\nfilegroup(\n name = \"includes\",\n srcs = glob([\n \"emscripten/cache/sysroot/include/c++/v1/**\",\n \"emscripten/cache/sysroot/include/compat/**\",\n \"emscripten/cache/sysroot/include/**\",\n \"lib/clang/**/include/**\",\n ]),\n)\n\nfilegroup(\n name = \"emcc_common\",\n srcs = [\n \"emscripten/emcc.py\",\n \"emscripten/embuilder.py\",\n \"emscripten/emscripten-version.txt\",\n \"emscripten/cache/sysroot_install.stamp\",\n \"emscripten/src/settings.js\",\n \"emscripten/src/settings_internal.js\",\n ] + glob(\n include = [\n \"emscripten/third_party/**\",\n \"emscripten/tools/**\",\n ],\n exclude = [\n \"**/__pycache__/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"compiler_files\",\n srcs = [\n \"bin/clang\",\n \"bin/clang++\",\n \":emcc_common\",\n \":includes\",\n ],\n)\n\nfilegroup(\n name = \"linker_files\",\n srcs = [\n \"bin/clang\",\n \"bin/llvm-ar\",\n \"bin/llvm-dwarfdump\",\n \"bin/llvm-nm\",\n \"bin/llvm-objcopy\",\n \"bin/wasm-ctor-eval\",\n \"bin/wasm-emscripten-finalize\",\n \"bin/wasm-ld\",\n \"bin/wasm-metadce\",\n \"bin/wasm-opt\",\n \"bin/wasm-split\",\n \"bin/wasm2js\",\n \":emcc_common\",\n ] + glob(\n include = [\n \"emscripten/cache/sysroot/lib/**\",\n \"emscripten/node_modules/**\",\n \"emscripten/src/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"ar_files\",\n srcs = [\n \"bin/llvm-ar\",\n \"emscripten/emar.py\",\n \"emscripten/emscripten-version.txt\",\n \"emscripten/src/settings.js\",\n \"emscripten/src/settings_internal.js\",\n ] + glob(\n include = [\n \"emscripten/tools/**\",\n ],\n exclude = [\n \"**/__pycache__/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"dwp_files\",\n srcs = [\n \"bin/llvm-dwp\",\n ],\n)\n\n", + "sha256": "5f1565fe45a1223cedf3b0300f5089c2c64954d2895b2aaedc85043c719be965", + "strip_prefix": "install", + "type": "tar.xz", + "url": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/linux/aaa43392544d695232b70eda706d751f18980c2a/wasm-binaries.tar.xz" + } + }, + "emscripten_bin_linux_arm64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\npackage(default_visibility = ['//visibility:public'])\n\nfilegroup(\n name = \"all\",\n srcs = glob([\"**\"]),\n)\n\nfilegroup(\n name = \"includes\",\n srcs = glob([\n \"emscripten/cache/sysroot/include/c++/v1/**\",\n \"emscripten/cache/sysroot/include/compat/**\",\n \"emscripten/cache/sysroot/include/**\",\n \"lib/clang/**/include/**\",\n ]),\n)\n\nfilegroup(\n name = \"emcc_common\",\n srcs = [\n \"emscripten/emcc.py\",\n \"emscripten/embuilder.py\",\n \"emscripten/emscripten-version.txt\",\n \"emscripten/cache/sysroot_install.stamp\",\n \"emscripten/src/settings.js\",\n \"emscripten/src/settings_internal.js\",\n ] + glob(\n include = [\n \"emscripten/third_party/**\",\n \"emscripten/tools/**\",\n ],\n exclude = [\n \"**/__pycache__/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"compiler_files\",\n srcs = [\n \"bin/clang\",\n \"bin/clang++\",\n \":emcc_common\",\n \":includes\",\n ],\n)\n\nfilegroup(\n name = \"linker_files\",\n srcs = [\n \"bin/clang\",\n \"bin/llvm-ar\",\n \"bin/llvm-dwarfdump\",\n \"bin/llvm-nm\",\n \"bin/llvm-objcopy\",\n \"bin/wasm-ctor-eval\",\n \"bin/wasm-emscripten-finalize\",\n \"bin/wasm-ld\",\n \"bin/wasm-metadce\",\n \"bin/wasm-opt\",\n \"bin/wasm-split\",\n \"bin/wasm2js\",\n \":emcc_common\",\n ] + glob(\n include = [\n \"emscripten/cache/sysroot/lib/**\",\n \"emscripten/node_modules/**\",\n \"emscripten/src/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"ar_files\",\n srcs = [\n \"bin/llvm-ar\",\n \"emscripten/emar.py\",\n \"emscripten/emscripten-version.txt\",\n \"emscripten/src/settings.js\",\n \"emscripten/src/settings_internal.js\",\n ] + glob(\n include = [\n \"emscripten/tools/**\",\n ],\n exclude = [\n \"**/__pycache__/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"dwp_files\",\n srcs = [\n \"bin/llvm-dwp\",\n ],\n)\n\n", + "sha256": "d8ed075930b397d3aed8a1c7558db1918ade786349b07d5c042dfa7f65f78563", + "strip_prefix": "install", + "type": "tar.xz", + "url": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/linux/aaa43392544d695232b70eda706d751f18980c2a/wasm-binaries-arm64.tar.xz" + } + }, + "emscripten_bin_mac": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\npackage(default_visibility = ['//visibility:public'])\n\nfilegroup(\n name = \"all\",\n srcs = glob([\"**\"]),\n)\n\nfilegroup(\n name = \"includes\",\n srcs = glob([\n \"emscripten/cache/sysroot/include/c++/v1/**\",\n \"emscripten/cache/sysroot/include/compat/**\",\n \"emscripten/cache/sysroot/include/**\",\n \"lib/clang/**/include/**\",\n ]),\n)\n\nfilegroup(\n name = \"emcc_common\",\n srcs = [\n \"emscripten/emcc.py\",\n \"emscripten/embuilder.py\",\n \"emscripten/emscripten-version.txt\",\n \"emscripten/cache/sysroot_install.stamp\",\n \"emscripten/src/settings.js\",\n \"emscripten/src/settings_internal.js\",\n ] + glob(\n include = [\n \"emscripten/third_party/**\",\n \"emscripten/tools/**\",\n ],\n exclude = [\n \"**/__pycache__/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"compiler_files\",\n srcs = [\n \"bin/clang\",\n \"bin/clang++\",\n \":emcc_common\",\n \":includes\",\n ],\n)\n\nfilegroup(\n name = \"linker_files\",\n srcs = [\n \"bin/clang\",\n \"bin/llvm-ar\",\n \"bin/llvm-dwarfdump\",\n \"bin/llvm-nm\",\n \"bin/llvm-objcopy\",\n \"bin/wasm-ctor-eval\",\n \"bin/wasm-emscripten-finalize\",\n \"bin/wasm-ld\",\n \"bin/wasm-metadce\",\n \"bin/wasm-opt\",\n \"bin/wasm-split\",\n \"bin/wasm2js\",\n \":emcc_common\",\n ] + glob(\n include = [\n \"emscripten/cache/sysroot/lib/**\",\n \"emscripten/node_modules/**\",\n \"emscripten/src/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"ar_files\",\n srcs = [\n \"bin/llvm-ar\",\n \"emscripten/emar.py\",\n \"emscripten/emscripten-version.txt\",\n \"emscripten/src/settings.js\",\n \"emscripten/src/settings_internal.js\",\n ] + glob(\n include = [\n \"emscripten/tools/**\",\n ],\n exclude = [\n \"**/__pycache__/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"dwp_files\",\n srcs = [\n \"bin/llvm-dwp\",\n ],\n)\n\n", + "sha256": "5823ef26fd45b5a960960fb53026513d43922eac7a1e3ba12d1344d7a94699f9", + "strip_prefix": "install", + "type": "tar.xz", + "url": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/mac/aaa43392544d695232b70eda706d751f18980c2a/wasm-binaries.tar.xz" + } + }, + "emscripten_bin_mac_arm64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\npackage(default_visibility = ['//visibility:public'])\n\nfilegroup(\n name = \"all\",\n srcs = glob([\"**\"]),\n)\n\nfilegroup(\n name = \"includes\",\n srcs = glob([\n \"emscripten/cache/sysroot/include/c++/v1/**\",\n \"emscripten/cache/sysroot/include/compat/**\",\n \"emscripten/cache/sysroot/include/**\",\n \"lib/clang/**/include/**\",\n ]),\n)\n\nfilegroup(\n name = \"emcc_common\",\n srcs = [\n \"emscripten/emcc.py\",\n \"emscripten/embuilder.py\",\n \"emscripten/emscripten-version.txt\",\n \"emscripten/cache/sysroot_install.stamp\",\n \"emscripten/src/settings.js\",\n \"emscripten/src/settings_internal.js\",\n ] + glob(\n include = [\n \"emscripten/third_party/**\",\n \"emscripten/tools/**\",\n ],\n exclude = [\n \"**/__pycache__/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"compiler_files\",\n srcs = [\n \"bin/clang\",\n \"bin/clang++\",\n \":emcc_common\",\n \":includes\",\n ],\n)\n\nfilegroup(\n name = \"linker_files\",\n srcs = [\n \"bin/clang\",\n \"bin/llvm-ar\",\n \"bin/llvm-dwarfdump\",\n \"bin/llvm-nm\",\n \"bin/llvm-objcopy\",\n \"bin/wasm-ctor-eval\",\n \"bin/wasm-emscripten-finalize\",\n \"bin/wasm-ld\",\n \"bin/wasm-metadce\",\n \"bin/wasm-opt\",\n \"bin/wasm-split\",\n \"bin/wasm2js\",\n \":emcc_common\",\n ] + glob(\n include = [\n \"emscripten/cache/sysroot/lib/**\",\n \"emscripten/node_modules/**\",\n \"emscripten/src/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"ar_files\",\n srcs = [\n \"bin/llvm-ar\",\n \"emscripten/emar.py\",\n \"emscripten/emscripten-version.txt\",\n \"emscripten/src/settings.js\",\n \"emscripten/src/settings_internal.js\",\n ] + glob(\n include = [\n \"emscripten/tools/**\",\n ],\n exclude = [\n \"**/__pycache__/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"dwp_files\",\n srcs = [\n \"bin/llvm-dwp\",\n ],\n)\n\n", + "sha256": "54234e108d6612eca5dc9280d1779ccec3d49ad4d8c8562a6b2046b0a5a8d5d4", + "strip_prefix": "install", + "type": "tar.xz", + "url": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/mac/aaa43392544d695232b70eda706d751f18980c2a/wasm-binaries-arm64.tar.xz" + } + }, + "emscripten_bin_win": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file_content": "\npackage(default_visibility = ['//visibility:public'])\n\nfilegroup(\n name = \"all\",\n srcs = glob([\"**\"]),\n)\n\nfilegroup(\n name = \"includes\",\n srcs = glob([\n \"emscripten/cache/sysroot/include/c++/v1/**\",\n \"emscripten/cache/sysroot/include/compat/**\",\n \"emscripten/cache/sysroot/include/**\",\n \"lib/clang/**/include/**\",\n ]),\n)\n\nfilegroup(\n name = \"emcc_common\",\n srcs = [\n \"emscripten/emcc.py\",\n \"emscripten/embuilder.py\",\n \"emscripten/emscripten-version.txt\",\n \"emscripten/cache/sysroot_install.stamp\",\n \"emscripten/src/settings.js\",\n \"emscripten/src/settings_internal.js\",\n ] + glob(\n include = [\n \"emscripten/third_party/**\",\n \"emscripten/tools/**\",\n ],\n exclude = [\n \"**/__pycache__/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"compiler_files\",\n srcs = [\n \"bin/clang.exe\",\n \"bin/clang++.exe\",\n \":emcc_common\",\n \":includes\",\n ],\n)\n\nfilegroup(\n name = \"linker_files\",\n srcs = [\n \"bin/clang.exe\",\n \"bin/llvm-ar.exe\",\n \"bin/llvm-dwarfdump.exe\",\n \"bin/llvm-nm.exe\",\n \"bin/llvm-objcopy.exe\",\n \"bin/wasm-ctor-eval.exe\",\n \"bin/wasm-emscripten-finalize.exe\",\n \"bin/wasm-ld.exe\",\n \"bin/wasm-metadce.exe\",\n \"bin/wasm-opt.exe\",\n \"bin/wasm-split.exe\",\n \"bin/wasm2js.exe\",\n \":emcc_common\",\n ] + glob(\n include = [\n \"emscripten/cache/sysroot/lib/**\",\n \"emscripten/node_modules/**\",\n \"emscripten/src/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"ar_files\",\n srcs = [\n \"bin/llvm-ar.exe\",\n \"emscripten/emar.py\",\n \"emscripten/emscripten-version.txt\",\n \"emscripten/src/settings.js\",\n \"emscripten/src/settings_internal.js\",\n ] + glob(\n include = [\n \"emscripten/tools/**\",\n ],\n exclude = [\n \"**/__pycache__/**\",\n ],\n ),\n)\n\nfilegroup(\n name = \"dwp_files\",\n srcs = [\n \"bin/llvm-dwp.exe\",\n ],\n)\n\n", + "sha256": "c2e1b9a2eed20f9d5903780b559ce2b384132713f07936512e6d962dd5a5dae6", + "strip_prefix": "install", + "type": "zip", + "url": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/win/aaa43392544d695232b70eda706d751f18980c2a/wasm-binaries.zip" + } + } + } + } + }, + "@@envoy+//bazel:extensions.bzl%envoy_build_config_ext": { + "general": { + "bzlTransitiveDigest": "gM+4MFQEhEBbNBGyiLVlJhaSpg+PYxiC5ggHyHH1K5Y=", + "usagesDigest": "hXcYHE/Dp6wWPc/BfVOhpmwVIXJo+egiHgop2RV+SwE=", + "recordedInputs": [ + "REPO_MAPPING:envoy+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:envoy+,bazel_tools bazel_tools", + "REPO_MAPPING:envoy+,cu envoy++wasm_cargo+cu", + "REPO_MAPPING:envoy+,envoy_toolshed envoy_toolshed+", + "REPO_MAPPING:envoy+,rules_rust rules_rust+", + "REPO_MAPPING:rules_rust+,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "envoy_build_config": { + "repoRuleId": "@@envoy+//bazel:envoy_build_config.bzl%default_envoy_build_config", + "attributes": {} + } + } + } + }, + "@@envoy+//bazel:extensions.bzl%envoy_llvm_extension": { + "general": { + "bzlTransitiveDigest": "gM+4MFQEhEBbNBGyiLVlJhaSpg+PYxiC5ggHyHH1K5Y=", + "usagesDigest": "2frsMvTYhSm06KaOlD06lMpwxLrMuLPog+GIIrRIGHI=", + "recordedInputs": [ + "REPO_MAPPING:envoy+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:envoy+,bazel_tools bazel_tools", + "REPO_MAPPING:envoy+,cu envoy++wasm_cargo+cu", + "REPO_MAPPING:envoy+,envoy_toolshed envoy_toolshed+", + "REPO_MAPPING:envoy+,rules_rust rules_rust+", + "REPO_MAPPING:rules_rust+,bazel_tools bazel_tools", + "REPO_MAPPING:envoy+,llvm_minimal_linux_x64 envoy_toolshed++llvm_minimal_extension+llvm_minimal_linux_x64", + "REPO_MAPPING:envoy+,llvm_minimal_linux_arm64 envoy_toolshed++llvm_minimal_extension+llvm_minimal_linux_arm64", + "REPO_MAPPING:envoy+,llvm_minimal_macos_arm64 envoy_toolshed++llvm_minimal_extension+llvm_minimal_macos_arm64" + ], + "generatedRepoSpecs": { + "llvm_toolchain_llvm": { + "repoRuleId": "@@envoy+//bazel:extensions.bzl%_llvm_alias_repo", + "attributes": { + "minimal_linux_x64": "@@envoy_toolshed++llvm_minimal_extension+llvm_minimal_linux_x64//:BUILD.bazel", + "minimal_linux_arm64": "@@envoy_toolshed++llvm_minimal_extension+llvm_minimal_linux_arm64//:BUILD.bazel", + "minimal_macos_arm64": "@@envoy_toolshed++llvm_minimal_extension+llvm_minimal_macos_arm64//:BUILD.bazel" + } + } + } + } + }, + "@@envoy+//bazel:extensions.bzl%envoy_module_graph_extension": { + "general": { + "bzlTransitiveDigest": "gM+4MFQEhEBbNBGyiLVlJhaSpg+PYxiC5ggHyHH1K5Y=", + "usagesDigest": "3kZLOs4LMLPfk4sJrOzP9Uiqq6maNbEmvUx7u9y0WpU=", + "recordedInputs": [ + "REPO_MAPPING:envoy+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:envoy+,bazel_tools bazel_tools", + "REPO_MAPPING:envoy+,cu envoy++wasm_cargo+cu", + "REPO_MAPPING:envoy+,envoy_toolshed envoy_toolshed+", + "REPO_MAPPING:envoy+,rules_rust rules_rust+", + "REPO_MAPPING:rules_rust+,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "envoy_mod_graph": { + "repoRuleId": "@@envoy+//bazel:extensions.bzl%_envoy_mod_graph_repo", + "attributes": { + "lockfile": "@@envoy+//:MODULE.bazel.lock" + } + } + } + } + }, + "@@envoy+//bazel:extensions.bzl%envoy_repo_extension": { + "general": { + "bzlTransitiveDigest": "gM+4MFQEhEBbNBGyiLVlJhaSpg+PYxiC5ggHyHH1K5Y=", + "usagesDigest": "JPan5EJba0XH4g5z0LkIL3XzA6Lo8N5AuJMtajlHkqg=", + "recordedInputs": [ + "REPO_MAPPING:envoy+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:envoy+,bazel_tools bazel_tools", + "REPO_MAPPING:envoy+,cu envoy++wasm_cargo+cu", + "REPO_MAPPING:envoy+,envoy_toolshed envoy_toolshed+", + "REPO_MAPPING:envoy+,rules_rust rules_rust+", + "REPO_MAPPING:rules_rust+,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "envoy_repo": { + "repoRuleId": "@@envoy+//bazel:repo.bzl%_envoy_repo", + "attributes": {} + } + } + } + }, + "@@envoy+//bazel:extensions.bzl%envoy_toolchains_extension": { + "general": { + "bzlTransitiveDigest": "gM+4MFQEhEBbNBGyiLVlJhaSpg+PYxiC5ggHyHH1K5Y=", + "usagesDigest": "WY4QAn4jcr1k1UynWUX8idOJIvH/64ZyE0GQQvqAI+8=", + "recordedInputs": [ + "REPO_MAPPING:envoy+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:envoy+,bazel_tools bazel_tools", + "REPO_MAPPING:envoy+,cu envoy++wasm_cargo+cu", + "REPO_MAPPING:envoy+,envoy_toolshed envoy_toolshed+", + "REPO_MAPPING:envoy+,rules_rust rules_rust+", + "REPO_MAPPING:rules_rust+,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "clang_platform": { + "repoRuleId": "@@envoy_toolshed+//repository:utils.bzl%arch_alias", + "attributes": { + "aliases": { + "amd64": "'@@envoy+//bazel/platforms/rbe:linux_x64'", + "aarch64": "'@@envoy+//bazel/platforms/rbe:linux_arm64'" + } + } + } + } + } + }, + "@@envoy_toolshed+//compile:extensions.bzl%libcxx_extension": { + "general": { + "bzlTransitiveDigest": "FAk0tz29uW57e0nJwa2r4vAg3PvC8JVFhZUHoK3t68E=", + "usagesDigest": "KpydMUF67Thjj7dxFRyP1XfRypHyTi2PieulXg/q++8=", + "recordedInputs": [], + "generatedRepoSpecs": { + "llvm_libcxx_aarch64": { + "repoRuleId": "@@envoy_toolshed+//compile:llvm_prebuilt.bzl%llvm_prebuilt", + "attributes": { + "sha256": "805efad2bb91cb4967fa569e0881d10c0f69c04461cf671cccbae19f547acc34", + "strip_prefix": "LLVM-22.1.8-Linux-ARM64/", + "url": "https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/LLVM-22.1.8-Linux-ARM64.tar.xz" + } + }, + "llvm_libcxx_x86_64": { + "repoRuleId": "@@envoy_toolshed+//compile:llvm_prebuilt.bzl%llvm_prebuilt", + "attributes": { + "sha256": "df0e1ecf16caf3489a272a5eea4eec9b0d82878f6477fa309504f918a0006384", + "strip_prefix": "LLVM-22.1.8-Linux-X64/", + "url": "https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/LLVM-22.1.8-Linux-X64.tar.xz" + } + } + } + } + }, + "@@envoy_toolshed+//compile:extensions.bzl%libcxx_libs_extension": { + "general": { + "bzlTransitiveDigest": "FAk0tz29uW57e0nJwa2r4vAg3PvC8JVFhZUHoK3t68E=", + "usagesDigest": "z47Defo42ymUqFSeAV/Zd/WotswORz2XQzadP9dIQ/I=", + "recordedInputs": [], + "generatedRepoSpecs": { + "libcxx_libs_aarch64": { + "repoRuleId": "@@envoy_toolshed+//compile:libcxx_libs.bzl%libcxx_libs", + "attributes": { + "version": "0.2.23", + "sha256": "b3bd8dfc1c250d5c2c36de174138ffef9754402b33e54abe9b5efb25982fa2f7", + "arch": "aarch64" + } + }, + "libcxx_libs_x86_64": { + "repoRuleId": "@@envoy_toolshed+//compile:libcxx_libs.bzl%libcxx_libs", + "attributes": { + "version": "0.2.23", + "sha256": "e40f39338ffe561dfa26541557c9e548fc7760db9d99f7b6c5de237b725482aa", + "arch": "x86_64" + } + } + } + } + }, + "@@envoy_toolshed+//compile:extensions.bzl%llvm_minimal_build_extension": { + "general": { + "bzlTransitiveDigest": "FAk0tz29uW57e0nJwa2r4vAg3PvC8JVFhZUHoK3t68E=", + "usagesDigest": "jRuNylX+Wvm9FUqKjwwEVWdejsJARKKUNm6FKUUVu90=", + "recordedInputs": [], + "generatedRepoSpecs": { + "llvm_tarball_linux_x86_64": { + "repoRuleId": "@@envoy_toolshed+//compile:llvm_minimal.bzl%llvm_tarball", + "attributes": { + "url": "https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/LLVM-22.1.8-Linux-X64.tar.xz", + "sha256": "df0e1ecf16caf3489a272a5eea4eec9b0d82878f6477fa309504f918a0006384", + "version": "22.1.8", + "platform": "Linux-X64" + } + }, + "llvm_tarball_linux_arm64": { + "repoRuleId": "@@envoy_toolshed+//compile:llvm_minimal.bzl%llvm_tarball", + "attributes": { + "url": "https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/LLVM-22.1.8-Linux-ARM64.tar.xz", + "sha256": "805efad2bb91cb4967fa569e0881d10c0f69c04461cf671cccbae19f547acc34", + "version": "22.1.8", + "platform": "Linux-ARM64" + } + }, + "llvm_tarball_macos_arm64": { + "repoRuleId": "@@envoy_toolshed+//compile:llvm_minimal.bzl%llvm_tarball", + "attributes": { + "url": "https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/LLVM-22.1.8-macOS-ARM64.tar.xz", + "sha256": "f260f4f7c0d430828a81ae8a3826a1d63fc0963ec2459489308cc23b1f7eab4f", + "version": "22.1.8", + "platform": "macOS-ARM64" + } + } + } + } + }, + "@@envoy_toolshed+//compile:extensions.bzl%llvm_minimal_extension": { + "general": { + "bzlTransitiveDigest": "FAk0tz29uW57e0nJwa2r4vAg3PvC8JVFhZUHoK3t68E=", + "usagesDigest": "nd8zmbfX+BIKHjNpn0Uu3prvphO/8AKVvH0kNcKYxq8=", + "recordedInputs": [], + "generatedRepoSpecs": { + "llvm_minimal_linux_x64": { + "repoRuleId": "@@envoy_toolshed+//compile:llvm_minimal.bzl%llvm_minimal_repo", + "attributes": { + "url": "https://github.com/envoyproxy/toolshed/releases/download/bins-v0.2.23/llvm-minimal-22.1.8-Linux-X64.tar.zst", + "sha256": "6cb4cca6df33be00c80fa1639062c973d1cafe4e7ad98a9b4bdf21bf9dec5806", + "strip_prefix": "llvm-minimal-22.1.8-Linux-X64" + } + }, + "llvm_minimal_linux_arm64": { + "repoRuleId": "@@envoy_toolshed+//compile:llvm_minimal.bzl%llvm_minimal_repo", + "attributes": { + "url": "https://github.com/envoyproxy/toolshed/releases/download/bins-v0.2.23/llvm-minimal-22.1.8-Linux-ARM64.tar.zst", + "sha256": "9a6cc0a84d524342e578db739b04e8a3875adb40b38887e4e074661e925f8a9c", + "strip_prefix": "llvm-minimal-22.1.8-Linux-ARM64" + } + }, + "llvm_minimal_macos_arm64": { + "repoRuleId": "@@envoy_toolshed+//compile:llvm_minimal.bzl%llvm_minimal_repo", + "attributes": { + "url": "https://github.com/envoyproxy/toolshed/releases/download/bins-v0.2.23/llvm-minimal-22.1.8-macOS-ARM64.tar.zst", + "sha256": "928e51aa7c97fbb8c5c50075118f4b36e36363b1a2c3af2dfef9aea1ef526ade", + "strip_prefix": "llvm-minimal-22.1.8-macOS-ARM64" + } + } + } + } + }, + "@@envoy_toolshed+//compile:extensions.bzl%sanitizer_extension": { + "general": { + "bzlTransitiveDigest": "FAk0tz29uW57e0nJwa2r4vAg3PvC8JVFhZUHoK3t68E=", + "usagesDigest": "hakpQpF46t2OQfRzm/zoeJQF2gQG+W9JVF7J4xeiVFk=", + "recordedInputs": [], + "generatedRepoSpecs": { + "msan_libs": { + "repoRuleId": "@@envoy_toolshed+//compile:sanitizer_libs.bzl%msan_libs", + "attributes": { + "version": "0.2.23", + "sha256": "b5f15d019676ee76819ad5af92cf24adc16906fc5092c1ceca5f8cc753bf552b" + } + }, + "tsan_libs": { + "repoRuleId": "@@envoy_toolshed+//compile:sanitizer_libs.bzl%tsan_libs", + "attributes": { + "version": "0.2.23", + "sha256": "3352042f6521380ad99ae268d3cb15a2690ee0db00b9ebc340c8c5024f62b0c7" + } + } + } + } + }, + "@@envoy_toolshed+//coverage/grcov:extensions.bzl%grcov_extension": { + "general": { + "bzlTransitiveDigest": "SyRcRSF+Fq3fTnEFDCNdy6s7CoJ04VJDp7lP6OLpgOM=", + "usagesDigest": "vKRLRKLTY5/jItKBUf9U/LlwpptIF7KnxaoBSXw/adU=", + "recordedInputs": [ + "REPO_MAPPING:envoy_toolshed+,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "grcov": { + "repoRuleId": "@@envoy_toolshed+//coverage/grcov:grcov_repository.bzl%_grcov_repo", + "attributes": {} + } + } + } + }, + "@@envoy_toolshed+//git:extensions.bzl%git_prebuilt_extension": { + "general": { + "bzlTransitiveDigest": "5ZRMRbIOT+BBABXHryAlS79rhb6WBwEZ1fVjRum1jeQ=", + "usagesDigest": "Q4r8Oa3HkQF1pFfbBkl3hDiRmhBpigAOf+9MvLoPeh8=", + "recordedInputs": [], + "generatedRepoSpecs": { + "cacert": { + "repoRuleId": "@@envoy_toolshed+//git/private:git_prebuilt.bzl%git_cacert", + "attributes": { + "sha256": "f66dff1bdf8f96060b8177976f8b7d9254bc89bc4db933d769f7384d28480bc9", + "url": "https://curl.se/ca/cacert-2026-08-13.pem" + } + }, + "git_prebuilt_linux_aarch64": { + "repoRuleId": "@@envoy_toolshed+//git/private:git_prebuilt.bzl%git_prebuilt", + "attributes": { + "sha256": "0dc042b8ff743cd586db630a859a6948395e99fe1c5ee258dea65322630092b4", + "strip_prefix": "git-2.55.0-linux-aarch64", + "url": "https://github.com/envoyproxy/toolshed/releases/download/bins-v0.2.23/git-2.55.0-linux-aarch64.tar.zst" + } + }, + "git_prebuilt_linux_x86_64": { + "repoRuleId": "@@envoy_toolshed+//git/private:git_prebuilt.bzl%git_prebuilt", + "attributes": { + "sha256": "6dd7d1fe0238bd655c9a9763e9f3bb6130f5d7f6c40b26e4935a17660e8525db", + "strip_prefix": "git-2.55.0-linux-x86_64", + "url": "https://github.com/envoyproxy/toolshed/releases/download/bins-v0.2.23/git-2.55.0-linux-x86_64.tar.zst" + } + }, + "git_toolchains": { + "repoRuleId": "@@envoy_toolshed+//git/private:git_prebuilt.bzl%git_toolchains_hub", + "attributes": { + "defs_label": "'@@envoy_toolshed+//git:defs.bzl'", + "linux_aarch64": "@@envoy_toolshed++git_prebuilt_extension+git_prebuilt_linux_aarch64//:BUILD.bazel", + "linux_x86_64": "@@envoy_toolshed++git_prebuilt_extension+git_prebuilt_linux_x86_64//:BUILD.bazel", + "toolchain_type_label": "'@@envoy_toolshed+//git:toolchain_type'" + } + } + } + } + }, + "@@envoy_toolshed+//pgp:extensions.bzl%sq_prebuilt_extension": { + "general": { + "bzlTransitiveDigest": "UxPiIQxK40GsEEIPdBH6fJPwRh1hI5+roUfjYxOmTlo=", + "usagesDigest": "yodpbbAW7VTcBmwifR9cm+T1W1CK0p9qDZx8TC1IVSw=", + "recordedInputs": [], + "generatedRepoSpecs": { + "sq_prebuilt_linux_aarch64": { + "repoRuleId": "@@envoy_toolshed+//pgp/private:sq_prebuilt.bzl%sq_prebuilt", + "attributes": { + "sha256": "cdff7b439ddf9e10c6b860ea780cfcc23f976691e0154a7567c0deb0135360c3", + "strip_prefix": "sq-1.4.0-Linux-ARM64", + "url": "https://github.com/envoyproxy/toolshed/releases/download/bins-v0.2.23/sq-1.4.0-Linux-ARM64.tar.zst" + } + }, + "sq_prebuilt_linux_x86_64": { + "repoRuleId": "@@envoy_toolshed+//pgp/private:sq_prebuilt.bzl%sq_prebuilt", + "attributes": { + "sha256": "cd0c003c86f6947cc43a6f4305ce04898e073deb297e598c7677b0d651fbf559", + "strip_prefix": "sq-1.4.0-Linux-X64", + "url": "https://github.com/envoyproxy/toolshed/releases/download/bins-v0.2.23/sq-1.4.0-Linux-X64.tar.zst" + } + }, + "sq_toolchains": { + "repoRuleId": "@@envoy_toolshed+//pgp/private:sq_prebuilt.bzl%sq_toolchains_hub", + "attributes": { + "defs_label": "'@@envoy_toolshed+//pgp:defs.bzl'", + "linux_aarch64": "@@envoy_toolshed++sq_prebuilt_extension+sq_prebuilt_linux_aarch64//:BUILD.bazel", + "linux_x86_64": "@@envoy_toolshed++sq_prebuilt_extension+sq_prebuilt_linux_x86_64//:BUILD.bazel", + "toolchain_type_label": "'@@envoy_toolshed+//pgp:toolchain_type'" + } + } + } + } + }, + "@@envoy_toolshed+//sysroot:extensions.bzl%sysroot_extension": { + "general": { + "bzlTransitiveDigest": "pSz8jmJCdz72tsMp9Bp93ZvZ/uGge14iL1mI9Kw7xa8=", + "usagesDigest": "nSDDX99vyIfwgBgpFKfFOenma3fzdgW2DxMaRUaLQuk=", + "recordedInputs": [], + "generatedRepoSpecs": { + "sysroot_linux_amd64": { + "repoRuleId": "@@envoy_toolshed+//sysroot:sysroot.bzl%sysroot", + "attributes": { + "version": "0.2.23", + "sha256": "a7292fa1631db7f385d142451776e088a17182f0140b299720b5213ab599e861", + "arch": "amd64", + "glibc_version": "2.31", + "stdcc_version": "13" + } + }, + "sysroot_linux_arm64": { + "repoRuleId": "@@envoy_toolshed+//sysroot:sysroot.bzl%sysroot", + "attributes": { + "version": "0.2.23", + "sha256": "2e2c3669a2066a2455864ef4a54ee53d5ff09ab76579d5249b4cbde6b5aa1e4c", + "arch": "arm64", + "glibc_version": "2.31", + "stdcc_version": "13" + } + } + } + } + }, + "@@go-fips+//:go_fips_ext.bzl%go_fips_ext": { + "general": { + "bzlTransitiveDigest": "lMQIBNIBBHD/UxyWYiJUKSQj23kpxdWAO/1DuRGPBdg=", + "usagesDigest": "KD7U/Yu7/GNh9AFeLAMZ/hLUi1pfm9TI4UUrwGRsaBU=", + "recordedInputs": [], + "generatedRepoSpecs": { + "go_fips_host": { + "repoRuleId": "@@go-fips+//:go_fips.bzl%go_fips", + "attributes": {} + } + } + } + }, + "@@googleapis+//:extensions.bzl%switched_rules": { + "general": { + "bzlTransitiveDigest": "1ZTg77R3Ks/ksx8QMNIoTRJetbJPRlzGFlJa9hoUn+Y=", + "usagesDigest": "ENbY7cA6Dq8i+MLmFyh8iUuqOOgsS08lNyoCC7tO8ck=", + "recordedInputs": [], + "generatedRepoSpecs": {} + } + }, + "@@grpc+//bazel:extensions.bzl%exec_properties": { + "general": { + "bzlTransitiveDigest": "C9g6ijTS6Lje+XG5c5mDmAaZaTlui4lk3BEeg1bUjFA=", + "usagesDigest": "DxxfBGY1W38OkvKpXj7NuZtWDNWR5jqAS99gtmGPBaQ=", + "recordedInputs": [ + "REPO_MAPPING:grpc+,bazel_toolchains grpc++_repo_rules+bazel_toolchains" + ], + "generatedRepoSpecs": { + "grpc_custom_exec_properties": { + "repoRuleId": "@@grpc++_repo_rules+bazel_toolchains//rules/exec_properties:exec_properties.bzl%_exec_property_sets_repository", + "attributes": { + "constants_bzl_content": "LARGE_MACHINE = {\"label:os\": \"ubuntu\", \"label:machine_size\": \"large\"}\n" + } + } + } + } + }, + "@@grpc-httpjson-transcoding+//:extensions.bzl%non_module_deps": { + "general": { + "bzlTransitiveDigest": "uHh/mUuFwB6Voj6CEKd0d2223B3VA6HTKMzGoGJxfjg=", + "usagesDigest": "12HwAa+jGkwAa6tGGKn6vop8VOPfANQP2FiMnhV71ns=", + "recordedInputs": [ + "REPO_MAPPING:grpc-httpjson-transcoding+,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "com_google_googleapis": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://github.com/googleapis/googleapis/archive/1d5522ad1056f16a6d593b8f3038d831e64daeea.tar.gz", + "sha256": "cd13e547cffaad217c942084fd5ae0985a293d0cce3e788c20796e5e2ea54758", + "strip_prefix": "googleapis-1d5522ad1056f16a6d593b8f3038d831e64daeea" + } + } + } + } + }, + "@@grpc-httpjson-transcoding+//:googleapis_ext.bzl%googleapis_ext": { + "general": { + "bzlTransitiveDigest": "n+E0pdKhXBNEdjfE/AGncepD7Eh9xX07wWf4cO5og6w=", + "usagesDigest": "Fc3I6XGHAyLwbQotH5z/MZl1mX7S7/kLiVXrDi7smjA=", + "recordedInputs": [ + "REPO_MAPPING:grpc-httpjson-transcoding+,com_google_googleapis grpc-httpjson-transcoding++non_module_deps+com_google_googleapis" + ], + "generatedRepoSpecs": { + "com_google_googleapis_imports": { + "repoRuleId": "@@grpc-httpjson-transcoding++non_module_deps+com_google_googleapis//:repository_rules.bzl%switched_rules", + "attributes": { + "rules": { + "proto_library_with_info": [ + "", + "" + ], + "moved_proto_library": [ + "", + "" + ], + "java_proto_library": [ + "", + "" + ], + "java_grpc_library": [ + "", + "" + ], + "java_gapic_library": [ + "", + "" + ], + "java_resource_name_proto_library": [ + "", + "" + ], + "java_gapic_test": [ + "", + "" + ], + "java_gapic_assembly_gradle_pkg": [ + "", + "" + ], + "py_proto_library": [ + "", + "" + ], + "py_grpc_library": [ + "", + "" + ], + "py_gapic_library": [ + "", + "" + ], + "py_gapic_assembly_pkg": [ + "", + "" + ], + "py_gapic_library2": [ + "", + "py_gapic_library" + ], + "py_gapic_assembly_pkg2": [ + "", + "py_gapic_assembly_pkg" + ], + "go_proto_library": [ + "", + "" + ], + "go_library": [ + "", + "" + ], + "go_test": [ + "", + "" + ], + "go_gapic_library": [ + "", + "" + ], + "go_gapic_assembly_pkg": [ + "", + "" + ], + "cc_proto_library": [ + "native.cc_proto_library", + "" + ], + "cc_grpc_library": [ + "", + "" + ], + "cc_gapic_library": [ + "", + "" + ], + "php_proto_library": [ + "", + "" + ], + "php_grpc_library": [ + "", + "" + ], + "php_gapic_library": [ + "", + "" + ], + "php_gapic_assembly_pkg": [ + "", + "" + ], + "nodejs_gapic_library": [ + "", + "typescript_gapic_library" + ], + "nodejs_gapic_assembly_pkg": [ + "", + "typescript_gapic_assembly_pkg" + ], + "ruby_proto_library": [ + "", + "" + ], + "ruby_grpc_library": [ + "", + "" + ], + "ruby_gapic_library": [ + "", + "" + ], + "ruby_ads_gapic_library": [ + "", + "" + ], + "ruby_cloud_gapic_library": [ + "", + "" + ], + "ruby_gapic_assembly_pkg": [ + "", + "" + ], + "csharp_proto_library": [ + "", + "" + ], + "csharp_grpc_library": [ + "", + "" + ], + "csharp_gapic_library": [ + "", + "" + ], + "csharp_gapic_assembly_pkg": [ + "", + "" + ] + } + } + } + } + } + }, + "@@protobuf+//python/dist:system_python.bzl%system_python_extension": { + "general": { + "bzlTransitiveDigest": "qh0n9IrXU/xS94wxKQrG1J63zrLkA1Wy2Y3BQxptPcI=", + "usagesDigest": "DCJhR7LPgXJ//Na7lsN0d5+HulnHLKpkspMdWCAmYDU=", + "recordedInputs": [], + "generatedRepoSpecs": { + "system_python": { + "repoRuleId": "@@protobuf+//python/dist:system_python.bzl%system_python", + "attributes": { + "minimum_python_version": "3.9" + } + } + } + } + }, + "@@rules_android+//bzlmod_extensions:apksig.bzl%apksig_extension": { + "general": { + "bzlTransitiveDigest": "c6mHv2L0P+tWDe7lh/mpzTEedvukBq17Gr9gP16UdxU=", + "usagesDigest": "zr/niBQ/s2fHozWAsg4vI70wAxcuFjG+QtM15qGkq9o=", + "recordedInputs": [ + "REPO_MAPPING:rules_android+,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "apksig": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://android.googlesource.com/platform/tools/apksig/+archive/24e3075e68ebe17c0b529bb24bfda819db5e2f3b.tar.gz", + "build_file": "@@rules_android+//bzlmod_extensions:apksig.BUILD" + } + } + } + } + }, + "@@rules_android+//bzlmod_extensions:com_android_dex.bzl%com_android_dex_extension": { + "general": { + "bzlTransitiveDigest": "BbM3I4LvjudqQ6/IwaP/LaJXdj2EPfqPleTjiFG4Lg0=", + "usagesDigest": "c1Y/KGGjUYCyd8zNIVTUh1bynVXRFz6xGKaSCBpQANM=", + "recordedInputs": [ + "REPO_MAPPING:rules_android+,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "com_android_dex": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://android.googlesource.com/platform/dalvik/+archive/5a81c499a569731e2395f7c8d13c0e0d4e17a2b6.tar.gz", + "build_file": "@@rules_android+//bzlmod_extensions:com_android_dex.BUILD" + } + } + } + } + }, + "@@rules_android+//rules/android_sdk_repository:rule.bzl%android_sdk_repository_extension": { + "general": { + "bzlTransitiveDigest": "+rMrzIrv7sImYmkbXJYv+gFpTJQ79X3MpwwMLI2A+oA=", + "usagesDigest": "iEGI2aNDMkHt9LXCdViLNUUOslpiVj2DrevWWXZEFnU=", + "recordedInputs": [], + "generatedRepoSpecs": { + "androidsdk": { + "repoRuleId": "@@rules_android+//rules/android_sdk_repository:rule.bzl%_android_sdk_repository", + "attributes": {} + } + } + } + }, + "@@rules_buf+//buf:extensions.bzl%buf": { + "general": { + "bzlTransitiveDigest": "IjW2he5lp+L/zEfsBKIilXijyHH6PC4Lf3y19MA6G4c=", + "usagesDigest": "Qg1rLbuptbACkOJHg4/XUGk3PZu3kdJ8kvvXmQ0GRFo=", + "recordedInputs": [ + "REPO_MAPPING:rules_buf+,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "rules_buf_toolchains": { + "repoRuleId": "@@rules_buf+//buf/internal:toolchain.bzl%buf_download_releases", + "attributes": { + "version": "v1.61.0", + "sha256": "366ed6c11819d56e122042c18cb8dbcf012f773456821f15324c22d192dfc65c" + } + } + } + } + }, + "@@rules_m4+//m4/internal:default_toolchain_ext.bzl%default_toolchain_ext": { + "general": { + "bzlTransitiveDigest": "tdX+2sxsI0cUAT/hNag1pWuAZVRyakmuNkW1hjVYEqA=", + "usagesDigest": "Ajj5C5Smb9328fDq6XiGNG7n46AVKp8cwF+3Rli07AA=", + "recordedInputs": [], + "generatedRepoSpecs": { + "m4_v1.4.18": { + "repoRuleId": "@@rules_m4+//m4/rules:m4_repository.bzl%m4_repository", + "attributes": { + "version": "1.4.18" + } + }, + "m4": { + "repoRuleId": "@@rules_m4+//m4/rules:m4_toolchain_repository.bzl%m4_toolchain_repository", + "attributes": { + "m4_repository": "@m4_v1.4.18" + } + } + }, + "moduleExtensionMetadata": { + "explicitRootModuleDirectDeps": [ + "m4" + ], + "explicitRootModuleDirectDevDeps": [], + "useAllRepos": "NO", + "reproducible": false + } + } + }, + "@@rules_nodejs+//nodejs:extensions.bzl%node": { + "general": { + "bzlTransitiveDigest": "q44Ox2Nwogn6OsO0Xw5lhjkd/xmxkvvpwVOn5P4pmHQ=", + "usagesDigest": "APcBjUh7j4UUNtZ16FonkFYE68qQt5/vMEYCyHxAeaQ=", + "recordedInputs": [], + "generatedRepoSpecs": { + "nodejs_linux_amd64": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "20.18.0", + "include_headers": false, + "platform": "linux_amd64" + } + }, + "nodejs_linux_arm64": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "20.18.0", + "include_headers": false, + "platform": "linux_arm64" + } + }, + "nodejs_linux_s390x": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "20.18.0", + "include_headers": false, + "platform": "linux_s390x" + } + }, + "nodejs_linux_ppc64le": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "20.18.0", + "include_headers": false, + "platform": "linux_ppc64le" + } + }, + "nodejs_darwin_amd64": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "20.18.0", + "include_headers": false, + "platform": "darwin_amd64" + } + }, + "nodejs_darwin_arm64": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "20.18.0", + "include_headers": false, + "platform": "darwin_arm64" + } + }, + "nodejs_windows_amd64": { + "repoRuleId": "@@rules_nodejs+//nodejs:repositories.bzl%_nodejs_repositories", + "attributes": { + "node_download_auth": {}, + "node_repositories": {}, + "node_urls": [ + "https://nodejs.org/dist/v{version}/{filename}" + ], + "node_version": "20.18.0", + "include_headers": false, + "platform": "windows_amd64" + } + }, + "nodejs": { + "repoRuleId": "@@rules_nodejs+//nodejs/private:nodejs_repo_host_os_alias.bzl%nodejs_repo_host_os_alias", + "attributes": { + "user_node_repository_name": "nodejs" + } + }, + "nodejs_host": { + "repoRuleId": "@@rules_nodejs+//nodejs/private:nodejs_repo_host_os_alias.bzl%nodejs_repo_host_os_alias", + "attributes": { + "user_node_repository_name": "nodejs" + } + }, + "nodejs_toolchains": { + "repoRuleId": "@@rules_nodejs+//nodejs/private:nodejs_toolchains_repo.bzl%nodejs_toolchains_repo", + "attributes": { + "user_node_repository_name": "nodejs" + } + } + } + } + }, + "@@rules_python+//python/uv:uv.bzl%uv": { + "general": { + "bzlTransitiveDigest": "DafUArm1CsjJZcemT0FvUq9rUch+pq38+JqfOBJCpm8=", + "usagesDigest": "/es1dlCJ3YpjHVj8EkSHb7nx0o2eC4dyZXjkDGxgiXY=", + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,platforms platforms" + ], + "generatedRepoSpecs": { + "uv": { + "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", + "attributes": { + "toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'", + "toolchain_names": [ + "none" + ], + "toolchain_implementations": { + "none": "'@@rules_python+//python:none'" + }, + "toolchain_compatible_with": { + "none": [ + "@platforms//:incompatible" + ] + }, + "toolchain_target_settings": {} + } + } + } + } + }, + "@@rules_rust+//crate_universe/private:internal_extensions.bzl%cu_nr": { + "general": { + "bzlTransitiveDigest": "kSFvEzee2s9COJDr+5d4xI+bjaVAOXds3Khfd3B6ss8=", + "usagesDigest": "+xr3f1ewo4VN0JZZlHeH6XP9L+y0pK5+0aldnWk0Z5o=", + "recordedInputs": [ + "REPO_MAPPING:apple_support+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:bazel_features+,bazel_features_globals bazel_features++version_extension+bazel_features_globals", + "REPO_MAPPING:bazel_features+,bazel_features_version bazel_features++version_extension+bazel_features_version", + "REPO_MAPPING:rules_cc+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_cc+,cc_compatibility_proxy rules_cc++compatibility_proxy+cc_compatibility_proxy", + "REPO_MAPPING:rules_cc+,rules_cc rules_cc+", + "REPO_MAPPING:rules_cc++compatibility_proxy+cc_compatibility_proxy,rules_cc rules_cc+", + "REPO_MAPPING:rules_rust+,apple_support apple_support+", + "REPO_MAPPING:rules_rust+,bazel_features bazel_features+", + "REPO_MAPPING:rules_rust+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:rules_rust+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_rust+,cui rules_rust++cu+cui", + "REPO_MAPPING:rules_rust+,rrc rules_rust++i2+rrc", + "REPO_MAPPING:rules_rust+,rules_cc rules_cc+", + "REPO_MAPPING:rules_rust+,rules_rust rules_rust+" + ], + "generatedRepoSpecs": { + "cargo_bazel_bootstrap": { + "repoRuleId": "@@rules_rust+//cargo/private:cargo_bootstrap.bzl%cargo_bootstrap_repository", + "attributes": { + "srcs": [ + "@@rules_rust+//crate_universe:src/api.rs", + "@@rules_rust+//crate_universe:src/api/lockfile.rs", + "@@rules_rust+//crate_universe:src/cli.rs", + "@@rules_rust+//crate_universe:src/cli/generate.rs", + "@@rules_rust+//crate_universe:src/cli/query.rs", + "@@rules_rust+//crate_universe:src/cli/render.rs", + "@@rules_rust+//crate_universe:src/cli/splice.rs", + "@@rules_rust+//crate_universe:src/cli/vendor.rs", + "@@rules_rust+//crate_universe:src/config.rs", + "@@rules_rust+//crate_universe:src/config/label_injection.rs", + "@@rules_rust+//crate_universe:src/context.rs", + "@@rules_rust+//crate_universe:src/context/crate_context.rs", + "@@rules_rust+//crate_universe:src/context/platforms.rs", + "@@rules_rust+//crate_universe:src/lib.rs", + "@@rules_rust+//crate_universe:src/lockfile.rs", + "@@rules_rust+//crate_universe:src/main.rs", + "@@rules_rust+//crate_universe:src/metadata.rs", + "@@rules_rust+//crate_universe:src/metadata/cargo_bin.rs", + "@@rules_rust+//crate_universe:src/metadata/cargo_tree_resolver.rs", + "@@rules_rust+//crate_universe:src/metadata/cargo_tree_rustc_wrapper.bat", + "@@rules_rust+//crate_universe:src/metadata/cargo_tree_rustc_wrapper.sh", + "@@rules_rust+//crate_universe:src/metadata/dependency.rs", + "@@rules_rust+//crate_universe:src/metadata/metadata_annotation.rs", + "@@rules_rust+//crate_universe:src/rendering.rs", + "@@rules_rust+//crate_universe:src/rendering/template_engine.rs", + "@@rules_rust+//crate_universe:src/rendering/templates/defs_bzl_shim.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/module_bzl.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/header.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/module/aliases_map.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/module/deps_map.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/module/repo_git.j2", + "@@rules_rust+//crate_universe:src/rendering/templates/partials/module/repo_http.j2", + "@@rules_rust+//crate_universe:src/rendering/verbatim/alias_rules.bzl", + "@@rules_rust+//crate_universe:src/select.rs", + "@@rules_rust+//crate_universe:src/splicing.rs", + "@@rules_rust+//crate_universe:src/splicing/cargo_config.rs", + "@@rules_rust+//crate_universe:src/splicing/crate_index_lookup.rs", + "@@rules_rust+//crate_universe:src/splicing/splicer.rs", + "@@rules_rust+//crate_universe:src/test.rs", + "@@rules_rust+//crate_universe:src/utils.rs", + "@@rules_rust+//crate_universe:src/utils/starlark.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/glob.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/label.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select_dict.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select_list.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select_scalar.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/select_set.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/serialize.rs", + "@@rules_rust+//crate_universe:src/utils/starlark/target_compatible_with.rs", + "@@rules_rust+//crate_universe:src/utils/symlink.rs", + "@@rules_rust+//crate_universe:src/utils/target_triple.rs" + ], + "binary": "cargo-bazel", + "cargo_lockfile": "@@rules_rust+//crate_universe:Cargo.lock", + "cargo_toml": "@@rules_rust+//crate_universe:Cargo.toml", + "version": "1.98.0", + "rust_toolchain_cargo_template": "@rust_host_tools//:bin/{tool}", + "rust_toolchain_rustc_template": "@rust_host_tools//:bin/{tool}", + "compressed_windows_toolchain_names": false, + "timeout": 900 + } + } + }, + "moduleExtensionMetadata": { + "explicitRootModuleDirectDeps": [ + "cargo_bazel_bootstrap" + ], + "explicitRootModuleDirectDevDeps": [], + "useAllRepos": "NO", + "reproducible": false + } + } + }, + "@@toolchains_llvm+//toolchain/extensions:distributions.bzl%llvm_distributions": { + "general": { + "bzlTransitiveDigest": "UjfWy+RWdwj4BIiZFchPZA3MIBFUkIKzj19B8/LDGko=", + "usagesDigest": "NoF2xWM7E9on7bEM7283H7kEJ95BRIGpgF8KYDK1VnY=", + "recordedInputs": [], + "generatedRepoSpecs": { + "llvm_distributions_data": { + "repoRuleId": "@@toolchains_llvm+//toolchain/internal:distributions_repo.bzl%llvm_distributions_repo", + "attributes": { + "srcs": [ + "@@toolchains_llvm+//toolchain/distributions:pre_github.jsonc", + "@@toolchains_llvm+//toolchain/distributions:github_legacy.jsonc", + "@@toolchains_llvm+//toolchain/distributions:github.jsonc", + "@@toolchains_llvm+//toolchain/distributions:extra.jsonc" + ] + } + } + } + } + }, + "@@yq.bzl+//yq:extensions.bzl%yq": { + "general": { + "bzlTransitiveDigest": "pBdvRkVUaEmOKUs6XG10RiM1hOIlKNePWVmOVaSA3zU=", + "usagesDigest": "hd8MT/67pD7UqQ3AU0Jhz5KEui9gNjbek0zoPemsW/c=", + "recordedInputs": [ + "REPO_MAPPING:yq.bzl+,bazel_lib bazel_lib+" + ], + "generatedRepoSpecs": { + "yq_darwin_amd64": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "darwin_amd64", + "version": "4.45.2" + } + }, + "yq_darwin_arm64": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "darwin_arm64", + "version": "4.45.2" + } + }, + "yq_linux_amd64": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "linux_amd64", + "version": "4.45.2" + } + }, + "yq_linux_arm64": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "linux_arm64", + "version": "4.45.2" + } + }, + "yq_linux_s390x": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "linux_s390x", + "version": "4.45.2" + } + }, + "yq_linux_riscv64": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "linux_riscv64", + "version": "4.45.2" + } + }, + "yq_linux_ppc64le": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "linux_ppc64le", + "version": "4.45.2" + } + }, + "yq_windows_amd64": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "windows_amd64", + "version": "4.45.2" + } + }, + "yq_windows_arm64": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", + "attributes": { + "platform": "windows_arm64", + "version": "4.45.2" + } + }, + "yq_toolchains": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:toolchain.bzl%yq_toolchains_repo", + "attributes": { + "user_repository_name": "yq" + } + }, + "yq": { + "repoRuleId": "@@yq.bzl+//yq/toolchain:toolchain.bzl%yq_host_alias_repo", + "attributes": {} + } + } + } + } + }, + "facts": { + "@@rules_go+//go:extensions.bzl%go_sdk": { + "1.22.4": { + "aix_ppc64": [ + "go1.22.4.aix-ppc64.tar.gz", + "b9647fa9fc83a0cc5d4f092a19eaeaecf45f063a5aa7d4962fde65aeb7ae6ce1" + ], + "darwin_amd64": [ + "go1.22.4.darwin-amd64.tar.gz", + "c95967f50aa4ace34af0c236cbdb49a9a3e80ee2ad09d85775cb4462a5c19ed3" + ], + "darwin_arm64": [ + "go1.22.4.darwin-arm64.tar.gz", + "242b78dc4c8f3d5435d28a0d2cec9b4c1aa999b601fb8aa59fb4e5a1364bf827" + ], + "dragonfly_amd64": [ + "go1.22.4.dragonfly-amd64.tar.gz", + "f2fbb51af4719d3616efb482d6ed2b96579b474156f85a7ddc6f126764feec4b" + ], + "freebsd_386": [ + "go1.22.4.freebsd-386.tar.gz", + "7c54884bb9f274884651d41e61d1bc12738863ad1497e97ea19ad0e9aa6bf7b5" + ], + "freebsd_amd64": [ + "go1.22.4.freebsd-amd64.tar.gz", + "88d44500e1701dd35797619774d6dd51bf60f45a8338b0a82ddc018e4e63fb78" + ], + "freebsd_arm64": [ + "go1.22.4.freebsd-arm64.tar.gz", + "726dc093cf020277be45debf03c3b02b43c2efb3e2a5d4fba8f52579d65327dc" + ], + "freebsd_armv6l": [ + "go1.22.4.freebsd-arm.tar.gz", + "3d9efe47db142a22679aba46b1772e3900b0d87ae13bd2b3bc80dbf2ac0b2cd6" + ], + "freebsd_riscv64": [ + "go1.22.4.freebsd-riscv64.tar.gz", + "5f6b67e5e32f1d6ccb2d4dcb44934a5e2e870a877ba7443d86ec43cfc28afa71" + ], + "illumos_amd64": [ + "go1.22.4.illumos-amd64.tar.gz", + "d56ecc2f85b6418a21ef83879594d0c42ab4f65391a676bb12254870e6690d63" + ], + "linux_386": [ + "go1.22.4.linux-386.tar.gz", + "47a2a8d249a91eb8605c33bceec63aedda0441a43eac47b4721e3975ff916cec" + ], + "linux_amd64": [ + "go1.22.4.linux-amd64.tar.gz", + "ba79d4526102575196273416239cca418a651e049c2b099f3159db85e7bade7d" + ], + "linux_arm64": [ + "go1.22.4.linux-arm64.tar.gz", + "a8e177c354d2e4a1b61020aca3562e27ea3e8f8247eca3170e3fa1e0c2f9e771" + ], + "linux_armv6l": [ + "go1.22.4.linux-armv6l.tar.gz", + "e2b143fbacbc9cbd448e9ef41ac3981f0488ce849af1cf37e2341d09670661de" + ], + "linux_loong64": [ + "go1.22.4.linux-loong64.tar.gz", + "e2ff9436e4b34bf6926b06d97916e26d67a909a2effec17967245900f0816f1d" + ], + "linux_mips": [ + "go1.22.4.linux-mips.tar.gz", + "73f0dcc60458c4770593b05a7bc01cc0d31fc98f948c0c2334812c7a1f2fc3f1" + ], + "linux_mips64": [ + "go1.22.4.linux-mips64.tar.gz", + "417af97fc2630a647052375768be4c38adcc5af946352ea5b28613ea81ca5d45" + ], + "linux_mips64le": [ + "go1.22.4.linux-mips64le.tar.gz", + "7486e2d7dd8c98eb44df815ace35a7fe7f30b7c02326e3741bd934077508139b" + ], + "linux_mipsle": [ + "go1.22.4.linux-mipsle.tar.gz", + "69479c8aad301e459a8365b40cad1074a0dbba5defb9291669f94809c4c4be6e" + ], + "linux_ppc64": [ + "go1.22.4.linux-ppc64.tar.gz", + "dd238847e65bc3e2745caca475a5db6522a2fcf85cf6c38fc36a06642b19efd7" + ], + "linux_ppc64le": [ + "go1.22.4.linux-ppc64le.tar.gz", + "a3e5834657ef92523f570f798fed42f1f87bc18222a16815ec76b84169649ec4" + ], + "linux_riscv64": [ + "go1.22.4.linux-riscv64.tar.gz", + "56a827ff7dc6245bcd7a1e9288dffaa1d8b0fd7468562264c1523daf3b4f1b4a" + ], + "linux_s390x": [ + "go1.22.4.linux-s390x.tar.gz", + "7590c3e278e2dc6040aae0a39da3ca1eb2e3921673a7304cc34d588c45889eec" + ], + "netbsd_386": [ + "go1.22.4.netbsd-386.tar.gz", + "ddd2eebe34471a2502de6c5dad04ab27c9fc80cbde7a9ad5b3c66ecec4504e1d" + ], + "netbsd_amd64": [ + "go1.22.4.netbsd-amd64.tar.gz", + "33af79f6f935f6fbacc5d23876450b3567b79348fc065beef8e64081127dd234" + ], + "netbsd_arm64": [ + "go1.22.4.netbsd-arm64.tar.gz", + "c9a2971dec9f6d320c6f2b049b2353c6d0a2d35e87b8a4b2d78a2f0d62545f8e" + ], + "netbsd_armv6l": [ + "go1.22.4.netbsd-arm.tar.gz", + "fa3550ebd5375a70b3bcd342b5a71f4bd271dcbbfaf4eabefa2144ab5d8924b6" + ], + "openbsd_386": [ + "go1.22.4.openbsd-386.tar.gz", + "d21af022331bfdc2b5b161d616c3a1a4573d33cf7a30416ee509a8f3641deb47" + ], + "openbsd_amd64": [ + "go1.22.4.openbsd-amd64.tar.gz", + "72c0094c43f7e5722ec49c2a3e9dfa7a1123ac43a5f3a63eecf3e3795d3ff0ae" + ], + "openbsd_arm64": [ + "go1.22.4.openbsd-arm64.tar.gz", + "a7ab8d4e0b02bf06ed144ba42c61c0e93ee00f2b433415dfd4ad4b6e79f31650" + ], + "openbsd_armv6l": [ + "go1.22.4.openbsd-arm.tar.gz", + "1096831ea3c5ea3ca57d14251d9eda3786889531eb40d7d6775dcaa324d4b065" + ], + "openbsd_ppc64": [ + "go1.22.4.openbsd-ppc64.tar.gz", + "9716327c8a628358798898dc5148c49dbbeb5196bf2cbf088e550721a6e4f60b" + ], + "plan9_386": [ + "go1.22.4.plan9-386.tar.gz", + "a8dd4503c95c32a502a616ab78870a19889c9325fe9bd31eb16dd69346e4bfa8" + ], + "plan9_amd64": [ + "go1.22.4.plan9-amd64.tar.gz", + "5423a25808d76fe5aca8607a2e5ac5673abf45446b168cb5e9d8519ee9fe39a1" + ], + "plan9_armv6l": [ + "go1.22.4.plan9-arm.tar.gz", + "6af939ad583f5c85c09c53728ab7d38c3cc2b39167562d6c18a07c5c6608b370" + ], + "solaris_amd64": [ + "go1.22.4.solaris-amd64.tar.gz", + "e8cabe69c03085725afdb32a6f9998191a3e55a747b270d835fd05000d56abba" + ], + "windows_386": [ + "go1.22.4.windows-386.zip", + "aca4e2c37278a10f1c70dd0df142f7d66b50334fcee48978d409202d308d6d25" + ], + "windows_amd64": [ + "go1.22.4.windows-amd64.zip", + "26321c4d945a0035d8a5bc4a1965b0df401ff8ceac66ce2daadabf9030419a98" + ], + "windows_arm64": [ + "go1.22.4.windows-arm64.zip", + "8a2daa9ea28cbdafddc6171aefed384f4e5b6e714fb52116fe9ed25a132f37ed" + ], + "windows_armv6l": [ + "go1.22.4.windows-arm.zip", + "5fcd0671a49cecf39b41021621ee1b6e7aa1370f37122b72e80d4fd4185833b6" + ] + }, + "1.23.0": { + "aix_ppc64": [ + "go1.23.0.aix-ppc64.tar.gz", + "257f8560bb4001fb81a5e0ee84f32fecbe18d4450343c9556557d296786847b6" + ], + "darwin_amd64": [ + "go1.23.0.darwin-amd64.tar.gz", + "ffd070acf59f054e8691b838f274d540572db0bd09654af851e4e76ab88403dc" + ], + "darwin_arm64": [ + "go1.23.0.darwin-arm64.tar.gz", + "b770812aef17d7b2ea406588e2b97689e9557aac7e646fe76218b216e2c51406" + ], + "dragonfly_amd64": [ + "go1.23.0.dragonfly-amd64.tar.gz", + "8fd2ab5ac8629fc97d25a056693e23f332446603dd3c2b764ccb496872004b0c" + ], + "freebsd_386": [ + "go1.23.0.freebsd-386.tar.gz", + "2c9b76ead3c44f5b3e40e10b980075addb837f2dd05dafe7c0e4c611fd239753" + ], + "freebsd_amd64": [ + "go1.23.0.freebsd-amd64.tar.gz", + "2c2252902b87ba605fdc0b12b4c860fe6553c0c5483c12cc471756ebdd8249fe" + ], + "freebsd_arm": [ + "go1.23.0.freebsd-arm.tar.gz", + "8ec48b8d99a515644ae00e79d093ad3b7645dcaf2a19c0a9c0d97916187f4514" + ], + "freebsd_arm64": [ + "go1.23.0.freebsd-arm64.tar.gz", + "f476bbe8efb0db18155671840545370bfb73903fec04ea897d510569dab16d9c" + ], + "freebsd_riscv64": [ + "go1.23.0.freebsd-riscv64.tar.gz", + "b0e254b2ea5752b4f1c69934ae43a44bbabf98e0c2843af44e1b6d12390eb551" + ], + "illumos_amd64": [ + "go1.23.0.illumos-amd64.tar.gz", + "09716dcc7a2e19891b3d1e2ea68a1aab22838fc664cdc5f82d5f8eef05db78cf" + ], + "linux_386": [ + "go1.23.0.linux-386.tar.gz", + "0e8a7340c2632e6fb5088d60f95b52be1f8303143e04cd34e9b2314fafc24edd" + ], + "linux_amd64": [ + "go1.23.0.linux-amd64.tar.gz", + "905a297f19ead44780548933e0ff1a1b86e8327bb459e92f9c0012569f76f5e3" + ], + "linux_arm64": [ + "go1.23.0.linux-arm64.tar.gz", + "62788056693009bcf7020eedc778cdd1781941c6145eab7688bd087bce0f8659" + ], + "linux_armv6l": [ + "go1.23.0.linux-armv6l.tar.gz", + "0efa1338e644d7f74064fa7f1016b5da7872b2df0070ea3b56e4fef63192e35b" + ], + "linux_loong64": [ + "go1.23.0.linux-loong64.tar.gz", + "dc8f723ce1a236e85c8b56d1e6749e270314e99dd41b80a58355e7ffcf9ea857" + ], + "linux_mips": [ + "go1.23.0.linux-mips.tar.gz", + "3332cc76c73c05b3413cdecccffc29aaa3469f87db8ed9f9b784ebb527ca5352" + ], + "linux_mips64": [ + "go1.23.0.linux-mips64.tar.gz", + "0ed5cee92433d09fd0816ec5adfbf4b16d712944e833f6342bbe2df18f7826ae" + ], + "linux_mips64le": [ + "go1.23.0.linux-mips64le.tar.gz", + "06a579dd6d1f9a84bc43cab063e7c759a92a6d4dd01fec3d860f22a32df93406" + ], + "linux_mipsle": [ + "go1.23.0.linux-mipsle.tar.gz", + "d522770d32d6ee963f61331a695c4f8a730f2445b965d8d56db0a2e75c62af57" + ], + "linux_ppc64": [ + "go1.23.0.linux-ppc64.tar.gz", + "8c884cb4f2593d897f58ec1b0f23f303acf5c78fd101e76cb48d6cb1fe5e90e7" + ], + "linux_ppc64le": [ + "go1.23.0.linux-ppc64le.tar.gz", + "8b26e20d4d43a4d7641cddbdc0298d7ba3804d910a9e06cda7672970dbf2829d" + ], + "linux_riscv64": [ + "go1.23.0.linux-riscv64.tar.gz", + "a87726205f1a283247f877ccae8ce147ff4e77ac802382647ac52256eb5642c7" + ], + "linux_s390x": [ + "go1.23.0.linux-s390x.tar.gz", + "003722971de02d97131a4dca2496abdab5cb175a6ee0ed9c8227c5ae9b883e69" + ], + "netbsd_386": [ + "go1.23.0.netbsd-386.tar.gz", + "b203fa2354874c66c40d828e96a6cce1f4e4db192414050a600d0a09b16cafd3" + ], + "netbsd_amd64": [ + "go1.23.0.netbsd-amd64.tar.gz", + "1502c82c3ba663959df99c2cc3ca5e7a5e1a75a1495fd26bef697d63bf1f291c" + ], + "netbsd_arm": [ + "go1.23.0.netbsd-arm.tar.gz", + "dd50c05c7f613522c8d3d74f598bfc1862c0fee9182b738225820c9b458c7be5" + ], + "netbsd_arm64": [ + "go1.23.0.netbsd-arm64.tar.gz", + "728a94a648f9502cd6175adaac2b770acde6b26f5f92dcbd8c5a1a43cc44bb10" + ], + "openbsd_386": [ + "go1.23.0.openbsd-386.tar.gz", + "e1ff3584778257778a4e3f0093b09044072423aebedf2015a550537853c46745" + ], + "openbsd_amd64": [ + "go1.23.0.openbsd-amd64.tar.gz", + "d2e30cdb0de256360b51a43f5e551587a7369d8c248120010d5e9432f698a6e8" + ], + "openbsd_arm": [ + "go1.23.0.openbsd-arm.tar.gz", + "bd5224c8a5f195f4128c866c0d418f1b61db865a1042913fd07714ed85da28db" + ], + "openbsd_arm64": [ + "go1.23.0.openbsd-arm64.tar.gz", + "fc0e0af3a1b4b7168455e8492a5bb6aa96ceaf46321cef1fc04187301c058890" + ], + "openbsd_ppc64": [ + "go1.23.0.openbsd-ppc64.tar.gz", + "ce7ea9343c7c2ef2700b55b80c45549ce39d164031e4d7bb98bec7ca593ed93d" + ], + "openbsd_riscv64": [ + "go1.23.0.openbsd-riscv64.tar.gz", + "90b6a97285981e06752a30a638cd8d32861086848c0131fb62faddf89e2de8e1" + ], + "plan9_386": [ + "go1.23.0.plan9-386.tar.gz", + "93b970a8a41f6c89113daaea12e39f2580038af155e823550d0a94a5502c5e2c" + ], + "plan9_amd64": [ + "go1.23.0.plan9-amd64.tar.gz", + "6231862acbb6c1e02b1455b35446b9789b0b4b3230d249953e6957c393a53011" + ], + "plan9_arm": [ + "go1.23.0.plan9-arm.tar.gz", + "632bdd3a1f84b2fe691203423dd2c3f536d4ab250bb52a48e9b05ebf327ae594" + ], + "solaris_amd64": [ + "go1.23.0.solaris-amd64.tar.gz", + "16773f85003d9e610960f9af67e00bc6c02359d7914de7224079538cc9c1e93d" + ], + "windows_386": [ + "go1.23.0.windows-386.zip", + "09448fedec0cdf98ad12397222e0c8bfc835b1d0894c0015ced653534b8d7427" + ], + "windows_amd64": [ + "go1.23.0.windows-amd64.zip", + "d4be481ef73079ee0ad46081d278923aa3fd78db1b3cf147172592f73e14c1ac" + ], + "windows_arm": [ + "go1.23.0.windows-arm.zip", + "006d93712246a672bdb57906dd5bffcab62facc36169e51a27d52340cdac661f" + ], + "windows_arm64": [ + "go1.23.0.windows-arm64.zip", + "0be62073ef8f5a2d3b9adcefddf18c417dab0a7975c71488ac2694856e2ff976" + ] + }, + "1.24.0": { + "aix_ppc64": [ + "go1.24.0.aix-ppc64.tar.gz", + "5d04588154d5923bd8e26b76111806340ec55c41af1b05623ea744fcb3d6bc22" + ], + "darwin_amd64": [ + "go1.24.0.darwin-amd64.tar.gz", + "7af054e5088b68c24b3d6e135e5ca8d91bbd5a05cb7f7f0187367b3e6e9e05ee" + ], + "darwin_arm64": [ + "go1.24.0.darwin-arm64.tar.gz", + "fd9cfb5dd6c75a347cfc641a253f0db1cebaca16b0dd37965351c6184ba595e4" + ], + "dragonfly_amd64": [ + "go1.24.0.dragonfly-amd64.tar.gz", + "d0dc34ad86aea746abe245994c68a9e1ad8f46ba8c4af901cd5861a4dd4c21df" + ], + "freebsd_386": [ + "go1.24.0.freebsd-386.tar.gz", + "4ee02b1f3812aff4da79c79464ee4038ca61ad74b3a9619850f30435f81c2536" + ], + "freebsd_amd64": [ + "go1.24.0.freebsd-amd64.tar.gz", + "838191001f9324da904dece35a586a3156d548687db87ac9461aa3d38fc88b09" + ], + "freebsd_arm": [ + "go1.24.0.freebsd-arm.tar.gz", + "ce6ad4e84a40a8a1d848b7e31b0cddfd1cee8f7959e7dc358a8fa8b5566ea718" + ], + "freebsd_arm64": [ + "go1.24.0.freebsd-arm64.tar.gz", + "511f7b0cac4c4ed1066d324072ce223b906ad6b2a85f2e1c5d260eb7d08b5901" + ], + "freebsd_riscv64": [ + "go1.24.0.freebsd-riscv64.tar.gz", + "a1e4072630dc589a2975ef51317b52c7d8599bf6f389fc59033c01e0a0fa705a" + ], + "illumos_amd64": [ + "go1.24.0.illumos-amd64.tar.gz", + "7593e9dcee9f07c3df6d099f7d259f5734a6c0dccc5f28962f18e7f501c9bb21" + ], + "linux_386": [ + "go1.24.0.linux-386.tar.gz", + "90521453a59c6ce20364d2dc7c38532949b033b602ba12d782caeb90af1b0624" + ], + "linux_amd64": [ + "go1.24.0.linux-amd64.tar.gz", + "dea9ca38a0b852a74e81c26134671af7c0fbe65d81b0dc1c5bfe22cf7d4c8858" + ], + "linux_arm64": [ + "go1.24.0.linux-arm64.tar.gz", + "c3fa6d16ffa261091a5617145553c71d21435ce547e44cc6dfb7470865527cc7" + ], + "linux_armv6l": [ + "go1.24.0.linux-armv6l.tar.gz", + "695dc54fa14cd3124fa6900d7b5ae39eeac23f7a4ecea81656070160fac2c54a" + ], + "linux_loong64": [ + "go1.24.0.linux-loong64.tar.gz", + "a201e4c9b7e6d29ed64c43296ed88e81a66f82f2093ce45b766d2c526941396f" + ], + "linux_mips": [ + "go1.24.0.linux-mips.tar.gz", + "f3ac039aae78ad0bfb08106406c2e62eaf763dd82ebaf0ecd539adadd1d729a6" + ], + "linux_mips64": [ + "go1.24.0.linux-mips64.tar.gz", + "f2e6456d45e024831b1da8d88b1bb6392cca9500c1b00841f525d76c9e9553e0" + ], + "linux_mips64le": [ + "go1.24.0.linux-mips64le.tar.gz", + "b847893ff119389c939adc2b8516b6500204b7cb49d5e19b25e1c2091d2c74c6" + ], + "linux_mipsle": [ + "go1.24.0.linux-mipsle.tar.gz", + "bd4aed27d02746c237c3921e97029ac6b6fe687a67436b8f52ff1f698d330bd9" + ], + "linux_ppc64": [ + "go1.24.0.linux-ppc64.tar.gz", + "007123c9b06c41729a4bb3f166f4df7196adf4e33c2d2ab0e7e990175f0ce1d4" + ], + "linux_ppc64le": [ + "go1.24.0.linux-ppc64le.tar.gz", + "a871a43de7d26c91dd90cb6e0adacb214c9e35ee2188c617c91c08c017efe81a" + ], + "linux_riscv64": [ + "go1.24.0.linux-riscv64.tar.gz", + "620dcf48c6297519aad6c81f8e344926dc0ab09a2a79f1e306964aece95a553d" + ], + "linux_s390x": [ + "go1.24.0.linux-s390x.tar.gz", + "544d78b077c6b54bf78958c4a8285abec2d21f668fb007261c77418cd2edbb46" + ], + "netbsd_386": [ + "go1.24.0.netbsd-386.tar.gz", + "8b143a7edefbaa2a0b0246c9df2df1bac9fbed909d8615a375c08da7744e697d" + ], + "netbsd_amd64": [ + "go1.24.0.netbsd-amd64.tar.gz", + "67150a6dd7bdb9c4e88d77f46ee8c4dc99d5e71deca4912d8c2c85f7a16d0262" + ], + "netbsd_arm": [ + "go1.24.0.netbsd-arm.tar.gz", + "446b2539f11218fd6f6f6e3dd90b20ae55a06afe129885eeb3df51eb344eb0f6" + ], + "netbsd_arm64": [ + "go1.24.0.netbsd-arm64.tar.gz", + "370115b6ff7d30b29431223de348eb11ab65e3c92627532d97fd55f63f94e7a8" + ], + "openbsd_386": [ + "go1.24.0.openbsd-386.tar.gz", + "cbda5f15f06ed9630f122a53542d9de13d149643633c74f1dcb45e79649b788a" + ], + "openbsd_amd64": [ + "go1.24.0.openbsd-amd64.tar.gz", + "926f601d0e655ab1e8d7f357fd82542e5cf206c38c4e2f9fccf0706987d38836" + ], + "openbsd_arm": [ + "go1.24.0.openbsd-arm.tar.gz", + "8a54892f8c933c541fff144a825d0fdc41bae14b0832aab703cb75eb4cb64f2c" + ], + "openbsd_arm64": [ + "go1.24.0.openbsd-arm64.tar.gz", + "ef7fddcef0a22c7900c178b7687cf5aa25c2a9d46a3cc330b77a6de6e6c2396b" + ], + "openbsd_ppc64": [ + "go1.24.0.openbsd-ppc64.tar.gz", + "b3b5e2e2b53489ded2c2c21900ddcbbdb7991632bb5b42f05f125d71675e0b76" + ], + "openbsd_riscv64": [ + "go1.24.0.openbsd-riscv64.tar.gz", + "fbcb1dbf1269b4079dc4fd0b15f3274b9d635f1a7e319c3fc1a907b03280348e" + ], + "plan9_386": [ + "go1.24.0.plan9-386.tar.gz", + "33b4221e1c174a16e3f661deab6c60838ac4ae6cb869a4da1d1115773ceed88b" + ], + "plan9_amd64": [ + "go1.24.0.plan9-amd64.tar.gz", + "111a89014019cdbd69c2978de9b3e201f77e35183c8ab3606fba339d38f28549" + ], + "plan9_arm": [ + "go1.24.0.plan9-arm.tar.gz", + "8da3d3997049f40ebe0cd336a9bb9e4bfa4832df3c90a32f07383371d6d74849" + ], + "solaris_amd64": [ + "go1.24.0.solaris-amd64.tar.gz", + "b6069da21dc95ccdbd047675b584e5480ffc3eba35f9e7c8b0e7b317aaf01e2c" + ], + "windows_386": [ + "go1.24.0.windows-386.zip", + "b53c28a4c2863ec50ab4a1dbebe818ef6177f86773b6f43475d40a5d9aa4ec9e" + ], + "windows_amd64": [ + "go1.24.0.windows-amd64.zip", + "96b7280979205813759ee6947be7e3bb497da85c482711116c00522e3bb41ff1" + ], + "windows_arm64": [ + "go1.24.0.windows-arm64.zip", + "53f73450fb66075d16be9f206e9177bd972b528168271918c4747903b5596c3d" + ] + }, + "1.24.6": { + "aix_ppc64": [ + "go1.24.6.aix-ppc64.tar.gz", + "5cafb2927af95969fc3d0884be1ad4df54f19103d86dda928d9f76494a5ae6a6" + ], + "darwin_amd64": [ + "go1.24.6.darwin-amd64.tar.gz", + "4a8d7a32052f223e71faab424a69430455b27b3fff5f4e651f9d97c3e51a8746" + ], + "darwin_arm64": [ + "go1.24.6.darwin-arm64.tar.gz", + "4e29202c49573b953be7cc3500e1f8d9e66ddd12faa8cf0939a4951411e09a2a" + ], + "dragonfly_amd64": [ + "go1.24.6.dragonfly-amd64.tar.gz", + "c6e21bf8347f7a1c653dd4136c8c27a858515e98501d2843023a4bb3f1f7fb63" + ], + "freebsd_386": [ + "go1.24.6.freebsd-386.tar.gz", + "9cd74ad74f3ad833e92529f2fd9b0d7d9ffaab46307eccadb0afcf9a1ba09553" + ], + "freebsd_amd64": [ + "go1.24.6.freebsd-amd64.tar.gz", + "4983e2b10ae1f754e4eb07e1e589691c7e1d0dc428a92c16bd0e2ba03cc23ed9" + ], + "freebsd_arm": [ + "go1.24.6.freebsd-arm.tar.gz", + "a8da621d8282a91ee17b257a46f2606391c019cc1a7d7be628638792ca8033ad" + ], + "freebsd_arm64": [ + "go1.24.6.freebsd-arm64.tar.gz", + "76a75ad5125217c268029c0ad9c7295cc7f6042fe9cba4bebf9a89f7f42ad8af" + ], + "freebsd_riscv64": [ + "go1.24.6.freebsd-riscv64.tar.gz", + "ac206417d8460662f26d46dc2ad0488b2f9e22039946069ba4b48a0cb646e8b0" + ], + "illumos_amd64": [ + "go1.24.6.illumos-amd64.tar.gz", + "c54199c46ec823c857c52335f859b493593433d71fe479b9e7f95d868a144ae2" + ], + "linux_386": [ + "go1.24.6.linux-386.tar.gz", + "bb5bf69d75e7edbc93339824753a1a4655a928451a2c5e13ff90959ad69e065b" + ], + "linux_amd64": [ + "go1.24.6.linux-amd64.tar.gz", + "bbca37cc395c974ffa4893ee35819ad23ebb27426df87af92e93a9ec66ef8712" + ], + "linux_arm64": [ + "go1.24.6.linux-arm64.tar.gz", + "124ea6033a8bf98aa9fbab53e58d134905262d45a022af3a90b73320f3c3afd5" + ], + "linux_armv6l": [ + "go1.24.6.linux-armv6l.tar.gz", + "7feb4d25f5e72f94fda81c99d4adb6630dfa2c35211e0819417d53af6e71809e" + ], + "linux_loong64": [ + "go1.24.6.linux-loong64.tar.gz", + "8424d9c52b254255d2720769366af73802747e4eaf339c6e86bb52e5a1809fcb" + ], + "linux_mips": [ + "go1.24.6.linux-mips.tar.gz", + "791964a6ce65f604a2099b7e61f71128cc7a3a4fcee858218d2ce99033fc2b09" + ], + "linux_mips64": [ + "go1.24.6.linux-mips64.tar.gz", + "2f5282fdf2eaca44515728d518caec888b0dc4948effecb8e7f2ddff1ff9aa9e" + ], + "linux_mips64le": [ + "go1.24.6.linux-mips64le.tar.gz", + "64ddc6b28907b4ab997f2d81c226be403511a59a6100536560af26ccfb10b4a4" + ], + "linux_mipsle": [ + "go1.24.6.linux-mipsle.tar.gz", + "5ca12d2d4939dea977100e76885f4e08cd3ef3b73823853527b58ecac4598fd3" + ], + "linux_ppc64": [ + "go1.24.6.linux-ppc64.tar.gz", + "9a4a61ffbba7a58b3ef97a6d3b2b394168f613f9ca6092016981a88c78a57f86" + ], + "linux_ppc64le": [ + "go1.24.6.linux-ppc64le.tar.gz", + "63fc9559a3d6dfd63aa902f714375b879bbc848466181c035c122489b9646e27" + ], + "linux_riscv64": [ + "go1.24.6.linux-riscv64.tar.gz", + "e92c19ff15a9004fe43e1f62d433555250ef9fe3fabee3dc29ebd4802c2b8021" + ], + "linux_s390x": [ + "go1.24.6.linux-s390x.tar.gz", + "4cde28d9ffb6eef86bf8dac6852a45db335009f67e60bee3e477dd0ba0ff9704" + ], + "netbsd_386": [ + "go1.24.6.netbsd-386.tar.gz", + "d238045676104d2aaad9da53c4ba3f489cf81b26d3315d2caad2b6e240664423" + ], + "netbsd_amd64": [ + "go1.24.6.netbsd-amd64.tar.gz", + "9f8a9245cf146f1ebdac6785f71646c3dd0edf07dcdb8e5a8df85ec6447e5308" + ], + "netbsd_arm": [ + "go1.24.6.netbsd-arm.tar.gz", + "2359c8af6b2d6979910060478a57fd216824682e0908ea1a4412ea8dc4a55db7" + ], + "netbsd_arm64": [ + "go1.24.6.netbsd-arm64.tar.gz", + "99101158c796997ec85023d395c133fa90c782bd5faa56f8c3824817d28b0ee8" + ], + "openbsd_386": [ + "go1.24.6.openbsd-386.tar.gz", + "b6193420489f24d5560b87ccb38caf52cecb308d892d99bf21d1ef0d2c99de04" + ], + "openbsd_amd64": [ + "go1.24.6.openbsd-amd64.tar.gz", + "8dc0d94afbc65be9cafebe543b88a841dcf3429e50f668ea714200ef9f4489bd" + ], + "openbsd_arm": [ + "go1.24.6.openbsd-arm.tar.gz", + "c29563d14d8e4b5fa89f130afac40abba7a1ee1e87fcc759a95f1e9b5831bf68" + ], + "openbsd_arm64": [ + "go1.24.6.openbsd-arm64.tar.gz", + "3d97bdc5e1997cccfaa398242c52e8a97d3b626d988a65248bbdbf2f1ab188bf" + ], + "openbsd_ppc64": [ + "go1.24.6.openbsd-ppc64.tar.gz", + "54cf517933db0bff58f3e527e7fa194f505d562c71b1fb0050d3365fcdda4914" + ], + "openbsd_riscv64": [ + "go1.24.6.openbsd-riscv64.tar.gz", + "f7bdd8f882ecbc01ff6c1782ce3e29298445dd99b3dd4299423257df307c7b0d" + ], + "plan9_386": [ + "go1.24.6.plan9-386.tar.gz", + "9bc0a801dc0d8d0705ac9493219b926b2e3c0105b8921c6c2fce69d14c4b9007" + ], + "plan9_amd64": [ + "go1.24.6.plan9-amd64.tar.gz", + "7133c28acc277d3c5e8317fd9454b3a0902138c384466f818644b504b8b89ffe" + ], + "plan9_arm": [ + "go1.24.6.plan9-arm.tar.gz", + "c4e2aa8aa4353f75fc083ca728b73917467cef88c6f5f917ca420578672c6d58" + ], + "solaris_amd64": [ + "go1.24.6.solaris-amd64.tar.gz", + "cfcb4f1f7e987c6dee893c4401546516cc271c1ac7d7fb37a32b25343dc7df32" + ], + "windows_386": [ + "go1.24.6.windows-386.zip", + "39b4d31b933d2f7c8913e70fb0fffef27252e441c386eac5c13632cbb28dfb6e" + ], + "windows_amd64": [ + "go1.24.6.windows-amd64.zip", + "4fbc8af2cfca9e5059019b5150a426eb78e1e57718bf08f0e52b1c942a2782bf" + ], + "windows_arm64": [ + "go1.24.6.windows-arm64.zip", + "45c41b237d00e92e4cf8adce11b4c5258048b47a92bfbb1f4ef3b928d6fcb0b2" + ] + }, + "1.25.0": { + "aix_ppc64": [ + "go1.25.0.aix-ppc64.tar.gz", + "e5234a7dac67bc86c528fe9752fc9d63557918627707a733ab4cac1a6faed2d4" + ], + "darwin_amd64": [ + "go1.25.0.darwin-amd64.tar.gz", + "5bd60e823037062c2307c71e8111809865116714d6f6b410597cf5075dfd80ef" + ], + "darwin_arm64": [ + "go1.25.0.darwin-arm64.tar.gz", + "544932844156d8172f7a28f77f2ac9c15a23046698b6243f633b0a0b00c0749c" + ], + "dragonfly_amd64": [ + "go1.25.0.dragonfly-amd64.tar.gz", + "5ed3cf9a810a1483822538674f1336c06b51aa1b94d6d545a1a0319a48177120" + ], + "freebsd_386": [ + "go1.25.0.freebsd-386.tar.gz", + "abea5d5c6697e6b5c224731f2158fe87c602996a2a233ac0c4730cd57bf8374e" + ], + "freebsd_amd64": [ + "go1.25.0.freebsd-amd64.tar.gz", + "86e6fe0a29698d7601c4442052dac48bd58d532c51cccb8f1917df648138730b" + ], + "freebsd_arm": [ + "go1.25.0.freebsd-arm.tar.gz", + "d90b78e41921f72f30e8bbc81d9dec2cff7ff384a33d8d8debb24053e4336bfe" + ], + "freebsd_arm64": [ + "go1.25.0.freebsd-arm64.tar.gz", + "451d0da1affd886bfb291b7c63a6018527b269505db21ce6e14724f22ab0662e" + ], + "freebsd_riscv64": [ + "go1.25.0.freebsd-riscv64.tar.gz", + "7b565f76bd8bda46549eeaaefe0e53b251e644c230577290c0f66b1ecdb3cdbe" + ], + "illumos_amd64": [ + "go1.25.0.illumos-amd64.tar.gz", + "b1e1fdaab1ad25aa1c08d7a36c97d45d74b98b89c3f78c6d2145f77face54a2c" + ], + "linux_386": [ + "go1.25.0.linux-386.tar.gz", + "8c602dd9d99bc9453b3995d20ce4baf382cc50855900a0ece5de9929df4a993a" + ], + "linux_amd64": [ + "go1.25.0.linux-amd64.tar.gz", + "2852af0cb20a13139b3448992e69b868e50ed0f8a1e5940ee1de9e19a123b613" + ], + "linux_arm64": [ + "go1.25.0.linux-arm64.tar.gz", + "05de75d6994a2783699815ee553bd5a9327d8b79991de36e38b66862782f54ae" + ], + "linux_armv6l": [ + "go1.25.0.linux-armv6l.tar.gz", + "a5a8f8198fcf00e1e485b8ecef9ee020778bf32a408a4e8873371bfce458cd09" + ], + "linux_loong64": [ + "go1.25.0.linux-loong64.tar.gz", + "cab86b1cf761b1cb3bac86a8877cfc92e7b036fc0d3084123d77013d61432afc" + ], + "linux_mips": [ + "go1.25.0.linux-mips.tar.gz", + "d66b6fb74c3d91b9829dc95ec10ca1f047ef5e89332152f92e136cf0e2da5be1" + ], + "linux_mips64": [ + "go1.25.0.linux-mips64.tar.gz", + "4082e4381a8661bc2a839ff94ba3daf4f6cde20f8fb771b5b3d4762dc84198a2" + ], + "linux_mips64le": [ + "go1.25.0.linux-mips64le.tar.gz", + "70002c299ec7f7175ac2ef673b1b347eecfa54ae11f34416a6053c17f855afcc" + ], + "linux_mipsle": [ + "go1.25.0.linux-mipsle.tar.gz", + "b00a3a39eff099f6df9f1c7355bf28e4589d0586f42d7d4a394efb763d145a73" + ], + "linux_ppc64": [ + "go1.25.0.linux-ppc64.tar.gz", + "df166f33bd98160662560a72ff0b4ba731f969a80f088922bddcf566a88c1ec1" + ], + "linux_ppc64le": [ + "go1.25.0.linux-ppc64le.tar.gz", + "0f18a89e7576cf2c5fa0b487a1635d9bcbf843df5f110e9982c64df52a983ad0" + ], + "linux_riscv64": [ + "go1.25.0.linux-riscv64.tar.gz", + "c018ff74a2c48d55c8ca9b07c8e24163558ffec8bea08b326d6336905d956b67" + ], + "linux_s390x": [ + "go1.25.0.linux-s390x.tar.gz", + "34e5a2e19f2292fbaf8783e3a241e6e49689276aef6510a8060ea5ef54eee408" + ], + "netbsd_386": [ + "go1.25.0.netbsd-386.tar.gz", + "f8586cdb7aa855657609a5c5f6dbf523efa00c2bbd7c76d3936bec80aa6c0aba" + ], + "netbsd_amd64": [ + "go1.25.0.netbsd-amd64.tar.gz", + "ae8dc1469385b86a157a423bb56304ba45730de8a897615874f57dd096db2c2a" + ], + "netbsd_arm": [ + "go1.25.0.netbsd-arm.tar.gz", + "1ff7e4cc764425fc9dd6825eaee79d02b3c7cafffbb3691687c8d672ade76cb7" + ], + "netbsd_arm64": [ + "go1.25.0.netbsd-arm64.tar.gz", + "e1b310739f26724216aa6d7d7208c4031f9ff54c9b5b9a796ddc8bebcb4a5f16" + ], + "openbsd_386": [ + "go1.25.0.openbsd-386.tar.gz", + "4802a9b20e533da91adb84aab42e94aa56cfe3e5475d0550bed3385b182e69d8" + ], + "openbsd_amd64": [ + "go1.25.0.openbsd-amd64.tar.gz", + "c016cd984bebe317b19a4f297c4f50def120dc9788490540c89f28e42f1dabe1" + ], + "openbsd_arm": [ + "go1.25.0.openbsd-arm.tar.gz", + "a1e31d0bf22172ddde42edf5ec811ef81be43433df0948ece52fecb247ccfd8d" + ], + "openbsd_arm64": [ + "go1.25.0.openbsd-arm64.tar.gz", + "343ea8edd8c218196e15a859c6072d0dd3246fbbb168481ab665eb4c4140458d" + ], + "openbsd_ppc64": [ + "go1.25.0.openbsd-ppc64.tar.gz", + "694c14da1bcaeb5e3332d49bdc2b6d155067648f8fe1540c5de8f3cf8e157154" + ], + "openbsd_riscv64": [ + "go1.25.0.openbsd-riscv64.tar.gz", + "aa510ad25cf54c06cd9c70b6d80ded69cb20188ac6e1735655eef29ff7e7885f" + ], + "plan9_386": [ + "go1.25.0.plan9-386.tar.gz", + "46f8cef02086cf04bf186c5912776b56535178d4cb319cd19c9fdbdd29231986" + ], + "plan9_amd64": [ + "go1.25.0.plan9-amd64.tar.gz", + "29b34391d84095e44608a228f63f2f88113a37b74a79781353ec043dfbcb427b" + ], + "plan9_arm": [ + "go1.25.0.plan9-arm.tar.gz", + "0a047107d13ebe7943aaa6d54b1d7bbd2e45e68ce449b52915a818da715799c2" + ], + "solaris_amd64": [ + "go1.25.0.solaris-amd64.tar.gz", + "9977f9e4351984364a3b2b78f8b88bfd1d339812356d5237678514594b7d3611" + ], + "windows_386": [ + "go1.25.0.windows-386.zip", + "df9f39db82a803af0db639e3613a36681ab7a42866b1384b3f3a1045663961a7" + ], + "windows_amd64": [ + "go1.25.0.windows-amd64.zip", + "89efb4f9b30812eee083cc1770fdd2913c14d301064f6454851428f9707d190b" + ], + "windows_arm64": [ + "go1.25.0.windows-arm64.zip", + "27bab004c72b3d7bd05a69b6ec0fc54a309b4b78cc569dd963d8b3ec28bfdb8c" + ] + } + }, + "@@rules_python+//python/extensions:pip.bzl%pip": { + "dist_hashes": { + "https://pypi.org/simple": { + "absl-py": { + "https://files.pythonhosted.org/packages/01/e4/dc0a1dcc4e74e08d7abedab278c795eef54a224363bb18f5692f416d834f/absl_py-2.0.0-py3-none-any.whl": "sha256:9a28abb62774ae4e8edbe2dd4c49ffcd45a6a848952a5eccc6a49f3f0fc1e2f3", + "https://files.pythonhosted.org/packages/7a/8f/fc001b92ecc467cc32ab38398bd0bfb45df46e7523bf33c2ad22a505f06e/absl-py-2.1.0.tar.gz": "sha256:7820790efbb316739cde8b4e19357243fc3608a152024288513dd968d7d959ff", + "https://files.pythonhosted.org/packages/a2/ad/e0d3c824784ff121c03cc031f944bc7e139a8f1870ffd2845cc2dd76f6c4/absl_py-2.1.0-py3-none-any.whl": "sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308", + "https://files.pythonhosted.org/packages/c6/09/fe8d9ab3e640b12322f8f73448db3428bf417b7dcfe14702fc7413e6c5c9/absl-py-2.0.0.tar.gz": "sha256:d9690211c5fcfefcdd1a45470ac2b5c5acd45241c3af71eed96bc5441746c0d5" + }, + "abstracts": { + "https://files.pythonhosted.org/packages/1f/6a/e115e8fbf5fd3912c12ce80f8ba21a112b2a8d1630ac38fb098fef6d04c4/abstracts-0.2.0-py3-none-any.whl": "sha256:995f326ab4408a6652a346439cb33169f48e66f25515c6baf9fc47f1a3e4652a", + "https://files.pythonhosted.org/packages/33/03/943f19f811619438044f53b959893c303e3add3fbcc90e5d9a8a1bb7aebd/abstracts-0.2.0.tar.gz": "sha256:1dd6df509a67cae1722c0dd9f58cdd6dee6e42f45bf0d7197e159b2e4c5e98e9" + }, + "aio-api-github": { + "https://files.pythonhosted.org/packages/70/0b/150978bc67eccf1761899a04289383c35f53e0edbabbf08d57a506f0eedb/aio_api_github-0.3.1.tar.gz": "sha256:d083ca09e5577d0c4217138e45b18ea63d57d0cbb030eb336cc2a979f8b244b4", + "https://files.pythonhosted.org/packages/71/f6/83bc0538af01d77637a99705337e68f8ab21c01196e00eb753e0edd1c34d/aio_api_github-0.3.1-py3-none-any.whl": "sha256:04d2e3fb4fcb55927b75f9a3cefae7673cefabd2387dd2416848ff19326d719c" + }, + "aio-core": { + "https://files.pythonhosted.org/packages/63/76/dee246fdd5c93314a9d6f1d673857bff1b5a9cce5a2d7aedb7db33d04801/aio_core-0.11.1-py3-none-any.whl": "sha256:76608a1dad3985866c1b3ffc81e0d08bd1a740e8e72125bfbf46d1ee6fc3abfe", + "https://files.pythonhosted.org/packages/6c/d3/62dc7243b034729be791bc5007969c914995945d3d29d7ba02979f5eff34/aio_core-0.11.1.tar.gz": "sha256:03f1202029655c68d5d41c2fa1d18e344d61515b71080f770f8cf6f99fbc5f5a" + }, + "aio-run-checker": { + "https://files.pythonhosted.org/packages/4a/5d/0cb1c6f9c547192735747bf186925aa0e660b42aefbe23e951a86d17e3bf/aio_run_checker-0.6.1.tar.gz": "sha256:0c929c3534600b5f163de177892841ed36267472a8d0609f550d717a523f28fd", + "https://files.pythonhosted.org/packages/c6/a4/7f03937df93be25970a296c7e71dda23f864c54acef3c87280dbb6443c26/aio_run_checker-0.6.1-py3-none-any.whl": "sha256:17f8ccf7976406adc062c5042888dab9507c5332bb00b697c3bd48e56a1ffee0" + }, + "aio-run-runner": { + "https://files.pythonhosted.org/packages/de/08/4a09d7103dec00e8fdd9151fc498c117109685013c758c8199313b1624b7/aio_run_runner-0.4.1.tar.gz": "sha256:43c80688c50ba3a528d88635fee5653b9f0f40fc4a036e1aeaddf8ada3794d2e", + "https://files.pythonhosted.org/packages/f9/24/8d03015cb159ff08ccc09bf80f37fb568b7b1e6ef34ed215b94026185ed3/aio_run_runner-0.4.1-py3-none-any.whl": "sha256:03c2978e4c7e1d02a55e25b0c081603d7900387bcce4fe80b8e8af8f3284e05b" + }, + "aiodocker": { + "https://files.pythonhosted.org/packages/3c/0d/e8f4164cbd950195900dd77aad23136f9ddc7feb0fb478d71839d1fda573/aiodocker-0.26.0-py3-none-any.whl": "sha256:f450acf0b402a03c6a6f1517d06bdff739c404e62578b332182ca272fde6e986", + "https://files.pythonhosted.org/packages/96/64/3b724f650cedc6d5c1cad7fdae3dd3b53c976d075547ff5268e2f1e56db5/aiodocker-0.26.0.tar.gz": "sha256:7e4ee40c6f98e6d1cf95d712f15aef3853087c0475bc7ea5ec499c2d485ba7ec" + }, + "aiofiles": { + "https://files.pythonhosted.org/packages/41/c3/534eac40372d8ee36ef40df62ec129bee4fdb5ad9706e58a29be53b2c970/aiofiles-25.1.0.tar.gz": "sha256:a8d728f0a29de45dc521f18f07297428d56992a742f0cd2701ba86e44d23d5b2", + "https://files.pythonhosted.org/packages/bc/8a/340a1555ae33d7354dbca4faa54948d76d89a27ceef032c8c3bc661d003e/aiofiles-25.1.0-py3-none-any.whl": "sha256:abe311e527c862958650f9438e859c1fa7568a141b22abcd015e120e86a85695" + }, + "aiohappyeyeballs": { + "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl": "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", + "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz": "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558" + }, + "aiohttp": { + "https://files.pythonhosted.org/packages/00/95/18bcbf830a21dc3aae24d8f6b6feaf3db1d2090242d00a7868db2ffb0b67/aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33", + "https://files.pythonhosted.org/packages/03/51/a3d29fdf2c25d796746af8ad6fe56a45d6256c38b0a8a2ed752e1160b3a2/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71", + "https://files.pythonhosted.org/packages/0e/da/f1b384465e51449d844056b75070461da03a9a23e6c1747003695bf4172a/aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl": "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a", + "https://files.pythonhosted.org/packages/11/b2/0c3d4114f0aee4f580f5b3b4eb71b24d7a23b834ea506a4dfebe76513f35/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl": "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15", + "https://files.pythonhosted.org/packages/13/d4/e7d09ba7d345fb2d74440fd2fa033c5e079fac05552927705986f41a364f/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl": "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0", + "https://files.pythonhosted.org/packages/18/d4/eb96299230e20acf2efae207cb8d69051f1f68e357e5ea5e479bf6fb097a/aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl": "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5", + "https://files.pythonhosted.org/packages/19/ce/967d628e910756f3539c6107cb7844a1b69440dcb3029a5ee7871b09ab63/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c", + "https://files.pythonhosted.org/packages/19/fe/26f9c5e6458385aa86497836b0dea6fb2f027827d63f37c7856cce9286ee/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl": "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25", + "https://files.pythonhosted.org/packages/1a/81/d217043a4c17fbce360905e3b2bdd20139ebc9a2de836d035d179c4da006/aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807", + "https://files.pythonhosted.org/packages/21/df/6061679faaf81fac746e7307c7adb71e858071a5d34c27583afefc64f543/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7", + "https://files.pythonhosted.org/packages/22/09/dec8189d62b45ade009f6792a2264b942a90cb88aeaf181239933cd72c3c/aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl": "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627", + "https://files.pythonhosted.org/packages/22/8c/c29d067df825a2df88ca432db848aa2fe8199598359cc06c12b09320cac9/aiohttp-3.14.3-cp314-cp314-win_arm64.whl": "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc", + "https://files.pythonhosted.org/packages/26/5e/57d42fca1d18cb5acc1cad945d017fabc5d6ae71d8a08ad66be8dc3ee544/aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24", + "https://files.pythonhosted.org/packages/28/24/2854869d29ed8a8b19d74f9ec6629515f7e04d02dd329d9d179201e58e47/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl": "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82", + "https://files.pythonhosted.org/packages/28/b7/1c2aab8c706436dcc28598452488ac9cd7c409da815237c28c27d58993e6/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl": "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427", + "https://files.pythonhosted.org/packages/29/9f/af66adce26a14af135c003cbd0f44ccaa68cebd30ff8ac99ca47fb4958f7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl": "sha256:6debfa7312ff9d4c124dc71d72e9a0a4b9e0879e48ba6fcb42bef5c3300289e2", + "https://files.pythonhosted.org/packages/29/a6/442e18b5afeade534d877a2dc3c3e392aff8d49787890b0cf84790410267/aiohttp-3.14.3-cp313-cp313-win32.whl": "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0", + "https://files.pythonhosted.org/packages/29/ba/2a0c38df3fc557620b6a5acd98364af050053b6285b4dc7ee74100c63c18/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl": "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919", + "https://files.pythonhosted.org/packages/2a/a3/ca0cc6724cca8114b05694abd916060758c79894c3aa5b012cdadc1bc28e/aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f", + "https://files.pythonhosted.org/packages/2a/e8/13a9d957a1ee40837f46aa30f0f4c657e673ad86a2e6362a9f9be20d26d9/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl": "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a", + "https://files.pythonhosted.org/packages/2d/4d/4a99fb425c5e0cad715eea7bd190aff46f38b959a0a2dadb993705d34b26/aiohttp-3.14.3-cp310-cp310-macosx_10_9_universal2.whl": "sha256:eb0495d778817619273c108784292be161a924b9f5ae5cbbc70a2caa6838250b", + "https://files.pythonhosted.org/packages/2f/90/28c390d4c9851effe52ac25b5a2e1d92246acd00728b4fc7975dafb67484/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_riscv64.whl": "sha256:f4e05329faa0ea1a404b37de4f034fd2c2defcca06a68dc6745e4e56c88e8a48", + "https://files.pythonhosted.org/packages/30/07/4bbc222cc8dbe31d4c3e8a5baad2286e4d42026ac0c570027b89afce6344/aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl": "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee", + "https://files.pythonhosted.org/packages/38/05/d33c680c1bcf1c7e130f9cbfc1fc02fe8bb0c4af2a94a53dd5fb56131e5c/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl": "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0", + "https://files.pythonhosted.org/packages/38/65/672df92e3172cd876aacfa97a952ac560877eb169384b2991ac5b273de4c/aiohttp-3.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:1b59533861b70a2185c8f4f350f791f39d64358ef6944ce71c5240c9ec0982c9", + "https://files.pythonhosted.org/packages/39/b6/19c8c592baeeb94b75f966547d40c02ac7590902306ec5863d5c027cf506/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl": "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1", + "https://files.pythonhosted.org/packages/3e/44/28dac80a8941b604f4da10ce21097614ca1bf905ce93dca28d8d7de9c1e7/aiohttp-3.14.3-cp312-cp312-win_arm64.whl": "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c", + "https://files.pythonhosted.org/packages/3f/5a/8f624384e5f1efabb5229b94157eb966b021e97bdb188c62860c2ae243c2/aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl": "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0", + "https://files.pythonhosted.org/packages/47/d1/8aba53f15ccb2238405f5e9d30e2a8ca44f93878c26e7165ade00d374b1c/aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30", + "https://files.pythonhosted.org/packages/48/d6/d51b7d4bf309af3693940d8ffd2b9ed0b682434ef85959b7c9c137f60cf8/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl": "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7", + "https://files.pythonhosted.org/packages/49/bd/40c3fee327529284375c6701cbb0fa4600cc2e8432af1378f897e2ef7d3a/aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9", + "https://files.pythonhosted.org/packages/49/ed/3b203fa6de1b338c14acdc06bf6ca9b043b7944f005966958c2ced932cde/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043", + "https://files.pythonhosted.org/packages/52/b7/7cd31f29d6055bd711ae6e669367fba6f5ae9de463910a793e30556a8db7/aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42", + "https://files.pythonhosted.org/packages/54/00/45e98b6645cd7f00a4b78b749ebd309094b0eaeb2d2e96157eadbc0d0050/aiohttp-3.14.3-cp310-cp310-win_arm64.whl": "sha256:eac645b09bcfdf73df7536331f0678c1086ea250981118ddb5199e17ccef72bb", + "https://files.pythonhosted.org/packages/54/50/94c28f08b131c4bf10984ea2c7a536c9920608bb2d6e7f95642c30cc87b7/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl": "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d", + "https://files.pythonhosted.org/packages/54/b9/42e74c46b7b7c794b995bbc1f573fb48950c38b19d8600c62a6804ee2d67/aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a", + "https://files.pythonhosted.org/packages/57/be/5afd201cc0ab139029aadb75392efe85a293403d9dd3a3226161c21ce00c/aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl": "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86", + "https://files.pythonhosted.org/packages/58/d9/22ce5786ac0c1653ae8b6c23bded02c1686d11f0dbb45b31ce128e0df985/aiohttp-3.14.3.tar.gz": "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc", + "https://files.pythonhosted.org/packages/5c/9a/dec94d6ad694552fe3424e3f1928d7a606a5d9d9433a04e7ecdd9d38ae7f/aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787", + "https://files.pythonhosted.org/packages/5e/19/08d41839658bdd44a0ed2480f3891705ecb487ce28c0dde62c9040c997e0/aiohttp-3.14.3-cp314-cp314t-win32.whl": "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963", + "https://files.pythonhosted.org/packages/60/ad/0ed7586cbef7a884e23a752fa2bb987a122e6a5dd50dab109258d0a95193/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl": "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41", + "https://files.pythonhosted.org/packages/63/5d/99e7d91c82f1399d1ae2a854e080bd1493fbc31e5e959dbc4ec33dac3bec/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl": "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c", + "https://files.pythonhosted.org/packages/64/af/38c33c4dd82fddcb4e56c4653b6f1072a8edbc6b7fa15809f14932c41e2d/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl": "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0", + "https://files.pythonhosted.org/packages/66/73/10b1ef93afa61f4963c746257b70ced619cf31a4798671de5fdb2608501d/aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b", + "https://files.pythonhosted.org/packages/68/96/021d386ae32d9b26d4b88df2e794546232ff56bb6be952bf6be227c0bbc7/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl": "sha256:cda5fd5c95ad7a125a2e8464acc78b98b94c475a3780d6aa0aa157c93f470f4d", + "https://files.pythonhosted.org/packages/6a/a4/9c033beb355d39b6147980597ec9645e4729243f686ee4dc73945de72030/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl": "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b", + "https://files.pythonhosted.org/packages/6b/ed/62bc4d74363ad346d518e0720363a949f63e2e23439a79eb5813d4d29bb3/aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b", + "https://files.pythonhosted.org/packages/6d/3e/834c26918be7d88068822b40e0db30fca50b5f4fe79104aa16a93f1d74e6/aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06", + "https://files.pythonhosted.org/packages/6e/7d/d51a706a8cbfa57f0611127daf61ab3ae02ab8420b0407412079227d1c65/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:5373dc80ad1aa2fb9ad95c83f24eef418bbda3a61375f128e5b0192e4f3f9b32", + "https://files.pythonhosted.org/packages/73/0c/2af9d1674baccd1dbd47282a93d660a22e57ef6167c856deb24b4214fbab/aiohttp-3.14.3-cp311-cp311-win_amd64.whl": "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d", + "https://files.pythonhosted.org/packages/74/e8/43b85dc55b8e950dc644babe762add781319ea881b57b33d2cce12017d12/aiohttp-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl": "sha256:c3c200cf9757edd785051dc699c7ecbec22110dbfcb3fefc7a9f9695eda8ea7a", + "https://files.pythonhosted.org/packages/76/9b/f2f8f108da17ecef2cc3efc424e8b7ad3782b1a8360f7b8eae8ced84f6ea/aiohttp-3.14.3-cp312-cp312-win_amd64.whl": "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a", + "https://files.pythonhosted.org/packages/79/03/e98c3c9e05a5bdf97defe5ff9169baba4f0ec9a901f2d60e0f060c2f051e/aiohttp-3.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:134ac5ddcf61c6fad984b9a5727d83492ada43d63471db20fb73042c13fca62f", + "https://files.pythonhosted.org/packages/7d/81/9d5d853ef892dc066d1eb6db0e87a47348b920c1c879aa554612fdbd9d79/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:0fdea2281997af69da84c77ffa6f5938a0285f21fb3887c249d67419ca865b3d", + "https://files.pythonhosted.org/packages/7e/a3/559639c34a345d2cf7c52dff6838119f2eaf29eb508227b5b83f573af813/aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl": "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80", + "https://files.pythonhosted.org/packages/7f/9e/73b582c4dbbc3c12ef4473822475effaabf1f934b56f14f5b03fe5d3a2af/aiohttp-3.14.3-cp310-cp310-macosx_11_0_arm64.whl": "sha256:fd51ebf9d3a00c074df4ede271023f4d2dba289bcc740b88191872716014e3c5", + "https://files.pythonhosted.org/packages/80/ca/87c32a0a7704583cfc49660bd817889bae5b830bf53b5dcb4e92145ac2da/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl": "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0", + "https://files.pythonhosted.org/packages/81/1b/6893d4bc57e434fc93a6c9217c637d967a0b651d989f6e3265179375754a/aiohttp-3.14.3-cp314-cp314-win32.whl": "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da", + "https://files.pythonhosted.org/packages/85/00/9c45f81de11710460edfa1dc81317b6e882703b160926c879a9d20da9fcc/aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce", + "https://files.pythonhosted.org/packages/85/1d/af798d306f7a74b6a632dbcabcf62a4c91391b7582d2a8c6d7712e2cc54e/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl": "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661", + "https://files.pythonhosted.org/packages/85/ed/0357a015892fd68058bf2d39d3fd1958e459b997a7db30aaa6aaa434ae96/aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl": "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b", + "https://files.pythonhosted.org/packages/86/e6/438b0c79ca6f45eb9fd9817dd4c01a91919a38c0de5ee9e05e2b4dc0ece7/aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100", + "https://files.pythonhosted.org/packages/88/11/e7a70a209eb9a067c0d3212b518a0134e3484f5178c7533878b6b514d469/aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl": "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228", + "https://files.pythonhosted.org/packages/8a/1d/f854878bbc69b88faefe924b619a34a6f59ec05fd387c77690667eaa75eb/aiohttp-3.14.3-cp311-cp311-win32.whl": "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa", + "https://files.pythonhosted.org/packages/8e/76/88401ff3fc95e85c5fc38d588f36f55e61ecb64343b2bc8d69326f453cc0/aiohttp-3.14.3-cp311-cp311-win_arm64.whl": "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39", + "https://files.pythonhosted.org/packages/91/cd/41e131f13afd1e7b0172a9d9eda085ef90eb8439f41f0d279db81ed3ae60/aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl": "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0", + "https://files.pythonhosted.org/packages/94/c6/bd959bd1e4771f9fd944e9e436224c48c77b018b73b519b5aad346335bcc/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl": "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb", + "https://files.pythonhosted.org/packages/95/b5/85b099c299c3ffd38ad9b3e43694c8a346934e4a30c88c4fd5a841234f77/aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d", + "https://files.pythonhosted.org/packages/97/21/6464573e53d69672cc1eada3e5c5cb2d2efa82701e8305a0f2047a576967/aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd", + "https://files.pythonhosted.org/packages/97/a3/7056b86dc0d9ec709ea9777eae3b0161428f943372f8b98c01c11593b682/aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl": "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646", + "https://files.pythonhosted.org/packages/97/ea/dbaed0d73e8a69aad653b045dab451c67c2454bb731a37b45a86593e9422/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl": "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf", + "https://files.pythonhosted.org/packages/99/5d/3cd6ef0a2b2851f7ab913b5b079334781bd50ff56a323e4454063377a080/aiohttp-3.14.3-cp314-cp314t-win_amd64.whl": "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b", + "https://files.pythonhosted.org/packages/9d/69/3d876ac02659f271cf7f6769f14a8e3de5b6e888ed8b5a7e998086a4cec8/aiohttp-3.14.3-cp313-cp313-win_amd64.whl": "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883", + "https://files.pythonhosted.org/packages/9e/8d/a71c6f2db52ac1ed142b133f7feddaa6b70539c3f4de24d7e226c95b794c/aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239", + "https://files.pythonhosted.org/packages/9e/c5/228dec7bfec1c373cc2217cdeb47d6456dcd7a13a4c55144930a75ae3851/aiohttp-3.14.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:1c5281acc88b92396f88c7e1e2748f8466689df22b80170e4f51efa712fb47a8", + "https://files.pythonhosted.org/packages/9e/d8/8ec0e471248c500acdce2be3f46db8fb62b5eb60efef072529cc85ee1d26/aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl": "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e", + "https://files.pythonhosted.org/packages/9f/3a/296a4135c6366376263aeef54b15caca1f07676c2ae0c525d7832f2f808a/aiohttp-3.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:f53bcd52f585e1ac3e590d61434eb61f9a88c38df041b4ea126d97144344a77b", + "https://files.pythonhosted.org/packages/a1/66/e13a02d0eeb1a9a502402a977abb4e4abff9fe4051c26f80558c57a7c975/aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8", + "https://files.pythonhosted.org/packages/a1/9d/0537cda4885ac8f5b7053d164dd06312f4c483a4edcb8ee5b8aaf2a989bf/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl": "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098", + "https://files.pythonhosted.org/packages/a3/84/072a91d68e1e1eb587985b54baab94221277f877e8ef274fc213a0ceae28/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl": "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d", + "https://files.pythonhosted.org/packages/a4/37/cfd1ed540a4d318da025590d96b728e63713c09e9377950fc655dadeb856/aiohttp-3.14.3-cp314-cp314t-win_arm64.whl": "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7", + "https://files.pythonhosted.org/packages/a5/11/3dd9b3fb3a170f6ec9011b5291d876a6fab4086714c9e158600edf01b4fd/aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f", + "https://files.pythonhosted.org/packages/a5/b9/2b8f0c0ce09c87a1daf80fd483431b56b1435d3f62789bc86f572e1245de/aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db", + "https://files.pythonhosted.org/packages/a6/26/4ff0164370deec18fb19254ee4ab10b7a73304ac0c860b13f5f84663759b/aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl": "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924", + "https://files.pythonhosted.org/packages/a8/92/ad720d472556a995049206867765e9410969684f86ee09423ff9969044c1/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl": "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22", + "https://files.pythonhosted.org/packages/a9/19/47f4968659c5e23606c3790c80fc624e691c153d036148449ee84d31b287/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl": "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f", + "https://files.pythonhosted.org/packages/aa/1e/147bdc6cc5de5f3ab011be8bf5d6e786633249f22c20bae06f85e45f5387/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl": "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde", + "https://files.pythonhosted.org/packages/ad/05/d5e1cb6480eeffd3f901d40a2c5e2d1e7effdc797837da3b490272699f13/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl": "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae", + "https://files.pythonhosted.org/packages/ad/a3/92cec936f78cc4bf0fa5554ebe593b73459d94e3c62303e1902a4cccb6f7/aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl": "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6", + "https://files.pythonhosted.org/packages/b1/04/6acdbf17315f7b55f1937e3387acb89a3cddeb4995689553d064af8e92ab/aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553", + "https://files.pythonhosted.org/packages/b2/0e/50d6e6471cd31edce8b282bdec59375a3a69124d8a989a0b1313355cae52/aiohttp-3.14.3-cp313-cp313-win_arm64.whl": "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2", + "https://files.pythonhosted.org/packages/b6/2b/6bb88ddba0fecd9122aa3ebcad25996cf6c083a4a7040dbb3a4f97972af6/aiohttp-3.14.3-cp312-cp312-win32.whl": "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559", + "https://files.pythonhosted.org/packages/b9/11/06ae6ed8f0d414edf4068861e233d8fe23ee699bfd4b3ceb8663db948a62/aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl": "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f", + "https://files.pythonhosted.org/packages/b9/3f/01264f820ee2e3712a827892b1cd6ff80f3300c1fcbffbb45714a915d47a/aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl": "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8", + "https://files.pythonhosted.org/packages/bb/6b/62cbd6577758699525f5c712d1ddef57d9875fbab0ae8d5f5a202fd598f8/aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85", + "https://files.pythonhosted.org/packages/bc/6b/e7f13410d391c6e55b4c007a8de024355389d7d459e3d64c42b2d33617e5/aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl": "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf", + "https://files.pythonhosted.org/packages/bd/ff/cb36724e8c8d17f90ada567a9ff3efe1d6e9b549fba697a242aece180f21/aiohttp-3.14.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:48d67b87db6279c044760787eb01f6413032c2e6f3ba1cafaa492b1c8e578479", + "https://files.pythonhosted.org/packages/c8/20/887fdcf832326571b370ffc347b3e70abe101096f3720126aac161b1d872/aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl": "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062", + "https://files.pythonhosted.org/packages/c9/90/b934682bcaefae18a9e04f3dff5b68522ba810906358ae5029b68110ea3b/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl": "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910", + "https://files.pythonhosted.org/packages/ca/1c/7da8d08e74d56f00070822f9638ff3f1c563f8ad87d1efa996c87bfc8644/aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5", + "https://files.pythonhosted.org/packages/cc/c9/49ab8572df7d66bc13d11e31f781292badb04180dd87ba98733066c6aed7/aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929", + "https://files.pythonhosted.org/packages/cd/0f/cf16bcf56896981c1a0319f5d5db9337994b5165730c48a8fa07e9b34be6/aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4", + "https://files.pythonhosted.org/packages/d0/9f/181e8a8bc79e47d13c7fc4540bd7a3b729d9505609c61f392a8dd2fbfe55/aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529", + "https://files.pythonhosted.org/packages/d1/16/bc4b55e3e5cb175fd69c53c90d60d2f47797cb343da5106e23863dc4dba4/aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c", + "https://files.pythonhosted.org/packages/d4/dd/57187c8be2a35aea65eaee3bd2c3dcbbcf0204f5106c89637e3610380cd1/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl": "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c", + "https://files.pythonhosted.org/packages/d5/b7/1da684a04175473fa4cddbf9a2f572e79514c3fd27a74597f43057d4f3da/aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147", + "https://files.pythonhosted.org/packages/d7/2c/26e60b694844dfd2176c57f913a22d0cd6a16f9ff202cbda7580d0328b98/aiohttp-3.14.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:70c987b27534f9ae1a723f47ae921571d616da21d3208282bf4c52af5164ac43", + "https://files.pythonhosted.org/packages/d8/15/fe5b8f6a71ae112bc677163d0b0701bda5dc15005249582258ede0eb88c7/aiohttp-3.14.3-cp310-cp310-win_amd64.whl": "sha256:bdd0e2834dce1a26c1bbe26464861e16bbe217042cbff619247c11594472518c", + "https://files.pythonhosted.org/packages/db/c2/00e23a1bf2abb70dd353f6987db7e7f2491d0261f7363997738c71c98f95/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_s390x.whl": "sha256:a3a8296e7ab5c295f53f1041487cb088e1480775aafbf7fe545d93b770a0f96f", + "https://files.pythonhosted.org/packages/dc/c9/4e9383150296f97f873b680c4de8fb2cd88608fb9f48c79edcb111611abc/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl": "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371", + "https://files.pythonhosted.org/packages/e0/eb/aad34e897e668424d6e995da5dff8a4a09af93363d3392488772957a63aa/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19", + "https://files.pythonhosted.org/packages/ec/4c/618b1db9b9ba079b8875d2cdf78e7c4a3bf72903bd5850fee7dd9544600a/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl": "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9", + "https://files.pythonhosted.org/packages/ec/b0/90bd5cd9fdd9787cb4211d284d1fb8401339a933cb0227a15b71e789232f/aiohttp-3.14.3-cp310-cp310-win32.whl": "sha256:a3e22975f905b89a55a488c2a08f2fdb2186175349e917d48985cc468a3d4c6e", + "https://files.pythonhosted.org/packages/f5/8b/c7baa1ba1eda4db6989baefe5de6d99834921b84ebd7918624febcb9f290/aiohttp-3.14.3-cp314-cp314-win_amd64.whl": "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100", + "https://files.pythonhosted.org/packages/f6/ec/9ca76b28a27525b0cc53e20842e0228b022f301ce1f436b7d814b4aaf2df/aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f", + "https://files.pythonhosted.org/packages/f8/5c/b3e4ff8ad43a8afef9602c5e90285936da1beaea8b029016b793891f03c3/aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl": "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3", + "https://files.pythonhosted.org/packages/fd/31/78388a9d6040ece2e11df62ea229a822cf5e52d238374b220ae9975b2623/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl": "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e", + "https://files.pythonhosted.org/packages/fe/45/f8919fd936e8b79fcd9bda7b6d8e62613462a713f4f17987fd7c34399142/aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716", + "https://files.pythonhosted.org/packages/fe/6f/76eac12a7f2480e1e304f842efdb07db33256b0d9165b866b6ef0806c202/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9" + }, + "aioquic": { + "https://files.pythonhosted.org/packages/23/f2/7b1908feffb29b89d2f6d4adc583e83543cd559676354f85c5b4b77a6428/aioquic-1.3.0-cp310-abi3-win32.whl": "sha256:ba30016244e45d9222fdd1fbd4e8b0e5f6811e81a5d0643475ad7024a537274a", + "https://files.pythonhosted.org/packages/43/60/a8cb5f85c5a6a3cc630124a45644ca5a0ab3eecae2df558b6e0ab7847e1c/aioquic-1.3.0-cp310-abi3-win_arm64.whl": "sha256:9d15a89213d38cbc4679990fa5151af8ea02655a1d6ce5ec972b0a6af74d5f1c", + "https://files.pythonhosted.org/packages/52/50/b421e7aedff4a96840bf8734c2c11c18a8434c780c0cb59dff7f0906cee8/aioquic-1.3.0-cp310-abi3-musllinux_1_2_i686.whl": "sha256:0538acdfbf839d87b175676664737c248cd51f1a2295c5fef8e131ddde478a86", + "https://files.pythonhosted.org/packages/6b/0c/858bb02e0ff96b40735b09ed7be25690197851e4c1bcde51af3348c851fc/aioquic-1.3.0.tar.gz": "sha256:28d070b2183e3e79afa9d4e7bd558960d0d53aeb98bc0cf0a358b279ba797c92", + "https://files.pythonhosted.org/packages/82/45/4e47404984d65ee31cc9e1370f1fbc4e8c92b25da71f61429dbdba437246/aioquic-1.3.0-cp310-abi3-win_amd64.whl": "sha256:2d7957ba14a6c5efcc14fdc685ccda7ecf0ad048c410a2bdcad1b63bf9527e8e", + "https://files.pythonhosted.org/packages/87/be/a141aafe8984ed380e610397d606a9d9818ef30ce352aa9ede048a966d81/aioquic-1.3.0-cp310-abi3-musllinux_1_2_aarch64.whl": "sha256:48292279a248422b6289fffd82159eba8d8b35ff4b1f660b9f74ff85e10ca265", + "https://files.pythonhosted.org/packages/9e/ea/ac91850a3e6c915802d8c0ee782f966ddfaeed9f870696c1cdb98b25c9a1/aioquic-1.3.0-cp310-abi3-macosx_11_0_arm64.whl": "sha256:48590fa38ec13f01a3d4e44fb3cfd373661094c9c7248f3c54d2d9512b6c3469", + "https://files.pythonhosted.org/packages/a8/65/383f3b3921e1d6b9b757bff3c805c24f7180eda690aecb5e8df50eb7b028/aioquic-1.3.0-cp310-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl": "sha256:019b16580d53541b5d77b4a44a61966921156554fad2536d74895713c800caa5", + "https://files.pythonhosted.org/packages/b9/00/66f9a2f95db35ccbe1d9384d44beae28072fceec6ca0ffa29f6c640516c2/aioquic-1.3.0-cp310-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl": "sha256:396e5f53f6ddb27713d9b5bb11d8f0f842e42857b7e671c5ae203bf618528550", + "https://files.pythonhosted.org/packages/bc/f4/3c674f4608883e7fc7212f067c599d1321b0c5dd45bda5c77ab5a1e73924/aioquic-1.3.0-cp310-abi3-musllinux_1_2_x86_64.whl": "sha256:a8881239801279188e33ced6f9849cedf033325a48a6f44d7e55e583abc555a3", + "https://files.pythonhosted.org/packages/c7/41/9a6cf092f2d21768091969dccd4723270f4cd8138d00097160d9c8eabeb8/aioquic-1.3.0-cp310-abi3-macosx_10_9_x86_64.whl": "sha256:59da070ff0f55a54f5623c9190dbc86638daa0bcf84bbdb11ebe507abc641435", + "https://files.pythonhosted.org/packages/d5/7a/f020815b9fa6ea9b83354deb213b90a25fd01466f5a8e517e1c0e672be8c/aioquic-1.3.0-cp310-abi3-manylinux_2_28_i686.whl": "sha256:4098afc6337adf19bdb54474f6c37983988e7bfa407892a277259c32eb664b00" + }, + "aiosignal": { + "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz": "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", + "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl": "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e" + }, + "anyio": { + "https://files.pythonhosted.org/packages/61/cc/a381afa6efea9f496eff839d4a6a1aed3bfafc7b3ab4b0d1b243a12573dd/anyio-4.14.2.tar.gz": "sha256:cfa139f3ed1a23ee8f88a145ddb5ac7605b8bbfd8592baacd7ce3d8bb4313c7f", + "https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl": "sha256:9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494" + }, + "attrs": { + "https://files.pythonhosted.org/packages/49/7c/fdf464bcc51d23881d110abd74b512a42b3d5d376a55a831b44c603ae17f/attrs-25.1.0.tar.gz": "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e", + "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl": "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", + "https://files.pythonhosted.org/packages/fc/0f/aafca9af9315aee06a89ffde799a10a582fe8de76c563ee80bbcdc08b3fb/attrs-24.2.0.tar.gz": "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", + "https://files.pythonhosted.org/packages/fc/30/d4986a882011f9df997a55e6becd864812ccfcd821d64aac8570ee39f719/attrs-25.1.0-py3-none-any.whl": "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a" + }, + "automat": { + "https://files.pythonhosted.org/packages/8d/2d/ede4ad7fc34ab4482389fa3369d304f2fa22e50770af706678f6a332fa82/automat-24.8.1.tar.gz": "sha256:b34227cf63f6325b8ad2399ede780675083e439b20c323d376373d8ee6306d88", + "https://files.pythonhosted.org/packages/af/cc/55a32a2c98022d88812b5986d2a92c4ff3ee087e83b712ebc703bba452bf/Automat-24.8.1-py3-none-any.whl": "sha256:bf029a7bc3da1e2c24da2343e7598affaa9f10bf0ab63ff808566ce90551e02a" + }, + "backports-tarfile": { + "https://files.pythonhosted.org/packages/86/72/cd9b395f25e290e633655a100af28cb253e4393396264a98bd5f5951d50f/backports_tarfile-1.2.0.tar.gz": "sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991", + "https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl": "sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34" + }, + "blinker": { + "https://files.pythonhosted.org/packages/1e/57/a6a1721eff09598fb01f3c7cda070c1b6a0f12d63c83236edf79a440abcc/blinker-1.8.2.tar.gz": "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83", + "https://files.pythonhosted.org/packages/bb/2a/10164ed1f31196a2f7f3799368a821765c62851ead0e630ab52b8e14b4d0/blinker-1.8.2-py3-none-any.whl": "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01" + }, + "cachetools": { + "https://files.pythonhosted.org/packages/d9/74/57df1ab0ce6bc5f6fa868e08de20df8ac58f9c44330c7671ad922d2bbeae/cachetools-5.5.1.tar.gz": "sha256:70f238fbba50383ef62e55c6aff6d9673175fe59f7c6782c7a0b9e38f4a9df95", + "https://files.pythonhosted.org/packages/ec/4e/de4ff18bcf55857ba18d3a4bd48c8a9fde6bb0980c9d20b263f05387fd88/cachetools-5.5.1-py3-none-any.whl": "sha256:b76651fdc3b24ead3c648bbdeeb940c1b04d365b38b4af66788f9ec4a81d42bb" + }, + "certifi": { + "https://files.pythonhosted.org/packages/0b/a7/71ac2cff56fec219ed242bb11b8efb69fcc4bec75db06fb7bfe35de520e6/certifi-2026.7.22-py3-none-any.whl": "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775", + "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl": "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", + "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz": "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", + "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl": "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", + "https://files.pythonhosted.org/packages/a3/c2/24167ea9858356b47a87a50d39908bfdb72ceeefe0041586e704e5376b3a/certifi-2026.7.22.tar.gz": "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55", + "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz": "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9" + }, + "cffi": { + "https://files.pythonhosted.org/packages/04/8c/b925975448cf20634a9fbd5efceb807219db452653648d2897c0989cab2d/cffi-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:89095c1968b4ba8285840e131bf2891b09ae137fe2146905acae0354fbce1b5e", + "https://files.pythonhosted.org/packages/05/eb/b86f2a2645b62adcfff53b0dd97e8dfafb5c8aa864bd0d9a2c2049a0d551/cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0", + "https://files.pythonhosted.org/packages/05/ef/6cd4f8c671517162379dc79cfae5aea9106bc38abb89628d5c16adf6a838/cffi-2.1.0-cp315-cp315-win_arm64.whl": "sha256:8d35c139744adb3e727cd51b1a18324bbe44b8bd41bf8322bca4d41289f48eda", + "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", + "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", + "https://files.pythonhosted.org/packages/0f/6f/ade5ce9863a57992a6ea3d0d10d7e29b8749fc127204b3d493d667b2815f/cffi-2.1.0-cp314-cp314-win32.whl": "sha256:1854b724d00f6654c742097d5387569021be12d3a0f770eae1df8f8acfcc6acd", + "https://files.pythonhosted.org/packages/11/b6/12fc55092817a5faa26fb8c40c7f9d662e11a46ee248c137aafc42517d92/cffi-2.1.0-cp315-cp315t-macosx_10_15_x86_64.whl": "sha256:f9912624a0c0b834b7520d7769b3644453aabc0a7e1c839da7359f050750e9bc", + "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl": "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", + "https://files.pythonhosted.org/packages/14/d0/117dcd9209255ad8571fbc8c92ef32593a1d294dcec91ddc4e4db50606f2/cffi-2.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:eb4e8997a49aa2c08a3e43c9045d224448b8941d88e7ac163c7d383e560cbf98", + "https://files.pythonhosted.org/packages/14/f0/134c00ce0779ec86dea2aa1aac69339c2741a8045072676763512363a2ea/cffi-2.1.0-cp314-cp314t-macosx_10_15_x86_64.whl": "sha256:7ea6b3e2c4250ff1de21c630fe72d0f63eb95c2c32ffbf64a358cf4a8836d714", + "https://files.pythonhosted.org/packages/15/12/a7a79bd0df4c3bff744b2d7e52cc1b68d5e7e427b384252c42366dc1ecbc/cffi-2.0.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165", + "https://files.pythonhosted.org/packages/19/e5/d3cc82a4a0be7902af279c04181ad038449c096734464a5ae1de3e1401bd/cffi-2.1.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:0611e7ebf90573a535ebdc33ae9da222d037853983e13359f580fab781ca017f", + "https://files.pythonhosted.org/packages/1b/dc/5620cf930688be01f2d673804291de757a934c90b946dbdc3d84130c2ea4/cffi-2.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:b6422532152adf4e59b110cb2808cee7a033800952f5c036b4af047ee43199e7", + "https://files.pythonhosted.org/packages/1e/85/990925db5df586ec90beb97529c853497e7f85ba0234830447faf41c3057/cffi-2.1.0-cp312-cp312-macosx_10_15_x86_64.whl": "sha256:df2b82571a1b30f58a87bf4e5a9e78d2b1eff6c6ce8fd3aa3757221f93f0863f", + "https://files.pythonhosted.org/packages/1f/74/cc4096ce66f5939042ae094e2e96f53426a979864aa1f96a621ad128be27/cffi-2.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63", + "https://files.pythonhosted.org/packages/20/71/7c8372d30e42415602ed9f268f7cfd66f1b855fed881ecd168bcb45dbc0b/cffi-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl": "sha256:1ff3456eab0d889592d1936d6125bbfbc7ae4d3354a700f8bd80450a66445d4d", + "https://files.pythonhosted.org/packages/21/7a/13b24e70d2f90a322f2900c5d8e1f14fa7e2a6b3332b7309ba7b2ba51a5a/cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495", + "https://files.pythonhosted.org/packages/22/d7/1a74539db16d8bfd839ff1515948948efbb162e574650fd3d846896eea95/cffi-2.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:88023dfe18799507b73f1dbb0d14326a17465de1bc9c9c7655c22845e9ddc3a2", + "https://files.pythonhosted.org/packages/22/f0/a2fc43084c0433caf7f461bccc013e28f848d04ee1c5ed7fce71423cf4d9/cffi-2.1.0-cp311-cp311-musllinux_1_2_i686.whl": "sha256:7762faa47e8ff7eb80bd261d9a7d8eea2d8baa69de5e95b70c1f338bbe712f02", + "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl": "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", + "https://files.pythonhosted.org/packages/28/3b/fad54de07260b93ddeef4b96d0131d57ea900675df1d410ae1deee52d7a6/cffi-2.1.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:33eb1ad83ebe8f313e0df035c406227d55a79456704a863fad9842136af5ad7d", + "https://files.pythonhosted.org/packages/28/ed/c127d3ac36e899c965e3361357c3befacd6578c03f40125183e41c3b219e/cffi-2.1.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:6ca4919c6e4f89aa99c42510b42cf54596892c00b3f9077f6bdd1505e24b9c8d", + "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl": "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", + "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl": "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", + "https://files.pythonhosted.org/packages/2b/e7/7c769804eb75e4c4b35e658dba01de1640a351a9653c3d49ca89d16ccc91/cffi-2.0.0-cp39-cp39-musllinux_1_2_x86_64.whl": "sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322", + "https://files.pythonhosted.org/packages/2c/0e/fac738d73728c6cea2a88a2883dca54892496cbba88a1dc1f2909cb8a6f5/cffi-2.1.0-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:2b71d409cccee78310ab5dec549aed052aaea483346e282c7b02362596e01bb0", + "https://files.pythonhosted.org/packages/2c/d8/772b8259bf75749adffb1c546828978381fb516f60cf701f6c83daf60c85/cffi-2.1.0-cp315-cp315-win32.whl": "sha256:0a42c688d19fca6e095a53c6a6e2295a5b050a8b289f109adab02a9e61a25de6", + "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl": "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", + "https://files.pythonhosted.org/packages/2e/1a/cc6ae6c2913a03aab8898eee57963cf1035b8df5872ed8b9115fcc7e2be8/cffi-2.1.0-cp314-cp314-win_arm64.whl": "sha256:7d28dff1db6764108bc30788d85d61c876beff416d9a49cb9dd7c5a9f34f5804", + "https://files.pythonhosted.org/packages/2e/d2/065fcae1c73979fac8e054462478d0ff8a29c40cdc2ed7ea5676a061df53/cffi-2.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:276f20fffd7b396e12516ba8edf9509210ac248cbbc5acbc39cd512f9f59ebe6", + "https://files.pythonhosted.org/packages/2f/dd/afa2191fc6d57fedd26e5844a2fe2fcc0bbfa00961bbaa5a41e4921e7cca/cffi-2.1.0-cp315-cp315-win_amd64.whl": "sha256:bccbbb5ee76a61f9d99b5bf3846a51d7fca4b6a732fe46f89295610edaf41853", + "https://files.pythonhosted.org/packages/32/f2/81b63e288295928739d715d00952c8c6034cb6c6a516b17d37e0c8be5600/cffi-2.0.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f", + "https://files.pythonhosted.org/packages/33/fa/072dd15ae27fbb4e06b437eb6e944e75b068deb09e2a2826039e49ee2045/cffi-2.0.0-cp310-cp310-win_amd64.whl": "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739", + "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", + "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl": "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", + "https://files.pythonhosted.org/packages/38/37/04f54b8e63a02f3d908332c9effbf8c366167c6f733ed8a3d4f79b7e2a1e/cffi-2.1.0-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:961be50688f7fba2fa65f63712d3b9b341a22311f5253460ce933f52f0de1c8c", + "https://files.pythonhosted.org/packages/38/66/04781a77b411f0bb5b234d62c1814754ab75ebe455ccff1b08e8d7aae98f/cffi-2.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:4d433a51f1870e43a13b6732f92aaf540ff77c2015097c78556f75a2d6c030e0", + "https://files.pythonhosted.org/packages/3a/a6/e879bb68cc23a2bc9ba8f4b7d8019f0c2694bad2ab6c4a3701d429439f58/cffi-2.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:ff067a8d8d880e7809e4ac88eb009bb848870115317b306666502ccad30b147f", + "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", + "https://files.pythonhosted.org/packages/3b/30/c806937ed5e4c2c7ac30d9d6b76b5dc57ff8b75d83800d9bb11a8253cf2a/cffi-2.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:a016194dbe13d14ee9556e734b772d8d67b947092b268d757fd4290e3ba2dfc2", + "https://files.pythonhosted.org/packages/3d/de/38d9726324e127f727b4ecc376bc85e505bfe61ef130eaf3f290c6847dd4/cffi-2.0.0-cp39-cp39-macosx_11_0_arm64.whl": "sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7", + "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl": "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", + "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl": "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", + "https://files.pythonhosted.org/packages/41/aa/3c1409cdd26094efacd1c36c66e0a6eb9d4296e4fd4f9901b8b2042f4323/cffi-2.1.0-cp310-cp310-musllinux_1_2_i686.whl": "sha256:c5f5df567f6eb216de69be06ce55c8b714090fae02b18a3b40da8163b8c5fa9c", + "https://files.pythonhosted.org/packages/41/de/92b9eeed4ae4a21d6fd9b2a2c8505cbed573299902ea73981cc13f7ff62c/cffi-2.1.0-cp314-cp314-win_amd64.whl": "sha256:1b96bfe2c4bd825681b7d311ad6d9b7280a091f43e8f63da5729638083cd3bfb", + "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", + "https://files.pythonhosted.org/packages/45/ca/f91641185cdd90c36d317a9dc7f85e88ef8682d8b300977baff5e23c35d8/cffi-2.1.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:19c54ac121cad98450b4896fa9a43ee0180d57bc4bc911a33db6cab1efab6cd3", + "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", + "https://files.pythonhosted.org/packages/49/72/ff2d12dbf21aca1b32a40ed792ee6b40f6dc3a9cf1644bd7ef6e95e0ac5e/cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb", + "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl": "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", + "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl": "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", + "https://files.pythonhosted.org/packages/4b/92/e7bb136ad6b5352603732cf907ef862ca103f20f2031c1735a46300c20c9/cffi-2.1.0-cp312-cp312-macosx_11_0_arm64.whl": "sha256:78474632761faa0fb96f30b1c928c84ebcf68713cbb80d15bab09dfe61640fde", + "https://files.pythonhosted.org/packages/4b/a4/77b53abbf7a1e0beb9637edbef2a94d15f9c822f591e85d439ffd91519a6/cffi-2.1.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:46b1c8db8f6122420f32d02fffb924c2fe9bc772d228c7c711748fff56aabb2b", + "https://files.pythonhosted.org/packages/4f/27/6933a8b2562d7bd1fb595074cf99cc81fc3789f6a6c05cdabb46284a3188/cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb", + "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl": "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", + "https://files.pythonhosted.org/packages/50/bd/b1a6362b80628111e6653c961f987faa55262b4002fcec42308cad1db680/cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl": "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c", + "https://files.pythonhosted.org/packages/50/d8/3b86aba791cb610d24e8a3e1b2cd529e71fa15096b04e4d4e360049d4a4c/cffi-2.1.0-cp314-cp314t-macosx_11_0_arm64.whl": "sha256:6af371f3767faeffc6ac1ef57cdfd25844403e9d3f476c5537caee499de96376", + "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", + "https://files.pythonhosted.org/packages/54/8f/a1e836f82d8e32a97e6b29cc8f641779181ac7363734f12df27db803ebda/cffi-2.0.0-cp39-cp39-win_amd64.whl": "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9", + "https://files.pythonhosted.org/packages/55/c7/8c8c50cb11c6750051daf12164098a9a6f027ac4356967fd4d800a07f242/cffi-2.1.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl": "sha256:2e9dabb9abcb7ad15938c7196ad5c1718a4e6d33cc79b4c0209bdb64c4a54a5c", + "https://files.pythonhosted.org/packages/57/5f/ff100cae70ebe9d8df1c01a00e510e45d9adb5c1fdda84791b199141de97/cffi-2.1.0.tar.gz": "sha256:efc1cdd798b1aaf39b4610bba7aad28c9bea9b910f25c784ccf9ec1fa719d1f9", + "https://files.pythonhosted.org/packages/58/0c/f528df19cc94b675087324d4760d9e6d5bfae97d6217aa4fac43de4f5fcc/cffi-2.1.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:d9fafc5aa2e2a39aaf7f8cc0c1f044a9b07fca12e558dca53a3cc5c654ad67a7", + "https://files.pythonhosted.org/packages/58/85/7ae00d5c8dd6266f4e944c3db630f3c5c9a98b61d469c714d848b1d8138a/cffi-2.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl": "sha256:a95b05f9baf29b91171b3a8bd2020b028835243e7b0ff6bb23e2a3c228518b1b", + "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl": "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", + "https://files.pythonhosted.org/packages/5a/02/d5e6c43ea85c41bda2a184a3418f195fe7cf602967a8d2b94e085b83deef/cffi-2.1.0-cp315-cp315-musllinux_1_2_x86_64.whl": "sha256:af5e2915d41fe6c961694d7bfdc8562942638200f3ce2765dfb8b745cf997629", + "https://files.pythonhosted.org/packages/5a/47/59eb7975cb0e4ef0afa764ea945b29a5bb4537a9f771cb7d6c8a5dd74c95/cffi-2.1.0-cp313-cp313-win_amd64.whl": "sha256:8e74a6135550c4748af665b1b1118b6aab33b1fc6a16f9aff630af107c3b4512", + "https://files.pythonhosted.org/packages/5a/67/9e6e09409336d9e515c58367e7cfcf4f89df06ad25252675595a58eb59d5/cffi-2.1.0-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:762f99479dcb369f60ab9017ad4ab97a36a1dd7c1ee5a3b15db0f4b8659120cd", + "https://files.pythonhosted.org/packages/5a/af/34fee85c48f8d94efc8597bc09470c9dd274c145f1c12e0fbc6ab6d38d74/cffi-2.1.0-cp313-cp313-win_arm64.whl": "sha256:2282cd5e38aa8accd03e99d1256af8411c84cdbee6a89d841b563fdbd1f3e50f", + "https://files.pythonhosted.org/packages/5d/7c/b7379a5704c79eda57ce075869ba70a0368d1c850f803b3c0d078d39dcaf/cffi-2.1.0-cp315-cp315-musllinux_1_2_aarch64.whl": "sha256:8f9ec95b8a043d3dfbc74d9abc6f7baf524dd27a8dc160b0a32ff9cdab650c28", + "https://files.pythonhosted.org/packages/60/99/c9dc110974c59cc981b1f5b66e1d8af8af764e00f0293266824d9c4254bc/cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl": "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5", + "https://files.pythonhosted.org/packages/62/f2/c9522a81c32132799a1972c39f5c5f8b4c8b9f00488a23feaa6c06f07741/cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:1e9f50d192a3e525b15a75ab5114e442d83d657b7ec29182a991bc9a88fd3a66", + "https://files.pythonhosted.org/packages/65/68/9f3ef890cf3c6ab97bd531c5677f67613d302165d16f8142b2811782a614/cffi-2.1.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl": "sha256:30b65779d598c370374fefabf138d456fd6f3216bfa7bedfab1ba82025b0cd93", + "https://files.pythonhosted.org/packages/68/5a/e536c528bc8057496c360c0978559a2dc45653f89dd6151078aa7d8fca1a/cffi-2.1.0-cp315-cp315t-win32.whl": "sha256:cb96698e3c7413d906ce83f8ffd245ec1bd94707541f299d0ce4d6b0193e982b", + "https://files.pythonhosted.org/packages/69/aa/24580a278de21fd7322635556334d9b535f1cbc00b0a3919447cdf464c65/cffi-2.1.0-cp310-cp310-macosx_11_0_arm64.whl": "sha256:164bff1657b2a74f0b6d54e11c9b375bc97b931f2ca9c43fcf875838da1570dd", + "https://files.pythonhosted.org/packages/6c/d0/47e338384ab6b1004241002fa616301020cea4fc95f283506565d252f276/cffi-2.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl": "sha256:c16914df9fb7f500e440e6875fa23ff5e0b31db01fa9c06af98d59a91f0dc2e4", + "https://files.pythonhosted.org/packages/6e/28/bd53988b9833e8f8ad539d26f4c07a6b3f6bcb1e9e02e7ca038250b3428d/cffi-2.1.0-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:98fff996e983a36d3aa2eca83af40c5821202e7e6f32d13ae94e3d2286f10cfe", + "https://files.pythonhosted.org/packages/6f/08/f2e7d62c460faae0926f2d6e423694aa409ced3bc1fe2927a0a6e5f05416/cffi-2.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:799416bae98336e400981ff6e532d67d5c709cfb30afb79865a1315f94b0e224", + "https://files.pythonhosted.org/packages/70/25/65bd5b58ea4bfdfc15cde02cb5365f89ef8ab8b2adfb8fe5c4bd4233382f/cffi-2.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl": "sha256:5ecbd0499275d57506d397eebe1981cee87b47fcd9ef5c22cab7ed7644a39a94", + "https://files.pythonhosted.org/packages/70/b6/9003c33a3e7d2c1306f5962e646457dcfe5a8cd8fce6bbe02d7af25db783/cffi-2.1.0-cp310-cp310-win32.whl": "sha256:9d72af0cf10a76a600a9690078fe31c63b9588c8e86bf9fd353f713c84b5db0f", + "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", + "https://files.pythonhosted.org/packages/79/99/0d0fd37f055224085f42bbb2c022d002e17dde4a97972822327b07d84101/cffi-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:379de10ce1ba048b1448599d1b37b24caee16309d1ac98d3982fc997f768700b", + "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl": "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", + "https://files.pythonhosted.org/packages/7d/95/8de304305cd9204974b0ca051b86d307cafca13aa575a0ef1b44d92c0d8c/cffi-2.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl": "sha256:702c436735fbe99d59ada02a1f65cfc0d31c0ee8b7290912f8fbc5cd1e4b16c3", + "https://files.pythonhosted.org/packages/84/4c/82f132cb4418ee6d953d982b19191e87e2a6372c8a4ce36e50b69d6ade4a/cffi-2.1.0-cp313-cp313-macosx_11_0_arm64.whl": "sha256:716ff8ec22f20b4d988b12884086bcef0fc99737043e503f7a3935a6be99b1ea", + "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", + "https://files.pythonhosted.org/packages/88/a9/02cae418ec4beb282ace11958d9d4737793439d561fadc7e6d56f2e2b354/cffi-2.1.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl": "sha256:c941bb58d5a6e1c3892d86e42927ed6c180302f07e6d395d08c416e594b98b46", + "https://files.pythonhosted.org/packages/88/f6/01890cfd63c08f8eb96a8319b0443690197d240a8bd6346048cf7bde9190/cffi-2.1.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:3b926723c13eba9f81d2ef3820d63aeceec3b2d4639906047bf675cb8a7a500d", + "https://files.pythonhosted.org/packages/8a/26/710688310447531c7a22f857c7f79d9855ec18b03e04494ced723fb37e2f/cffi-2.1.0-cp310-cp310-win_amd64.whl": "sha256:fb62edb5bb52cca65fab91a63afa7561607120d26090a7e8fda6fb9f064726da", + "https://files.pythonhosted.org/packages/8b/31/e115c985105dd7ffb32444505f18ceb874bb42d992af05d5dced7ecf1980/cffi-2.1.0-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:3681e031db29958a7502f5c0c9d6bbc4c36cb20f7b104086fa642d1799631ff8", + "https://files.pythonhosted.org/packages/8c/e9/45c3a76ad8d43ad9261f4c95436da61128d3ca545d72b9612c0ab5be0b1c/cffi-2.1.0-cp313-cp313-macosx_10_15_x86_64.whl": "sha256:15faec4adfff450819f3aee0e2e02c812de6edb88203aa58807955db2003472a", + "https://files.pythonhosted.org/packages/8d/2e/cdac88979f295fde5daa69622c7d2111e56e7ceb94f211357fbe452339e4/cffi-2.1.0-cp315-cp315t-macosx_11_0_arm64.whl": "sha256:df92f2aba50eb4d96718b68ef76f2e57a57b54f2fa62333496d16c6d585a85ca", + "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl": "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", + "https://files.pythonhosted.org/packages/93/d7/516d984057745a6cd96575eea814fe1edd6646ee6efd552fb7b0921dec83/cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl": "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44", + "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl": "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", + "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl": "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", + "https://files.pythonhosted.org/packages/96/88/a996879e2eeccb815f6e3a5967b12a308257412acec882039d386bd2aa7b/cffi-2.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl": "sha256:10537b1df4967ca26d21e5072d7d54188354483b91dc75058968d3f0cf13fbda", + "https://files.pythonhosted.org/packages/98/29/9b366e70e243eb3d14a5cb488dfd3a0b6b2f1fb001a203f653b93ccfac88/cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453", + "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", + "https://files.pythonhosted.org/packages/99/e2/67680bf19a6b60d2bb7ff83baefa2a4c3d2d7dc0f3277034b802e1fc504c/cffi-2.1.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl": "sha256:37f525a7e7e50c017fdebe58b787be310ad59357ae43a053943a6e1a6c526001", + "https://files.pythonhosted.org/packages/9b/13/c92e36358fbcc39cf0962e83223c9522154ee8630e1df7c0b3a39a8124e2/cffi-2.0.0-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl": "sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c", + "https://files.pythonhosted.org/packages/9e/4e/e8d7cb5783f1841a3c8fb3a7735838d7484d08ec08c9f984b14cac1ac0e9/cffi-2.1.0-cp311-cp311-win_arm64.whl": "sha256:35aaea0c7ee0e58a5cd8c2fd1a48fdf7ece0d2699b7ecdda08194e9ce5dd9b3d", + "https://files.pythonhosted.org/packages/9e/84/ad6a0b408daa859246f57c03efd28e5dd1b33c21737c2db84cae8c237aa5/cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl": "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49", + "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl": "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", + "https://files.pythonhosted.org/packages/9f/e0/6cbe77a53acf5acc7c08cc186c9928864bd7c005f9efd0d126884858a5fe/cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4", + "https://files.pythonhosted.org/packages/a0/17/1073b53b68c9b5ca6914adf5f8bf55aacc2d3be102418c90700160ea8605/cffi-2.1.0-cp315-cp315t-win_arm64.whl": "sha256:cbb7640ce37159548d2147b5b8c241f962143d4c71231431820783f4dc78f210", + "https://files.pythonhosted.org/packages/a0/1c/4ed5a0e5bdca6cbc275556de3328dd1b76fd0c11cc13c88fe66d1d8715f2/cffi-2.1.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl": "sha256:63960549e4f8dc41e31accb97b975abaecfc44c03e396c093a6436763c2ea7db", + "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl": "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", + "https://files.pythonhosted.org/packages/a2/a5/d4fe77b589e5e82d43ebc809bf2e6474afe8e48e32ea050b9357645b6471/cffi-2.1.0-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:9d8272c0e483b024e1b9ad029821470ed8ec65631dbd90217469da0e7cd89f1c", + "https://files.pythonhosted.org/packages/a3/ad/5c51c1c7600bdd7ed9a24a203ec255dccdd0ebf4527f7b922a0bde2fb6ed/cffi-2.0.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534", + "https://files.pythonhosted.org/packages/a6/cf/2b684132056f438567b61e19d690dd31cd0921ace051e0a458be6074369e/cffi-2.1.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:47ff3a8bfd8cb9da1af7524b965127095055654c177fcfc7578debcb015eecd0", + "https://files.pythonhosted.org/packages/a8/eb/f636456ff21a83fc13c032b58cc5dde061691546ac79efa284b2989b7982/cffi-2.1.0-cp312-cp312-win_amd64.whl": "sha256:c97f080ea627e2863524c5af3836e2270b5f5dfff1f104392b959f8df0c5d384", + "https://files.pythonhosted.org/packages/a9/d6/c72eecca433cd3e681c65ed313ab4835d9d4a379704d0f628a6a05f51c2e/cffi-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:bf5c6cf48238b0eb4c086978c492ad1cbc22373fc5b2d7353b3a598ce6db887a", + "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", + "https://files.pythonhosted.org/packages/aa/d9/6218d78f920dcd7507fc16a766b5ef8f3b913cc7aa938e7fc80b9978d089/cffi-2.0.0-cp39-cp39-win32.whl": "sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a", + "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl": "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", + "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl": "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", + "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl": "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", + "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl": "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", + "https://files.pythonhosted.org/packages/b0/80/c138990aa2a70b1a269f6e06348729836d733d6f970867943f61d367f8cc/cffi-2.1.0-cp312-cp312-win32.whl": "sha256:9b8f0f26ca4e7513c534d351eca551947d053fac438f2a04ac96d882909b0d3a", + "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl": "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", + "https://files.pythonhosted.org/packages/b3/c1/6dbd291ee2ae5a50a034aa057207081f545923bbf15dad4511e985aafff5/cffi-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl": "sha256:dbf7c7a88e2bac086f06d14577332760bdeecc42bdec8ac4077f6260557d9326", + "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", + "https://files.pythonhosted.org/packages/b5/9f/d4dc66ca651eb1145a133314cda721abf13cfac3d28c4a0402263ae6ad75/cffi-2.1.0-cp315-cp315t-musllinux_1_2_x86_64.whl": "sha256:ba00f661f8ba35d075c937174e27c2c421cec3942fd2e0ea3e66996757c0fdd9", + "https://files.pythonhosted.org/packages/b6/3d/f20f8b886b254e3ad10e15cd4186d3aed49f3e6a35ab37aab9f8f25f7c03/cffi-2.1.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:bf01d8c84cbea96b944c73b22182e6c7c432b3475632b8111dbfdc95ddad6e13", + "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", + "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", + "https://files.pythonhosted.org/packages/b9/26/d00496b22de4d4228f32dde94ad996f350c8aad676d63bcca0743c8dea4d/cffi-2.1.0-cp314-cp314t-win_amd64.whl": "sha256:0582a58f3051372229ca8e7f5f589f9e5632678208d8636fea3676711fdf7fe5", + "https://files.pythonhosted.org/packages/b9/65/b434abc97ce7cecc2c640fde160507c0ecc7e21544b483ba3325d2e2ea17/cffi-2.1.0-cp315-cp315t-musllinux_1_2_aarch64.whl": "sha256:86cf8755a791f72c85dc287128cc62d4f24d392e3f1e15837245623f4a33cccc", + "https://files.pythonhosted.org/packages/ba/b0/e131a9c41f10607926278453d9596163594fe1c4ebc46efe3b5e5b34eb84/cffi-2.1.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:a5781494d4d400a3f47f8f1da94b324f6e6b440a53387774002890a2a2f4b50f", + "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl": "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", + "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", + "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", + "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl": "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", + "https://files.pythonhosted.org/packages/c0/cc/08ed5a43f2996a16b462f64a7055c6e962803534924b9b2f1371d8c00b7b/cffi-2.0.0-cp39-cp39-macosx_10_13_x86_64.whl": "sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf", + "https://files.pythonhosted.org/packages/c0/e9/6d7724983b3d5a0908dbf74f64038ade77c18646ff6636ec7894fd392ce1/cffi-2.1.0-cp310-cp310-macosx_10_15_x86_64.whl": "sha256:b65f590ef2a44640f9a05dbb548a429b4ade77913ce683ac8b1480777658a6c0", + "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", + "https://files.pythonhosted.org/packages/c3/c0/d1ec30ffb370f748f2fb54425972bfef9871e0132e82fb589c46b6676049/cffi-2.1.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl": "sha256:5972433ad71a9e46516584ef60a0fda12d9dc459938d1539c3ddecf9bdc1368d", + "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl": "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", + "https://files.pythonhosted.org/packages/c6/4b/e706f67279140f92939da3475ad610df18bfd52d50f14953a8e5fede71d5/cffi-2.1.0-cp313-cp313-win32.whl": "sha256:db3eb7d46527159a878ec3460e9d40615bc25ba337d477db681aea6e4f05c5d2", + "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl": "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", + "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", + "https://files.pythonhosted.org/packages/cc/82/3d5c705acb7abbba9bbd7d79b8e62e0f25b6120eb7ae6ac49f1b721722fe/cffi-2.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:ac0f1a2d0cfa7eea3f2aaf006ab6e70e8feeb16b75d65b7e5939982ca2f11056", + "https://files.pythonhosted.org/packages/cc/d7/97d3136f81db489ec8d1d67748c110d6c994268fd7528014aa9f2b085e4e/cffi-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:d53d10f7da99ae46f7373b9150393e9c5eab9b224909982b43832668de4779f5", + "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", + "https://files.pythonhosted.org/packages/d0/9a/bb1d5ed9c3fcae158e9f6391bf309c95d98c2ac37ed56573228471d0af5e/cffi-2.1.0-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:3d7f118b5adbfdfead90c25822690b02bc8074fba949bb7858bec4ebd55adb43", + "https://files.pythonhosted.org/packages/d3/0b/0ffe8b82d3875bced5fa1e7986a7a46b748262a40ab7f60b475eb9fb1bb3/cffi-2.1.0-cp315-cp315t-win_amd64.whl": "sha256:f146d154428a2523f9cc7936c02353c2459b8f6cf07d3cd1ee1c0a611109c5d5", + "https://files.pythonhosted.org/packages/d3/27/93195977168ee63aed233a1a0993a2178798654d1f4bddcdd321d6fd3b21/cffi-2.1.0-cp314-cp314-musllinux_1_2_aarch64.whl": "sha256:c351efb95e832a853a29361675f33a7ce53de1a109cd73fd47af0712213aa4ce", + "https://files.pythonhosted.org/packages/d3/67/85c89a59ba36a671e79638f44d466749f08179266a57e4f2ffdf92174072/cffi-2.1.0-cp311-cp311-macosx_10_15_x86_64.whl": "sha256:02cb7ff33ded4f1532476731f89ede53e2e488a8e6205515a82144246ffa7dcc", + "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", + "https://files.pythonhosted.org/packages/d5/dd/0c7dbf815a579ff005008a2d815a55d6bb047c349eef536d9dc53d3f0a8d/cffi-2.1.0-cp314-cp314t-win_arm64.whl": "sha256:510aeeeac94811b138077451da1fb18b308a5feab47dd2b603af55804155e1c8", + "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", + "https://files.pythonhosted.org/packages/d6/5c/584e626835f0375c928176c04137c96927165cb8733cdb3150ec04e5ee5e/cffi-2.1.0-cp314-cp314-macosx_11_0_arm64.whl": "sha256:c4165821e131d6d4ca444347c2b694e2311bcfa3fe5a861cc72968f28867beac", + "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", + "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", + "https://files.pythonhosted.org/packages/d8/f0/81478e482afa03f6d18dc8f2afb5edc45b3080853b634b5ed91961be0998/cffi-2.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl": "sha256:d2117334c3af3bdcb9a88522b844a2bdb5efdc4f71c6c822df55486ae1c3347a", + "https://files.pythonhosted.org/packages/dc/78/aa01ac599a8a4322533d45a1f9bc93b338276d2d59dabbe7c6d92a775c81/cffi-2.1.0-cp314-cp314t-win32.whl": "sha256:7d034dcffa09e9a46c93fa3a3be402096cb5354ac6e41ab8e5cc9cd8b642ad76", + "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", + "https://files.pythonhosted.org/packages/dd/2c/400ea43e721727dca8a65c4521390e9196757caba4a45643acb2b63271b8/cffi-2.1.0-cp312-cp312-win_arm64.whl": "sha256:6d194185eabd279f1c05ebe3504265ddfc5ad2b58d0714f7db9f01da592e9eb6", + "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl": "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", + "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", + "https://files.pythonhosted.org/packages/e0/27/1d0b408497e41a74795af122d7b603c418c5fed0171450f899afd04e594f/cffi-2.1.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:0520e1f4c35f44e209cbbb421b67eec42e6a157f59444dfb6058874ff3610e5d", + "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl": "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", + "https://files.pythonhosted.org/packages/e2/cc/027d7fb82e58c48ea717149b03bcadcbdc293553edb283af792bd4bcbb3f/cffi-2.0.0-cp310-cp310-win32.whl": "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a", + "https://files.pythonhosted.org/packages/e5/4b/1f4c36ab273980d7aa75bb126ea4f8971f24a96108acad3a0a084028c57b/cffi-2.1.0-cp315-cp315-macosx_11_0_arm64.whl": "sha256:cdf2448aab5f661c9315308ec8b93f4e8a1a67a3c733f8631067a2b67d5913dc", + "https://files.pythonhosted.org/packages/e6/3f/0b04a700dd64f465c93020253a793a82c9b4dff9961f48facd0df945d9b8/cffi-2.1.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:7d3538f9c0e50670f4deb93dbb696576e60590369cae2faf7de681e597a8a1f1", + "https://files.pythonhosted.org/packages/e8/be/f6424d1dc46b1091ffcc8964fa7c0ab0cd36839dd2761b49c90481a6ba1b/cffi-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl": "sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2", + "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl": "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", + "https://files.pythonhosted.org/packages/ea/dd/e3b0baa2d3d6a857ac72b7efbf18e32e487c9cdafcc13049ad765495b15e/cffi-2.1.0-cp311-cp311-macosx_11_0_arm64.whl": "sha256:f5bce581e6b8c235e566a14768a943b172ada3ed73537bb0c0be1edee312d4e7", + "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz": "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", + "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl": "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", + "https://files.pythonhosted.org/packages/eb/d8/df4543cc087245044ed02ef3ad8e0a26619d0075ac7a77a12dc81177851b/cffi-2.1.0-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:6274dcb2d15cef48daa73ed1be5a40d501d74dccd0cd6db364776d12cb6ba022", + "https://files.pythonhosted.org/packages/eb/da/5c4918a2d61d86fa927d716cb3d8e4626ef8dc8f605a599d32f33897f59a/cffi-2.1.0-cp311-cp311-win32.whl": "sha256:64c753a0f87a256020004f37a1c8c02c480e725f910f0b2a0f3f07debd1b2479", + "https://files.pythonhosted.org/packages/ec/d1/9a5b7169499e8e8d8e636de70b97ac7c9447104d2ff1a2cd94790cea5162/cffi-2.1.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:0a96b74cda968eebbad56d973efe5098974f0a9fb323865bf99ea1fd24e3e64c", + "https://files.pythonhosted.org/packages/ed/a5/e8bbb1ce5b3ac2f53ad6a10bde44318a5a8d99d4f4a000d44a6e39aeb3e4/cffi-2.1.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:7d5980a3433d4b71a5e120f9dd551403d7824e31e2e67124fe2769c404c06913", + "https://files.pythonhosted.org/packages/ed/da/4bbe583a3b3a5c8c60892124fe17f3fa3656523faf0d3484eae90f091853/cffi-2.1.0-cp315-cp315-macosx_10_15_x86_64.whl": "sha256:95f2954c2c9473d892eca6e0409f3568b37ab62a8eedb122461f73cc273476e3", + "https://files.pythonhosted.org/packages/ef/c3/ad299dc38f3583f8d916b299f028af418a9ec98bc695fcbebeae7420691c/cffi-2.1.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:90bec57cf82089383bd06a605b3eb8daebf7e5a668520beaf6e327a83a947699", + "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", + "https://files.pythonhosted.org/packages/f7/e0/dda537c2309817edf60109e39265f24f24aa7f050767e22c98c53fe7f48b/cffi-2.0.0-cp39-cp39-musllinux_1_2_i686.whl": "sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65", + "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl": "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", + "https://files.pythonhosted.org/packages/f9/c8/6c2de1d55cf35ef8b92885d5ef280790f0fb9634d87ea1cc315176aecd61/cffi-2.1.0-cp311-cp311-win_amd64.whl": "sha256:4f26194e3d95e06501b942642855aed4f953d55e95d7d01b7c4483db3ecff458", + "https://files.pythonhosted.org/packages/f9/cf/398272b8bbfd58aa314fda5a7f1cdbb26d1d78ae324a11211521315dd1f0/cffi-2.1.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:03e9810d18c646077e501f661b682fbf5dee4676048527ca3cffe66faa9960dd", + "https://files.pythonhosted.org/packages/fa/75/74dfb7c3fc6ebbd408038476bd4c1d7e925c62614e7b9c534ecc34218288/cffi-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:11b3fb55f4f8ad92274ed26705f65d8f91457de71f5380061eb6d125a768fecd", + "https://files.pythonhosted.org/packages/fb/d2/4398416cd699b35167947c6e22aca52c47e69ad5695073c9f1f2c52e04aa/cffi-2.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:aa7a1b53a2a4452ada2d1b5dade9960b2522f1e61293a811a077439e39029565", + "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl": "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe" + }, + "chardet": { + "https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl": "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970", + "https://files.pythonhosted.org/packages/f3/0d/f7b6ab21ec75897ed80c17d79b15951a719226b9fababf1e40ea74d69079/chardet-5.2.0.tar.gz": "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7" + }, + "charset-normalizer": { + "https://files.pythonhosted.org/packages/00/5e/17398df3a139985ba9d11ed072531986f408c8fca952835ef1ab1820c02b/charset_normalizer-3.4.9-cp314-cp314t-macosx_10_15_universal2.whl": "sha256:609b3ba8fcc0fb5ab7af00719d0fb6ad0cb518e48e7712d12fd68f1327951198", + "https://files.pythonhosted.org/packages/01/09/11d684ea5819e5a8f5100fb0b38cf8d02b514746607934134d31233e02c8/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", + "https://files.pythonhosted.org/packages/01/c4/4fa4c8b3097a11f3c5f09a35b72ed6855fb1d332469504962ab7bafcc702/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:5e226f6218febc71f6c1fc2fafb91c226f75bdc1d8fb12d66823716e891608fd", + "https://files.pythonhosted.org/packages/01/da/a44bd7a13d426e69e4894557106cd58669097bfad4a8681123b618fbfc5d/charset_normalizer-3.4.9-cp310-cp310-win_arm64.whl": "sha256:375b83ed0aecfce76c16d198fbc21f3b11b337d68662bea0a995046682a11419", + "https://files.pythonhosted.org/packages/03/d2/3f392f23f042615689456e9a274640c1d2e5dd1d52de36ab8f7955f8f050/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", + "https://files.pythonhosted.org/packages/04/d2/42fd330901aaa4b805a1097856c2edf5095e260a597f65def493f4b8c833/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl": "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", + "https://files.pythonhosted.org/packages/05/31/e1f51c76db7be1d4aef220d29fbfa5dbb4a99165d9833dcbf166753b6dc0/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", + "https://files.pythonhosted.org/packages/05/8c/eb854996d5fef5e4f33ad56927ad053d04dc820e4a3d39023f35cad72617/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", + "https://files.pythonhosted.org/packages/07/07/7e554f2bbce3295e191f7e653ff15d55309a9ca40d0362fcdab36f01063c/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", + "https://files.pythonhosted.org/packages/08/06/9f5a12939db324d905dc1f70591ae7d7898d030d7662f0d426e2286f68c9/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", + "https://files.pythonhosted.org/packages/0a/97/a183d752295997d95d20f2aa34d66ff6abda5af5482d0e7995dbbc9a753a/charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl": "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e", + "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl": "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", + "https://files.pythonhosted.org/packages/0b/e3/85ec501f206fb049259288c1f3506e53876937fb00edb47009348e66756b/charset_normalizer-3.4.9-cp311-cp311-macosx_10_9_universal2.whl": "sha256:0e94703ec9684807f20cfb5eed95c70f67f2a8f21ad620146d7b5a13677b93e5", + "https://files.pythonhosted.org/packages/0b/fe/4ade940a1b4bac031357b4a74fc8406a2ecd9dfc007dea850c5b7ee348de/charset_normalizer-3.4.1-cp37-cp37m-win32.whl": "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487", + "https://files.pythonhosted.org/packages/0c/5a/0b59704c38470df6768aa154cc87b1ac7c9bb687990a1559dc8765e8627e/charset_normalizer-3.4.1-cp39-cp39-win32.whl": "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", + "https://files.pythonhosted.org/packages/0c/74/2f62c8821b969ea3bd67cc2e6976834f48ca5d12664d2559ebcd9bcfbed7/charset_normalizer-3.4.9-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:871ff67ea1aad4dfd91736464934d56b32dac49f9fbe16cddba36198a7b3a0db", + "https://files.pythonhosted.org/packages/0c/e7/aaf6da33fc9f4691cda8f7efbc9f69179d3d39ec8a4799baf273ee1d8db0/charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_armv7l.whl": "sha256:65a7ff3f705e57d392f7261b6d0550fe137c3019477431f1c355e0db0a7d3e15", + "https://files.pythonhosted.org/packages/0d/58/5580c1716040bc89206c77d8f74418caf82ce519aae06450393ca73475d1/charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl": "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", + "https://files.pythonhosted.org/packages/0e/42/6dbc00b8cd16011691203e33570fa42ed5746599a2e878112d16eab403a3/charset_normalizer-3.4.9-cp312-cp312-win32.whl": "sha256:78841cccf1af7b40f6f716338d50c0902dbe88d9f800b3c973b7a9a0a693a642", + "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl": "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", + "https://files.pythonhosted.org/packages/0f/6c/2bee440303d705b6fb1e2ec789543edec83d32d258299b16eed28aad48e0/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", + "https://files.pythonhosted.org/packages/10/2f/6e2c727649d5e97ee17230f4c064480c69eb563f52ba87df448647d77a99/charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e", + "https://files.pythonhosted.org/packages/10/bd/6517ea94f2672e801011d50b5d06be2a0deaf566aea27bcdcd47e5195357/charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl": "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c", + "https://files.pythonhosted.org/packages/10/e0/47c079dd82d217c807479cd59ffd30af56307ea31c108b75758970459ad3/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:4d1c96a7a18b9690a4d46df09e3e3382406ae3213727cd1019ebade1c4a81917", + "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", + "https://files.pythonhosted.org/packages/13/82/83c188028b6f38d39538442dd127dc794c602ae6d45d66c469f4063a4c30/charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl": "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", + "https://files.pythonhosted.org/packages/13/f8/eefae0629fa9260f83b826ee3363e311bb03cfdd518dad1bd10d57cb2d84/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl": "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", + "https://files.pythonhosted.org/packages/14/cb/1db8b96547ee3186cd2dd7f2e59dd560a9b80748f3604171f3c153d62811/charset_normalizer-3.4.9-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:58150c9f9b9a552505912d182ccdf26f6396fb6094816ceebcbb20eecabaed94", + "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz": "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", + "https://files.pythonhosted.org/packages/16/ea/a9e284aa38cccea06b7056d4cbc7adf37670b1f8a668a312864abf1ff7c6/charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl": "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", + "https://files.pythonhosted.org/packages/17/6d/bff78a4bacc4891bc63ec5bdc6776d8c85e47fab93d0d5f6223068fad0a4/charset_normalizer-3.4.9-cp39-cp39-win32.whl": "sha256:93d59d504b230e83c7a843251681959a0b6a9cd76f6e146ce1b8a80eb8739af9", + "https://files.pythonhosted.org/packages/19/28/573147271fd041d351b438a5665be8223f1dd92f273713cb882ddafe214c/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl": "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", + "https://files.pythonhosted.org/packages/19/79/55c32d06d76ae4feafe053f061f3e3ab70bcf19f4007797ce8c3efda7830/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_armv7l.whl": "sha256:f7fb7d750cfa0a070d2c24e831fd3481019a60dd317ea2b39acbcebc08b6ed81", + "https://files.pythonhosted.org/packages/1d/85/181c652953eb5276d198f375b1dd641047392050098100a3a02d6534f657/charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:e9701d0049d92c16703a42771b98d560b95248949f23f8cf7b4eddd201814fb9", + "https://files.pythonhosted.org/packages/1e/0d/38ef4ae41e9248d63fc4998d933cae22473b1b2ac4122cf908d0f5eb32aa/charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c", + "https://files.pythonhosted.org/packages/1e/49/7ab74d4ac537ece3bc3334ee08645e231f39f7d6df6347b29a74b0537103/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl": "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", + "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl": "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", + "https://files.pythonhosted.org/packages/1f/8d/33c860a7032da5b93382cbe2873261f81467e7b37f4ed91e25fed62fd49b/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", + "https://files.pythonhosted.org/packages/20/95/d75e82f8ce9fd323ebf059c16c9aadefb22a1ecde13b7840b35835e4886c/charset_normalizer-3.4.9-cp314-cp314-win_arm64.whl": "sha256:40a126142a56b2dfc0aacbad1de8310cbf60da7656db0e6b16eebd48e3e93519", + "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl": "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", + "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", + "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", + "https://files.pythonhosted.org/packages/24/9d/2e3ef673dfd5be0154b20363c5cdcc5606f35666544381bee15af3778239/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl": "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", + "https://files.pythonhosted.org/packages/26/ae/23d6041322a3556e4da139663d02fb1b3c59a23ab2e2b56432bd2ad63ded/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl": "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", + "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl": "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", + "https://files.pythonhosted.org/packages/28/76/e6222113b83e3622caa4bb41032d0b1bf785250607392e1b778aca0b8a7d/charset_normalizer-3.3.2-py3-none-any.whl": "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", + "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl": "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", + "https://files.pythonhosted.org/packages/28/e9/9fb6099b868c82a40698a748ae0fbd4f31ccc13844c176a07158ba2abbfd/charset_normalizer-3.4.9-cp39-cp39-win_arm64.whl": "sha256:476743fe6dfe14a2da12e3ac79125dc84a3b2cf8094369a47a1529b0cd8549fe", + "https://files.pythonhosted.org/packages/2a/9d/a6d15bd1e3e2914af5955c8eb15f4071997e7078419328fee93dfd497eb7/charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl": "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", + "https://files.pythonhosted.org/packages/2b/61/095a0aa1a84d1481998b534177c8566fdc50bb1233ea9a0478cd3cc075bd/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl": "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", + "https://files.pythonhosted.org/packages/2b/f9/ef4a69ea338ad3c0deceea0f5f7d2380ae8b52132b06d652cb0d2cd86706/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:8a79d9f4d8001473a30c163556b3c3bfebec837495a412dde78b51672f6134f9", + "https://files.pythonhosted.org/packages/2d/ce/3cbed41cff67e455a386fb5e5dd8906cdda2ed92fbc6297921f2e4419309/charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl": "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", + "https://files.pythonhosted.org/packages/2d/dc/9dacba68c9ac0ae781d40e1a0c0058e26302ea0660e574ddf6797a0347f7/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl": "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", + "https://files.pythonhosted.org/packages/2e/37/9223632af0872c86d8b851787f0edd3fe66be4a5378f51242b25212f8374/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", + "https://files.pythonhosted.org/packages/2e/7d/2259318c202f3d17f3fe6438149b3b9e706d1070fe3fcbb28049730bb25c/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl": "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", + "https://files.pythonhosted.org/packages/2f/0e/d7303ccae9735ff8ff01e36705ad6233ad2002962e8668a970fc000c5e1b/charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl": "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", + "https://files.pythonhosted.org/packages/33/95/ef68482e4a6adf781fae8d183fb48d6f2be8facb414f49c90ba6a5149cd1/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", + "https://files.pythonhosted.org/packages/33/9a/895095b83e7907abd6d3d99aad3a38ad0d9686cc186cb0c94c24320fe63e/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:60f44ade2cf573dad7a277e6f8ca9a51a21dda572b13bd7d8539bb3cd5dbedde", + "https://files.pythonhosted.org/packages/33/c3/3b96a435c5109dd5b6adc8a59ba1d678b302a97938f032e3770cc84cd354/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl": "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", + "https://files.pythonhosted.org/packages/34/2a/f392457d45e24a0c9bfc012887ed4f3c54bf5d4d05a5deb970ffec4b7fc0/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", + "https://files.pythonhosted.org/packages/36/31/a276bb2e66243072a3fd06fdcab9cbb61a305b02143d70d2bda21d888fa8/charset_normalizer-3.4.9-cp310-cp310-manylinux_2_31_armv7l.whl": "sha256:bcf74c1df76758a395bf0af608c04c82257523f55c9868b334f06270d0f2112b", + "https://files.pythonhosted.org/packages/37/8d/ca39a7559a4797505530d084fd3a49a2c959efbbbff146302fb7be4e3b35/charset_normalizer-3.4.9-cp310-cp310-win_amd64.whl": "sha256:8c041122946b7ba21bb32c45b1aa57b1be35527690aeb3c5c234521085632eee", + "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", + "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl": "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", + "https://files.pythonhosted.org/packages/39/f4/d9f4f712d0951dcbfd42920d3db81b00dd23b6ab520419626f4023334056/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", + "https://files.pythonhosted.org/packages/3a/25/45f30093ae27dd7b92a793b61882a38685f993700113ca36e0c9c14965e1/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:a4fbdde9dd4a9ce5fd52c2b3a347bb50cc89483ef783f1cb00d408c13f7a96c0", + "https://files.pythonhosted.org/packages/3a/52/9f9d17c3b54dc238de384c4cb5a2ef0e27985b42a0e5cc8e8a31d918d48d/charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl": "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", + "https://files.pythonhosted.org/packages/3d/04/cb42585f07f6f9fd3219ffb6f37d5a39b4fd2db2355b23683060029c35f7/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", + "https://files.pythonhosted.org/packages/3d/09/d82fe4a34c5f0585f9ea1df090e2a71eb9bb1e469723053e1ee9f57c16f3/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", + "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", + "https://files.pythonhosted.org/packages/3d/85/5b7416b349609d20611a64718bed383b9251b5a601044550f0c8983b8900/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", + "https://files.pythonhosted.org/packages/3d/c6/eee9dca4439b1061f76373f06ea855678cc4a64c1c3c90b50e479edbb8eb/charset_normalizer-3.4.9-cp314-cp314t-win_arm64.whl": "sha256:19ac87f93086ce37b86e098888555c4b4bc48102279bae3350098c0ed664b501", + "https://files.pythonhosted.org/packages/3d/ca/ad1d7c7d3077dab873f539d3e1d083c0845a762cb0bafdfbe3ef93add598/charset_normalizer-3.4.9-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:920079c3f7456fa213e0829ed2073aaa727fd39d889ead5b4f35d0de5460d04f", + "https://files.pythonhosted.org/packages/3d/ef/d96ec496cfea0c21db43b0ad03891308b02388d054cc902cf0e5a1ad6a88/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:fa36ec09ef71d158186bc79e359ff5fdd6e7996fe8ab638f00d6b93139ba4fcf", + "https://files.pythonhosted.org/packages/3e/33/21a875a61057165e92227466e54ee076b73af1e21fe1b31f1e292251aa1e/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl": "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", + "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", + "https://files.pythonhosted.org/packages/3f/ba/3f5e7be00b215fa10e13d64b1f6237eb6ebea66676a41b2bcdd09fe74323/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", + "https://files.pythonhosted.org/packages/40/26/f35951c45070edc957ba40a5b1db3cf60a9dbb1b350c2d5bef03e01e61de/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", + "https://files.pythonhosted.org/packages/40/bb/20affbbd9ea29c71ea123769dc568a6d42052ff5089c5fe23e21e21084a6/charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl": "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4", + "https://files.pythonhosted.org/packages/42/ab/b9bc2e77d6b44a7e46ef62ec5cac1c9a6ba7b9135a5d560f002696ec9995/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_aarch64.whl": "sha256:a4cfde78a9f2880208d16a93b795726a3017d5977e08d1e162a7a31322479c41", + "https://files.pythonhosted.org/packages/43/01/754cdb29dd0560f58290aaaa284d43eea343ad0512e6ad3b8b5c11f08592/charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a", + "https://files.pythonhosted.org/packages/43/05/3bf613e719efe68fb3a77f9c536a389f35b95d75424b96b426a47a45ef1d/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl": "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", + "https://files.pythonhosted.org/packages/44/80/b339237b4ce635b4af1c73742459eee5f97201bd92b2371c53e11958392e/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", + "https://files.pythonhosted.org/packages/44/95/80282cce0fae9c3061203d723ee87da996aed79679e65d8935050ee7ca1f/charset_normalizer-3.4.9-cp311-cp311-manylinux_2_31_armv7l.whl": "sha256:c0323c9daef75ef2e5083624b4585018a0c9d5e3b40f607eed81a311270b934b", + "https://files.pythonhosted.org/packages/45/59/3d27019d3b447a88fe7e7d004a1e04be220227760264cc41b405e863891b/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl": "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", + "https://files.pythonhosted.org/packages/46/6a/d5c26c41c49b546860cc1acabdddf48b0b3fb2685f4f5617ac59261b44ae/charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl": "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", + "https://files.pythonhosted.org/packages/48/18/c8f397329c35e32f6a837e488986f4ae03bd2abebc453b48714991630c2f/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:416c229f77e5ea25b3dfd4b582f8d73d7e43c22320302b9ab128a2d3a0b38efe", + "https://files.pythonhosted.org/packages/49/2b/999d0314e4ee0cff3cb83e6bc9aeddd397eeed693edb4facb901eb8fbb69/charset_normalizer-3.4.1-cp310-cp310-win32.whl": "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", + "https://files.pythonhosted.org/packages/49/ba/768fa3f36048d81c477a0ce61f813bc1454d80917ccfe550abd9f44f5e24/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:f840ed6d8ecba8255df8c42b87fadeda98ddfc6eeec05e2dc66e26d46dd6f58a", + "https://files.pythonhosted.org/packages/49/fd/a1d26144398c67486422a72bf5812cda22cb4ccfcd95a290fb41ceb4b8e2/charset_normalizer-3.4.9-cp314-cp314-win_amd64.whl": "sha256:16b65ea0f2465b6fb52aa22de5eca612aa964ddfec00a912e26f4656cbef890b", + "https://files.pythonhosted.org/packages/4b/4c/5361f9aa7f2cb58d94f2ab831b3d493f69efb1d239654b4744e3c09527cb/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:9104ed0bd76a429d46f9ec0dbc9b08ad1d2dcdf2b00a5a0daa1c145329b35b44", + "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl": "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", + "https://files.pythonhosted.org/packages/4e/6e/de0229a7ef40f6f9d28a837eebf4ec47bdca5dab4e900c84f22919af636a/charset_normalizer-3.4.9-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:4773092f8019072343a7447203308b176e10199920eb02d6195e81bbb3274c29", + "https://files.pythonhosted.org/packages/4f/8d/1569f4d0032d6ba2a4fe4591c35bf87868c600c41a71eb5c2e1ffa8464c2/charset_normalizer-3.4.9-cp311-cp311-win_arm64.whl": "sha256:1d22856ffbe153a602df38e4a5464f0b748a54002e0d69ac6d2ad0a197cc99ec", + "https://files.pythonhosted.org/packages/4f/d1/d547cc26acdb0cc458b152f79b2679d7422f29d41581e6fa907861e88af1/charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl": "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", + "https://files.pythonhosted.org/packages/50/78/ce342ca4ff30b2eb49fe6d9578df85974f90c67d294113e94efdd9664cbd/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:7b86a2b16095d250c6f58b3d9b2eee6f4147754344f3dab0922f7c9bf7d226c9", + "https://files.pythonhosted.org/packages/51/fd/0ee5b1c2860bb3c60236d05b6e4ac240cf702b67471138571dad91bcfed8/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl": "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", + "https://files.pythonhosted.org/packages/52/94/af74dde74a3996bd959c350709bfe50e297823d70a8c1cbd54b838880863/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_armv7l.whl": "sha256:f86c6358749bd4fda175388691e3ba8c46e24c5347d0afd20f9b7edfc9faf07d", + "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", + "https://files.pythonhosted.org/packages/53/cd/aa4b8a4d82eeceb872f83237b2d27e43e637cac9ffaef19a1321c3bafb67/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl": "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", + "https://files.pythonhosted.org/packages/54/54/2412a5b093acb17f0222de007cc129ec0e0df198b5ad2ce5699355269dfe/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", + "https://files.pythonhosted.org/packages/54/7f/cad0b328759630814fcf9d804bfabaf47776816ad4ef2e9938b7e1123d04/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl": "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561", + "https://files.pythonhosted.org/packages/57/ec/80c8d48ac8b1741d5b963797b7c0c869335619e13d4744ca2f67fc11c6fc/charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl": "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", + "https://files.pythonhosted.org/packages/58/78/a0bc646900994df12e07b4ae5c713f2b3e5998f58b9d3720cce2aa45652f/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl": "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", + "https://files.pythonhosted.org/packages/58/a2/0c63d5d7ffac3104b86631b7f2690058c97bf72d3145c0a9cd4fb90c58c2/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", + "https://files.pythonhosted.org/packages/5a/6d/e2773862b043dcf8a221342954f375392bb2ce6487bcd9f2c1b34e1d6781/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", + "https://files.pythonhosted.org/packages/5b/ae/ce2c12fcac59cb3860b2e2d76dc405253a4475436b1861d95fe75bdea520/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl": "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", + "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", + "https://files.pythonhosted.org/packages/5e/be/7ee4453d7e88dfbc4104ccd34900b9f2c7c17dac22881865fe0e82424a25/charset_normalizer-3.4.9-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:b5314963fce9b0b12743891de876e724997864ee22aa496f903f426c7e2fa5b2", + "https://files.pythonhosted.org/packages/5f/c0/6eec7bdabe6cbbcc274ec04596f6d93865751a0541d33d60d1ce179bd372/charset_normalizer-3.4.9-cp39-cp39-musllinux_1_2_armv7l.whl": "sha256:ad41ba96094304aa090f5a30cb6e4fb3b3f1c264c523394b4c39bbacc4dc92ba", + "https://files.pythonhosted.org/packages/63/01/f2fb3bd3a73be48b173ee0c6aa8d2497af97d5663a8c4c4b491de4c62f7a/charset_normalizer-3.4.9-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:79580094b00d1789d1f93ea55bc43cb2f611910c72235b7657f3482ddcc1b22d", + "https://files.pythonhosted.org/packages/63/09/c1bc53dab74b1816a00d8d030de5bf98f724c52c1635e07681d312f20be8/charset-normalizer-3.3.2.tar.gz": "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", + "https://files.pythonhosted.org/packages/66/fe/c7d3da40a66a6bf2920cce0f436fa1f62ee28aaf92f412f0bf3b84c8ad6c/charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl": "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", + "https://files.pythonhosted.org/packages/68/77/02839016f6fbbf808e8b38601df6e0e66c17bbab76dff4613f7511413597/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl": "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", + "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", + "https://files.pythonhosted.org/packages/6a/05/c94d5cd23396289c54c93b02e0273b4dd8921641d9968c4828caf9bbaad9/charset_normalizer-3.4.9-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:df7276909358e5635ae203673ab7e509ddd224225a8d6b0790bf13eb2bde1cc5", + "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl": "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", + "https://files.pythonhosted.org/packages/6c/c2/4a583f800c0708dd22096298e49f887b49d9746d0e78bfc1d7e29816614c/charset_normalizer-3.3.2-cp311-cp311-win32.whl": "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", + "https://files.pythonhosted.org/packages/6c/ef/2473d3c4d869155be4af1191111d59c4d5c4e0173026f7e85b176e23bf65/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:69b157c5d3292bcd443faca052f3096f637f1e074b98212a933c074ae23dc3b8", + "https://files.pythonhosted.org/packages/6d/46/79847edd07244a4a2d443c6655a7b6ee94203c21539414b059f32713c357/charset_normalizer-3.4.9-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:3c09a49d6cde137258beb3d551994a2927fd35ad5cf96aed573f61bbd67c5f84", + "https://files.pythonhosted.org/packages/6e/fb/d560d1d1555debbfe7849d9cac6145c1b537709d79576bf22557ed803b82/charset_normalizer-3.4.9-cp313-cp313-win_arm64.whl": "sha256:611057cc5d5c0afc743ba8be6bd828c17e0aaa8643f9d0a9b9bb7dea80eb8012", + "https://files.pythonhosted.org/packages/6f/7f/0c0dad447819e90b93f8ed238cc8f11b91353c23c19e70fa80483a155bed/charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl": "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd", + "https://files.pythonhosted.org/packages/70/4a/ecbd131485c07fcdfad54e28946d513e3da22ef3b4bd854dcafae54ec739/charset_normalizer-3.4.9-cp312-cp312-macosx_10_13_universal2.whl": "sha256:45b0cc4e3556cd875e09102988d1ab8356c998b596c9fced84547c8138b487a0", + "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", + "https://files.pythonhosted.org/packages/72/1a/641d5c9f59e6af4c7b53da463d07600a695b9824e20849cb6eea8a627761/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", + "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl": "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", + "https://files.pythonhosted.org/packages/74/20/8923a06f15eb3d7f6a306729360bd58f9ead1dc39bc7ea8831f4b407e4ae/charset_normalizer-3.3.2-cp38-cp38-win32.whl": "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", + "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", + "https://files.pythonhosted.org/packages/74/f1/0d9fe69ac441467b737ba7f48c68241487df2f4522dd7246d9426e7c690e/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", + "https://files.pythonhosted.org/packages/78/ad/98aae8630ac71f16711968e38a5acfecce41b778bf2f0312851020f565a8/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_armv7l.whl": "sha256:cd6c3d4b783c556fa00bf540854e42f135e2f256abd29669fcd0da0f2dec79c2", + "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl": "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", + "https://files.pythonhosted.org/packages/79/66/8946baa705c588521afe10b2d7967300e49380ded089a62d38537264aece/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", + "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", + "https://files.pythonhosted.org/packages/7b/ef/5eb105530b4da8ae37d506ccfa25057961b7b63d581def6f99165ea89c7e/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl": "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", + "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", + "https://files.pythonhosted.org/packages/7e/8d/496817fa0944239ecae662dd57ea765cfeaec6a735f9f025d4b7b72e7143/charset_normalizer-3.4.9-cp314-cp314-macosx_10_15_universal2.whl": "sha256:0327fcd59a935777d83410750c50600ee9571af2846f71ce40f25b13da1ef380", + "https://files.pythonhosted.org/packages/7f/c0/b913f8f02836ed9ab32ea643c6fe4d3325c3d8627cf6e78098671cafff86/charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl": "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", + "https://files.pythonhosted.org/packages/7f/f4/ffbb83546e1f198ecc70ecd372b65cf2b50f9068b380abd67640f17a8e18/charset_normalizer-3.4.9-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:16d10d789dd9bcca1173c95af82c58433122564b7bc39385124be735a35cbe99", + "https://files.pythonhosted.org/packages/80/33/6c99c1b3e6b8bf730e1bc809b9a2608f224145069114c479a2e9e1494346/charset_normalizer-3.4.9-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:c1225416b463483160e4af85d5fc3a9690ccb53fd4b1865a6437825f5ede3209", + "https://files.pythonhosted.org/packages/80/3f/bd97d3d9c613013d07cb7733d299385b41df37f0471310f5a73dc359f0b8/charset_normalizer-3.4.9-cp314-cp314t-win_amd64.whl": "sha256:9b8e0f3107e2200b76f6054de99016eac3ee6762713587b36baaa7e4bd2ae177", + "https://files.pythonhosted.org/packages/80/cc/f920afd1a23c58ccd53c1d36085a71893a4737ff5e66e0371efab6809850/charset_normalizer-3.4.9-cp312-cp312-win_amd64.whl": "sha256:4b3dac63058cc36820b0dd072f89898604e2d39686fe05321729d00d8ac185a0", + "https://files.pythonhosted.org/packages/81/b2/160893421adfa3c45554fb418e321ed342bb10c0a4549e855b2b2a3699cb/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", + "https://files.pythonhosted.org/packages/83/d5/9096aa3cf532dfad237861544eb47a0f20d5adbf1039760fed8eaae935d9/charset_normalizer-3.4.9-cp311-cp311-win32.whl": "sha256:ac351b3b8014eead140e77e9717e2992c6bbe30b63bc3422422eb84865412e3d", + "https://files.pythonhosted.org/packages/83/dc/9b29fa4412b318bf3bfea985c35d67eb55e04b59a7c3f2237168b0e0be6f/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:03d07803992c6c7bbc976327f34b18b6160327fc81cb82c9d504720ac0be3b62", + "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl": "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", + "https://files.pythonhosted.org/packages/85/2d/a9790237cb4d01a6d57afadc8573c8b73c609ade20b80f4cda30802009ee/charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl": "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", + "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl": "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", + "https://files.pythonhosted.org/packages/86/7e/5ce0bba863470fd1902d5e5843968951bddf38abe4742fc97116ef4598b3/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_armv7l.whl": "sha256:75286256590a6320cf106a0d28970d3560aad9ee09aa7b34fb40524792436d35", + "https://files.pythonhosted.org/packages/87/3a/ad914516df7e358a81aae018caa5e0470ba827fa6d763b1d2e87d920a5f6/charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_armv7l.whl": "sha256:90c44bc373b7687f6948b693cceaea1348ae0975d7474746559494468e3c1d84", + "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", + "https://files.pythonhosted.org/packages/89/17/74bb34d02d62a21cc626c7d4db475b6f2207980f6beb002051db8342b139/charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl": "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d", + "https://files.pythonhosted.org/packages/8c/e7/5ddfd76fc061eb52de219658a4aa431cbacadf0a0219c8854f00da50d289/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:33bdcc2a32c0a0e861f60841a512c8acc658c87c2ac59d89e3a46dacf7d866e4", + "https://files.pythonhosted.org/packages/8d/af/779ad72a4da0aed925e1139d458adc486e61076d7ecdcc09e610ea8678db/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl": "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", + "https://files.pythonhosted.org/packages/8d/b7/9e95102e9a8cce6654b85770794b582dda2921ec1fd924c10fbcf215ad31/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl": "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", + "https://files.pythonhosted.org/packages/8e/09/9f8abcc6fff60fb727268b63c376c8c79cc37b833c2dfe1f535dfb59523b/charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl": "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824", + "https://files.pythonhosted.org/packages/8f/aa/73a89701dd661d9b5d24d0594c42ed0f7a3aed4448cc4f8f7315d0701399/charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl": "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd", + "https://files.pythonhosted.org/packages/91/33/749df346e93d7a30cdcb90cbfdd41a06026317bfbfb62cd68307c1a3c543/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", + "https://files.pythonhosted.org/packages/91/95/e2cfa7ce962e6c4b59a44a6e19e541c3a0317e543f0e0923f844e8d7d21d/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl": "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", + "https://files.pythonhosted.org/packages/92/8f/3a47a3667c83c2df9483d91644c6c107de3bf8874aa1793da9d3012eb986/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:e4fd89cc178bced6ad29cb3e6dd4aa63fa5017c3524dbd0b25998fb64a87cc8b", + "https://files.pythonhosted.org/packages/93/62/5e89cdfe04584cb7f4d36003ffa2936681b03ecc0754f8e969c2becb7e24/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", + "https://files.pythonhosted.org/packages/94/22/b8f2081c6a77cb20d97e57e0b385b481887aa08019d2459dc2858ed64871/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl": "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", + "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", + "https://files.pythonhosted.org/packages/96/c6/f62d90c0e66525a374c35a1389f4290e5d7a731cd2cfacd9740272f927f9/charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl": "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa", + "https://files.pythonhosted.org/packages/96/fc/0cae31c0f150cd1205a2a208079de865f69a8fd052a98856c40c99e36b3c/charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl": "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", + "https://files.pythonhosted.org/packages/98/2b/f97f1c193fb855c345d678f5077d6926034db0722df74c8f057020e05a25/charset_normalizer-3.4.9-py3-none-any.whl": "sha256:68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5", + "https://files.pythonhosted.org/packages/98/69/5d8751b4b670d623aa7a47bef061d69c279e9f922f6705147983aa76c3ce/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", + "https://files.pythonhosted.org/packages/99/b0/9c365f6d79a9f0f3c379ddb40a256a67aa69c59609608fe7feb6235896e1/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", + "https://files.pythonhosted.org/packages/9b/f2/c0d4b8508565a36bc5c624e88ed297f5b0b1095011034d7f5b83a69908b5/charset_normalizer-3.4.9-cp314-cp314-win32.whl": "sha256:c1c948747b03be832dceed96ca815cef7360de9aa19d37c730f8e3f6101aca48", + "https://files.pythonhosted.org/packages/9e/af/3a97a4fa3c53586f1910dadfc916e9c4f35eeada36de4108f5096cb7215f/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl": "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", + "https://files.pythonhosted.org/packages/9e/ef/cd47a63d3200b232792e361cd67530173a09eb011813478b1c0fb8aa7226/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl": "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", + "https://files.pythonhosted.org/packages/a0/b1/4e72ef73d68ebdd4748f2df97130e8428c4625785f2b6ece31f555590c2d/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl": "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", + "https://files.pythonhosted.org/packages/a1/34/ef5c05f412f42520d7709b7d3784d19640839eb7366ded1755511585429f/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_armv7l.whl": "sha256:a1786910334ed46ab1dd73222f2cd1e05c2c3bb39f6dddb4f8b36fc382058a39", + "https://files.pythonhosted.org/packages/a2/51/e5023f937d7f307c948ed3e5c29c4b7a3e42ed2ee0b8cdf8f3a706089bf0/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl": "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", + "https://files.pythonhosted.org/packages/a2/55/86048bde1c9d0352940bd7b87d825091a52aef67d01cde6c6f7342c5b552/charset_normalizer-3.4.9-cp39-cp39-win_amd64.whl": "sha256:ddf4af30b417d9fe16481e9b81c27ab2a7cde1ff7ba3e85653b02db7d145dc7b", + "https://files.pythonhosted.org/packages/a2/a0/4af29e22cb5942488cf45630cbdd7cefd908768e69bdd90280842e4e8529/charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl": "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", + "https://files.pythonhosted.org/packages/a5/34/49b9060e8418b14fb5cba9cf6bfb383111e2538a03a1fb18e66a95aeb3d5/charset_normalizer-3.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:04ce310cb89c15df659582aee80a0603788732a5e017d5bd5c81158106ce249c", + "https://files.pythonhosted.org/packages/a5/ff/c946d63bc3786d5b84d960b0f7ab7e25b828486a946b5aa997625bcaf6a6/charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_armv7l.whl": "sha256:3d92613ec25e43b05f042302531ec0f00b8445190e43325880cbd6ab7c2581da", + "https://files.pythonhosted.org/packages/a6/ec/81e22253f4b7091eca6515bb3da5e45d05a663f7f567bb745695dc60f892/charset_normalizer-3.4.9-cp39-cp39-macosx_10_9_universal2.whl": "sha256:253a4a220747e8b5faf57ec320c4f5efb0cef05f647420bf267143ec15dba10a", + "https://files.pythonhosted.org/packages/a8/00/b8b43690ecac81e5038dc6332681757123ee9c4c15eb4a6ecf0232393f59/charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl": "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534", + "https://files.pythonhosted.org/packages/a8/31/47d018ef89f95b8aded95c589a77c072c55e94b50a41aa99c0a2008a45a4/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl": "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", + "https://files.pythonhosted.org/packages/a8/6f/4ff299b97da2ed6358154b6eb3a2db67da2ae204e53d205aacb18a7e4f34/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl": "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", + "https://files.pythonhosted.org/packages/a9/ac/ab729a15c516da2ab70a05f8722ecfccc3f04ed7a18e45c75bbbaa347d61/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", + "https://files.pythonhosted.org/packages/aa/17/c94be7ee0d142687e047fe1de72060f6d6837f40eedc26e87e6e124a3fc6/charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8", + "https://files.pythonhosted.org/packages/ad/81/8e983840c6e5b93b33c2ba81aa3d52c2e42f0e9a690ce7607a2e61da4a5c/charset_normalizer-3.4.9-cp310-cp310-macosx_10_9_universal2.whl": "sha256:cd6280cf040f233bd7d3407b743b4b4c74f70e8e1c4199cb112a62c941c0772a", + "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", + "https://files.pythonhosted.org/packages/ae/d5/4fecf1d58bedb1340a50f165ba1c7ddc0400252d6832ff619c4568b36cc0/charset_normalizer-3.3.2-cp310-cp310-win32.whl": "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", + "https://files.pythonhosted.org/packages/af/ba/5e5007c370702f85d2ef75791fac7943ed41e080364a673b20142e430e3e/charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:280081916dc341820640489a66e4696049401ef1cf6dd672f672e70ad915aca3", + "https://files.pythonhosted.org/packages/b0/3e/faee8f9de92b14ee1198e9163252bb15efee7301b31256a3b6d9ebfdd0dd/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_armv7l.whl": "sha256:5b10cd92fc5c498b35a8635df6d5a100207f88b63a4dc1de7ef9a548e1e2cd63", + "https://files.pythonhosted.org/packages/b1/27/693ee5e8a18191eb38647360c51cd505013e2bd3b366aa43fd5344c21e3c/charset_normalizer-3.4.9-cp314-cp314t-win32.whl": "sha256:0d861473f743244d349b50f850d10eb87aeb22bbdcc8e64f79273c94af5a8226", + "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl": "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", + "https://files.pythonhosted.org/packages/b2/06/97ec2aeae780b31d742b6352218b43841a6871e2564578ca522dce4a45c3/charset_normalizer-3.4.9-cp313-cp313-macosx_10_13_universal2.whl": "sha256:440eede837960000d74978f0eba527be106b5b9aee0daf779d395276ed0b0614", + "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl": "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", + "https://files.pythonhosted.org/packages/b2/62/5a5dcb9a71390a9511a253bde19c9c89e0b20118e41080185ea69fb2c209/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", + "https://files.pythonhosted.org/packages/b3/46/03ddc7da576d814fe0a36dd1f0fd3258e95404b4b2e3c026b7923d7e133f/charset_normalizer-3.4.9-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:304b13570067b2547562e308af560b3963857b1fa90bd6afd978130130fe2d6a", + "https://files.pythonhosted.org/packages/b3/c1/ebca8e87c714a6a561cfee063f0655f742e54b8ae6e78151f60ba8708b3a/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl": "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", + "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", + "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl": "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", + "https://files.pythonhosted.org/packages/b6/7c/8debebb4f90174074b827c63242c23851bdf00a532489fba57fef3416e40/charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl": "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", + "https://files.pythonhosted.org/packages/b8/60/e2f67915a51be59d4539ed189eb0a2b0d292bf79270410746becb32bc2c3/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", + "https://files.pythonhosted.org/packages/b9/f8/ca440ef60d8f8916022859885f231abb07ada3c347c03d63f283bec32ef5/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", + "https://files.pythonhosted.org/packages/ba/cd/861883ba5160c7a9bd242c30b2c71074cda2aefcc0addc91118e0d4e0765/charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl": "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd", + "https://files.pythonhosted.org/packages/bb/a6/3a22521736a3a75263ce930a2257eb60fd2a6b8fd9293ea1271a074a202f/charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089", + "https://files.pythonhosted.org/packages/bd/28/7ea29e73eea52c7e15b4b9108d0743fc9e4cc2cdb00d275af1df3d46d360/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl": "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", + "https://files.pythonhosted.org/packages/bd/2a/23f34ec9d04624958e137efdc394888716353190e75f25dd22c7a2c7a8aa/charset_normalizer-3.4.9.tar.gz": "sha256:673611bbd43f0810bec0b0f028ddeaaa501190339cac411f347ac76917c3ae7b", + "https://files.pythonhosted.org/packages/be/4d/9e370f8281cec2fcc9452c4d1ac513324c32957c5f70c73dd2fa8442a21a/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", + "https://files.pythonhosted.org/packages/be/e5/3f363dad2e24378f88ccf63ecc39e817c29f32e308ef21a7a6d9c1201165/charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl": "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca", + "https://files.pythonhosted.org/packages/c1/9d/254a2f1bcb0ce9acad838e94ed05ba71a7cb1e27affaa4d9e1ca3958cdb6/charset_normalizer-3.3.2-cp39-cp39-win32.whl": "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", + "https://files.pythonhosted.org/packages/c2/1e/fa099993d17c00addbb76b3bfcd3ab1692fefc4e193ba738e111c09cfbe2/charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d", + "https://files.pythonhosted.org/packages/c2/65/52aaf47b3dd616c11a19b1052ce7fa6321250a7a0b975f48d8c366733b9f/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl": "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", + "https://files.pythonhosted.org/packages/c2/95/8725b2b2fcb418abe048b5558af42e444161433a76b47759539fe5bb7992/charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf", + "https://files.pythonhosted.org/packages/c2/b6/7aa450b278e7aa92cf7732140bfd8be21f5f29d5bf334ae987c945276639/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl": "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", + "https://files.pythonhosted.org/packages/c3/69/2a5385192e67175f7d8bd5ce4f57c24bc956439adeae5c13a99aa28a53d1/charset_normalizer-3.4.9-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:2a441ea71902098ffe78c5abe6c494f44160b4af614ed16c3d9a3b1d17fd8ee2", + "https://files.pythonhosted.org/packages/c4/02/c57a22739fe05246b0b5783b3bfb6afaac4eebb46f3ececdfb2f048f780e/charset_normalizer-3.4.9-cp310-cp310-win32.whl": "sha256:432786d3561e69aeeae6c7e8648964ce0ad05736120135601f87ac26b9c83381", + "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl": "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", + "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", + "https://files.pythonhosted.org/packages/c7/0b/c5ec5092747f801b8b093cdf5610e732b809d6cb11f4c51e35fc28d1d389/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl": "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", + "https://files.pythonhosted.org/packages/c8/53/a8c042eb9eee4716f4d42a0f5a571eb32a09ec429be9fb0b8b9d765393ba/charset_normalizer-3.4.9-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:68ce9f4d6b26d5ccbf7fd4459bf75f74a0a146677ebba80597df60cbdb20e6f4", + "https://files.pythonhosted.org/packages/c8/ce/09d6845504246d95c7443b8c17d0d3911ec5fdc838c3213e16c5e47dee44/charset_normalizer-3.3.2-cp37-cp37m-win32.whl": "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", + "https://files.pythonhosted.org/packages/c9/7a/6d8767fac16f2c80c7fa9f14e0f53d4638271635c306921844dc0b5fd8a6/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", + "https://files.pythonhosted.org/packages/cb/32/2e64bd2be10e89c61e57ebe6a93fd98ae88eb7ebe414b5121f22c96c69eb/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:cc1b0fff8ead343dae06305f954eb8468ba0ec1a97881f42489d198e4ce3c632", + "https://files.pythonhosted.org/packages/cc/94/f7cf5e5134175de79ad2059edf2adce18e0685ebdb9227ff0139975d0e93/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl": "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", + "https://files.pythonhosted.org/packages/cd/91/7253a32e86b7e1d1239b1b36ba6dd0f021a21107ab33054b53119cc083b9/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:51447e9aa2684679af07ca5021c3db526e0284347ebf4ffcec1154c3350cfe32", + "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl": "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", + "https://files.pythonhosted.org/packages/cf/7c/f3b682fa053cc21373c9a839e6beba7705857075686a05c72e0f8c4980ca/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl": "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", + "https://files.pythonhosted.org/packages/d0/11/00341177ae71c6f5159a08168bcb98c6e6d196d372c94511f9f6c9afe0c6/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", + "https://files.pythonhosted.org/packages/d0/39/8ff066c672434225f8d25f8b739f992af250944392173dcc88362681c9bf/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:21e764fd1e70b6a3e205a0e46f3051701f98a8cb3fad66eeb80e48bb502f8698", + "https://files.pythonhosted.org/packages/d0/a3/53ddae3db108a088156aa8ddfafd411ebbc1340f48c5573f697b27f69a39/charset_normalizer-3.4.9-cp313-cp313-win32.whl": "sha256:51307f5c71007673a2bf8232ad973483d281e74cb99c8c5a990af1eefa6277d9", + "https://files.pythonhosted.org/packages/d1/2f/0d1efd07c74c52b6886c32a3b906fb8afd2fecf448650e73ecb90a5a27f1/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl": "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", + "https://files.pythonhosted.org/packages/d1/b2/fcedc8255ec42afee97f9e6f0145c734bbe104aac28300214593eb326f1d/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl": "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", + "https://files.pythonhosted.org/packages/d3/81/396e7d7f5d7420da8273c91175d2e9a3f569288e3611d521685e4b9ac9cc/charset_normalizer-3.4.1-cp38-cp38-win32.whl": "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e", + "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", + "https://files.pythonhosted.org/packages/d4/ce/9af95f7876194bd7a14e3dfe4a4de2e0bff02666a3910d72beafd06cc297/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:df115d4d83168fdf2cae48ef1ff6d1cb4c466364e30861b37121de0f3bf1b990", + "https://files.pythonhosted.org/packages/d7/74/3c12f9755717dfe5c5c87da63f35d765fa0c00382ec26bf23f7fae34f2ba/charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:9cdef90ae47919cae358d8ab15797a800ed41da7aba5d72419fb510729e2ed4b", + "https://files.pythonhosted.org/packages/d8/b5/eb705c313100defa57da79277d9207dc8d8e45931035862fa64b625bfead/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl": "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", + "https://files.pythonhosted.org/packages/d9/8d/feabb82cb49fcad14515b1d7d1ca4787b0da7fc723a212bf89bc9e0fac52/charset_normalizer-3.4.9-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:67830fc78e67501f47bb950471b2dcb9b35b140084429318e862895a8e89c993", + "https://files.pythonhosted.org/packages/da/f1/3702ba2a7470666a62fd81c58a4c40be00670e5006a67f4d626e57f013ae/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", + "https://files.pythonhosted.org/packages/db/fb/d29e343e7c57bbf1231275939f6e75eb740cd47a9d7cb2c52ffeb62ef869/charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl": "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", + "https://files.pythonhosted.org/packages/dd/51/68b61b90b24ca35495956b718f35a9756ef7d3dd4b3c1508056fa98d1a1b/charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl": "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", + "https://files.pythonhosted.org/packages/de/d1/b4319dc3229d8272fba305e206fc0a148e2de8d4087917ce62ae6382f359/charset_normalizer-3.4.9-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:aa99adc8f081b475a12843953db36831eaf83ec33eb46a90629ca6a5de45a616", + "https://files.pythonhosted.org/packages/df/3e/a06b18788ca2eb6695c9b22325b6fde7dde0f1d1838b1792a0076f58fe9d/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", + "https://files.pythonhosted.org/packages/e1/9c/60729bf15dc82e3aaf5f71e81686e42e50715a1399770bcde1a9e43d09db/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl": "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", + "https://files.pythonhosted.org/packages/e4/10/a78c0e91f487b4ad0ef7480ac765e15b774f83de2597f1b6ef0eaf7a2f99/charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl": "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b", + "https://files.pythonhosted.org/packages/e4/56/6c745619ac397e8871e2bcd3cea1eec86b877488f33888b3aef5c3ed506e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl": "sha256:83aed2c10721ddd90f68140685391b50811a880af20654c59af6b6c66c40513c", + "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", + "https://files.pythonhosted.org/packages/e4/a6/7ee57823d46331ddc37dd00749c95b0edec2c79b15fc0d6e6efb532e89ac/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", + "https://files.pythonhosted.org/packages/e5/0d/815a2ba3f283b4eeaa5ece57acade365c5b4135f65a807a083c818716582/charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9", + "https://files.pythonhosted.org/packages/e8/5f/b98b8da398637b551e427e7be922bdec19177dc54d6811dcdaa503f23aac/charset_normalizer-3.4.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:9bb41182d93ea91f60b4bc8fbf4c820c69ef8a12ab2d917f3f1834f1acad07e8", + "https://files.pythonhosted.org/packages/e8/ef/6953a77c7cf2c2ff9998e6f575ab3e380119f100223381565a4f94c1f836/charset_normalizer-3.4.9-cp313-cp313-win_amd64.whl": "sha256:fe2c7201c642b7c308f1675355ad7ff7b66acfe3541625efe5a3ad38f29d6115", + "https://files.pythonhosted.org/packages/e9/1b/0cad3a4f1906dc36a9cc89093d36b134638463e8e43479dbb96fd47d99ef/charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a", + "https://files.pythonhosted.org/packages/ea/f8/72eb13dcabe7257035cea8aefd922caad2f110d252bf9f67c4c2ca763aee/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:84fd18bcc17526fc2b3c1af7d2b9217d32c9c04448c16ec693b9b4f1985c3d33", + "https://files.pythonhosted.org/packages/eb/5c/97d97248af4920bc68687d9c3b3c0f47c910e21a8ff80af4565a576bd2f0/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl": "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", + "https://files.pythonhosted.org/packages/eb/78/59344ff9a4a7b5f6530bf7bec2c980047cc42c3a616596cdbd8cb5c1a1af/charset_normalizer-3.4.9-cp39-cp39-musllinux_1_2_x86_64.whl": "sha256:43b9e366a31fdd1c87d0eb08f579b4a82b723ea54338f040d6b4e518a026ea29", + "https://files.pythonhosted.org/packages/ec/96/5d9364e3342d69f3a045e1777bc47c85c383e6e9466d561b33fdb419d1f9/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:9b2aff1c7b3884512b9512c3eaadd9bab39fb45042ffaaa1dd08ff2b9f8109d9", + "https://files.pythonhosted.org/packages/ec/a3/2db14427b37cefbf9a9ec3d3c861e1b1721e4d4507536df102c2854966dc/charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl": "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e", + "https://files.pythonhosted.org/packages/ec/b4/ef5a49b2e77c00deb43bb3256592b115ba9e4346016e82c516b8d215bf68/charset_normalizer-3.4.9-cp39-cp39-manylinux_2_31_armv7l.whl": "sha256:231ddcbb35e2ff8973e1365db41fe0572662893b99a05deb183b68ad4c0c8bd4", + "https://files.pythonhosted.org/packages/ed/3a/a448bf035dce5da359daf9ae8a16b8a39623cc395a2ffb1620aa1bce62b0/charset_normalizer-3.3.2-cp312-cp312-win32.whl": "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", + "https://files.pythonhosted.org/packages/ed/61/710738687f90d01c06a04ed52d6ca1e62dd9b1d8cc2567098167c4691034/charset_normalizer-3.4.9-cp39-cp39-musllinux_1_2_aarch64.whl": "sha256:0fa1aec2d32bcc03c8fa0f6f1712caad1adc38509f31142112e5c9daf5b9c833", + "https://files.pythonhosted.org/packages/ed/a1/e29995109e455dc8eff8d0fac6ae509be39561318a7cfeac5d33ad029213/charset_normalizer-3.4.9-cp311-cp311-win_amd64.whl": "sha256:6366a16e1a25018694d6a5d784d09b046edc9eac40ea2b54065c3052672516a1", + "https://files.pythonhosted.org/packages/ee/f0/f1c4fe746c395922961b5916ed1d7d6e7d4c84851d19ed43cc89980ec953/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:32286a2c8d167e897177b673176c1e3e00d4057caf5d2b64eef9a3666b03018e", + "https://files.pythonhosted.org/packages/ee/fb/14d30eb4956408ee3ae09ad34299131fb383c47df355ddb428a7331cfa1e/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", + "https://files.pythonhosted.org/packages/ef/d4/a1d72a8f6aa754fdebe91b848912025d30ab7dced61e9ed8aabbf791ed65/charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl": "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", + "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", + "https://files.pythonhosted.org/packages/f0/e6/0386d43a261ff4e4b30c5857af7df877254b46bec7b9d1b74b6bf969a90b/charset_normalizer-3.4.9-cp312-cp312-win_arm64.whl": "sha256:78fa18e436a1a0e58dbd7e02fc4473f3f32cceb12df9dfca542d075961c307d2", + "https://files.pythonhosted.org/packages/f1/60/b22cdbee7e4013dab8b0d7647fc6181120fbbbc8f7025c226d15bd5a47fc/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:bd47ba7fc3ca94896759ea0109775132d3e7ab921fbf54038e1bab2e46c313c9", + "https://files.pythonhosted.org/packages/f1/78/c9c71d599f5aa2d42bcdd35cbbd46d7f535351a57e40ff7d8e5a7e219401/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_armv7l.whl": "sha256:d4d6fcde76f94f5cb9e43e9e9a61f16dacefd228cbbf6f1a09bd9b219a92f1a1", + "https://files.pythonhosted.org/packages/f2/0e/e06bc07ef4673e4d24dc461333c254586bb759fdd075031539bab6514d07/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl": "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", + "https://files.pythonhosted.org/packages/f2/e3/e20aae5e1039a2cd9b08d9205f52142329f887f8cf70da3650326670bddf/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl": "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", + "https://files.pythonhosted.org/packages/f4/c4/b3e049d2aa3766180c78507110543d9d50894cc97f57de543f1be521dcdc/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:c25fe15c70c59eb7c5ce8c06a1f3fa1da0ecc5ea1e7a5922c40fd2fa9b0d5046", + "https://files.pythonhosted.org/packages/f6/39/c914445c321a845097ce4f6ac7de9a18228a77b766272125a1ce00d851eb/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_x86_64.whl": "sha256:898f0e9068ca27d37f8e83a5b962821df851532e6c4a7d615c1c033f9da6eedf", + "https://files.pythonhosted.org/packages/f6/93/bb6cbeec3bf9da9b2eba458c15966658d1daa8b982c642f81c93ad9b40e1/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", + "https://files.pythonhosted.org/packages/f6/d3/bfc699ab2c4f9245867060744e8136d359412ff1e5ad93be38a46d160f9d/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", + "https://files.pythonhosted.org/packages/f7/33/557ac796c47165fc141e4fb71d7b0310f67e05cb420756f3a82e0a0068e0/charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6", + "https://files.pythonhosted.org/packages/f7/40/9593d54209765207a7f11073c06494c1721e4ca4a0a426c597679bf7f91e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl": "sha256:ee2f2a527e3c1a6e6411eb4209642e138b544a2d72fe5d0d76daf77b24063534", + "https://files.pythonhosted.org/packages/f7/9d/bcf4a449a438ed6f19790eee543a86a740c77508fbc5ddab210ab3ba3a9a/charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl": "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", + "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl": "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2" + }, + "coloredlogs": { + "https://files.pythonhosted.org/packages/a7/06/3d6badcf13db419e25b07041d9c7b4a2c331d3f4e7134445ec5df57714cd/coloredlogs-15.0.1-py2.py3-none-any.whl": "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934", + "https://files.pythonhosted.org/packages/cc/c7/eed8f27100517e8c0e6b923d5f0845d0cb99763da6fdee00478f91db7325/coloredlogs-15.0.1.tar.gz": "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0" + }, + "constantly": { + "https://files.pythonhosted.org/packages/4d/6f/cb2a94494ff74aa9528a36c5b1422756330a75a8367bf20bd63171fc324d/constantly-23.10.4.tar.gz": "sha256:aa92b70a33e2ac0bb33cd745eb61776594dc48764b06c35e0efd050b7f1c7cbd", + "https://files.pythonhosted.org/packages/b8/40/c199d095151addf69efdb4b9ca3a4f20f70e20508d6222bffb9b76f58573/constantly-23.10.4-py3-none-any.whl": "sha256:3fd9b4d1c3dc1ec9757f3c52aef7e53ad9323dbe39f51dfd4c43853b68dfa3f9" + }, + "cryptography": { + "https://files.pythonhosted.org/packages/00/f2/c166af87e95ce6ae6d38471a7e039d3a0549c2d55d74e059680162052824/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl": "sha256:d97cf502abe2ab9eff8bd5e4aca274da8d06dd3ef08b759a8d6143f4ad65d4b4", + "https://files.pythonhosted.org/packages/01/77/2cf79bbfc4d12ca106437a6e170d6aaa01a373e93093118aaaef0e801bd4/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl": "sha256:9aa87839c383bdbab6ef865787a1fb877af8dd03464c4400322726feaaadfc6d", + "https://files.pythonhosted.org/packages/01/b6/0b9e125e90f3d2dcf599a218a899cda7326a3158cfa258723f0b398b08f6/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl": "sha256:8eb5e1172eb569ea8a872796576e6a67c276351728b6455d5beb01242b027c6a", + "https://files.pythonhosted.org/packages/03/37/73d005be173aff344af30e9fd2a576575cb2391a7101d9cd3842e1fa8cce/cryptography-50.0.0-cp39-abi3-macosx_11_0_arm64.whl": "sha256:ccdc4a71a4dabae05de219404f9f4abc38e3b58422177ff93d0da05967dafa07", + "https://files.pythonhosted.org/packages/04/19/030f400de0bccccc09aa262706d90f2ec23d56bc4eb4f4e8268d0ddf3fb8/cryptography-45.0.7-cp311-abi3-musllinux_1_2_x86_64.whl": "sha256:fa26fa54c0a9384c27fcdc905a2fb7d60ac6e47d14bc2692145f2b3b1e2cfdbd", + "https://files.pythonhosted.org/packages/06/1e/63a1027cb7fec360a182208e1b7767d5aa1fe57be3d6aa856e69a321edc0/cryptography-50.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl": "sha256:8d89f3976b10b4ce31118de72329025f70d2c6ead14a8217c5514dd2c6d5a78f", + "https://files.pythonhosted.org/packages/09/41/3797cfaf69cae04a13ee78ebd83f0678d9c02b4779d21ce24445326f1a69/cryptography-49.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:36d1709f992593689b45bda411498d62c6e365f2ca00b84657d4dadd24de16db", + "https://files.pythonhosted.org/packages/0b/11/09700ddad7443ccb11d674efdbe9a832b4455dc1f16566d9bd3834922ce5/cryptography-45.0.7-cp37-abi3-musllinux_1_2_x86_64.whl": "sha256:1993a1bb7e4eccfb922b6cd414f072e08ff5816702a0bdb8941c247a6b1b287c", + "https://files.pythonhosted.org/packages/0c/91/925c0ac74362172ae4516000fe877912e33b5983df735ff290c653de4913/cryptography-45.0.7-cp311-abi3-macosx_10_9_universal2.whl": "sha256:3be4f21c6245930688bd9e162829480de027f8bf962ede33d4f8ba7d67a00cee", + "https://files.pythonhosted.org/packages/0e/e4/b3e68a4ac363406a56cf7b741eeb80d05284d8c60ee1a55cdc7587e2a553/cryptography-45.0.7-cp311-abi3-manylinux_2_34_x86_64.whl": "sha256:b6a0e535baec27b528cb07a119f321ac024592388c5681a5ced167ae98e9fff3", + "https://files.pythonhosted.org/packages/11/2d/5e1fb307cb5931881516b464c98774b3f2c36b5d4bb9a2830253cf553cad/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl": "sha256:d8ecde755e2e91bf773fc94e8c9d730cd7f2007004cb492263a794ec3899a1c8", + "https://files.pythonhosted.org/packages/12/dd/b2882b65db8fc944585d7fb00d67cf84a9cef4e77d9ba8f69082e911d0de/cryptography-45.0.7-cp37-abi3-manylinux_2_34_aarch64.whl": "sha256:48c41a44ef8b8c2e80ca4527ee81daa4c527df3ecbc9423c41a420a9559d0e27", + "https://files.pythonhosted.org/packages/13/3e/e42f1528ca1ea82256b835191eab1be014e0f9f934b60d98b0be8a38ed70/cryptography-45.0.7-pp310-pypy310_pp73-macosx_10_9_x86_64.whl": "sha256:de58755d723e86175756f463f2f0bddd45cc36fbd62601228a3f8761c9f58252", + "https://files.pythonhosted.org/packages/15/37/36a9c479bbe49acea2636c7fd3360d20f7b7e079c300352011c44850b181/cryptography-50.0.0-cp311-abi3-manylinux_2_31_armv7l.whl": "sha256:900131fafd8aead39ac7dd3a7e833be754c17a95cfd91221636949fe4eb0aa8a", + "https://files.pythonhosted.org/packages/16/b9/e96e0b6cb86eae27ea51fa8a3151535a18e66fe7c451fa90f7f89c85f541/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl": "sha256:c987dad82e8c65ebc985f5dae5e74a3beda9d0a2a4daf8a1115f3772b59e5141", + "https://files.pythonhosted.org/packages/16/ce/5f6ff59ea9c7779dba51b84871c19962529bdcc12e1a6ea172664916c550/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl": "sha256:06ce84dc14df0bf6ea84666f958e6080cdb6fe1231be2a51f3fc1267d9f3fb34", + "https://files.pythonhosted.org/packages/17/50/983e838c7fd0d87fd8c969bcdd328edaf5f756e38df5281637424c155873/cryptography-49.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl": "sha256:07cab27cc7b7e0fd28e5e26bb9eeedde5c135c868b46de4a27845abe94af6122", + "https://files.pythonhosted.org/packages/19/2a/5bb823f5bedcf80718cea7fbc95ec5515cca3769633c4b01a32be7f30e7c/cryptography-49.0.0-cp39-abi3-macosx_11_0_arm64.whl": "sha256:ec5e529fb80935c94fe7b729f9972b50e351a0e6b50aa294fd5cabb109fcc29a", + "https://files.pythonhosted.org/packages/1a/28/b555a365adff1cca2fbe7b9e487d68a40de6bc67ff2cb587473eb43de0e7/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl": "sha256:d58c3db7cd6eed54e6c06744db55456b65ebd7492ddeae9c1e93cfca7aa857d3", + "https://files.pythonhosted.org/packages/1c/c5/8c59d6b7c7b439ba4fc8d0cab868027fd095f215031bc123c3a070962912/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl": "sha256:2f641b64acc00811da98df63df7d59fd4706c0df449da71cb7ac39a0732b40ae", + "https://files.pythonhosted.org/packages/1d/dd/7c77d26285cc7f6991efce64a0f5b4f9383bfa5dd8c5033003eaf7db4cdb/cryptography-50.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl": "sha256:d764dcf130c428ef66786f866dd750f53182bc608813489915e9fc106bb0c82f", + "https://files.pythonhosted.org/packages/1f/09/f42b1d190c5ba75f72062a387f8030d1d75f6ab035788f1d9c4b01de6525/cryptography-49.0.0-cp311-abi3-win_amd64.whl": "sha256:e5dfc1e64de5677cec922ffa8da89c546d0415bf6efdf081842e5d44c84e1f0e", + "https://files.pythonhosted.org/packages/1f/99/d1c90d6041656cc6ee229dc99cd67fd0cd5aec3c5f7d72fffc27cc750054/cryptography-49.0.0.tar.gz": "sha256:f89660a348f4f78a92366240a61404e337586ef7f5909a2fef59ca88ef505493", + "https://files.pythonhosted.org/packages/20/2c/0622f20ff02b2ef32558733443805dc82fd4c275be01b2d19d14676f3a1b/cryptography-49.0.0-cp311-abi3-manylinux_2_28_x86_64.whl": "sha256:2afe9051da7ae7bd5905da5a949280c7d2bb75682e188f650a9d0f2756b834c6", + "https://files.pythonhosted.org/packages/22/49/2c93f3cd4e3efc8cb22b02678c1fad691cff9dd71bb889e030d100acbfe0/cryptography-45.0.7-cp311-abi3-musllinux_1_2_aarch64.whl": "sha256:a24ee598d10befaec178efdff6054bc4d7e883f615bfbcd08126a0f4931c83a6", + "https://files.pythonhosted.org/packages/22/f6/ec13b470172126464a86bf54d2294a46d29837fc51ba3e45d4047946fb5e/cryptography-50.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl": "sha256:f89831ef99dd7dd169ab06d63a831adb9e20a87aac6d380266bbda5823349169", + "https://files.pythonhosted.org/packages/23/87/7ce86f3fa14bc11a5a48c30d8103c26e09b6465f8d8e9d74cf7a0714f043/cryptography-45.0.7-pp311-pypy311_pp73-win_amd64.whl": "sha256:1f3d56f73595376f4244646dd5c5870c14c196949807be39e79e7bd9bac3da63", + "https://files.pythonhosted.org/packages/24/01/186c825898477d77e2324d5360fefe622ff1d8d1963ec0554e2cada8ec77/cryptography-49.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl": "sha256:9e82dcc8e56052715fb18b2429e3bca4823b1629136a2084fc45a9a5cecb9b64", + "https://files.pythonhosted.org/packages/24/06/09b6f6a2fc43474a32b8fe259038eef1500ee3d3c141599b57ac6c57612c/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl": "sha256:258e0dff86d1d891169b5af222d362468a9570e2532923088658aa866eb11130", + "https://files.pythonhosted.org/packages/27/20/c930314a2ab476d15dec966ec87e2e9637bb02b06106b12c0396c57bb603/cryptography-50.0.0-cp311-abi3-musllinux_1_2_x86_64.whl": "sha256:7cec5b856506da6defb290f30c9ee687d5f5e8cb0bd3f6459dde43b0b4fa40ef", + "https://files.pythonhosted.org/packages/29/56/3034a3a353efa65116fa20eb3c990a8c9f0d3db4085429040a7eef9ada5f/cryptography-45.0.7-cp311-abi3-win32.whl": "sha256:bef32a5e327bd8e5af915d3416ffefdbe65ed975b646b3805be81b23580b57b8", + "https://files.pythonhosted.org/packages/2c/99/2d13299eb3dd27b02dcfaafcc91d6b5cb3329f7cbd6d8f51921acd566c1a/cryptography-49.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:35b151772baff2c74cba7fa290ceaff4c3b11c0c881eb93eb5dbc05a7cfbba18", + "https://files.pythonhosted.org/packages/30/82/85f0f7425c856b9f96459411eb12e74ef72df9caf6f8f15bf23a33ff131f/cryptography-50.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:80b63928fa35083b33966ce1efb70e5b9607181e49dcd1c22c8c005e319f667f", + "https://files.pythonhosted.org/packages/32/2e/c9db68a0c4bfa28e310707527c0ee3a2bd254104d2e02e68f368e197aa4c/cryptography-50.0.0-cp311-abi3-win_amd64.whl": "sha256:bd1c592e4d5974f0d08d4888e432157adba757c66da0246918e43677fafa2d30", + "https://files.pythonhosted.org/packages/32/98/8a151d64367204cbc63ec65d37502f1d9c53cf4bfc6ec3c532614dbec60d/cryptography-50.0.0-cp311-abi3-manylinux_2_34_aarch64.whl": "sha256:07949c449a1abcf60d1ee6e88956d89404c7df3c8258f46589e912988e551987", + "https://files.pythonhosted.org/packages/36/8b/fc61f87931bc030598e1876c45b936867bb72777eac693e905ab89832670/cryptography-45.0.7-cp37-abi3-musllinux_1_2_aarch64.whl": "sha256:dd342f085542f6eb894ca00ef70236ea46070c8a13824c6bde0dfdcd36065b9b", + "https://files.pythonhosted.org/packages/36/d0/36e8ee39274e9d77baf7d0dafda680cba6e52f3936b846f0d56d64fec915/cryptography-45.0.7-pp310-pypy310_pp73-win_amd64.whl": "sha256:c13b1e3afd29a5b3b2656257f14669ca8fa8d7956d509926f0b130b600b50ab7", + "https://files.pythonhosted.org/packages/38/14/6120e5bd7c5aa022ad15424ba4d5c5269d0d9448ed4d55e492ea91e3c1c4/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl": "sha256:11b74db56cdbe3cdee6e3f6982ecb70334fa10dce99ed58bf7894aaaa3b2a037", + "https://files.pythonhosted.org/packages/3a/63/504ccfbbe61fd8aa983f7f146399cdf034c72c2fc55f5b2dfdcdcdb20c99/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl": "sha256:ecfed7367f965a0328cfbdd70da860f15441f002f613185668c6e6ebf5a0ac11", + "https://files.pythonhosted.org/packages/3d/df/40577043ca124e17012f408ddddaeb213b856336ac82ddb3bc915f39e29f/cryptography-49.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:f78ff2c9ed8dc2d036b0f4d640e22522213d047c1b14e61205a7e55c80a494d4", + "https://files.pythonhosted.org/packages/46/c9/f60aed34c013f317f92817b6c171c2d22a78270fa41109bd4b08af26b194/cryptography-50.0.0-cp39-abi3-manylinux_2_28_x86_64.whl": "sha256:105110f43a471dbd0060b9c9516cb8a6a79233631a04cc2ba16f28323ac6e025", + "https://files.pythonhosted.org/packages/47/f1/1d3eaa243bfc5de4a187b22aa8c048b3e4980bfbe830ac46e6bac2e66947/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl": "sha256:f37d847238971164fdbc68ade6f6574aecc9c0af714190e2083429ff68f4ce9d", + "https://files.pythonhosted.org/packages/4a/91/01ce7303a4579e6d3a6abef01bd322848e9ea7a219adcabc5048b9033571/cryptography-49.0.0-cp311-abi3-manylinux_2_28_aarch64.whl": "sha256:53ecee2e23f7169b6117e99fc8a944e5e50f79e69758a83b52a00cb98ab2b2d2", + "https://files.pythonhosted.org/packages/4c/fe/93ecac273d3738939d023612ad12cca9a3740a5345d69fda04134c43fd96/cryptography-49.0.0-cp314-cp314t-win_amd64.whl": "sha256:33cd0565932807baddb67b96dbee92f2c374b5c89dee09fd74079aeb8c8dba61", + "https://files.pythonhosted.org/packages/4f/01/339573cf1023163a400b0b5d16f6d507de413b9f60be6fd1b77feeaf6737/cryptography-49.0.0-cp311-abi3-musllinux_1_2_aarch64.whl": "sha256:b87e65d263b3e5d3bb92a57e2a6638e2f31110fa7aa890c7b2dbba42248d0a3f", + "https://files.pythonhosted.org/packages/53/c9/a5151588710785a96d7bc4de27d4cd62f263bbbcb203cfe29df537eb6505/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl": "sha256:910d11e1a385c654bf738bf3e6b8e6ed5de0f5610fcae2be9e5b398d8081d20e", + "https://files.pythonhosted.org/packages/55/32/05385c86d6ca9ab0b4d5bb442d2e3d85e727939a11f3e163fc776ce5eb40/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl": "sha256:f5414a788ecc6ee6bc58560e85ca624258a55ca434884445440a810796ea0e0b", + "https://files.pythonhosted.org/packages/57/30/4a22984d4f1bdfb8c054f07a92bc176b97a3134cc1d6c4b3bffb1f3688b4/cryptography-50.0.0-cp39-abi3-win_amd64.whl": "sha256:d24fead1d4d076e1bfb006dcec392074a3cd8d7b4fc8a595aa64073b2b7a96ba", + "https://files.pythonhosted.org/packages/57/ef/8f2df13c7216bcad3e1c74e07f6e193d93e998e114f524a53877c9af27ad/cryptography-50.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:fd9192b7b70c573d7f214eb1ae35e00d359f6f5e4b27c7e21e30de1fc6204645", + "https://files.pythonhosted.org/packages/58/39/2d51306721330c486495853eda1c567880ff036de15a14c4b74f399934af/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl": "sha256:c2bc30226390d60ea19d9f82b19db005fe0452154a23c1c410c12ea801e43561", + "https://files.pythonhosted.org/packages/58/67/3f5b26937fe1218c40e95ef4ff8d23c8dc05aa950d54200cc7ea5fb58d28/cryptography-45.0.7-cp311-abi3-manylinux_2_34_aarch64.whl": "sha256:8978132287a9d3ad6b54fcd1e08548033cc09dc6aacacb6c004c73c3eb5d3ac3", + "https://files.pythonhosted.org/packages/59/aa/e947693ab08674a2663ed2534cd8d345cf17bf6a1facf99273e8ec8986dc/cryptography-45.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl": "sha256:a20e442e917889d1a6b3c570c9e3fa2fdc398c20868abcea268ea33c024c4083", + "https://files.pythonhosted.org/packages/5d/fa/1d5745d878048699b8eb87c984d4ccc5da4f5008dfd3ad7a94040caca23a/cryptography-45.0.7-cp37-abi3-manylinux_2_34_x86_64.whl": "sha256:f3df7b3d0f91b88b2106031fd995802a2e9ae13e02c36c1fc075b43f420f3a17", + "https://files.pythonhosted.org/packages/62/15/219075012ab13e8905f3cd572204f4acb4b111df787104346b9bc0cea789/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl": "sha256:07479a1cb08219ab719147e742e76090c9c773321959bb94946fffdd397a6437", + "https://files.pythonhosted.org/packages/62/62/24203e7cbcc9bd7c94739428cd30680b18ae6b18377ae66075c8e4771b1b/cryptography-45.0.7-cp311-abi3-manylinux_2_28_aarch64.whl": "sha256:4bd3e5c4b9682bc112d634f2c6ccc6736ed3635fc3319ac2bb11d768cc5a00d8", + "https://files.pythonhosted.org/packages/62/99/a2c95cf8293f07491e9e27c20cc4dcd18176d944e674679adeb1d0173fd6/cryptography-49.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl": "sha256:2eda353d8a27bcbcaa4cbed18994a74ab4d19a2ca897db188ea269ab9b71419b", + "https://files.pythonhosted.org/packages/63/d3/4a83af35d65e3fad632c926fad684c193ea4398569ccb0bbbc7fe8f5dc9a/cryptography-49.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl": "sha256:fc1e275c2f1d97b1a6450b8b0ea3ebfa6e087a611c2b26cb2404d48588abab7b", + "https://files.pythonhosted.org/packages/63/e8/c436233ddf19c5f15b25ace33979a9dd2e7aa1a59209a0ee8554179f1cc0/cryptography-45.0.7-cp37-abi3-macosx_10_9_universal2.whl": "sha256:bfb4c801f65dd61cedfc61a83732327fafbac55a47282e6f26f073ca7a41c3b2", + "https://files.pythonhosted.org/packages/64/a2/4615c8f7d81a00b1d6e6afe19f694e1543582349fb5f4076f6cb5dc36485/cryptography-50.0.0-cp39-abi3-musllinux_1_2_aarch64.whl": "sha256:c87f62a3d3b9888ed0fdde100ec06aa61ca9cd44bad9057d1dff9a516b5f5bb9", + "https://files.pythonhosted.org/packages/67/d0/a5fcd3515f0bae49a7b6d0413cc1bdccdcc1fc0047037a0d480642cdc5d6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl": "sha256:6fc361c34fb6aac015ce19435876635e5c6d21db31998b0920f675f131e043b8", + "https://files.pythonhosted.org/packages/68/28/8a3ad4653662c93fc44dc4e5d8fd374c25c42e07b34bbfbadf49cf57a5a8/cryptography-49.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:7abcee80084cda3f7691f3eb1ce480d8df49cec637b429aa35986c1de71738aa", + "https://files.pythonhosted.org/packages/6b/16/d3008eff98c764979865834c3d386d4fd041b5f52e7f34fc29ac1a5eb515/cryptography-50.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl": "sha256:6e7d61120573a7f2cd94cc095f9e81f6967c61ccdf194285aa143ecec8e0b708", + "https://files.pythonhosted.org/packages/6b/72/a1116d683a6d7ece94590013882515de087edf9ef0e6292aae615a44df73/cryptography-50.0.0-cp311-abi3-manylinux_2_28_x86_64.whl": "sha256:b42a28c1844fd9de8f3f7d540e36b66f3a9c83fceac7170ebc7a6a19edd9dcae", + "https://files.pythonhosted.org/packages/6c/72/3e798c064bc39e471008075d0f9bc9daf77a80879c092e4a8e170c585ed4/cryptography-49.0.0-cp39-abi3-manylinux_2_31_armv7l.whl": "sha256:8c25ceb16df5b9435f3f6a9829204985b0e0cbee3b48aacd432c7d2c850b44d9", + "https://files.pythonhosted.org/packages/6c/a0/db537264e234f7273a73ec020873d6d6b39dfd8a53db78b550ca8320440e/cryptography-49.0.0-cp39-abi3-musllinux_1_2_aarch64.whl": "sha256:67e1d20ad9ef3a563c59ef22e7a8a0b8210bd26604369ea4a30a7c66aefe504e", + "https://files.pythonhosted.org/packages/6d/88/05563c7fe2e914e87d1a536d06fe83e66b4e1d95cb593e05aea375531da8/cryptography-49.0.0-cp311-abi3-manylinux_2_34_aarch64.whl": "sha256:ccac2bfebc306b862133e3bb71f3f6ee8bb525240089b2d952e4144b3a6d5da7", + "https://files.pythonhosted.org/packages/71/ed/8f4c1337e9d3b94d8e50ae0b08ad0304a5709d483bfcadfcc77a23dbcb52/cryptography-45.0.7-cp37-abi3-win32.whl": "sha256:18fcf70f243fe07252dcb1b268a687f2358025ce32f9f88028ca5c364b123ef5", + "https://files.pythonhosted.org/packages/71/fd/577302e213a1be9468f92d1afef66fcf1ef83d516819d9992ca547f592bd/cryptography-49.0.0-cp311-abi3-musllinux_1_2_x86_64.whl": "sha256:66ec79c3904820572d7e987abdf304281f141d37ad9a489b8e97066e7b9b6459", + "https://files.pythonhosted.org/packages/72/d8/f52538140cc719df62a01cf87d1c7142318d235817109d6f4054d7c352d6/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl": "sha256:df2a58a472f332225671c35b0a830208b86d004f82baa8530fa3782c85646533", + "https://files.pythonhosted.org/packages/74/9a/02ffe35b2853d121689871eb5dce862092562b3a1ed5cc98f1aaed441506/cryptography-50.0.0-cp314-cp314t-win_amd64.whl": "sha256:12b9c6996425c76ea6c457ace4f3073e715b8c545add07cd1a8f3a4f90691269", + "https://files.pythonhosted.org/packages/7b/20/4fe50b619a48c2525cc46e2dbc1ac490708d704be5d467bdaac6dc955682/cryptography-50.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl": "sha256:3f5735ffe4996d28b809371756219f5354864902a3b9e7c0b9ee87041209fc9c", + "https://files.pythonhosted.org/packages/7d/ff/b6ce0954962e7f7b969f850a883744197bb3910bdfd7b6da162eab7d9f68/cryptography-50.0.0-cp311-abi3-manylinux_2_28_aarch64.whl": "sha256:a1b30560f2acc95aa8b2e06e716a13dbfc97314747b80d9707e307f77b40d6b3", + "https://files.pythonhosted.org/packages/83/dc/4dab2ff0a871cc2d81d3ae6d780991c0192b259c35e4d83fe1de18b20c70/cryptography-45.0.7-cp37-abi3-manylinux_2_28_x86_64.whl": "sha256:b04f85ac3a90c227b6e5890acb0edbaf3140938dbecf07bff618bf3638578cf1", + "https://files.pythonhosted.org/packages/85/4f/0fa8c2f4428198f15d9ff8d63400e27afbf94ce833f6108da1eb3753f945/cryptography-50.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:a91296cb61e8df6f86d0c19cc4068228da256bf59bf86049fbd821084565327f", + "https://files.pythonhosted.org/packages/86/12/c48a424f38db03027be9f7ed5c7dc5de9933dbee992865f98b13727a009d/cryptography-49.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:196ecd6a36e4e9aa10270393bb98d8df88fccee0bf1e5128b91ae4eb4375896d", + "https://files.pythonhosted.org/packages/8e/b5/c2c5fce26f0ee40d21bafe7f191d29a34b35a65ac4fe8a1191d1983612e9/cryptography-50.0.0-pp311-pypy311_pp73-win_amd64.whl": "sha256:c99c003e088647b8a5b7c145d6f78c335f6348332b62e142d411c4b63d1460b9", + "https://files.pythonhosted.org/packages/92/91/3a31366e183343d3703f8995c095f5734676bd6938118047e50fcf279eb4/cryptography-50.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl": "sha256:1b4a266766514614f8aa60416e71f2fc6e575d36e7bdc90f644fadb2f4b75b95", + "https://files.pythonhosted.org/packages/93/77/8df9eb486495979bccecd1062e2eaf435250e84437040295b57d09048b0b/cryptography-49.0.0-cp39-abi3-musllinux_1_2_x86_64.whl": "sha256:42b0684e0e40cf26122427802486f6d93aea593612603a94fbf260c7eb1e9c1b", + "https://files.pythonhosted.org/packages/94/64/2923570ac1c0bd3a737aa366ac3abbbbde273042308b8cde95e2364a6e6a/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl": "sha256:b47db11c2c3525083296069b98ac5221907455e989ae0c2e3008bde851921615", + "https://files.pythonhosted.org/packages/96/b8/bca71059e79a0bb2f8e4ec61d9c205fbe97876318566cde3b5092529faa9/cryptography-45.0.7-cp311-abi3-manylinux_2_28_x86_64.whl": "sha256:16ede8a4f7929b4b7ff3642eba2bf79aa1d71f24ab6ee443935c0d269b6bc513", + "https://files.pythonhosted.org/packages/99/4e/49199a4c82946938a3e05d2e8ad9482484ba48bbc1e809e3d506c686d051/cryptography-45.0.7-pp311-pypy311_pp73-macosx_10_9_x86_64.whl": "sha256:4a862753b36620af6fc54209264f92c716367f2f0ff4624952276a6bbd18cbde", + "https://files.pythonhosted.org/packages/9b/22/adf66990e63584a68dfb50c24f48a125c07b1699899381c8151e63ed458c/cryptography-49.0.0-cp311-abi3-macosx_11_0_arm64.whl": "sha256:966fe0e9c67490071f14c0d2b1cb2dfb3023c5ce39457343931415f08382f2db", + "https://files.pythonhosted.org/packages/9c/f8/d97f9603efda3888187bfdb893f26c41be4735c10631d05d284ee6b047c4/cryptography-50.0.0-cp39-abi3-manylinux_2_34_x86_64.whl": "sha256:37fdb0d0111f1e2ff07139dfb79f1b49531f8e213c46f1163dd7642979b58c47", + "https://files.pythonhosted.org/packages/9d/3e/e54cde8c01631a5a8226ccd617eab9e57fd5cfdad90f1a9e6bb570794631/cryptography-50.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl": "sha256:5e34edd123674534acd70147f0ca331eaa2c74e6325fb2028c886aa26ba0b68c", + "https://files.pythonhosted.org/packages/a0/84/84fe36f19caf857d61cb7fc9c63035a47ffabd84ea12d1d393148efa3615/cryptography-49.0.0-cp39-abi3-manylinux_2_34_x86_64.whl": "sha256:2400ef9c9e2299a25614eb1dea3db54a69b1349efd043bfac9c67630d136df36", + "https://files.pythonhosted.org/packages/a3/5b/c5246635d5fd3b64e0d45ae10e99fd32fe9676a79915ccfe5a61ba9af1a5/cryptography-49.0.0-cp311-abi3-manylinux_2_31_armv7l.whl": "sha256:0b82e28ee398a386f0807bba7884d30f25218855690f45115831bcce5d90822c", + "https://files.pythonhosted.org/packages/a5/4d/9c0cd02f95e2602dd5e563da149ee0830abef3537be8b34dc56281ebe27a/cryptography-49.0.0-cp39-abi3-manylinux_2_28_aarch64.whl": "sha256:0f21641cf4b30fca7aee061ced0ec7ad7b073518088b7c9969a297c0ae796c69", + "https://files.pythonhosted.org/packages/a7/35/c495bffc2056f2dadb32434f1feedd79abde2a7f8363e1974afa9c33c7e2/cryptography-45.0.7.tar.gz": "sha256:4b1654dfc64ea479c242508eb8c724044f1e964a47d1d1cacc5132292d851971", + "https://files.pythonhosted.org/packages/a7/f5/8f571d7e27c55bce9f76f026143bcb1e040a4233149ecca0bea5fa5dd5f7/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl": "sha256:b20133d204d2bb56ba047642199603876c872026ca53e79c35b83772ab2cc505", + "https://files.pythonhosted.org/packages/a8/b2/2193fc74f81aee4f9b62733133b73b5176718932ed8f2e4b03fa040480a6/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl": "sha256:4ae387c9cb68ea569ca17e490d66d8142b81c3cc814bf179974b7d146e490bbb", + "https://files.pythonhosted.org/packages/a9/3c/f3ad17eecc1a57b0ba236dc01f90e783c51f4a2f35f64777cc4f47a184b2/cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl": "sha256:cbc77da8c523d5abd028635ba850a6966fcee2c82e2bf65a41d1d8afe0f98be9", + "https://files.pythonhosted.org/packages/aa/50/a9caea39ad19c431c1a3f8a31114df65b260cdfe67786b6c7e7c040c4c44/cryptography-49.0.0-pp311-pypy311_pp73-win_amd64.whl": "sha256:be9fcb48a55f023493482827d4f459bd263cc20efde64f204b97c123201850c6", + "https://files.pythonhosted.org/packages/ab/f8/614dc7e051418cfe53d55173c1e24c6b0085e89996fe90508c2fdf769aef/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl": "sha256:084ef1af862eb07ec46d25f68689f2102a9fc0e05ce7b80f14f5fe51e4eef0f6", + "https://files.pythonhosted.org/packages/b3/61/0ab90f421c6194705a99d0fa9f6ee2045d916e4455fdbb095a9c2c9a520f/cryptography-45.0.7-cp311-abi3-win_amd64.whl": "sha256:3808e6b2e5f0b46d981c24d79648e5c25c35e59902ea4391a0dcb3e667bf7443", + "https://files.pythonhosted.org/packages/b8/56/d4f07ea21434bf891faa088a6ac15d6d98093a66e75e30ad08e88aa2b9ba/cryptography-45.0.7-cp37-abi3-manylinux_2_28_aarch64.whl": "sha256:dad43797959a74103cb59c5dac71409f9c27d34c8a05921341fb64ea8ccb1dd4", + "https://files.pythonhosted.org/packages/b8/7b/62cbbab75d0659865bf0273790031544a0b16c8072d258f9428dcd8190dc/cryptography-49.0.0-cp39-abi3-manylinux_2_28_x86_64.whl": "sha256:6f2debedf9ca60cf1d5bd466475638af5130f89965605cd818484d19987d3a21", + "https://files.pythonhosted.org/packages/b9/26/814681d14248d95d73d5c3eea0c39a94eb8302df966f670a2c60de90974b/cryptography-49.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl": "sha256:32703d93296f5c1f4b53349ad3a250c2cae0fdecd3a3dd5d47e616d8d616af27", + "https://files.pythonhosted.org/packages/bc/29/c238dd9107f10bfde09a4d1c52fd38828b1aa353ced11f358b5dd2507d24/cryptography-45.0.7-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:577470e39e60a6cd7780793202e63536026d9b8641de011ed9d8174da9ca5339", + "https://files.pythonhosted.org/packages/bc/4c/8f57f2500d0ccd2675c5d0cc462095adf3faa8c52294ba085c036befb901/cryptography-45.0.7-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:81823935e2f8d476707e85a78a405953a03ef7b7b4f55f93f7c2d9680e5e0691", + "https://files.pythonhosted.org/packages/bc/ff/026513ecad58dacd45d1d24ebe52b852165a26e287177de1d545325c0c25/cryptography-45.0.7-cp37-abi3-win_amd64.whl": "sha256:7285a89df4900ed3bfaad5679b1e668cb4b38a8de1ccbfc84b05f34512da0a90", + "https://files.pythonhosted.org/packages/be/f3/f9a0173b139372c3a48ed98154b45cc6b9de17c789d5ab552e621c293609/cryptography-50.0.0-cp39-abi3-manylinux_2_31_armv7l.whl": "sha256:828743d939e9629bc267b8e2d08d8bb67cd4319c771a33d4b18b22dd8fb7440a", + "https://files.pythonhosted.org/packages/c2/e6/f60198ea8d9dfa15fff9ed4ca02ce362f6eadd9ba757dcc50634c4257b63/cryptography-49.0.0-cp39-abi3-win_amd64.whl": "sha256:026ac7423e6fa66872d3bf889be5974507da3944f866f704fa200eadacd00001", + "https://files.pythonhosted.org/packages/c3/fb/951032a3bf22a5697c83183fb6294a4843772947a70e616c57b3ff5f522e/cryptography-50.0.0-cp314-cp314t-macosx_11_0_arm64.whl": "sha256:49e7d93abdbd2990caced757e5fade25302f719c3c8fb6e6fff2dde98999fc41", + "https://files.pythonhosted.org/packages/c4/b6/d7696e4e890d6ae1469935164c9e5215c557671cb78d6e3f458ccceaa632/cryptography-49.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl": "sha256:d0527ce944105f257f605a827d6ebead966c752038b6e8656abb9c5edee6fc68", + "https://files.pythonhosted.org/packages/c5/5c/59086b4aac5e879d38ddbcf74e4be7ade89cebc3eb199a55da998c3bb46a/cryptography-50.0.0-cp311-abi3-macosx_11_0_arm64.whl": "sha256:031e2d5dd4bb9caa3ca9c82e5a197fd8ae680232cee62603d1a813f3f07e3d03", + "https://files.pythonhosted.org/packages/c7/1a/15b92b25eb6ce3089cd49377ae990a0f3ad485a510f968aed1f19dbdcdf2/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl": "sha256:62598a8a57f815db4c6259a4e97d857dab56697e7de8e8ab02352ab74da1995d", + "https://files.pythonhosted.org/packages/ca/dc/bd72b26be8953f80625f63151efd38eee71c76ca6cf591c08ff34615a79e/cryptography-50.0.0-cp311-abi3-musllinux_1_2_aarch64.whl": "sha256:1489e263a8048bb8b6a8bac662eb2d402ea5d2b7b4699b72f385f1e2772db105", + "https://files.pythonhosted.org/packages/cd/e3/e7de4771a08620eef2389b86cd87a2c50326827dea5528feb70595439ce4/cryptography-45.0.7-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl": "sha256:465ccac9d70115cd4de7186e60cfe989de73f7bb23e8a7aa45af18f7412e75bf", + "https://files.pythonhosted.org/packages/ce/13/b3cfbd257ac96da4b88b46372e662009b7a16833bfc5da33bb97dd5631ae/cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl": "sha256:d0c5c6bac22b177bf8da7435d9d27a6834ee130309749d162b26c3105c0795a9", + "https://files.pythonhosted.org/packages/d1/63/54dd723490ba2dc09b299682c10b38db38f159728bcaae8c591b8af2f22d/cryptography-50.0.0-cp39-abi3-manylinux_2_28_aarch64.whl": "sha256:e722f16708d854fe924790e051061f6704a472c3bac347b6fd88033ea8dd0dc5", + "https://files.pythonhosted.org/packages/d2/1a/efcfb02f91407149a0dacffffab791f7e19bf6385f63b3666dc8b5e5c9c8/cryptography-50.0.0-cp39-abi3-musllinux_1_2_x86_64.whl": "sha256:65c2c3add92b45fd0709db8594536aea39c2a67af0e27ffcf049c498501140b7", + "https://files.pythonhosted.org/packages/d4/67/91eb047e69c5e845f2f14b8a2e4a1aab0f283cb885531e9e22c8adb176bc/cryptography-50.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:19736989797678c6af1e55cd49055cdbcb55d8f6b5583ac5335f933aba9101dc", + "https://files.pythonhosted.org/packages/d6/a7/f9dac0ab7f80368c56993a7bf638ef9935f825c91902798481fac0898138/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl": "sha256:c83782480a4a9da4d0feb51950131ba32e12e70813848b3343f6e18c28a66838", + "https://files.pythonhosted.org/packages/d7/70/2ba3769dd0ae167e2f33dfa9592d45db6ff9a61d62ca1a5b3d1bdd09068f/cryptography-49.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl": "sha256:b39efa323140595abd3ecca8529d321ae50f55f3aa3ba9cc81ea56a6011953d5", + "https://files.pythonhosted.org/packages/d8/36/83bb81f6e569bc38e1e4a7bc80f29b46bb9601920bc455fc8e888f5d5742/cryptography-50.0.0-cp39-abi3-manylinux_2_34_aarch64.whl": "sha256:2a8183b489dc1f7f80f135780fadc1108f14b31b8a40411c7a5b17425f65f28b", + "https://files.pythonhosted.org/packages/d9/41/029086c34d91052fc3b88bcc8056f709a7c915c7a23b235a54eb800b1c97/cryptography-50.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:06a32a980526a6ab9a4b9bf8f7385800791e2bb960903cb6b530e4817509a3b7", + "https://files.pythonhosted.org/packages/da/3a/f05e32c99d440c9bb891ea0e36c9091891e36be5a9a87ab2ee6ea20729f6/cryptography-50.0.0-cp311-abi3-manylinux_2_34_x86_64.whl": "sha256:82148ec5bddac30b51a5b3c1945075f896fa022cb93f8e4a01e9f6ee95292c5f", + "https://files.pythonhosted.org/packages/de/41/6cbdcf9142d00fe82836fbb51e503e58088575cf7a0fe1dbff6695bf0840/cryptography-50.0.0.tar.gz": "sha256:eeac2acb5a20ed25e0ad6d1df9891a520b78b404266b6d11778f25d5d691a6c9", + "https://files.pythonhosted.org/packages/e4/c0/bff5a02ee731d207d6a1ed51732549d8c53d2bc8da1d10ec6f2844201d68/cryptography-49.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl": "sha256:e3fb64c420688e5319ae25113a354015abbd8dffbfbc41781a1ea66fc7622ac3", + "https://files.pythonhosted.org/packages/e5/45/8aae2972c520145377ea3559a605a899bebe227bf070b33cdb445929a9b9/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl": "sha256:6ba6a53445bd3cfa809ef3ef5f1589aa6ba08784a1d962bf47d0940e871dab1c", + "https://files.pythonhosted.org/packages/e6/8b/43011f7ebe515a8aa20d61f290a326cd890c2e738e16e59eaff8d9c3a412/cryptography-49.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:0e959b578856a3924bc0cbb710fc12c387b9412a951389f3ca61704a9e25f325", + "https://files.pythonhosted.org/packages/e7/84/0e27016a6fc5a0886f797018b26aa42f40c09a82332bff77822a451deaaa/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl": "sha256:b970c6da94d5bb18629db453d14f2a1300f6bf59b61e9b82377931ef95504866", + "https://files.pythonhosted.org/packages/e8/ac/924a723299848b4c741c1059752c7cfe09473b6fd77d2920398fc26bfb53/cryptography-45.0.7-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl": "sha256:ce7a453385e4c4693985b4a4a3533e041558851eae061a58a5405363b098fcd3", + "https://files.pythonhosted.org/packages/eb/ac/59b7790b4ccaed739fc44775ce4645c9b8ce54cbec53edf16c74fd80cb2b/cryptography-45.0.7-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:3994c809c17fc570c2af12c9b840d7cea85a9fd3e5c0e0491f4fa3c029216d59", + "https://files.pythonhosted.org/packages/ec/9e/db72b3ae7fc9cfad53e630e56c6ae83b9b6ff0bf3718ffb8012d20b3aabf/cryptography-49.0.0-cp314-cp314t-macosx_11_0_arm64.whl": "sha256:73a205dce83953d131a4aa1e0fd917a2fd1c5b1eef251e9d7152efefcbf5caf7", + "https://files.pythonhosted.org/packages/f0/ee/6fca21d1ac73e06f8bef71940abfd4d2f6472b4bca284d770f32bd4086f6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_aarch64.whl": "sha256:28d8b15e6275f12c8a207dc309dfa957903c927d08d0cc937ee3f63f200693cc", + "https://files.pythonhosted.org/packages/fa/71/190bf38c3ee2e0f8efc9860ae100c9df4169742eef274b91e7aa1cb133b9/cryptography-50.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl": "sha256:f59e38625469987d7ef6d495323c55e7db6c212eaf6112267e0d3b565a2e9c9f", + "https://files.pythonhosted.org/packages/fc/63/43641c5acce3a6105cf8bd5baeceeb1846bb63067d26dae3e5db59f1513a/cryptography-45.0.7-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:67285f8a611b0ebc0857ced2081e30302909f571a46bfa7a3cc0ad303fe015c6", + "https://files.pythonhosted.org/packages/ff/c6/7a6202a534e32103a285b7834a120869557fe198d51d7cfe59754c8bda9c/cryptography-50.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:910e1d2668e7de9648f2bcee30e180db2a6b15c30f887d7c4c93ddf96e3992e3" + }, + "cssmin": { + "https://files.pythonhosted.org/packages/8e/d8/dc9da69bb186303f7ab41adef0a5b6d34da2fdba006827620877760241c3/cssmin-0.2.0.tar.gz": "sha256:e012f0cc8401efcf2620332339011564738ae32be8c84b2e43ce8beaec1067b6" + }, + "dependatool": { + "https://files.pythonhosted.org/packages/10/a7/60d2555fe674f61c086a5f1047941a53e17fc4fd1e427435b2be5bc997e3/dependatool-0.3.1-py3-none-any.whl": "sha256:265fc69e8b1605edb8e33872a36d3a2c2cc055743bec8e58d1ed3c72a17a9431", + "https://files.pythonhosted.org/packages/1b/51/c429246d60b388ba57c6c1590b1c91841c9ab016a56c392b86ef6e349a74/dependatool-0.3.1.tar.gz": "sha256:6be19ce9fbdffccf639bad0393e454080b7bba8510a98edc78855a6a93895020" + }, + "deprecated": { + "https://files.pythonhosted.org/packages/6e/c6/ac0b6c1e2d138f1002bcf799d330bd6d85084fece321e662a14223794041/Deprecated-1.2.18-py2.py3-none-any.whl": "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec", + "https://files.pythonhosted.org/packages/98/97/06afe62762c9a8a86af0cfb7bfdab22a43ad17138b07af5b1a58442690a2/deprecated-1.2.18.tar.gz": "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d" + }, + "docutils": { + "https://files.pythonhosted.org/packages/32/91/30151a39f7570f448ed84529390628a651d7f27c87d73c9b887f8189695e/docutils-0.23-py3-none-any.whl": "sha256:25d013af9bf23bc1c7b2b093dff4208166c53a94786c9e447808335ef1185fea", + "https://files.pythonhosted.org/packages/39/a4/5180d9afc57e8fca05601dd652bdff19604c218814037fe90ffc7625a50a/docutils-0.23.tar.gz": "sha256:746f5060322511280a1e50eb76846ed6bf2342984b2ac04dc42caa1a8d78799e" + }, + "envoy-base-utils": { + "https://files.pythonhosted.org/packages/bd/98/e3c1a16a299fe399092c45cb91e148c2f99a4a7a551d6729dd411ffc4c3d/envoy_base_utils-0.6.12.tar.gz": "sha256:d2ab511a1f6f59f7319c6dc6b70088bad139be2165466ed9ce6932b0c96faa02", + "https://files.pythonhosted.org/packages/d9/4d/275e6c7033b8b5d4f59216034d98c303feb2d99185da479963e458083699/envoy_base_utils-0.6.12-py3-none-any.whl": "sha256:8b860c9d88493f1eb1044cc48fa9ae953cd31d9da77102d05e9c6af65ff14eae" + }, + "envoy-ci-report": { + "https://files.pythonhosted.org/packages/43/c9/24aceda89afab59b701ea7f9f004c422a9e4adfb63003e086692a3c9a0dc/envoy_ci_report-0.1.1.tar.gz": "sha256:481115be4d05941b83ffbbd8fdac241f10e9823c076f850d8bef7f0308aa382d", + "https://files.pythonhosted.org/packages/85/a8/d694c1b8d931b985f75146f8ac0168f7fe2ece7679a0cf66653efe1c0f22/envoy_ci_report-0.1.1-py3-none-any.whl": "sha256:a38da2e996b266b32ff80f2f404018d1887f156ad086e3fa8fd4233bb4cd6fe7" + }, + "envoy-code-check": { + "https://files.pythonhosted.org/packages/0c/12/b36eed1f6c7402bba14d1567122919aea69beeed312d71b229465eb1826d/envoy_code_check-0.6.9.tar.gz": "sha256:9a212107476b4a36b3743fb550eacad3ede72b3cdbf825dc944c25e48e4e1eb6", + "https://files.pythonhosted.org/packages/7d/4f/c97a5be443f8a3f40cf56864f94d578cfb1b6d500c20e04946713251d347/envoy_code_check-0.6.9-py3-none-any.whl": "sha256:9ded56211e8e81ffc27c97b923e17dd7a6dd60e72454755f07bb1555ca019279" + }, + "envoy-dependency-check": { + "https://files.pythonhosted.org/packages/06/7c/afcea506f6d304321ce8deca1ff7e21e6fc4c34e6431e66409219afb49b3/envoy_dependency_check-0.2.1-py3-none-any.whl": "sha256:a037ab34b7db9893ecf07247c8e9149481148de26f340f1c27e4adfa7a48e227", + "https://files.pythonhosted.org/packages/9d/47/ba5c7e0e202aff1344dfe0e785c545eaf4ce31f1ea5b97533ff83b63dbcf/envoy_dependency_check-0.2.1.tar.gz": "sha256:d91134dc18d2a6a69694623b70a7cb0571647f141a493f0e1bff12d843ec9f7b" + }, + "envoy-distribution-release": { + "https://files.pythonhosted.org/packages/77/dc/ad4b296af95e41dc7446cbf3c421640161461e822c0aa55d1638af0052f6/envoy_distribution_release-0.1.2.tar.gz": "sha256:0a784b46563d2611eb7c68a10c46dbe1821161f0b9fa0018220e5ec373a3b7f3", + "https://files.pythonhosted.org/packages/8f/cd/b9fad02bcd502e87a9a1826786413c9aa7511365130c55d7f36618834c3b/envoy_distribution_release-0.1.2-py3-none-any.whl": "sha256:c15873e88743970143d8ac9fd911bac8cbf34aef6b0315ab78c003a242ef60ef" + }, + "envoy-distribution-verify": { + "https://files.pythonhosted.org/packages/bf/6b/7d8f19343b9729502bf7887feaa6a67d28e3a0436066ca65f77ad640a0ab/envoy_distribution_verify-0.1.1.tar.gz": "sha256:21bf9cbb259c81d953ed768fca9b6d96e65b46c731cc406fe1d3cba5398591bc", + "https://files.pythonhosted.org/packages/e5/81/21dd9002ed06bf2c2580a6dfc90d0a114086ccf903f35544a0486c48427b/envoy_distribution_verify-0.1.1-py3-none-any.whl": "sha256:f96840fd1c2f37f39e72f2a7e9d11d3076f67fe20f598ecc1d96153e19c7b09c" + }, + "envoy-docker-utils": { + "https://files.pythonhosted.org/packages/ad/29/a9f62e03e25a836c42c8bfbcb114e8f37a779ebc8d94522dd3c8aa3a2275/envoy_docker_utils-0.1.1-py3-none-any.whl": "sha256:2375ae633783c07652f42c86e2db190cb34f4d0486468b8a475cf3417a8d67b5", + "https://files.pythonhosted.org/packages/b2/ed/7b7d370490d0d28a385eb33c74462301b1e81a9ffd84634b24200ff2f618/envoy_docker_utils-0.1.1.tar.gz": "sha256:9c3df7ca912972f17469661f56b29cd7785705bf2176606dbfded283dab85f4d" + }, + "envoy-github-release": { + "https://files.pythonhosted.org/packages/09/ef/a3d1770a04cfe43bc4f0072d9ee185dc5e9a9b5b752eb1ed7b57bfd80398/envoy_github_release-0.1.2.tar.gz": "sha256:30f31f1767112719c098b1ea3cdb610fd60719944a1e9c23e94d219c12a626d9", + "https://files.pythonhosted.org/packages/ed/93/2f75721c52f81f3a60be0925b81e1f787bf712188c37c01ac5614a4c9cff/envoy_github_release-0.1.2-py3-none-any.whl": "sha256:4b8c8a6e0df215fd19e45a645b53046ca96d3a490eaa07ba1a2581b9d074ce56" + }, + "feedgenerator": { + "https://files.pythonhosted.org/packages/5e/4e/0efde53652edbae3f86c0ec67260bb53287edc67033ac8d00fe08cd02557/feedgenerator-2.1.0.tar.gz": "sha256:f075f23f28fd227f097c36b212161c6cf012e1c6caaf7ff53d5d6bb02cd42b9d", + "https://files.pythonhosted.org/packages/bd/a1/b7b1711d9bf43c3795366431633ab6ba6942744243aad809272ebfa59b39/feedgenerator-2.1.0-py3-none-any.whl": "sha256:93b7ce1c5a86195cafd6a8e9baf6a2a863ebd6d9905e840ce5778f73efd9a8d5" + }, + "flake8": { + "https://files.pythonhosted.org/packages/9b/af/fbfe3c4b5a657d79e5c47a2827a362f9e1b763336a52f926126aa6dc7123/flake8-7.3.0.tar.gz": "sha256:fe044858146b9fc69b551a4b490d69cf960fcb78ad1edcb84e7fbb1b4a8e3872", + "https://files.pythonhosted.org/packages/9f/56/13ab06b4f93ca7cac71078fbe37fcea175d3216f31f85c3168a6bbd0bb9a/flake8-7.3.0-py2.py3-none-any.whl": "sha256:b9696257b9ce8beb888cdbe31cf885c90d31928fe202be0889a7cdafad32f01e" + }, + "frozendict": { + "https://files.pythonhosted.org/packages/00/a4/10f94462b4c342f27bbd3ef2dfab7dd25260320856baefd2183e05dee6d0/frozendict-2.4.7-cp36-cp36m-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl": "sha256:91a06ee46b3e3ef3b237046b914c0c905eab9fdfeac677e9b51473b482e24c28", + "https://files.pythonhosted.org/packages/02/2b/53465fddfcb8d22ec8ba61940efd8a47fd3ad9e7ce4cf0410147624ce736/frozendict-2.4.7-cp37-cp37m-macosx_10_9_x86_64.whl": "sha256:8ef11dd996208c5a96eab0683f7a17cb4b992948464d2498520efd75a10a2aac", + "https://files.pythonhosted.org/packages/03/73/070efd7a26106b4a22a9e78aa20685c87c4aad6a8af7dc8f790fd7209e9e/frozendict-2.4.7-cp38-cp38-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl": "sha256:f42e2c25d3eee4ea3da88466f38ed0dce8c622a1a9d92572e5ee53b7a6bb9ef1", + "https://files.pythonhosted.org/packages/0a/08/8769e62be061ea1c843b87ab68917c7fbc2dacbd1d8e5b6bcff6bfc8381d/frozendict-2.4.7-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:7ddffe7c0b3be414f88185e212758989c65b497315781290eb029e2c1e1fd64e", + "https://files.pythonhosted.org/packages/0a/77/57c4bd1bcf7e4494bdb5284cb4055536d6505a7256b4d4b9a6e2713daabe/frozendict-2.4.7-cp37-cp37m-win32.whl": "sha256:d10c2ea7c90ba204cd053167ba214d0cdd00f3184c7b8d117a56d7fd2b0c6553", + "https://files.pythonhosted.org/packages/0a/fb/b25a52b04261f03d98d53acdd97fcd6f7b002c76ffe4bf7f270a5950333c/frozendict-2.4.7-cp37-cp37m-musllinux_1_2_x86_64.whl": "sha256:39abe54264ae69a0b2e00fabdb5118604f36a5b927d33e7532cd594c5142ebf4", + "https://files.pythonhosted.org/packages/10/4c/af931d88c51ee2fcbf8c817557dcb975133a188f1b44bfa82caa940beeab/frozendict-2.4.7-cp310-cp310-macosx_11_0_arm64.whl": "sha256:5c1781f28c4bbb177644b3cb6d5cf7da59be374b02d91cdde68d1d5ef32e046b", + "https://files.pythonhosted.org/packages/12/bd/44c2be466baa994cc9138395081e3ca2a4f996b81a8a3419ddd4a49de5d9/frozendict-2.4.7-cp38-cp38-musllinux_1_2_aarch64.whl": "sha256:a265e95e7087f44b88a6d78a63ea95a2ca0eb0a21ab4f76047f4c164a8beb413", + "https://files.pythonhosted.org/packages/12/d1/ed1606feac2a734b6ce3c070913f2d31e568c4802732f2dfe2fb3d508cb2/frozendict-2.4.7-cp38-cp38-win32.whl": "sha256:6991469a889ee8a108fe5ed1b044447c7b7a07da9067e93c59cbfac8c1d625cf", + "https://files.pythonhosted.org/packages/13/29/06bd92d3f8c93c63bec2fd5d9d99d9211f5329ffd960709def12d51ca2f6/frozendict-2.4.7-cp39-cp39-musllinux_1_2_i686.whl": "sha256:78a55f320ca924545494ce153df02d4349156cd95dc4603c1f0e80c42c889249", + "https://files.pythonhosted.org/packages/1b/e6/2bbc456b49dcb6077f3998e806c5cb7bd44050d05908dedd7df2b28afd6b/frozendict-2.4.7-cp37-cp37m-musllinux_1_2_armv7l.whl": "sha256:c93827e0854393cd904b927ceb529afc17776706f5b9e45c7eaf6a40b3fc7b25", + "https://files.pythonhosted.org/packages/21/bd/20198a3df90617f1d126c93521d347f7686681292e20a92e9d8d4396956d/frozendict-2.4.7-cp39-cp39-win_amd64.whl": "sha256:8dfe2f4840b043436ee5bdd07b0fa5daecedf086e6957e7df050a56ab6db078d", + "https://files.pythonhosted.org/packages/25/c2/1536bc363dbce414e6b632f496aa8219c0db459a99eeafa02eba380e4cfa/frozendict-2.4.7-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:294a7d7d51dd979021a8691b46aedf9bd4a594ce3ed33a4bdf0a712d6929d712", + "https://files.pythonhosted.org/packages/26/9e/7702cda30bd38a470d7c2c997af0ea20ecf7ba5e89ab31f35e5e5a4d46d7/frozendict-2.4.7-cp39-cp39-macosx_11_0_arm64.whl": "sha256:11d35075f979c96f528d74ccbf89322a7ef8211977dd566bc384985ebce689be", + "https://files.pythonhosted.org/packages/29/09/6cf62c9917ba30098e74dd76a4e1910a0de424f61c964cda837645f53cac/frozendict-2.4.7-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl": "sha256:fc43257a06e6117da6a8a0779243b974cdb9205fed82e32eb669f6746c75d27d", + "https://files.pythonhosted.org/packages/29/18/6b39d038e4f39a0bffc6ece529a958f5fa27faabc3bd8d0a9696053e2bf5/frozendict-2.4.7-cp36-cp36m-win_amd64.whl": "sha256:ca17ac727ffeeba6c46f5a88e0284a7cb1520fb03127645fcdd7041080adf849", + "https://files.pythonhosted.org/packages/29/63/3e9efb490c00a0bf3c7bbf72fc73c90c4a6ebe30595e0fc44f59182b2ae7/frozendict-2.4.7-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:f65d1b90e9ddc791ea82ef91a9ae0ab27ef6c0cfa88fadfa0e5ca5a22f8fa22f", + "https://files.pythonhosted.org/packages/29/ab/6112c9a59230e8535125e8bba17bd07e65175ed565e681cd496809b9d7d6/frozendict-2.4.7-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:5694417864875ca959932e3b98e2b7d5d27c75177bf510939d0da583712ddf58", + "https://files.pythonhosted.org/packages/29/d3/6bcdb2ede07ca33f354416473ff44215ad3aef2378db49191a6b30ac0d23/frozendict-2.4.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:b22d337c76b765cb7961d4ee47fe29f89e30921eb47bf856b14dc7641f4df3e5", + "https://files.pythonhosted.org/packages/2a/00/2cfc8dac3eb9ba0db8369e98d341a96dde1f774a8081d33ed38601c1ceda/frozendict-2.4.7-cp39-cp39-win_arm64.whl": "sha256:cc2085926872a1b26deda4b81b2254d2e5d2cb2c4d7b327abe4c820b7c93f40b", + "https://files.pythonhosted.org/packages/2a/a9/96d53271dd89166fe670f14ea372fdabc5b8a43f0826b75db5841e62aa5d/frozendict-2.4.7-cp38-cp38-musllinux_1_2_riscv64.whl": "sha256:708382875c3cfe91be625dddcba03dee2dfdadbad2c431568a8c7f2f2af0bbee", + "https://files.pythonhosted.org/packages/2f/99/544787cac16556b32b23f052db5bf0cfe56bd19b243380ddd2c9c18ddd03/frozendict-2.4.7-cp37-cp37m-win_amd64.whl": "sha256:346a53640f15c1640a3503f60ba99df39e4ab174979f10db4304bbb378df5cbd", + "https://files.pythonhosted.org/packages/30/7e/6656361397a7ed2a583385d16431b2b8fd978cc97b297142b8ff1e61770f/frozendict-2.4.7-cp39-cp39-musllinux_1_2_riscv64.whl": "sha256:1e801d62e35df24be2c6f7f43c114058712efa79a8549c289437754dad0207a3", + "https://files.pythonhosted.org/packages/33/fa/255d29f5a5e59f3a5d89ec670888012a2557138bafece65863b306d08c6e/frozendict-2.4.7-cp37-cp37m-musllinux_1_2_ppc64le.whl": "sha256:ec846bde66b75d68518c7b24a0a46d09db0aee5a6aefd2209d9901faf6e9df21", + "https://files.pythonhosted.org/packages/35/46/9b817989997ba549352dd46530bc669738fa94ea1e62111004071e3881a9/frozendict-2.4.7-cp37-cp37m-musllinux_1_2_aarch64.whl": "sha256:830d181781bb263c9fa430b81f82c867546f5dcb368e73931c8591f533a04afb", + "https://files.pythonhosted.org/packages/38/25/097f3c0dc916d7c76f782cb65544e683ff3940a0ed997fc32efdb0989c45/frozendict-2.4.7-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:d774df483c12d6cba896eb9a1337bbc5ad3f564eb18cfaaee3e95fb4402f2a86", + "https://files.pythonhosted.org/packages/38/74/f94141b38a51a553efef7f510fc213894161ae49b88bffd037f8d2a7cb2f/frozendict-2.4.7-py3-none-any.whl": "sha256:972af65924ea25cf5b4d9326d549e69a9a4918d8a76a9d3a7cd174d98b237550", + "https://files.pythonhosted.org/packages/3e/d8/6e33ec7d5c1b81c9719d3d591c15f2b082cf544585b8761a5f87261dcd16/frozendict-2.4.7-cp38-cp38-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:f556ea05d9c5f6dae50d57ce6234e4ab1fbf4551dd0d52b4fed6ef537d9f3d3c", + "https://files.pythonhosted.org/packages/3f/07/71408d8f6870b545a00f98624ba8fb335b47f66f9f1530adbb0ebc9b3fa9/frozendict-2.4.7-cp39-cp39-win32.whl": "sha256:eab9ef8a9268042e819de03079b984eb0894f05a7b63c4e5319b1cf1ef362ba7", + "https://files.pythonhosted.org/packages/40/2b/435583b11f5332cd3eb479d0a67a87bc9247c8b094169b07bd8f0777fc48/frozendict-2.4.7-cp310-cp310-musllinux_1_2_s390x.whl": "sha256:0ff6f57854cc8aa8b30947ec005f9246d96e795a78b21441614e85d39b708822", + "https://files.pythonhosted.org/packages/42/c9/36095b9d5918ba7a9ccbf21be8ce115dd3a7217006ea8b6911655847e6db/frozendict-2.4.7-cp38-cp38-win_amd64.whl": "sha256:ebae8f4a07372acfc3963fc8d68070cdaab70272c3dd836f057ebbe9b7d38643", + "https://files.pythonhosted.org/packages/44/ab/5ceabc7e7284c53b9e63de147fa431ac4435a36e3360131f7e2de6c4a883/frozendict-2.4.7-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:176a66094428b9fd66270927b9787e3b8b1c9505ef92723c7b0ef1923dbe3c4a", + "https://files.pythonhosted.org/packages/46/6b/0cf8ebc2524052ab99a5daabc740e56625f6c72fb49dcb68da2348dfe714/frozendict-2.4.7-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl": "sha256:d4d7ec24d3bfcfac3baf4dffd7fcea3fa8474b087ce32696232132064aa062cf", + "https://files.pythonhosted.org/packages/4d/d9/ddd0be8c406b09b252d552daa3319e8efc495745d4c9ce18b89215dccc60/frozendict-2.4.7-cp36-cp36m-win32.whl": "sha256:2808bab8e21887a8c106cca5f6f0ab5bda7ee81e159409a10f53d57542ccd99c", + "https://files.pythonhosted.org/packages/52/c9/f23966c2e9e4243f7a29dd83396cedbabf65b3dc185432c4b1e9bbf4f707/frozendict-2.4.7-cp39-cp39-musllinux_1_2_aarch64.whl": "sha256:de8d2c98777ba266f5466e211778d4e3bd00635a207c54f6f7511d8613b86dd3", + "https://files.pythonhosted.org/packages/54/28/6dc76479d212581286060b1d1ccc9739cffc57c94e54b5455bddb65a0747/frozendict-2.4.7-cp37-cp37m-musllinux_1_2_i686.whl": "sha256:6d30dbba6eb1497c695f3108c2c292807e7a237c67a1b9ff92c04e89969d22d1", + "https://files.pythonhosted.org/packages/5b/c3/f919c2719a7eca7abf4107430a2d91c7ad2e9ff9f7d55ec015dbbeacef65/frozendict-2.4.7-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:34233deb8d09e798e874a6ac00b054d2e842164d982ebd43eb91b9f0a6a34876", + "https://files.pythonhosted.org/packages/5c/9b/38a762f4e76903efd4340454cac2820f583929457822111ef6a00ff1a3f4/frozendict-2.4.7-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:a4d2b27d8156922c9739dd2ff4f3934716e17cfd1cf6fb61aa17af7d378555e9", + "https://files.pythonhosted.org/packages/5e/66/d25b1e94f9b0e64025d5cadc77b9b857737ebffd8963ee91de7c5a06415a/frozendict-2.4.7-cp310-cp310-musllinux_1_2_armv7l.whl": "sha256:82d5272d08451bcef6fb6235a0a04cf1816b6b6815cec76be5ace1de17e0c1a4", + "https://files.pythonhosted.org/packages/5f/35/dc956462af347eef8cbe2ca3a9b65927af5de9999f3086ad9420095dafed/frozendict-2.4.7-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:739ee81e574f33b46f1e6d9312f3ec2c549bdd574a4ebb6bf106775c9d85ca7b", + "https://files.pythonhosted.org/packages/61/a6/c8686733b5a030131bc0b400222c86c64b481ff06f317403411fc5255311/frozendict-2.4.7-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:d1b4426457757c30ad86b57cdbcc0adaa328399f1ec3d231a0a2ce7447248987", + "https://files.pythonhosted.org/packages/61/d1/6964158524484d7f3410386ff27cbc8f33ef06f8d9ee0e188348efb9a139/frozendict-2.4.7-cp310-cp310-win32.whl": "sha256:a10d38fa300f6bef230fae1fdb4bc98706b78c8a3a2f3140fde748469ef3cfe8", + "https://files.pythonhosted.org/packages/65/c9/3bb916d82c0fd570a60a8f19fc752455c2891d742cb0d8803699a0e6d05d/frozendict-2.4.7-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:57a754671c5746e11140363aa2f4e7a75c8607de6e85a2bf89dcd1daf51885a7", + "https://files.pythonhosted.org/packages/68/0f/6d5ef26b71a143d954b848bc403084155121c7c65b43c9ea256ebbb3b24b/frozendict-2.4.7-cp38-cp38-macosx_11_0_arm64.whl": "sha256:a404857e48d85a517bb5b974d740f8c4fccb25d8df98885f3a2a4d950870b845", + "https://files.pythonhosted.org/packages/68/cf/cd10cacb03e947effbb98ca45f4bba9723ea951ccc4f18574412bf575da3/frozendict-2.4.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:0664092614d2b9d0aa404731f33ad5459a54fe8dab9d1fd45aa714fa6de4d0ef", + "https://files.pythonhosted.org/packages/6d/df/84f6827f1f3c74bab264339eccdaa19f19a22ea146e8e2787520dbd8aeb0/frozendict-2.4.7-cp38-cp38-musllinux_1_2_armv7l.whl": "sha256:1662f1b72b4f4a2ffdfdc4981ece275ca11f90244208ac1f1fc2c17fc9c9437a", + "https://files.pythonhosted.org/packages/70/49/7ffd8424f08025f741010139760728099e90ce1a78befbe4667c401226ba/frozendict-2.4.7-cp39-cp39-musllinux_1_2_armv7l.whl": "sha256:1e307be0e1f26cbc9593f6bdad5238a1408a50f39f63c9c39eb93c7de5926767", + "https://files.pythonhosted.org/packages/71/be/b179b5f200cb0f52debeccc63b786cabcc408c4542f47c4245f978ad36e3/frozendict-2.4.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:4c64d34b802912ee6d107936e970b90750385a1fdfd38d310098b2918ba4cbf2", + "https://files.pythonhosted.org/packages/74/15/41add8c90b965317faf604ded5da0d552df65ad25c9c92a788d16c60da91/frozendict-2.4.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:05dd27415f913cd11649009f53d97eb565ce7b76787d7869c4733738c10e8d27", + "https://files.pythonhosted.org/packages/78/27/9ad439525cf13f6cfaec66183414d47596ad302c56b4c817714829564ba3/frozendict-2.4.7-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:0ece525da7d0aa3eb56c3e479f30612028d545081c15450d67d771a303ee7d4c", + "https://files.pythonhosted.org/packages/79/bc/507c0c690d3c2714a370509260343a1ccf8a1b7a1a3af4124b7e581813c6/frozendict-2.4.7-cp36-cp36m-musllinux_1_2_armv7l.whl": "sha256:176dd384dfe1d0d79449e05f67764c57c6f0f3095378bf00deb33165d5d2df5b", + "https://files.pythonhosted.org/packages/7b/40/c4b80a21eea9be40103c289a17798377695169b88d2d5e713b39cdc16110/frozendict-2.4.7-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:313e0e1d8b22b317aa1f7dd48aec8cbb0416ddd625addf7648a69148fcb9ccff", + "https://files.pythonhosted.org/packages/7e/52/e3e3049ad3773b0bd260e5459553b296848e5cbf4c1d4d924d3b3d2a7de5/frozendict-2.4.7-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:48ab42b01952bc11543577de9fe5d9ca7c41b35dda36326a07fb47d84b3d5f22", + "https://files.pythonhosted.org/packages/7e/61/689212ea4124fcbd097c0ac02c2c6a4e345ccc132d9104d054ff6b43ab64/frozendict-2.4.7-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:75eefdf257a84ea73d553eb80d0abbff0af4c9df62529e4600fd3f96ff17eeb3", + "https://files.pythonhosted.org/packages/82/7d/518c641e093b53403db072756b4ae3b96779434bf3fadb311ee991afcff5/frozendict-2.4.7-cp38-cp38-macosx_10_9_universal2.whl": "sha256:cc520f3f4af14f456143a534d554175dbc0f0636ffd653e63675cd591862a9d9", + "https://files.pythonhosted.org/packages/84/7a/cabf7414e664269ed0fc37da02da45470a94a72e7518a01498b116c78363/frozendict-2.4.7-cp39-cp39-musllinux_1_2_s390x.whl": "sha256:3ed9e2f3547a59f4ef5c233614c6faa6221d33004cb615ae1c07ffc551cfe178", + "https://files.pythonhosted.org/packages/84/84/f53bdd5eda30327c10e00966e2da63cfaac1f9c7a70697754776b8fbd63c/frozendict-2.4.7-cp36-cp36m-macosx_10_9_x86_64.whl": "sha256:735be62d757e1e7e496ccb6401efe82b473faa653e95eec0826cd7819a29a34c", + "https://files.pythonhosted.org/packages/8c/33/0af76558ef89cb5376f67a042e468833f3214478bd91217418ad0221d0e5/frozendict-2.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl": "sha256:e89492dfcc4c27a718f8b5a4c8df1a2dec6c689718cccd70cb2ceba69ab8c642", + "https://files.pythonhosted.org/packages/8d/59/67334a76a394b708f88c0e5f37127b27433b3ac1ea3a94321b94b254bacb/frozendict-2.4.7-cp36-cp36m-musllinux_1_2_i686.whl": "sha256:b1a94e8935c69ae30043b465af496f447950f2c03660aee8657074084faae0b3", + "https://files.pythonhosted.org/packages/90/b2/2a3d1374b7780999d3184e171e25439a8358c47b481f68be883c14086b4c/frozendict-2.4.7.tar.gz": "sha256:e478fb2a1391a56c8a6e10cc97c4a9002b410ecd1ac28c18d780661762e271bd", + "https://files.pythonhosted.org/packages/93/c4/580b7c9da6c36bb63f520444f00509666b81b131191effb82e213abd2081/frozendict-2.4.7-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:fff8584e3bbdc5c1713cd016fbf4b88babfffd4e5e89b39020f2a208dd24c900", + "https://files.pythonhosted.org/packages/94/27/2df17e4c3432635d1546c069ad1db5518dde14bcd1e318ffe86611552033/frozendict-2.4.7-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:115a822ecd754574e11205e0880e9d61258d960863d6fd1b90883aa800f6d3b3", + "https://files.pythonhosted.org/packages/94/27/c22d614332c61ace4406542787edafaf7df533c6f02d1de8979d35492587/frozendict-2.4.7-cp310-cp310-win_amd64.whl": "sha256:dd518f300e5eb6a8827bee380f2e1a31c01dc0af069b13abdecd4e5769bd8a97", + "https://files.pythonhosted.org/packages/9b/77/378da27a6a66ec1def0415ed37de855207a2576d16220c634df3bb50e297/frozendict-2.4.7-cp36-cp36m-musllinux_1_2_x86_64.whl": "sha256:7469912c1a04102457871ff675aebe600dbb7e79a6450a166cc8079b88f6ca79", + "https://files.pythonhosted.org/packages/9e/5d/e072243d6c87cc8ceb0b3de60adcd7960aa1073a33954050938a76ab7277/frozendict-2.4.7-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:fd7ba56cf6340c732ecb78787c4e9600c4bd01372af7313ded21037126d33ec6", + "https://files.pythonhosted.org/packages/a3/5d/0e7e3294e18bf41d38dbc9ee82539be607c8d26e763ae12d9e41f03f2dae/frozendict-2.4.7-cp310-cp310-musllinux_1_2_i686.whl": "sha256:5943c3f683d3f32036f6ca975e920e383d85add1857eee547742de9c1f283716", + "https://files.pythonhosted.org/packages/a6/9c/e3e186925b1d84f816d458be4e2ea785bbeba15fd2e9e85c5ae7e7a90421/frozendict-2.4.7-cp310-cp310-macosx_10_9_x86_64.whl": "sha256:2b96f224a5431889f04b2bc99c0e9abe285679464273ead83d7d7f2a15907d35", + "https://files.pythonhosted.org/packages/a8/db/e971bfb67a797185bd72142d22815b6bf0aa6b15df263974855cc5767aa6/frozendict-2.4.7-cp36-cp36m-musllinux_1_2_ppc64le.whl": "sha256:c570649ceccfa5e11ad9351e9009dc484c315a51a56aa02ced07ae97644bb7aa", + "https://files.pythonhosted.org/packages/ad/1c/d3541d61684e18a9a1dfb5f43e082a8615cbb3a5c874ab51a76916d979b9/frozendict-2.4.7-cp38-cp38-musllinux_1_2_ppc64le.whl": "sha256:2cf0a665bf2f1ce69d3cd8b6d3574b1d32ae00981a16fa1d255d2da8a2e44b7c", + "https://files.pythonhosted.org/packages/ad/b7/e40bfb78606d4f1b39c689489c1c0ee250bbc411f1b638fdcf92b461579a/frozendict-2.4.7-cp38-cp38-musllinux_1_2_x86_64.whl": "sha256:d8930877a2dd40461968d9238d95c754e51b33ce7d2a45500f88ffeed5cb7202", + "https://files.pythonhosted.org/packages/b2/9f/bcae0fa919a680ec287941752a0bdfe2b159f00c088e2677f49d1d42db6b/frozendict-2.4.7-cp39-cp39-musllinux_1_2_x86_64.whl": "sha256:ad0448ed5569f0a9b9b010af9fb5b6d9bdc0b4b877a3ddb188396c4742e62284", + "https://files.pythonhosted.org/packages/b4/af/3a01ecd5475070c9ecfc4ac401f86531a6796e754ed9b5cce5e2972b7398/frozendict-2.4.7-cp38-cp38-musllinux_1_2_s390x.whl": "sha256:7fe194f37052a8f45a1a8507e36229e28b79f3d21542ae55ea6a18c6a444f625", + "https://files.pythonhosted.org/packages/ba/7a/c1fd4f736758cf93939cc3b7c8399fe1db0c121881431d41fcdbae344343/frozendict-2.4.7-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl": "sha256:8a06f6c3d3b8d487226fdde93f621e04a54faecc5bf5d9b16497b8f9ead0ac3e", + "https://files.pythonhosted.org/packages/bc/d8/9d6604357b1816586612e0e89bab6d8a9c029e95e199862dc99ce8ae2ed5/frozendict-2.4.7-cp310-cp310-win_arm64.whl": "sha256:3842cfc2d69df5b9978f2e881b7678a282dbdd6846b11b5159f910bc633cbe4f", + "https://files.pythonhosted.org/packages/bd/b0/304294f7cd099582a98d63e7a9cec34a9905d07f7628b42fc3f9c9a9bc94/frozendict-2.4.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:b809d1c861436a75b2b015dbfd94f6154fa4e7cb0a70e389df1d5f6246b21d1e", + "https://files.pythonhosted.org/packages/be/69/be233a196c36f37af92f4dcc0587d5c7d95620e08e71890eaaf8e17e8d69/frozendict-2.4.7-cp37-cp37m-musllinux_1_2_s390x.whl": "sha256:1df8e22f7d24172c08434b10911f3971434bb5a59b4d1b0078ae33a623625294", + "https://files.pythonhosted.org/packages/c2/02/82f64efc5a27200e1343a8cb04ad56c44b0e1874dde6eb87eff206404286/frozendict-2.4.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:b960e700dc95faca7dd6919d0dce183ef89bfe01554d323cf5de7331a2e80f83", + "https://files.pythonhosted.org/packages/c7/d9/e13af40bd9ef27b5c9ba10b0e31b03acac9468236b878dab030c75102a47/frozendict-2.4.7-cp310-cp310-musllinux_1_2_riscv64.whl": "sha256:ffd1a9f9babec9119712e76a39397d8aa0d72ef8c4ccad917c6175d7e7f81b74", + "https://files.pythonhosted.org/packages/ca/85/7e2ff9bfeca4373363747fd6c8ca88ce215634458824fb15bd1d6370204e/frozendict-2.4.7-cp36-cp36m-musllinux_1_2_s390x.whl": "sha256:e0d450c9d444befe2668bf9386ac2945a2f38152248d58f6b3feea63db59ba08", + "https://files.pythonhosted.org/packages/cb/41/6e86663ec25f305e335734d4710df05d8034695444f9a52b70c51114e5fa/frozendict-2.4.7-cp38-cp38-macosx_10_9_x86_64.whl": "sha256:7fd0d0bd3a79e009dddbf5fedfd927ad495c218cd7b13a112d28a37e2079725c", + "https://files.pythonhosted.org/packages/cc/f4/3af68ca89cf155a185387c628b68392c5ebc7fef4e9404d0d6dbbc0ba277/frozendict-2.4.7-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:57134ef5df1dd32229c148c75a7b89245dbdb89966a155d6dfd4bda653e8c7af", + "https://files.pythonhosted.org/packages/cd/89/2f9851cf1af2e0181b1645797c4338abae16718c92f71995d2ec06c6d812/frozendict-2.4.7-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:a1a083e9ee7a1904e545a6307c7db1dd76200077520fcbf7a98d886f81b57dd7", + "https://files.pythonhosted.org/packages/cf/41/9751e9ec1a2e810e8f961aea4f8958953157478daff6b868277ab7c5ef8c/frozendict-2.4.7-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:2ebd953c41408acfb8041ff9e6c3519c09988fb7e007df7ab6b56e229029d788", + "https://files.pythonhosted.org/packages/d1/1b/e7a923500c6462e85863d499713a5deb385ea6533bb66769b140870b288f/frozendict-2.4.7-cp39-cp39-macosx_10_9_x86_64.whl": "sha256:70e655c3aa5f893807830f549a7275031a181dbebeaf74c461b51adc755d9335", + "https://files.pythonhosted.org/packages/d1/bd/920b1c5ff1df427a5fc3fd4c2f13b0b0e720c3d57fafd80557094c1fefe0/frozendict-2.4.7-cp310-cp310-macosx_10_9_universal2.whl": "sha256:bd37c087a538944652363cfd77fb7abe8100cc1f48afea0b88b38bf0f469c3d2", + "https://files.pythonhosted.org/packages/d5/49/1509f63862979b0f328c58214e7ffa07be8d499b578334e4e1796962f6fb/frozendict-2.4.7-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:76bd99f3508cb2ec87976f2e3fe7d92fb373a661cacffb863013d15e4cfaf0eb", + "https://files.pythonhosted.org/packages/d7/32/a32960b01a81edf73abe1661c33da5fd97ae4b3507d9c6197c0c224df132/frozendict-2.4.7-cp38-cp38-musllinux_1_2_i686.whl": "sha256:2e5d2c30f4a3fea83a14b0a5722f21c10de5c755ab5637c70de5eb60886d58cd", + "https://files.pythonhosted.org/packages/dc/45/a22f6b4d9f244f78d87d7feeb59df343a8562248f17a393d31d5baaee517/frozendict-2.4.7-cp36-cp36m-musllinux_1_2_aarch64.whl": "sha256:c89617a784e1c24a31f5aa4809402f8072a26b64ddbc437897f6391ff69b0ee9", + "https://files.pythonhosted.org/packages/e0/fb/b72c9b261ac7a7803528aa63bba776face8ad8d39cc4ca4825ddaa7777a9/frozendict-2.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl": "sha256:88c6bea948da03087035bb9ca9625305d70e084aa33f11e17048cb7dda4ca293", + "https://files.pythonhosted.org/packages/ea/2c/641c71a84ecbbcba54c5af0dbad18faede9173da5decfca44d4e0d167851/frozendict-2.4.7-cp39-cp39-macosx_10_9_universal2.whl": "sha256:1c521ad3d747aa475e9040e231f5f1847c04423bae5571c010a9d969e6983c40", + "https://files.pythonhosted.org/packages/ee/22/d2f10f153cc18d8577c120eb81d83266c23dd4cb004b7dc18a1efa2a0509/frozendict-2.4.7-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:de1fff2683d8af01299ec01eb21a24b6097ce92015fc1fbefa977cecf076a3fc" + }, + "frozenlist": { + "https://files.pythonhosted.org/packages/01/bc/8d33f2d84b9368da83e69e42720cff01c5e199b5a868ba4486189a4d8fa9/frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl": "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0", + "https://files.pythonhosted.org/packages/05/08/40159d706a6ed983c8aca51922a93fc69f3c27909e82c537dd4054032674/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068", + "https://files.pythonhosted.org/packages/05/6b/e76e740c826acc2ebb5ad5eb06bac15269cd950fc51bd86bbcdbbc04a863/frozenlist-1.4.1-cp38-cp38-win32.whl": "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497", + "https://files.pythonhosted.org/packages/07/eb/71b5531dfb71eb6272b6e2281139d7d46b6adaf43c59850bc8ff64ac1860/frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl": "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826", + "https://files.pythonhosted.org/packages/0b/f2/b8158a0f06faefec33f4dff6345a575c18095a44e52d4f10c678c137d0e0/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd", + "https://files.pythonhosted.org/packages/0c/fa/ef6a96b7757c969b3d7be55c3e70951409509464f5177624d62c894656b6/frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl": "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701", + "https://files.pythonhosted.org/packages/0f/6e/542af762beb9113f13614a590cafe661e0e060cddddee6107c8833605776/frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl": "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9", + "https://files.pythonhosted.org/packages/12/5d/147556b73a53ad4df6da8bbb50715a66ac75c491fdedac3eca8b0b915345/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl": "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82", + "https://files.pythonhosted.org/packages/1a/05/ebad68130e6b6eb9b287dacad08ea357c33849c74550c015b355b75cc714/frozenlist-1.4.1-cp311-cp311-win32.whl": "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17", + "https://files.pythonhosted.org/packages/29/eb/2110c4be2f622e87864e433efd7c4ee6e4f8a59ff2a93c1aa426ee50a8b8/frozenlist-1.4.1-cp39-cp39-win_amd64.whl": "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0", + "https://files.pythonhosted.org/packages/2e/ec/4fb5a88f6b9a352aed45ab824dd7ce4801b7bcd379adcb927c17a8f0a1a8/frozenlist-1.4.1-cp310-cp310-win32.whl": "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1", + "https://files.pythonhosted.org/packages/31/fb/d6dc05b56cc30bf6abef2f2100ff6d6d417c33b956a642d768d5e11b5fdf/frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl": "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09", + "https://files.pythonhosted.org/packages/32/c7/cc0db0d69ee0dbd85fb453650ce86436f15c39a8cde4d2b432fddc77a80e/frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl": "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d", + "https://files.pythonhosted.org/packages/36/ce/dc6f29e0352fa34ebe45421960c8e7352ca63b31630a576e8ffb381e9c08/frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c", + "https://files.pythonhosted.org/packages/37/ff/a613e58452b60166507d731812f3be253eb1229808e59980f0405d1eafbf/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl": "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b", + "https://files.pythonhosted.org/packages/3b/75/30ff63c92b4c561803662bb7e75b5a6863a2af434e6ff05be8a514a41dd2/frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6", + "https://files.pythonhosted.org/packages/3e/dc/96647994a013bc72f3d453abab18340b7f5e222b7b7291e3697ca1fcfbd5/frozenlist-1.4.1-cp312-cp312-win_amd64.whl": "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", + "https://files.pythonhosted.org/packages/3f/ab/c543c13824a615955f57e082c8a5ee122d2d5368e80084f2834e6f4feced/frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl": "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b", + "https://files.pythonhosted.org/packages/43/ec/362807e1682bb0f6a5f34d15994125d72fc7e52fb9b8e4953b13384dcc94/frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d", + "https://files.pythonhosted.org/packages/44/7e/f3177ed74571eb55779bc3c9ac486505ffc4306852f48c6ee5bd82baecb0/frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl": "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0", + "https://files.pythonhosted.org/packages/45/4d/175b16d42daae8013bb1872f6d0870abd87da93e0a36706da4c9ba655d19/frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b", + "https://files.pythonhosted.org/packages/46/03/69eb64642ca8c05f30aa5931d6c55e50b43d0cd13256fdd01510a1f85221/frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl": "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb", + "https://files.pythonhosted.org/packages/4a/32/21329084b61a119ecce0b2942d30312a34a7a0dccd01dcf7b40bda80f22c/frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897", + "https://files.pythonhosted.org/packages/4c/f9/8894c05dc927af2a09663bdf31914d4fb5501653f240a5bbaf1e88cab1d3/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl": "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1", + "https://files.pythonhosted.org/packages/4d/23/7f01123d0e5adcc65cbbde5731378237dea7db467abd19e391f1ddd4130d/frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl": "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d", + "https://files.pythonhosted.org/packages/51/47/159ac53faf8a11ae5ee8bb9db10327575557504e549cfd76f447b969aa91/frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe", + "https://files.pythonhosted.org/packages/53/82/274e19f122e124aee6d113188615f63b0736b4242a875f482a81f91e07e2/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl": "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75", + "https://files.pythonhosted.org/packages/54/72/716a955521b97a25d48315c6c3653f981041ce7a17ff79f701298195bca3/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480", + "https://files.pythonhosted.org/packages/57/0e/63fba1e3a50f2e55d980aa633b8b58062ec7777333aabf0cc3a07a13eb5e/frozenlist-1.4.1-cp38-cp38-win_amd64.whl": "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09", + "https://files.pythonhosted.org/packages/57/15/172af60c7e150a1d88ecc832f2590721166ae41eab582172fe1e9844eab4/frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0", + "https://files.pythonhosted.org/packages/5b/9c/f12b69997d3891ddc0d7895999a00b0c6a67f66f79498c0e30f27876435d/frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl": "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced", + "https://files.pythonhosted.org/packages/5d/e7/b2469e71f082948066b9382c7b908c22552cc705b960363c390d2e23f587/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl": "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74", + "https://files.pythonhosted.org/packages/61/15/2b5d644d81282f00b61e54f7b00a96f9c40224107282efe4cd9d2bf1433a/frozenlist-1.4.1-cp310-cp310-win_amd64.whl": "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439", + "https://files.pythonhosted.org/packages/65/d8/934c08103637567084568e4d5b4219c1016c60b4d29353b1a5b3587827d6/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09", + "https://files.pythonhosted.org/packages/6e/4f/b8a5a2f10c4a58c52a52a40cf6cf1ffcdbf3a3b64f276f41dab989bf3ab5/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl": "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950", + "https://files.pythonhosted.org/packages/70/b0/6f1ebdabfb604e39a0f84428986b89ab55f246b64cddaa495f2c953e1f6b/frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7", + "https://files.pythonhosted.org/packages/70/bb/d3b98d83ec6ef88f9bd63d77104a305d68a146fd63a683569ea44c3085f6/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a", + "https://files.pythonhosted.org/packages/7a/35/1328c7b0f780d34f8afc1d87ebdc2bb065a123b24766a0b475f0d67da637/frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl": "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac", + "https://files.pythonhosted.org/packages/83/10/466fe96dae1bff622021ee687f68e5524d6392b0a2f80d05001cd3a451ba/frozenlist-1.4.1-py3-none-any.whl": "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", + "https://files.pythonhosted.org/packages/83/61/2087bbf24070b66090c0af922685f1d0596c24bb3f3b5223625bdeaf03ca/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl": "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec", + "https://files.pythonhosted.org/packages/8b/c9/a81e9af48291954a883d35686f32308238dc968043143133b8ac9e2772af/frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl": "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8", + "https://files.pythonhosted.org/packages/8c/a4/3dc43e259960ad268ef8f2bf92912c2d2cd2e5275a4838804e03fd6f085f/frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b", + "https://files.pythonhosted.org/packages/90/e4/d205655ac3db4dc1bb96ccb1dd59c0d38d54349408ad840bea85a3dd66e9/frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a", + "https://files.pythonhosted.org/packages/96/86/d5e9cd583aed98c9ee35a3aac2ce4d022ce9de93518e963aadf34a18143b/frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl": "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5", + "https://files.pythonhosted.org/packages/97/94/a1305fa4716726ae0abf3b1069c2d922fcfd442538cb850f1be543f58766/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl": "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98", + "https://files.pythonhosted.org/packages/a0/9f/255b4d34a4f8ff7f31db79406917c403032aa19b39a651ad0a0d6b467317/frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl": "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb", + "https://files.pythonhosted.org/packages/a0/c1/458cf031fc8cd29a751e305b1ec773785ce486106451c93986562c62a21e/frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0", + "https://files.pythonhosted.org/packages/a3/05/50c53f1cdbfdf3d2cb9582a4ea5e12cd939ce33bd84403e6d07744563486/frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl": "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742", + "https://files.pythonhosted.org/packages/a5/c2/e42ad54bae8bcffee22d1e12a8ee6c7717f7d5b5019261a8c861854f4776/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl": "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", + "https://files.pythonhosted.org/packages/a7/76/180ee1b021568dad5b35b7678616c24519af130ed3fa1e0f1ed4014e0f93/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106", + "https://files.pythonhosted.org/packages/a8/be/a235bc937dd803258a370fe21b5aa2dd3e7bfe0287a186a4bec30c6cccd6/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl": "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a", + "https://files.pythonhosted.org/packages/a9/b8/438cfd92be2a124da8259b13409224d9b19ef8f5a5b2507174fc7e7ea18f/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86", + "https://files.pythonhosted.org/packages/ac/6e/e0322317b7c600ba21dec224498c0c5959b2bce3865277a7c0badae340a9/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0", + "https://files.pythonhosted.org/packages/ae/83/bcdaa437a9bd693ba658a0310f8cdccff26bd78e45fccf8e49897904a5cd/frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl": "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776", + "https://files.pythonhosted.org/packages/af/b2/904500d6a162b98a70e510e743e7ea992241b4f9add2c8063bf666ca21df/frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl": "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49", + "https://files.pythonhosted.org/packages/b0/2c/7be3bdc59dbae444864dbd9cde82790314390ec54636baf6b9ce212627ad/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl": "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc", + "https://files.pythonhosted.org/packages/b3/21/c5aaffac47fd305d69df46cfbf118768cdf049a92ee6b0b5cb029d449dcf/frozenlist-1.4.1-cp311-cp311-win_amd64.whl": "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825", + "https://files.pythonhosted.org/packages/b3/c9/0bc5ee7e1f5cc7358ab67da0b7dfe60fbd05c254cea5c6108e7d1ae28c63/frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19", + "https://files.pythonhosted.org/packages/b4/db/4cf37556a735bcdb2582f2c3fa286aefde2322f92d3141e087b8aeb27177/frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl": "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae", + "https://files.pythonhosted.org/packages/b6/61/56bad8cb94f0357c4bc134acc30822e90e203b5cb8ff82179947de90c17f/frozenlist-1.4.1-cp312-cp312-win32.whl": "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", + "https://files.pythonhosted.org/packages/b8/28/899931015b8cffbe155392fe9ca663f981a17e1adc69589ee0e1e7cdc9a2/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl": "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5", + "https://files.pythonhosted.org/packages/b8/3d/cbc6f057f7d10efb7f1f410e458ac090f30526fd110ed2b29bb56ec38fe1/frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl": "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea", + "https://files.pythonhosted.org/packages/b8/d5/35bba11c3f32283996611dbd88c5357b3ff7bcea63509f8e35b62fa9525a/frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887", + "https://files.pythonhosted.org/packages/cc/6e/0091d785187f4c2020d5245796d04213f2261ad097e0c1cf35c44317d517/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl": "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e", + "https://files.pythonhosted.org/packages/cf/3d/2102257e7acad73efc4a0c306ad3953f68c504c16982bbdfee3ad75d8085/frozenlist-1.4.1.tar.gz": "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", + "https://files.pythonhosted.org/packages/d3/fb/6f2a22086065bc16797f77168728f0e59d5b89be76dd184e06b404f1e43b/frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl": "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e", + "https://files.pythonhosted.org/packages/d4/e9/759043ab7d169b74fe05ebfbfa9ee5c881c303ebc838e308346204309cd0/frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a", + "https://files.pythonhosted.org/packages/db/1b/6a5b970e55dffc1a7d0bb54f57b184b2a2a2ad0b7bca16a97ca26d73c5b5/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl": "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2", + "https://files.pythonhosted.org/packages/dc/c9/21abed93eddf089dd0ddd7e09203f2f3dad5d2b784674603a319b0f0c02c/frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl": "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7", + "https://files.pythonhosted.org/packages/e0/18/9f09f84934c2b2aa37d539a322267939770362d5495f37783440ca9c1b74/frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2", + "https://files.pythonhosted.org/packages/ea/a2/20882c251e61be653764038ece62029bfb34bd5b842724fff32a5b7a2894/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl": "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6", + "https://files.pythonhosted.org/packages/ea/db/8b611e23fda75da5311b698730a598df54cfe6236678001f449b1dedb241/frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl": "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6", + "https://files.pythonhosted.org/packages/eb/06/732cefc0c46c638e4426a859a372a50e4c9d62e65dbfa7ddcf0b13e6a4f2/frozenlist-1.4.1-cp39-cp39-win32.whl": "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932", + "https://files.pythonhosted.org/packages/eb/59/e4d3a794b2d9b7ca86a266b61a949f5cccec7a88d818f3b6ad8b80b3ad65/frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl": "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11", + "https://files.pythonhosted.org/packages/ec/25/0c87df2e53c0c5d90f7517ca0ff7aca78d050a8ec4d32c4278e8c0e52e51/frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a", + "https://files.pythonhosted.org/packages/f4/d6/ca016b0adcf8327714ccef969740688808c86e0287bf3a639ff582f24e82/frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl": "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868", + "https://files.pythonhosted.org/packages/f8/ce/b9de7dc61e753dc318cf0de862181b484178210c5361eae6eaf06792264d/frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad" + }, + "gevent": { + "https://files.pythonhosted.org/packages/06/6e/19a9bee9092be45679cb69e4dd2e0bf5f897b7140b4b39c57cc123d24829/gevent-25.9.1-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:8d94936f8f8b23d9de2251798fcb603b84f083fdf0d7f427183c1828fb64f117", + "https://files.pythonhosted.org/packages/07/c0/a7b1f25c42db3c5dc787ea7e23b87ec9a534ca757a25906849b7e7cc765e/gevent-25.9.1-cp39-cp39-musllinux_1_2_x86_64.whl": "sha256:b274a53e818124a281540ebb4e7a2c524778f745b7a99b01bdecf0ca3ac0ddb0", + "https://files.pythonhosted.org/packages/08/75/6bbe57c19a7aa4527cc0f9afcdf5a5f2aed2603b08aadbccb5bf7f607ff4/gevent-25.9.1-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:e4e17c2d57e9a42e25f2a73d297b22b60b2470a74be5a515b36c984e1a246d47", + "https://files.pythonhosted.org/packages/0f/d8/b1178b70538c91493bec283018b47c16eab4bac9ddf5a3d4b7dd905dab60/gevent-25.9.1-cp310-cp310-win_amd64.whl": "sha256:a8ae9f895e8651d10b0a8328a61c9c53da11ea51b666388aa99b0ce90f9fdc27", + "https://files.pythonhosted.org/packages/10/3e/791d1bf1eb47748606d5f2c2aa66571f474d63e0176228b1f1fd7b77ab37/gevent-25.9.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:88b6c07169468af631dcf0fdd3658f9246d6822cc51461d43f7c44f28b0abb82", + "https://files.pythonhosted.org/packages/15/1a/948f8167b2cdce573cf01cec07afc64d0456dc134b07900b26ac7018b37e/gevent-25.9.1-cp314-cp314-macosx_11_0_universal2.whl": "sha256:1a3fe4ea1c312dbf6b375b416925036fe79a40054e6bf6248ee46526ea628be1", + "https://files.pythonhosted.org/packages/1d/6c/bb21fd9c095506aeeaa616579a356aa50935165cc0f1e250e1e0575620a7/gevent-25.9.1-cp311-cp311-win_amd64.whl": "sha256:72152517ecf548e2f838c61b4be76637d99279dbaa7e01b3924df040aa996586", + "https://files.pythonhosted.org/packages/26/8b/6851e9cd3e4f322fa15c1d196cbf1a8a123da69788b078227dd13dd4208f/gevent-25.9.1-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:03c74fec58eda4b4edc043311fca8ba4f8744ad1632eb0a41d5ec25413581975", + "https://files.pythonhosted.org/packages/2e/ae/49bf0a01f95a1c92c001d7b3f482a2301626b8a0617f448c4cd14ca9b5d4/gevent-25.9.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:fe1599d0b30e6093eb3213551751b24feeb43db79f07e89d98dd2f3330c9063e", + "https://files.pythonhosted.org/packages/31/e8/5c1f6968e5547e501cfa03dcb0239dff55e44c3660a37ec534e32a0c008f/gevent-25.9.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:b28b61ff9216a3d73fe8f35669eefcafa957f143ac534faf77e8a19eb9e6883a", + "https://files.pythonhosted.org/packages/35/5d/5f83f17162301662bd1ce702f8a736a8a8cac7b7a35e1d8b9866938d1f9d/gevent-25.9.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:427f869a2050a4202d93cf7fd6ab5cffb06d3e9113c10c967b6e2a0d45237cb8", + "https://files.pythonhosted.org/packages/3c/2e/9d5f204ead343e5b27bbb2fedaec7cd0009d50696b2266f590ae845d0331/gevent-25.9.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:9cdbb24c276a2d0110ad5c978e49daf620b153719ac8a548ce1250a7eb1b9245", + "https://files.pythonhosted.org/packages/49/2a/3010ed6c44179a3a5c5c152e6de43a30ff8bc2c8de3115ad8733533a018f/gevent-25.9.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:2951bb070c0ee37b632ac9134e4fdaad70d2e660c931bb792983a0837fe5b7d7", + "https://files.pythonhosted.org/packages/4c/1e/de96bd033c03955f54c455b51a5127b1d540afcfc97838d1801fafce6d2e/gevent-25.9.1-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:c5fa9ce5122c085983e33e0dc058f81f5264cebe746de5c401654ab96dddfca8", + "https://files.pythonhosted.org/packages/4f/63/0d7f38c4a2085ecce26b50492fc6161aa67250d381e26d6a7322c309b00f/gevent-25.9.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:323a27192ec4da6b22a9e51c3d9d896ff20bc53fdc9e45e56eaab76d1c39dd74", + "https://files.pythonhosted.org/packages/5a/77/b97f086388f87f8ad3e01364f845004aef0123d4430241c7c9b1f9bde742/gevent-25.9.1-cp313-cp313-macosx_11_0_universal2.whl": "sha256:4f84591d13845ee31c13f44bdf6bd6c3dbf385b5af98b2f25ec328213775f2ed", + "https://files.pythonhosted.org/packages/5f/35/f6b3a31f0849a62cfa2c64574bcc68a781d5499c3195e296e892a121a3cf/gevent-25.9.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:1cdf6db28f050ee103441caa8b0448ace545364f775059d5e2de089da975c457", + "https://files.pythonhosted.org/packages/60/45/8b6b68ac1d4ef97ae62058aeaf53be75290bc2d2fb940b2a73dfbf8c3260/gevent-25.9.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:f18f80aef6b1f6907219affe15b36677904f7cfeed1f6a6bc198616e507ae2d7", + "https://files.pythonhosted.org/packages/65/58/7bc52544ea5e63af88c4a26c90776feb42551b7555a1c89c20069c168a3f/gevent-25.9.1-cp314-cp314-musllinux_1_2_x86_64.whl": "sha256:ddd3ff26e5c4240d3fbf5516c2d9d5f2a998ef87cfb73e1429cfaeaaec860fa6", + "https://files.pythonhosted.org/packages/66/1e/75055950aa9b48f553e061afa9e3728061b5ccecca358cef19166e4ab74a/gevent-25.9.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:812debe235a8295be3b2a63b136c2474241fa5c58af55e6a0f8cfc29d4936235", + "https://files.pythonhosted.org/packages/76/24/c0c7c7db70ca74c7b1918388ebda7c8c2a3c3bff0bbfbaa9280ed04b3340/gevent-25.9.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:b56cbc820e3136ba52cd690bdf77e47a4c239964d5f80dc657c1068e0fe9521c", + "https://files.pythonhosted.org/packages/7a/8d/7236c3a8f6ef7e94c22e658397009596fa90f24c7d19da11ad7ab3a9248e/gevent-25.9.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:7a834804ac00ed8a92a69d3826342c677be651b1c3cd66cc35df8bc711057aa2", + "https://files.pythonhosted.org/packages/81/86/03f8db0704fed41b0fa830425845f1eb4e20c92efa3f18751ee17809e9c6/gevent-25.9.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:18e5aff9e8342dc954adb9c9c524db56c2f3557999463445ba3d9cbe3dada7b7", + "https://files.pythonhosted.org/packages/83/cd/cf5e74e353f60dab357829069ffc300a7bb414c761f52cf8c0c6e9728b8d/gevent-25.9.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:c049880175e8c93124188f9d926af0a62826a3b81aa6d3074928345f8238279e", + "https://files.pythonhosted.org/packages/88/3f/266d2eb9f5d75c184a55a39e886b53a4ea7f42ff31f195220a363f0e3f9e/gevent-25.9.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:f0d8b64057b4bf1529b9ef9bd2259495747fba93d1f836c77bfeaacfec373fd0", + "https://files.pythonhosted.org/packages/95/18/da5211dfc54c7a57e7432fd9a6ffeae1ce36fe5a313fa782b1c96529ea3d/gevent-25.9.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:6ea78b39a2c51d47ff0f130f4c755a9a4bbb2dd9721149420ad4712743911a51", + "https://files.pythonhosted.org/packages/9b/ec/726b146d1d3aad82e03d2e1e1507048ab6072f906e83f97f40667866e582/gevent-25.9.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:0adb937f13e5fb90cca2edf66d8d7e99d62a299687400ce2edee3f3504009356", + "https://files.pythonhosted.org/packages/9e/48/b3ef2673ffb940f980966694e40d6d32560f3ffa284ecaeb5ea3a90a6d3f/gevent-25.9.1.tar.gz": "sha256:adf9cd552de44a4e6754c51ff2e78d9193b7fa6eab123db9578a210e657235dd", + "https://files.pythonhosted.org/packages/a6/5a/7bb5ec8e43a2c6444853c4a9f955f3e72f479d7c24ea86c95fb264a2de65/gevent-25.9.1-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:dc45cd3e1cc07514a419960af932a62eb8515552ed004e56755e4bf20bad30c5", + "https://files.pythonhosted.org/packages/a8/40/8acba57c18ab5aacd1a88a82590c7ca43292b710a2265b75ad7056c5225b/gevent-25.9.1-cp39-cp39-win32.whl": "sha256:c6c91f7e33c7f01237755884316110ee7ea076f5bdb9aa0982b6dc63243c0a38", + "https://files.pythonhosted.org/packages/aa/88/63dc9e903980e1da1e16541ec5c70f2b224ec0a8e34088cb42794f1c7f52/gevent-25.9.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:f2b54ea3ca6f0c763281cd3f96010ac7e98c2e267feb1221b5a26e2ca0b9a692", + "https://files.pythonhosted.org/packages/ae/c7/2c60fc4e5c9144f2b91e23af8d87c626870ad3183cfd09d2b3ba6d699178/gevent-25.9.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:856b990be5590e44c3a3dc6c8d48a40eaccbb42e99d2b791d11d1e7711a4297e", + "https://files.pythonhosted.org/packages/c0/2c/ebc5d38a7542af9fb7657bfe10932a558bb98c8a94e4748e827d3823fced/gevent-25.9.1-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:5e4b6278b37373306fc6b1e5f0f1cf56339a1377f67c35972775143d8d7776ff", + "https://files.pythonhosted.org/packages/c2/69/a7c4ba2ffbc7c7dbf6d8b4f5d0f0a421f7815d229f4909854266c445a3d4/gevent-25.9.1-cp314-cp314-win_amd64.whl": "sha256:bb63c0d6cb9950cc94036a4995b9cc4667b8915366613449236970f4394f94d7", + "https://files.pythonhosted.org/packages/ca/4f/50de9afd879440e25737e63f5ba6ee764b75a3abe17376496ab57f432546/gevent-25.9.1-cp313-cp313-win_amd64.whl": "sha256:eb51c5f9537b07da673258b4832f6635014fee31690c3f0944d34741b69f92fa", + "https://files.pythonhosted.org/packages/ca/d4/b63a0a60635470d7d986ef19897e893c15326dd69e8fb342c76a4f07fe9e/gevent-25.9.1-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:34e01e50c71eaf67e92c186ee0196a039d6e4f4b35670396baed4a2d8f1b347f", + "https://files.pythonhosted.org/packages/d5/98/caf06d5d22a7c129c1fb2fc1477306902a2c8ddfd399cd26bbbd4caf2141/gevent-25.9.1-cp312-cp312-win_amd64.whl": "sha256:4acd6bcd5feabf22c7c5174bd3b9535ee9f088d2bbce789f740ad8d6554b18f3", + "https://files.pythonhosted.org/packages/dd/65/b9a4526d4a4edce26fe4b3b993914ec9dc64baabad625a3101e51adb17f3/gevent-25.9.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:b5a67a0974ad9f24721034d1e008856111e0535f1541499f72a733a73d658d1c", + "https://files.pythonhosted.org/packages/e5/be/7d35731dfaf8370795b606e515d964a0967e129db76ea7873f552045dd39/gevent-25.9.1-cp314-cp314-musllinux_1_2_aarch64.whl": "sha256:1d0f5d8d73f97e24ea8d24d8be0f51e0cf7c54b8021c1fddb580bf239474690f", + "https://files.pythonhosted.org/packages/e6/26/e1d7d6c8ffbf76fe1fbb4e77bdb7f47d419206adc391ec40a8ace6ebbbf0/gevent-25.9.1-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:d99f0cb2ce43c2e8305bf75bee61a8bde06619d21b9d0316ea190fc7a0620a56", + "https://files.pythonhosted.org/packages/f2/5c/9ad0229b2b4d81249ca41e4f91dd8057deaa0da6d4fbe40bf13cdc5f7a47/gevent-25.9.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:b7bb0e29a7b3e6ca9bed2394aa820244069982c36dc30b70eb1004dd67851a48", + "https://files.pythonhosted.org/packages/f3/06/7e576ec64711778fa6fd40a5ee7c5311052bf2dee107ea31c6a5b63c1e2f/gevent-25.9.1-cp39-cp39-win_amd64.whl": "sha256:012a44b0121f3d7c800740ff80351c897e85e76a7e4764690f35c5ad9ec17de5", + "https://files.pythonhosted.org/packages/f7/49/e55930ba5259629eb28ac7ee1abbca971996a9165f902f0249b561602f24/gevent-25.9.1-cp312-cp312-macosx_11_0_universal2.whl": "sha256:46b188248c84ffdec18a686fcac5dbb32365d76912e14fda350db5dc0bfd4f86" + }, + "gidgethub": { + "https://files.pythonhosted.org/packages/35/d4/6374d7a1d276ec23f5bc71a2571d36824cd121693cc2eaefa04484c02551/gidgethub-5.4.0.tar.gz": "sha256:7470d7723d7c1743471a2d62e79c8752fba12b1c0972e4bad57252338a501dbd", + "https://files.pythonhosted.org/packages/70/48/847be03638905119b9310d15057d18f923c0ec5c846381d2fa2ccc1b7c54/gidgethub-5.4.0-py3-none-any.whl": "sha256:522bd3a846a315c3163925a840930c4c9a0d685d5853afe852fd589cb472daf5" + }, + "gitdb": { + "https://files.pythonhosted.org/packages/19/0d/bbb5b5ee188dec84647a4664f3e11b06ade2bde568dbd489d9d64adef8ed/gitdb-4.0.11.tar.gz": "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b", + "https://files.pythonhosted.org/packages/fd/5b/8f0c4a5bb9fd491c277c21eff7ccae71b47d43c4446c9d0c6cff2fe8c2c4/gitdb-4.0.11-py3-none-any.whl": "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4" + }, + "gitpython": { + "https://files.pythonhosted.org/packages/d6/0b/29d7965215f8ef830a7ca1f42997fe13e5693d85e9edb18f938d063ef5f2/gitpython-3.1.62-py3-none-any.whl": "sha256:7002251225e10e29d2e1f49e6532613fe5d5d9f0b6f1f02997a52b38fe56899e", + "https://files.pythonhosted.org/packages/e0/db/3ca813cbacb23ab6fe46ff38a9b5ef8e73e970c8051f2ce903aacafe0446/gitpython-3.1.62.tar.gz": "sha256:1791de66309bc0c7cfca40bf8d2e3de7ca091cbf94e6051be1ad0722c61062af" + }, + "google-auth": { + "https://files.pythonhosted.org/packages/9d/47/603554949a37bca5b7f894d51896a9c534b9eab808e2520a748e081669d0/google_auth-2.38.0-py2.py3-none-any.whl": "sha256:e7dae6694313f434a2727bf2906f27ad259bae090d7aa896590d86feec3d9d4a", + "https://files.pythonhosted.org/packages/c6/eb/d504ba1daf190af6b204a9d4714d457462b486043744901a6eeea711f913/google_auth-2.38.0.tar.gz": "sha256:8285113607d3b80a3f1543b75962447ba8a09fe85783432a784fdeef6ac094c4" + }, + "googleapis-common-protos": { + "https://files.pythonhosted.org/packages/20/18/a746c8344152d368a5aac738d4c857012f2c5d1fd2eac7e17b647a7861bd/googleapis_common_protos-1.74.0.tar.gz": "sha256:57971e4eeeba6aad1163c1f0fc88543f965bb49129b8bb55b2b7b26ecab084f1", + "https://files.pythonhosted.org/packages/b6/b0/be5d3329badb9230b765de6eea66b73abd5944bdeb5afb3562ddcd80ae84/googleapis_common_protos-1.74.0-py3-none-any.whl": "sha256:702216f78610bb510e3f12ac3cafd281b7ac45cc5d86e90ad87e4d301a3426b5" + }, + "greenlet": { + "https://files.pythonhosted.org/packages/03/b8/704d753a5a45507a7aab61f18db9509302ed3d0a27ac7e0359ec2905b1a6/greenlet-3.2.4.tar.gz": "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d", + "https://files.pythonhosted.org/packages/09/16/2c3792cba130000bf2a31c5272999113f4764fd9d874fb257ff588ac779a/greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246", + "https://files.pythonhosted.org/packages/0b/55/2321e43595e6801e105fcfdee02b34c0f996eb71e6ddffca6b10b7e1d771/greenlet-3.2.4-cp313-cp313-win_amd64.whl": "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b", + "https://files.pythonhosted.org/packages/0d/da/343cd760ab2f92bac1845ca07ee3faea9fe52bee65f7bcb19f16ad7de08b/greenlet-3.2.4-cp314-cp314-musllinux_1_2_x86_64.whl": "sha256:015d48959d4add5d6c9f6c5210ee3803a830dce46356e3bc326d6776bde54681", + "https://files.pythonhosted.org/packages/19/0d/6660d55f7373b2ff8152401a83e02084956da23ae58cddbfb0b330978fe9/greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl": "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0", + "https://files.pythonhosted.org/packages/1c/53/f9c440463b3057485b8594d7a638bed53ba531165ef0ca0e6c364b5cc807/greenlet-3.2.4-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:6e343822feb58ac4d0a1211bd9399de2b3a04963ddeec21530fc426cc121f19b", + "https://files.pythonhosted.org/packages/1f/8e/abdd3f14d735b2929290a018ecf133c901be4874b858dd1c604b9319f064/greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl": "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8", + "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl": "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", + "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl": "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", + "https://files.pythonhosted.org/packages/25/5d/382753b52006ce0218297ec1b628e048c4e64b155379331f25a7316eb749/greenlet-3.2.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:0db5594dce18db94f7d1650d7489909b57afde4c580806b8d9203b6e79cdc079", + "https://files.pythonhosted.org/packages/27/45/80935968b53cfd3f33cf99ea5f08227f2646e044568c9b1555b58ffd61c2/greenlet-3.2.4-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:ee7a6ec486883397d70eec05059353b8e83eca9168b9f3f9a361971e77e0bcd0", + "https://files.pythonhosted.org/packages/2a/fc/102ec1a2fc015b3a7652abab7acf3541d58c04d3d17a8d3d6a44adae1eb1/greenlet-3.2.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:94385f101946790ae13da500603491f04a76b6e4c059dab271b3ce2e283b2590", + "https://files.pythonhosted.org/packages/31/da/0386695eef69ffae1ad726881571dfe28b41970173947e7c558d9998de0f/greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9", + "https://files.pythonhosted.org/packages/3b/16/035dcfcc48715ccd345f3a93183267167cdd162ad123cd93067d86f27ce4/greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968", + "https://files.pythonhosted.org/packages/3f/c7/12381b18e21aef2c6bd3a636da1088b888b97b7a0362fac2e4de92405f97/greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl": "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f", + "https://files.pythonhosted.org/packages/3f/cc/b07000438a29ac5cfb2194bfc128151d52f333cee74dd7dfe3fb733fc16c/greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl": "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa", + "https://files.pythonhosted.org/packages/44/69/9b804adb5fd0671f367781560eb5eb586c4d495277c93bde4307b9e28068/greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl": "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd", + "https://files.pythonhosted.org/packages/46/e9/d2a80c99f19a153eff70bc451ab78615583b8dac0754cfb942223d2c1a0d/greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb", + "https://files.pythonhosted.org/packages/47/e4/3bb4240abdd0a8d23f4f88adec746a3099f0d86bfedb623f063b2e3b4df0/greenlet-3.2.4-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:ca7f6f1f2649b89ce02f6f229d7c19f680a6238af656f61e0115b24857917929", + "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl": "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", + "https://files.pythonhosted.org/packages/4b/bf/7bd33643e48ed45dcc0e22572f650767832bd4e1287f97434943cc402148/greenlet-3.2.4-cp39-cp39-musllinux_1_2_aarch64.whl": "sha256:28a3c6b7cd72a96f61b0e4b2a36f681025b60ae4779cc73c1535eb5f29560b10", + "https://files.pythonhosted.org/packages/4d/f5/33f05dc3ba10a02dedb1485870cf81c109227d3d3aa280f0e48486cac248/greenlet-3.2.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:27890167f55d2387576d1f41d9487ef171849ea0359ce1510ca6e06c8bece11d", + "https://files.pythonhosted.org/packages/5d/65/deb2a69c3e5996439b0176f6651e0052542bb6c8f8ec2e3fba97c9768805/greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl": "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52", + "https://files.pythonhosted.org/packages/5f/d3/844e714a9bbd39034144dca8b658dcd01839b72bb0ec7d8014e33e3705f0/greenlet-3.2.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:16458c245a38991aa19676900d48bd1a6f2ce3e16595051a4db9d012154e8433", + "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", + "https://files.pythonhosted.org/packages/66/71/1928e2c80197353bcb9b50aa19c4d8e26ee6d7a900c564907665cf4b9a41/greenlet-3.2.4-cp39-cp39-musllinux_1_1_x86_64.whl": "sha256:81701fd84f26330f0d5f4944d4e92e61afe6319dcd9775e39396e39d7c3e5f98", + "https://files.pythonhosted.org/packages/67/24/28a5b2fa42d12b3d7e5614145f0bd89714c34c08be6aabe39c14dd52db34/greenlet-3.2.4-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:c9c6de1940a7d828635fbd254d69db79e54619f165ee7ce32fda763a9cb6a58c", + "https://files.pythonhosted.org/packages/68/88/69bf19fd4dc19981928ceacbc5fd4bb6bc2215d53199e367832e98d1d8fe/greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6", + "https://files.pythonhosted.org/packages/69/02/b7c30e5e04752cb4db6202a3858b149c0710e5453b71a3b2aec5d78a1aab/greenlet-3.2.4-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:326d234cbf337c9c3def0676412eb7040a35a768efc92504b947b3e9cfc7543d", + "https://files.pythonhosted.org/packages/6a/05/03f2f0bdd0b0ff9a4f7b99333d57b53a7709c27723ec8123056b084e69cd/greenlet-3.2.4-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:03c5136e7be905045160b1b9fdca93dd6727b180feeafda6818e6496434ed8c5", + "https://files.pythonhosted.org/packages/6b/4c/f3de2a8de0e840ecb0253ad0dc7e2bb3747348e798ec7e397d783a3cb380/greenlet-3.2.4-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl": "sha256:c9913f1a30e4526f432991f89ae263459b1c64d1608c0d22a5c79c287b3c70df", + "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl": "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", + "https://files.pythonhosted.org/packages/7d/ed/6bfa4109fcb23a58819600392564fea69cdc6551ffd5e69ccf1d52a40cbc/greenlet-3.2.4-cp310-cp310-macosx_11_0_universal2.whl": "sha256:8c68325b0d0acf8d91dde4e6f930967dd52a5302cd4062932a6b2e7c2969f47c", + "https://files.pythonhosted.org/packages/7f/3b/3a3328a788d4a473889a2d403199932be55b1b0060f4ddd96ee7cdfcad10/greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504", + "https://files.pythonhosted.org/packages/7f/91/ae2eb6b7979e2f9b035a9f612cf70f1bf54aad4e1d125129bef1eae96f19/greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl": "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d", + "https://files.pythonhosted.org/packages/89/48/a5dc74dde38aeb2b15d418cec76ed50e1dd3d620ccda84d8199703248968/greenlet-3.2.4-cp39-cp39-win32.whl": "sha256:65458b409c1ed459ea899e939f0e1cdb14f58dbc803f2f93c5eab5694d32671b", + "https://files.pythonhosted.org/packages/89/80/7332915adc766035c8980b161c2e5d50b2f941f453af232c164cff5e0aeb/greenlet-3.2.4-cp39-cp39-musllinux_1_1_aarch64.whl": "sha256:b90654e092f928f110e0007f572007c9727b5265f7632c2fa7415b4689351594", + "https://files.pythonhosted.org/packages/8e/1a/c953fdedd22d81ee4629afbb38d2f9d71e37d23caace44775a3a969147d4/greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl": "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0", + "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", + "https://files.pythonhosted.org/packages/9b/74/4bc433f91d0d09a1c22954a371f9df928cb85e72640870158853a83415e5/greenlet-3.2.4-cp39-cp39-musllinux_1_2_x86_64.whl": "sha256:52206cd642670b0b320a1fd1cbfd95bca0e043179c1d8a045f2c6109dfe973be", + "https://files.pythonhosted.org/packages/9f/7c/e7833dbcd8f376f3326bd728c845d31dcde4c84268d3921afcae77d90d08/greenlet-3.2.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:c8c9e331e58180d0d83c5b7999255721b725913ff6bc6cf39fa2a45841a4fd4b", + "https://files.pythonhosted.org/packages/a1/8d/88f3ebd2bc96bf7747093696f4335a0a8a4c5acfcf1b757717c0d2474ba3/greenlet-3.2.4-cp310-cp310-musllinux_1_1_x86_64.whl": "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f", + "https://files.pythonhosted.org/packages/a2/15/0d5e4e1a66fab130d98168fe984c509249c833c1a3c16806b90f253ce7b9/greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl": "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae", + "https://files.pythonhosted.org/packages/a4/de/f28ced0a67749cac23fecb02b694f6473f47686dff6afaa211d186e2ef9c/greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl": "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2", + "https://files.pythonhosted.org/packages/ae/8f/95d48d7e3d433e6dae5b1682e4292242a53f22df82e6d3dda81b1701a960/greenlet-3.2.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3", + "https://files.pythonhosted.org/packages/b2/a7/9476decef51a0844195f99ed5dc611d212e9b3515512ecdf7321543a7225/greenlet-3.2.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:18d9260df2b5fbf41ae5139e1be4e796d99655f023a636cd0e11e6406cca7d58", + "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl": "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", + "https://files.pythonhosted.org/packages/bd/e0/849b9159cbb176f8c0af5caaff1faffdece7a8417fcc6fe1869770e33e21/greenlet-3.2.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:671df96c1f23c4a0d4077a325483c1503c96a1b7d9db26592ae770daa41233d4", + "https://files.pythonhosted.org/packages/c0/aa/687d6b12ffb505a4447567d1f3abea23bd20e73a5bed63871178e0831b7a/greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5", + "https://files.pythonhosted.org/packages/c5/26/80383131d55a4ac0fb08d71660fd77e7660b9db6bdb4e8884f46d9f2cc04/greenlet-3.2.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:f10fd42b5ee276335863712fa3da6608e93f70629c631bf77145021600abc23c", + "https://files.pythonhosted.org/packages/c8/e2/1572b8eeab0f77df5f6729d6ab6b141e4a84ee8eb9bc8c1e7918f94eda6d/greenlet-3.2.4-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:af41be48a4f60429d5cad9d22175217805098a9ef7c40bfef44f7669fb9d74d8", + "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", + "https://files.pythonhosted.org/packages/d5/5e/405965351aef8c76b8ef7ad370e5da58d57ef6068df197548b015464001a/greenlet-3.2.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:4d1378601b85e2e5171b99be8d2dc85f594c79967599328f95c1dc1a40f1c633", + "https://files.pythonhosted.org/packages/d6/6f/b60b0291d9623c496638c582297ead61f43c4b72eef5e9c926ef4565ec13/greenlet-3.2.4-cp310-cp310-win_amd64.whl": "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c", + "https://files.pythonhosted.org/packages/d8/0f/30aef242fcab550b0b3520b8e3561156857c94288f0332a79928c31a52cf/greenlet-3.2.4-cp311-cp311-win_amd64.whl": "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9", + "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", + "https://files.pythonhosted.org/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl": "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01", + "https://files.pythonhosted.org/packages/e5/44/342c4591db50db1076b8bda86ed0ad59240e3e1da17806a4cf10a6d0e447/greenlet-3.2.4-cp39-cp39-win_amd64.whl": "sha256:d2e685ade4dafd447ede19c31277a224a239a0a1a4eca4e6390efedf20260cfb", + "https://files.pythonhosted.org/packages/e9/08/b0814846b79399e585f974bbeebf5580fbe59e258ea7be64d9dfb253c84f/greenlet-3.2.4-cp312-cp312-win_amd64.whl": "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02", + "https://files.pythonhosted.org/packages/e9/49/547b93b7c0428ede7b3f309bc965986874759f7d89e4e04aeddbc9699acb/greenlet-3.2.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:58b97143c9cc7b86fc458f215bd0932f1757ce649e05b640fea2e79b54cedb31", + "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl": "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", + "https://files.pythonhosted.org/packages/f1/29/74242b7d72385e29bcc5563fba67dad94943d7cd03552bac320d597f29b2/greenlet-3.2.4-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:f47617f698838ba98f4ff4189aef02e7343952df3a615f847bb575c3feb177a7", + "https://files.pythonhosted.org/packages/f2/d6/6adde57d1345a8d0f14d31e4ab9c23cfe8e2cd39c3baf7674b4b0338d266/greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a", + "https://files.pythonhosted.org/packages/f7/0b/bc13f787394920b23073ca3b6c4a7a21396301ed75a655bcb47196b50e6e/greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc", + "https://files.pythonhosted.org/packages/f7/85/433de0c9c0252b22b16d413c9407e6cb3b41df7389afc366ca204dbc1393/greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl": "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5", + "https://files.pythonhosted.org/packages/f7/c0/93885c4106d2626bf51fdec377d6aef740dfa5c4877461889a7cf8e565cc/greenlet-3.2.4-cp39-cp39-macosx_11_0_universal2.whl": "sha256:b6a7c19cf0d2742d0809a4c05975db036fdff50cd294a93632d6a310bf9ac02c" + }, + "humanfriendly": { + "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz": "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", + "https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl": "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477" + }, + "hyperlink": { + "https://files.pythonhosted.org/packages/3a/51/1947bd81d75af87e3bb9e34593a4cf118115a8feb451ce7a69044ef1412e/hyperlink-21.0.0.tar.gz": "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b", + "https://files.pythonhosted.org/packages/6e/aa/8caf6a0a3e62863cbb9dab27135660acba46903b703e224f14f447e57934/hyperlink-21.0.0-py2.py3-none-any.whl": "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4" + }, + "icalendar": { + "https://files.pythonhosted.org/packages/47/2b/1bbf82d316df18c3331d9a06228819c8a5814ceda545a3e9980e52ffce1b/icalendar-7.3.0.tar.gz": "sha256:7bd001c8e648205e1bde5c6a5b77096598e8d0893dcf57755c6c597635620132", + "https://files.pythonhosted.org/packages/bb/82/50bff78b0bb0c7d7c0cb39e0ee189b92f611fff6bd7cf57f25e92d5a7551/icalendar-7.3.0-py3-none-any.whl": "sha256:8355acfe17be81b368f0b1e3740817cea9b56ea889931f8f1a87c62f2d28db0b" + }, + "id": { + "https://files.pythonhosted.org/packages/42/77/de194443bf38daed9452139e960c632b0ef9f9a5dd9ce605fdf18ca9f1b1/id-1.6.1-py3-none-any.whl": "sha256:f5ec41ed2629a508f5d0988eda142e190c9c6da971100612c4de9ad9f9b237ca", + "https://files.pythonhosted.org/packages/6d/04/c2156091427636080787aac190019dc64096e56a23b7364d3c1764ee3a06/id-1.6.1.tar.gz": "sha256:d0732d624fb46fd4e7bc4e5152f00214450953b9e772c182c1c22964def1a069" + }, + "idna": { + "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl": "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", + "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl": "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", + "https://files.pythonhosted.org/packages/82/77/7b3966d0b9d1d31a36ddf1746926a11dface89a83409bf1483f0237aa758/idna-3.15.tar.gz": "sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc", + "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz": "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", + "https://files.pythonhosted.org/packages/d2/23/408243171aa9aaba178d3e2559159c24c1171a641aa83b67bdd3394ead8e/idna-3.15-py3-none-any.whl": "sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8", + "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz": "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9" + }, + "importlib-metadata": { + "https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl": "sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7", + "https://files.pythonhosted.org/packages/a0/d9/a1e041c5e7caa9a05c925f4bdbdfb7f006d1f74996af53467bc394c97be7/importlib_metadata-8.5.0-py3-none-any.whl": "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b", + "https://files.pythonhosted.org/packages/a9/01/15bb152d77b21318514a96f43af312635eb2500c96b55398d020c93d86ea/importlib_metadata-9.0.0.tar.gz": "sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc", + "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz": "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7" + }, + "incremental": { + "https://files.pythonhosted.org/packages/0d/38/221e5b2ae676a3938c2c1919131410c342b6efc2baffeda395dd66eeca8f/incremental-24.7.2-py3-none-any.whl": "sha256:8cb2c3431530bec48ad70513931a760f446ad6c25e8333ca5d95e24b0ed7b8fe", + "https://files.pythonhosted.org/packages/27/87/156b374ff6578062965afe30cc57627d35234369b3336cf244b240c8d8e6/incremental-24.7.2.tar.gz": "sha256:fb4f1d47ee60efe87d4f6f0ebb5f70b9760db2b2574c59c8e8912be4ebd464c9" + }, + "jaraco-classes": { + "https://files.pythonhosted.org/packages/06/c0/ed4a27bc5571b99e3cff68f8a9fa5b56ff7df1c2251cc715a652ddd26402/jaraco.classes-3.4.0.tar.gz": "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", + "https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl": "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790" + }, + "jaraco-context": { + "https://files.pythonhosted.org/packages/af/50/4763cd07e722bb6285316d390a164bc7e479db9d90daa769f22578f698b4/jaraco_context-6.1.2.tar.gz": "sha256:f1a6c9d391e661cc5b8d39861ff077a7dc24dc23833ccee564b234b81c82dfe3", + "https://files.pythonhosted.org/packages/f2/58/bc8954bda5fcda97bd7c19be11b85f91973d67a706ed4a3aec33e7de22db/jaraco_context-6.1.2-py3-none-any.whl": "sha256:bf8150b79a2d5d91ae48629d8b427a8f7ba0e1097dd6202a9059f29a36379535" + }, + "jaraco-functools": { + "https://files.pythonhosted.org/packages/02/36/ecc85bc96c273dc8a11273ed4782272975e6338d4a3e9228621175edf0e3/jaraco_functools-4.6.0-py3-none-any.whl": "sha256:99e3dc0060c5cbe8fcd1cdb36258e2a65ca40f1566b2033b12abb1bb44dd3c30", + "https://files.pythonhosted.org/packages/6c/1f/c23395957d41ccf27c4e535c3d334c4051e5395b3752057ba4cbaec35c56/jaraco_functools-4.6.0.tar.gz": "sha256:880c577ec9720b3a052d5bc611fb9f2269b3d87902ef42440df443b88e443280" + }, + "jeepney": { + "https://files.pythonhosted.org/packages/7b/6f/357efd7602486741aa73ffc0617fb310a29b588ed0fd69c2399acbb85b0c/jeepney-0.9.0.tar.gz": "sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732", + "https://files.pythonhosted.org/packages/b2/a3/e137168c9c44d18eff0376253da9f1e9234d0239e0ee230d2fee6cea8e55/jeepney-0.9.0-py3-none-any.whl": "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683" + }, + "jinja2": { + "https://files.pythonhosted.org/packages/20/9a/e5d9ec41927401e41aea8af6d16e78b5e612bca4699d417f646a9610a076/Jinja2-3.0.3-py3-none-any.whl": "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8", + "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl": "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", + "https://files.pythonhosted.org/packages/91/a5/429efc6246119e1e3fbf562c00187d04e83e54619249eb732bb423efa6c6/Jinja2-3.0.3.tar.gz": "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7", + "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz": "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d" + }, + "keyring": { + "https://files.pythonhosted.org/packages/43/4b/674af6ef2f97d56f0ab5153bf0bfa28ccb6c3ed4d1babf4305449668807b/keyring-25.7.0.tar.gz": "sha256:fe01bd85eb3f8fb3dd0405defdeac9a5b4f6f0439edbb3149577f244a2e8245b", + "https://files.pythonhosted.org/packages/81/db/e655086b7f3a705df045bf0933bdd9c2f79bb3c97bfef1384598bb79a217/keyring-25.7.0-py3-none-any.whl": "sha256:be4a0b195f149690c166e850609a477c532ddbfbaed96a404d4e43f8d5e2689f" + }, + "libsass": { + "https://files.pythonhosted.org/packages/55/2f/6af938651ff3aec0a0b00742209df1172bc297fa73531f292801693b7315/libsass-0.23.0-cp38-abi3-macosx_14_0_arm64.whl": "sha256:ea97d1b45cdc2fc3590cb9d7b60f1d8915d3ce17a98c1f2d4dd47ee0d9c68ce6", + "https://files.pythonhosted.org/packages/79/b4/ab091585eaa77299558e3289ca206846aefc123fb320b5656ab2542c20ad/libsass-0.23.0.tar.gz": "sha256:6f209955ede26684e76912caf329f4ccb57e4a043fd77fe0e7348dd9574f1880", + "https://files.pythonhosted.org/packages/e5/13/fc1bea1de880ca935137183727c7d4dd921c4128fc08b8ddc3698ba5a8a3/libsass-0.23.0-cp38-abi3-macosx_11_0_x86_64.whl": "sha256:34cae047cbbfc4ffa832a61cbb110f3c95f5471c6170c842d3fed161e40814dc", + "https://files.pythonhosted.org/packages/e5/fc/275783f5120970d859ae37d04b6a60c13bdec2aa4294b9dfa8a37b5c2513/libsass-0.23.0-cp38-abi3-win32.whl": "sha256:31e86d92a5c7a551df844b72d83fc2b5e50abc6fbbb31e296f7bebd6489ed1b4", + "https://files.pythonhosted.org/packages/ef/20/caf3c7cf2432d85263119798c45221ddf67bdd7dae8f626d14ff8db04040/libsass-0.23.0-cp38-abi3-win_amd64.whl": "sha256:a2ec85d819f353cbe807432d7275d653710d12b08ec7ef61c124a580a8352f3c", + "https://files.pythonhosted.org/packages/fd/5a/eb5b62641df0459a3291fc206cf5bd669c0feed7814dded8edef4ade8512/libsass-0.23.0-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.whl": "sha256:4a218406d605f325d234e4678bd57126a66a88841cb95bee2caeafdc6f138306" + }, + "markdown": { + "https://files.pythonhosted.org/packages/29/6f/da4c6aea59b3001f2e8c0ec7497475aadaf3b021c10cab5b2858f0f32b26/markdown-3.10.3.tar.gz": "sha256:3589362618f743188b4d955b874402bc814f4f83f544dc207719f4baa7d9c45f", + "https://files.pythonhosted.org/packages/64/69/4a5af2bc115a9a33fefe51709749de8262be3f9ba063d1753a837cdbc49c/markdown-3.10.3-py3-none-any.whl": "sha256:fa6c92a00a4a3c98b22728c64a935ae1928250ae65058a6ded814d2cc29a4cea" + }, + "markdown-it-py": { + "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz": "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", + "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz": "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", + "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl": "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl": "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a" + }, + "markupsafe": { + "https://files.pythonhosted.org/packages/00/0b/23f4b2470accb53285c613a3ab9ec19dc944eaf53592cb6d9e2af8aa24cc/MarkupSafe-2.1.5-cp311-cp311-win32.whl": "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", + "https://files.pythonhosted.org/packages/02/8c/ab9a463301a50dab04d5472e998acbd4080597abc048166ded5c7aa768c8/MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl": "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", + "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", + "https://files.pythonhosted.org/packages/0a/7b/85681ae3c33c385b10ac0f8dd025c30af83c78cec1c37a6aa3b55e67f5ec/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", + "https://files.pythonhosted.org/packages/0b/cc/48206bd61c5b9d0129f4d75243b156929b04c94c09041321456fd06a876d/MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl": "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", + "https://files.pythonhosted.org/packages/0c/40/2e73e7d532d030b1e41180807a80d564eda53babaf04d65e15c1cf897e40/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", + "https://files.pythonhosted.org/packages/0e/7d/968284145ffd9d726183ed6237c77938c021abacde4e073020f920e060b2/MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl": "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", + "https://files.pythonhosted.org/packages/0f/31/780bb297db036ba7b7bbede5e1d7f1e14d704ad4beb3ce53fb495d22bc62/MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl": "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", + "https://files.pythonhosted.org/packages/11/e7/291e55127bb2ae67c64d66cef01432b5933859dfb7d6949daa721b89d0b3/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl": "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", + "https://files.pythonhosted.org/packages/18/46/5dca760547e8c59c5311b332f70605d24c99d1303dd9a6e1fc3ed0d73561/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl": "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", + "https://files.pythonhosted.org/packages/1c/cf/35fe557e53709e93feb65575c93927942087e9b97213eabc3fe9d5b25a55/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", + "https://files.pythonhosted.org/packages/29/fe/a36ba8c7ca55621620b2d7c585313efd10729e63ef81e4e61f52330da781/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", + "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", + "https://files.pythonhosted.org/packages/2f/69/30d29adcf9d1d931c75001dd85001adad7374381c9c2086154d9f6445be6/MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl": "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", + "https://files.pythonhosted.org/packages/30/39/8d845dd7d0b0613d86e0ef89549bfb5f61ed781f59af45fc96496e897f3a/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl": "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", + "https://files.pythonhosted.org/packages/3a/03/63498d05bd54278b6ca340099e5b52ffb9cdf2ee4f2d9b98246337e21689/MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl": "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", + "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl": "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", + "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl": "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", + "https://files.pythonhosted.org/packages/4a/1d/c4f5016f87ced614eacc7d5fb85b25bcc0ff53e8f058d069fc8cbfdc3c7a/MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", + "https://files.pythonhosted.org/packages/4c/6f/f2b0f675635b05f6afd5ea03c094557bdb8622fa8e673387444fe8d8e787/MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68", + "https://files.pythonhosted.org/packages/4f/14/6f294b9c4f969d0c801a4615e221c1e084722ea6114ab2114189c5b8cbe0/MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl": "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", + "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", + "https://files.pythonhosted.org/packages/51/e0/393467cf899b34a9d3678e78961c2c8cdf49fb902a959ba54ece01273fb1/MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl": "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", + "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl": "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", + "https://files.pythonhosted.org/packages/5f/5a/360da85076688755ea0cceb92472923086993e86b5613bbae9fbc14136b0/MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", + "https://files.pythonhosted.org/packages/60/ae/9c60231cdfda003434e8bd27282b1f4e197ad5a710c14bee8bea8a9ca4f0/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl": "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", + "https://files.pythonhosted.org/packages/65/dc/1510be4d179869f5dafe071aecb3f1f41b45d37c02329dfba01ff59e5ac5/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl": "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", + "https://files.pythonhosted.org/packages/68/79/11b4fe15124692f8673b603433e47abca199a08ecd2a4851bfbdc97dc62d/MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl": "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", + "https://files.pythonhosted.org/packages/69/48/acbf292615c65f0604a0c6fc402ce6d8c991276e16c80c46a8f758fbd30c/MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl": "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", + "https://files.pythonhosted.org/packages/6a/18/ae5a258e3401f9b8312f92b028c54d7026a97ec3ab20bfaddbdfa7d8cce8/MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", + "https://files.pythonhosted.org/packages/6a/4a/a4d49415e600bacae038c67f9fecc1d5433b9d3c71a4de6f33537b89654c/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl": "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", + "https://files.pythonhosted.org/packages/6b/cb/aed7a284c00dfa7c0682d14df85ad4955a350a21d2e3b06d8240497359bf/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl": "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", + "https://files.pythonhosted.org/packages/6c/4c/3577a52eea1880538c435176bc85e5b3379b7ab442327ccd82118550758f/MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl": "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", + "https://files.pythonhosted.org/packages/6c/77/d77701bbef72892affe060cdacb7a2ed7fd68dae3b477a8642f15ad3b132/MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl": "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", + "https://files.pythonhosted.org/packages/6d/c5/27febe918ac36397919cd4a67d5579cbbfa8da027fa1238af6285bb368ea/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl": "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", + "https://files.pythonhosted.org/packages/7c/52/2b1b570f6b8b803cef5ac28fdf78c0da318916c7d2fe9402a84d591b394c/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", + "https://files.pythonhosted.org/packages/81/d4/fd74714ed30a1dedd0b82427c02fa4deec64f173831ec716da11c51a50aa/MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", + "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz": "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", + "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl": "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", + "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl": "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", + "https://files.pythonhosted.org/packages/92/21/357205f03514a49b293e214ac39de01fadd0970a6e05e4bf1ddd0ffd0881/MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl": "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", + "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl": "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", + "https://files.pythonhosted.org/packages/97/18/c30da5e7a0e7f4603abfc6780574131221d9148f323752c2755d48abad30/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", + "https://files.pythonhosted.org/packages/a7/88/a940e11827ea1c136a34eca862486178294ae841164475b9ab216b80eb8e/MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl": "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", + "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl": "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", + "https://files.pythonhosted.org/packages/b3/fb/c18b8c9fbe69e347fdbf782c6478f1bc77f19a830588daa224236678339b/MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", + "https://files.pythonhosted.org/packages/b7/a2/c78a06a9ec6d04b3445a949615c4c7ed86a0b2eb68e44e7541b9d57067cc/MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl": "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", + "https://files.pythonhosted.org/packages/bc/29/9bc18da763496b055d8e98ce476c8e718dcfd78157e17f555ce6dd7d0895/MarkupSafe-2.1.5-cp39-cp39-win32.whl": "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", + "https://files.pythonhosted.org/packages/bf/f3/ecb00fc8ab02b7beae8699f34db9357ae49d9f21d4d3de6f305f34fa949e/MarkupSafe-2.1.5-cp38-cp38-win32.whl": "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", + "https://files.pythonhosted.org/packages/c7/5c/356a6f62e4f3c5fbf2602b4771376af22a3b16efa74eb8716fb4e328e01e/MarkupSafe-2.1.5-cp310-cp310-win32.whl": "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", + "https://files.pythonhosted.org/packages/c7/bd/50319665ce81bb10e90d1cf76f9e1aa269ea6f7fa30ab4521f14d122a3df/MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", + "https://files.pythonhosted.org/packages/cb/06/0d28bd178db529c5ac762a625c335a9168a7a23f280b4db9c95e97046145/MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", + "https://files.pythonhosted.org/packages/d1/06/a41c112ab9ffdeeb5f77bc3e331fdadf97fa65e52e44ba31880f4e7f983c/MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl": "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", + "https://files.pythonhosted.org/packages/d9/a7/1e558b4f78454c8a3a0199292d96159eb4d091f983bc35ef258314fe7269/MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", + "https://files.pythonhosted.org/packages/e4/54/ad5eb37bf9d51800010a74e4665425831a9db4e7c4e0fde4352e391e808e/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl": "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", + "https://files.pythonhosted.org/packages/ed/88/408bdbf292eb86f03201c17489acafae8358ba4e120d92358308c15cea7c/MarkupSafe-2.1.5-cp37-cp37m-win32.whl": "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", + "https://files.pythonhosted.org/packages/f6/02/5437e2ad33047290dafced9df741d9efc3e716b75583bbd73a9984f1b6f7/MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl": "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", + "https://files.pythonhosted.org/packages/f6/f8/4da07de16f10551ca1f640c92b5f316f9394088b183c6a57183df6de5ae4/MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl": "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", + "https://files.pythonhosted.org/packages/f8/81/56e567126a2c2bc2684d6391332e357589a96a76cb9f8e5052d85cb0ead8/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl": "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", + "https://files.pythonhosted.org/packages/f8/ff/2c942a82c35a49df5de3a630ce0a8456ac2969691b230e530ac12314364c/MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl": "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a" + }, + "mccabe": { + "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl": "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", + "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz": "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325" + }, + "mdurl": { + "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl": "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz": "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + }, + "more-itertools": { + "https://files.pythonhosted.org/packages/de/1d/f4da6f02cdffe04d6362210b807146a26044c88d839208aec273bb0d9184/more_itertools-11.1.0.tar.gz": "sha256:48e8f4d9e7e5878571ecf6f2b4e57634f93cd474cc8cfbd2376f2d11b396e30d", + "https://files.pythonhosted.org/packages/e8/3d/1087453384dbde46a8c7f9356eead2c58be8a7bf156bca40243377c85715/more_itertools-11.1.0-py3-none-any.whl": "sha256:4b65538ae22f6fed0ce4874efd317463a7489796a0939fa66824dd542125a192" + }, + "multidict": { + "https://files.pythonhosted.org/packages/00/8d/e93bc0dc947c7f872e502cfaa7ad9d98f001e1c93cfa6f4940457a6e187a/multidict-6.9.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:7a0c98f6a636adf0d7edd60c61589eaf52d149239af754d0bfeb0effedba53a8", + "https://files.pythonhosted.org/packages/01/ab/0120a650d7ce4fe167299c13a13cc4ee2dc72458a9c0e9e9330b824b73c9/multidict-6.9.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:0dd655518f136febd96c05131a76a863e32fc2a1d7acd4e3c959e3ceb77d8345", + "https://files.pythonhosted.org/packages/02/8b/b2c2805c3eb6fa4cdf5512fb95ac6174dde71e34dd601c5be52f4df5dc82/multidict-6.9.1-cp315-cp315t-win_amd64.whl": "sha256:e96ca64383efa107262ee3949f047af5ee4f1845ba09463466c04d35a83bd3ec", + "https://files.pythonhosted.org/packages/04/15/f28c71af461dd4ff15653a165cfd8ddaf01f3387ff80d2dd0de057d527d0/multidict-6.9.1-cp315-cp315-macosx_11_0_arm64.whl": "sha256:7c708566da8014b120a64b1eb6d200c6c0c8cb36296383723cdb6fc82038270b", + "https://files.pythonhosted.org/packages/05/0d/e44b90d9e77e44ec3473c4c7ac7ea95764d7e8fbf6d5a085ef9bff7ce0c2/multidict-6.9.1-cp311-cp311-musllinux_1_2_armv7l.whl": "sha256:658f90f49cf5af2441cad0a2b801c3ef520471989a1ec55bcb25b255b2ca8d2f", + "https://files.pythonhosted.org/packages/08/64/4f2a5eeea10b6d42634ba168ec6efc732ef218772e57b8239cd485c202f6/multidict-6.9.1-cp314-cp314t-macosx_10_15_universal2.whl": "sha256:0b2fb8c349d1103863750b5d8cb5ace766917f4b35f3d883c8f778853eaa9f76", + "https://files.pythonhosted.org/packages/0d/16/9642ae41fbfbdc546aa481c2b07ae1bc087a94ab5f5020b4d9ab77da401f/multidict-6.9.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:b66ccc5c2cdd26e74fa5d4c29ffae424cc6148bf93ce574821783fb3b6d452c5", + "https://files.pythonhosted.org/packages/0e/87/8b7016d1084854729c80acfae71c5a51ea7e7c9411d66c3e2729772f5723/multidict-6.9.1-cp310-cp310-musllinux_1_2_armv7l.whl": "sha256:1c9f3c25df6c9d3bbae4f6fd3f514b1c5c740a2110f56ccf36069c85417e289c", + "https://files.pythonhosted.org/packages/14/48/628b978413518159228c2b2ec38645362ceb6427e935d83d716e26490a49/multidict-6.9.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:d73fed4e37158ff00cd271871170b79e40138db51e625fd352fa17c6acb34f67", + "https://files.pythonhosted.org/packages/15/10/d8aac5acacbe7f5c117866c776ec26d5f15a868759b6f37ad8e7ed3b5b02/multidict-6.9.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:e58952f04772f59f11c6e007471449809a30165188669bca8fdb19dde40a8f24", + "https://files.pythonhosted.org/packages/15/f4/7ea4a907e053e924e2e1694d90560f79f72056504bfd5e8483695f9527d2/multidict-6.9.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:963a8d8f97057082679523d0fd4c53a38f86bc58cabe4556faef682ae53fa2fa", + "https://files.pythonhosted.org/packages/17/1b/b958f06aac2d8b1e485eb1c105b1b159cbf3868249e5142142451577dad2/multidict-6.9.1-cp313-cp313-macosx_10_13_universal2.whl": "sha256:8f2973bbd2bebd9d2e0cd6394c1292a1a19ccd56bdcbe1e174059f1a39be5b40", + "https://files.pythonhosted.org/packages/19/0a/714f796f7293a8b1c5c3f465a26996231d5450c54e85d64ef1258c091134/multidict-6.9.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:d35a4f1c63f07fbb8c8f9946dea98b21eddf6c57421585f71d91864be3ba2a24", + "https://files.pythonhosted.org/packages/19/bd/057fdff5f4e04dcd40a960e38f77d19d3c4b67dd243ffa5f43718edb29fc/multidict-6.9.1-cp312-cp312-musllinux_1_2_riscv64.whl": "sha256:63ada7ee2e9345695f9e9bc4c65d72222253f07b1ac94fd0e37555cc6f3c7f60", + "https://files.pythonhosted.org/packages/19/de/5ee4050c3ddad88c605a89fc1cd18e89abd40a64f183e6fb5276b6eb7f52/multidict-6.9.1-cp315-cp315-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl": "sha256:042fb0196047e786936a730bd302de83143950da45f2c16078da8f35e1cf7919", + "https://files.pythonhosted.org/packages/1a/5f/ade05795c6fb9adfccd61695a0f0509bc793583f589c4b1b87f27215a139/multidict-6.9.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:c9648ed33dc8179e4ec04bbc73bd7f0038e1e81217a69467f61f02a78bf07e88", + "https://files.pythonhosted.org/packages/1d/1e/c32ddf53234c228b1a374ddabca19f542ac7f32752f5155982abe2304833/multidict-6.9.1-cp314-cp314t-musllinux_1_2_i686.whl": "sha256:372c063f37480f62c1ae32dc3a1a0a5942b180c883f99789075a8a8ec3c4e709", + "https://files.pythonhosted.org/packages/1d/b6/96b93808e1bec0b51d49d89859e49b82a94f7b2e58eca0fc44ffcafd3ae5/multidict-6.9.1-cp314-cp314-musllinux_1_2_aarch64.whl": "sha256:7814bbee202acd3bd240204c17d8b87a4c48c81064fd8674dbe527d94d5a4290", + "https://files.pythonhosted.org/packages/1e/44/78e366efc6c004185295cc9eb9711c10f13eadf3b547603b9c5526329976/multidict-6.9.1-cp313-cp313-musllinux_1_2_ppc64le.whl": "sha256:b65121091567847a8cb520d364ab22ba90e00d3cc55fa9eb34bb439f0684bcd1", + "https://files.pythonhosted.org/packages/1e/7d/4665cad8fc326787d218879be879d86dfe32f006c1f88ae47b04d3b52fd5/multidict-6.9.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:9d0a21cf76153de8f2d96a877991d6bc59b9ab5180b949e50db73cc193b4a694", + "https://files.pythonhosted.org/packages/1f/6e/420e9e879b21cbdb5036214ee238efabcfab7bf262d3fc124132050f79ff/multidict-6.9.1-cp314-cp314t-musllinux_1_2_s390x.whl": "sha256:23136f5a564654eb61061ec6d5620a4c1ea32c8f552b65e9982a12b72bff601b", + "https://files.pythonhosted.org/packages/22/a6/eab8aaf59892169a0f4e8e78a5516a6caa6abd8e96e6410111258f4ef0ef/multidict-6.9.1-cp315-cp315-musllinux_1_2_armv7l.whl": "sha256:40aec5299e1ed71fbb988389059da381c3c1a60e0c649acceb2a35d9b128848e", + "https://files.pythonhosted.org/packages/23/db/95bd0afb130a0149c955f1f066143528d60864e64f41ff5a1e1313609361/multidict-6.9.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl": "sha256:024123f0ab402ab33828e24eb80fa8f25167d0d3783ba5f287e39ed741e6abf9", + "https://files.pythonhosted.org/packages/24/14/10b1ded0a4085a51c3054125f854da4f47ce4fec724a2d2503231b83f3db/multidict-6.9.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:13849a1d4f54c3809ae721e9e83ab28f5ea602f33660cb84eb6ef261eac706c1", + "https://files.pythonhosted.org/packages/24/79/0969a9b38b814e5fa3af1b0a57708c49b3d9b3d55c208bac6e98b87bb028/multidict-6.9.1-cp314-cp314t-musllinux_1_2_armv7l.whl": "sha256:ca65cced0d67a9039e93bcd98a369920e499bf98296844ff56ead01c9085321f", + "https://files.pythonhosted.org/packages/27/50/f420de3683f9b047fc5588064d84043ef57a7152ef451b8373dfc7068d22/multidict-6.9.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:e8f1e362c9352b50ed120f001046fdbb80810c9d56580f4c3fc13bbe30823387", + "https://files.pythonhosted.org/packages/29/f2/f0ff3384a756227741c72f4ee94cadf1f9900df0ae961e48639f96115b1c/multidict-6.9.1-cp314-cp314t-win32.whl": "sha256:35ba0263bae5dd3ad5aad767cc9afc01a8598c7dae30f1b3b2de98b1b32c28bd", + "https://files.pythonhosted.org/packages/2b/f3/9fc997861920bdbf70db82bdce5c802ec6477754c4bd78cff2898e3c63f9/multidict-6.9.1-cp310-cp310-musllinux_1_2_ppc64le.whl": "sha256:8ed78ccad4c7b421804f5d524b7740946a7ef75d89dc0dac52e9d7c24c472410", + "https://files.pythonhosted.org/packages/2d/00/bf59d6bb22a4c152e4039574c29490caf3c65107715121807b4bd7cde244/multidict-6.9.1-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:b828cf64d62dc09ac183f03c1aeedd164ade96a2ce4934109452edf29de1dd13", + "https://files.pythonhosted.org/packages/2d/58/72a3e8d56c1e05146d2d1841dbaacf8986375eded1e5a58d30eef191a580/multidict-6.9.1-cp315-cp315t-musllinux_1_2_ppc64le.whl": "sha256:abc7c2e4b47bfe6a9aea434d3fdebb9597ee636e914e92ba352f2068b9142f4c", + "https://files.pythonhosted.org/packages/2e/09/7e6ebaecc4e226d7fe27973c271d58b75c14c24e84c23736d21dc39997dd/multidict-6.9.1-cp314-cp314t-musllinux_1_2_riscv64.whl": "sha256:9b0124b9c17e9890f0819b2e7a5f65ec9a2f5aabd6c8e7ad090c1675cf70dee6", + "https://files.pythonhosted.org/packages/2f/3e/b96779dcac28ec6d491fd821112a0156b519b6701bba186cdf6f6df737f4/multidict-6.9.1-cp314-cp314-macosx_10_15_x86_64.whl": "sha256:db4d697b18b6ef5528b1f36bfa25072cd2a421869f5963bc0e92c8a34b9e2800", + "https://files.pythonhosted.org/packages/2f/52/5464a2675579e3adb48b7cd4707a59da499660f0e22c024bc7281d2d9bdf/multidict-6.9.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:ad4528cdce058b684f75fad1faf4a6a6c992fe2f08376370ca66e4ce5916a84a", + "https://files.pythonhosted.org/packages/32/ce/c68d08ac2096c1528ff20d77fd10f7e401db3e534ac5a1c7726e36a77c2f/multidict-6.9.1-cp314-cp314t-macosx_10_15_x86_64.whl": "sha256:56d834b74c993a7d7cb2b8ab33a0d55c3e0d4a3d2f2da2808a4ad3d79189711b", + "https://files.pythonhosted.org/packages/33/50/df96f961b178b621ab0adbf9221d4fd21534e1064fd9f5e85c1fa27fea55/multidict-6.9.1-cp313-cp313-musllinux_1_2_armv7l.whl": "sha256:9e14d17773b1b3c758ff153659a1824608a0cb562c45f484b5ed8a433428444a", + "https://files.pythonhosted.org/packages/33/51/0de5fc980df34d1ffed9ef68f60ce86c2d4baa3d422598a53f8730c56757/multidict-6.9.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:4736d350371337825cac1793c9f7c40701c32a03912548c2a7608e51679cbb96", + "https://files.pythonhosted.org/packages/33/81/014bb2128aedc8157d2848f0ec8a0209c6b822fb88deea012834e1c4a4e8/multidict-6.9.1-cp314-cp314-win_amd64.whl": "sha256:acddcac38adc8342ba48aba98896faa7928854bebb62542362138655b5367ee3", + "https://files.pythonhosted.org/packages/33/92/cf6d665a45663bbe216420fe632da10e9f4f842b07ce02bc3ddf8eb882b8/multidict-6.9.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:9c62e71e6289d78c0108d8aeb495f8bd3cad4bc1632fedddc9297ddf287ecc20", + "https://files.pythonhosted.org/packages/34/1d/da27bdd49b0cb84263288f5f48dbd915f2d17fd228fee2078ca607e80277/multidict-6.9.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:0f3bd290711c6e9486173a6ee7cd4e7f00c3971c7908c1ec1b6e5437c5e4c6f9", + "https://files.pythonhosted.org/packages/36/eb/6ae44062466c26c8469ef43f2481a6a48d8cea0587b2d54514ec92e2adfd/multidict-6.9.1-cp312-cp312-macosx_11_0_arm64.whl": "sha256:6ed30be8918e18c8bed0a2e8b70639ecf02feb61ed00ca2e41cfcb2a50fa3f42", + "https://files.pythonhosted.org/packages/38/eb/fd56c9d83ba0cdc3cf66f9acb278b24ef1f043b620b96d145685a3b57338/multidict-6.9.1-cp315-cp315t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl": "sha256:38c9986f9ce50c459b10de216a05f4bd7ed5ac63887d56e500a52bb464b861ce", + "https://files.pythonhosted.org/packages/39/3e/80bd4729635a7af371ff4dcc312594cf96e73f98854491be8740792de430/multidict-6.9.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:3adf06c66041aa21eeb8a71e82379b74773298c8e6d3d839b151aae441a99b94", + "https://files.pythonhosted.org/packages/3a/3c/f27f4f045198bf1c4bcd6eb3b6cf06be2dceaceb6e67222b903fce7a6749/multidict-6.9.1-cp311-cp311-win32.whl": "sha256:2c1aeb92eea59d824f004341b26d5e4b47a8a441cf9726769b9a90abf9d0e08f", + "https://files.pythonhosted.org/packages/3a/9a/9f5c270c88fe289b4876fe28f9932a70e015a7916aff1e5b0325f7597b11/multidict-6.9.1-cp314-cp314t-macosx_11_0_arm64.whl": "sha256:783ba7d845d79ce976afd9c1e91a4e5714671defa198ee789e8b23316083a485", + "https://files.pythonhosted.org/packages/3d/25/f3539b5bdc147beba66015795dfe589eedcc580348fb1a8c69b1df4196b5/multidict-6.9.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:b4c9e5d05b126b267ac048a89a0e2d9b48b1b648add62d4872906304a8590610", + "https://files.pythonhosted.org/packages/3d/db/0922594c601a691eb4365a83f4f92104ef87a9728d8066fa25c99349e754/multidict-6.9.1-cp310-cp310-musllinux_1_2_s390x.whl": "sha256:bc94a68ea5e18f8e85dc6b522bcb53093f692c8eb62b4837ac047da73956cbe4", + "https://files.pythonhosted.org/packages/3f/24/61be5fe1616d033532e8d63dc789c0f35b9793917834713eefe050589ba9/multidict-6.9.1-cp315-cp315-musllinux_1_2_aarch64.whl": "sha256:877ca17fdcfdf5c397493a71e5ff97a87bb181417fe717fdadc77c08c09301ac", + "https://files.pythonhosted.org/packages/3f/de/9ace933ee8dad808632523726f42255b09600087219e3d4ead7369820910/multidict-6.9.1-cp312-cp312-musllinux_1_2_s390x.whl": "sha256:3c95601ed98fad3f6e2f8fe809c3b526b0fab31ef525e00a155e227f3d17f58a", + "https://files.pythonhosted.org/packages/41/01/e1e9abe27f492b22dede492bc423015597412b14ce074f7475f4ecd80185/multidict-6.9.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:e7386aa18d98d6b8af44b92173654ec469237fda35f8e8523e43b581a86f476a", + "https://files.pythonhosted.org/packages/42/b1/d1e14bab80a74babf6e2ac971a878b84fdcf3a972f3ec3400ca12260fac5/multidict-6.9.1-cp315-cp315-musllinux_1_2_i686.whl": "sha256:4a409ccc42aefec904038695d5d7fd6d8f3af2721b7b6401d55135ec7d6d298e", + "https://files.pythonhosted.org/packages/43/7e/9c6a3e7619459407d8958f7e56ab3dda7f0738f5aed9bb4ad48076e8de83/multidict-6.9.1-cp315-cp315t-macosx_11_0_arm64.whl": "sha256:14c56f73e78faa1f68bbb826197cd5871994e70e841b8590829c35912ece5c64", + "https://files.pythonhosted.org/packages/45/a1/3bab1827edd813dfb90712af5cbb7fc1473ed4d9c871d103df4f4bb950c2/multidict-6.9.1-cp311-cp311-win_arm64.whl": "sha256:5800368526647146978389dfaa46da3356291e9f0fff9a4ef12e8c2bef964a0d", + "https://files.pythonhosted.org/packages/45/eb/9a333346c02c928a9e82534638bce85697c10c46b4901fcd70af19357356/multidict-6.9.1-cp315-cp315t-musllinux_1_2_s390x.whl": "sha256:557a4e1708df428ebe6c3081c83a273d275dad2446ce0d81fc648ac71afdb18d", + "https://files.pythonhosted.org/packages/46/46/9b4c1127cece0289fb207d04aae5116382ddfcb2a4dc8e0cb49a33f3c7b3/multidict-6.9.1-cp313-cp313-macosx_11_0_arm64.whl": "sha256:e5ccad4b7bac125722f48d6f862bed3b514d8526deea06316bb72f152cd30a7c", + "https://files.pythonhosted.org/packages/4c/04/dbe59cf4ea3778600e8e70e30b31aa9118ad6da2844bc9f717804cbaa000/multidict-6.9.1-cp314-cp314-musllinux_1_2_s390x.whl": "sha256:f0700527dd5bfa8b7204b08330542f4f388899d3c14d885d8a368992e0eb562d", + "https://files.pythonhosted.org/packages/52/48/22baa3b95375096369b04c4348af14139570f302f951773d2c68bf0ccf2e/multidict-6.9.1-cp314-cp314-macosx_10_15_universal2.whl": "sha256:b2483da477932ad1983d1d33c18bc3771c6fb00cfbaaed70a875fd547ef8e840", + "https://files.pythonhosted.org/packages/55/58/dd86067bdd2e961fdee8ec659fabc50f4e76403616b508714ec2686b0a49/multidict-6.9.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:02fe09dc197b8ae7e355371e51e5dce2f39060cd5a8badf94904527e23a3f188", + "https://files.pythonhosted.org/packages/59/97/eda4fe0cad51f96096363ed32d3e0f8df28dab00beff4d92adc9db517726/multidict-6.9.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:b8a65621b98984a62e59403009591b8a5a7736273aefe1cab64cfb85b365cc07", + "https://files.pythonhosted.org/packages/5a/44/e21be702efc9c9ba097c8be874c68860b1cb6cf9c85611263039bf95b37e/multidict-6.9.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:8b193bf7a443c97d81c47052f60c486071a4bdef4a573fa2514f920089414d45", + "https://files.pythonhosted.org/packages/5a/be/30fbb2cab22203128928066de94be247dc9a3230bf2bfc54437ac3b5f9f7/multidict-6.9.1-cp314-cp314-musllinux_1_2_ppc64le.whl": "sha256:1a938761c77e0e6edb0c93d02f4e988d44a69e5195e5a3b893e5553311347132", + "https://files.pythonhosted.org/packages/5c/d9/133aa472fc1be181de29a0c2e1c4cd778280882f532b404395f646742e46/multidict-6.9.1-cp315-cp315t-musllinux_1_2_aarch64.whl": "sha256:3100d169ceb7bc8f05f89a6db11d1b21f119975fc26f29dc45a472e3569f0879", + "https://files.pythonhosted.org/packages/5d/09/7a99a3daafd987330abb865a2d36e432fd8bf18e790ddda55c5de15eb98f/multidict-6.9.1-cp314-cp314t-musllinux_1_2_ppc64le.whl": "sha256:827c92145b3b976b39430129c89d213b250dacbe5fce678e9a03940e6e848983", + "https://files.pythonhosted.org/packages/5e/c9/945b44493fbe7af26ffe1e43c506b376daeab070fc1a0923bef9bbf572eb/multidict-6.9.1-cp314-cp314t-musllinux_1_2_aarch64.whl": "sha256:6e6b7e3a1520c39a2772f414cd9ddf5995f77e4e823dfa1522af383addd465a3", + "https://files.pythonhosted.org/packages/60/b2/c996349a61e0f43c7c95877943a67476261bf906ff993670afbd33ff5bf4/multidict-6.9.1-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:d9d6544790ba50438a9c1a903c3c4afb1ec8a7832db5518549275b40ef0dd4b1", + "https://files.pythonhosted.org/packages/62/ff/52a0082adeb69656b634609d4fb0ae65456deaae4cca3d5a12656626dc50/multidict-6.9.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:b22ff30006a2f28f8bff878fb93413cbe3a4d1fd517c28081d848c90e9cfd2c8", + "https://files.pythonhosted.org/packages/64/bf/a91256ce00199e7544e3eda79c4e9544eb7388c38fa22f11638c2e357ccb/multidict-6.9.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:c57541034d12b215ab0a2bfa371d1a8a198da18176d0426c27105b9161a6862d", + "https://files.pythonhosted.org/packages/64/cb/07bca86d4a361a87128f3019540d7689800fdcad44e3b3ad08f1f035ed74/multidict-6.9.1-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:73533644e1f69ea1164d56cc6505f564c6c44072b646b66d67df2d31fed0348c", + "https://files.pythonhosted.org/packages/66/34/8f43c03c2d8821a2320b8c560d8a49d0be2920627edfac3f546922f91969/multidict-6.9.1-cp314-cp314-win_arm64.whl": "sha256:32217133dddc58c927805cf6c0731d8144584176b768042ee886d51e71860bc9", + "https://files.pythonhosted.org/packages/66/6a/62c2af80fb085e6234805017af857b8e913dfac7a55e9c1349c27768c58a/multidict-6.9.1-cp312-cp312-musllinux_1_2_armv7l.whl": "sha256:1a53de2772cfb74559df2eb4456ec4eeb908435ec55a84b69370d9d745d62aa8", + "https://files.pythonhosted.org/packages/66/6f/a7b26167173c3b73d6e5ebb0856c5154ad005156c3a2fa4062329921819c/multidict-6.9.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:ef01d29fca550ab871fd99154f82c6472aacf8e7def272dfb07b460123850390", + "https://files.pythonhosted.org/packages/67/2f/1d936c4e45c8199db6082b6836e9182e31aa393de0de652637790831ca4b/multidict-6.9.1-cp315-cp315t-musllinux_1_2_x86_64.whl": "sha256:475d04d5192eba487a3e2f935976340baa24529046e9c1c9c7a3b7bf80445ae1", + "https://files.pythonhosted.org/packages/69/4f/5cbbe852b45d8a7f0ab3ed042386e4894e463010eb230603596cb15d0fee/multidict-6.9.1-cp315-cp315-win32.whl": "sha256:a3ffe881246d28a862f1985824f484cb7361f44d6b99c4c620436ef56462f38d", + "https://files.pythonhosted.org/packages/6a/69/36331fe1d3aeb0c525a9972d6cf82791075a395aa96f026f060009d691ae/multidict-6.9.1-cp311-cp311-macosx_10_9_x86_64.whl": "sha256:33fa55b990f81c2927e01399ace0d18926c69d69baa8cdaa819424132fb97987", + "https://files.pythonhosted.org/packages/6d/d3/f4ae5945ea2de597eaeb4eca3a74c59783ace54482c9b49435442b63efa8/multidict-6.9.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl": "sha256:03d47df72f084f757c1cb771188d5f4e3a805e4abc4d67e32509272343ae9382", + "https://files.pythonhosted.org/packages/6f/b9/911084c04530a682a54536b4f738d3992a593b5ff6fea1d6a1f02f3acc6b/multidict-6.9.1-cp315-cp315t-musllinux_1_2_riscv64.whl": "sha256:7ab379f95caee071a37cbd8be86d4c65accc651d391f9f97748fef006f38769c", + "https://files.pythonhosted.org/packages/6f/e4/774700cc5739353fe88a7204ed30e78a9403d98d4bb2496cc91f096d2e71/multidict-6.9.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:bd82c4977196681a499bb6ca9e462afbc5c91c1c15b6a991dfbd72733fea4dd2", + "https://files.pythonhosted.org/packages/70/e2/2d4e3c3ee70f583334ff236fe6a3babf7a05ce56169a15df65453af647c0/multidict-6.9.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:a2212a0c842c723d919ea4a22a9296cb6b244b386e4e6ea92adfc7fbf3095519", + "https://files.pythonhosted.org/packages/76/e1/9509dafc1fc68948e75842a74533ddfa64af57f2b17810e9cacfa68a829b/multidict-6.9.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:1fee9a16d88a1c4865610de31ef5c666671020d7a81d1f510eaf3c97d00ebeba", + "https://files.pythonhosted.org/packages/7a/3d/801653b6aa9343a7430cecdefa1bf71ff24432224c02f15cc15e47837652/multidict-6.9.1-cp310-cp310-musllinux_1_2_i686.whl": "sha256:cf22b43f35b7dbb9f71e8ee2041b5c00029cdfc28ede3a2f31cf8906f9a6c126", + "https://files.pythonhosted.org/packages/7c/63/c9a0b131354dd949426166cef712d708f436a8cf261114f8d5d2aec440ca/multidict-6.9.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl": "sha256:4d718fa1b5f0d0dd75e86fbbc5b0c93ea3a5d65216c85c61cd5d7cdddfe08455", + "https://files.pythonhosted.org/packages/7d/3a/54209920324bc3928f5f2ba28b01a6dd957a9d48c3aaff77e38faaf5668d/multidict-6.9.1-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:bb0d664505f4b112f384cffeee82e91e3f6448d8e574989479db4439b68cba05", + "https://files.pythonhosted.org/packages/7f/24/f7179ecdf9cdd3581ace3292c3b883a1a500a374aa4e619bf6eb521c62e5/multidict-6.9.1-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl": "sha256:a8b75dd3d3638d9a19f23e84af4ffab3b8940422c0df2da2a77005ef5aa3d7ea", + "https://files.pythonhosted.org/packages/7f/95/64dd049bb4c53426e2fee7afb874daaa8b4426c41878785883a94511ecf8/multidict-6.9.1-cp314-cp314t-win_arm64.whl": "sha256:ac348379cf4de5538a0a213be1532d289aa801ec5d267c5909446b9ea2f8e2c3", + "https://files.pythonhosted.org/packages/80/41/495ef65bf5bba29d142d81b3fe1b8154b919bed70e96491b1e93c3c26f0f/multidict-6.9.1-cp312-cp312-musllinux_1_2_ppc64le.whl": "sha256:5b30ddf7234e611ca877575b62840e6af5977f92f1f9d532eedbb05a44ff8004", + "https://files.pythonhosted.org/packages/89/ab/1b9ca66251899981b21138b87da9d5a9c2c81af12b1ea7d19466972f7fe2/multidict-6.9.1-cp312-cp312-macosx_10_13_x86_64.whl": "sha256:19e31815d41cefc365489e591d105d2baceb2f65aa75d29471fbdbda8651e006", + "https://files.pythonhosted.org/packages/8b/90/284d10b3a9e5b312a8ec5b7a175fc7d560eefdc99886320449891a197992/multidict-6.9.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:9ae9614c317c50836689ce2dfde07c05fe0b16378562e2221746c3913ede3c80", + "https://files.pythonhosted.org/packages/8c/73/5f9dc2b5ac7dd7a82458ae9cd283b99c185834f23442ace295362dcc5e45/multidict-6.9.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:79da2491348b30810728050b4a8ec0416f85884125c2fd44655b3d01150d9c3e", + "https://files.pythonhosted.org/packages/8c/ca/5860651f782078ef13f2761c2593f4ba066d76f626b2f30f23a7f838b775/multidict-6.9.1-cp311-cp311-macosx_11_0_arm64.whl": "sha256:369b5aa01b241cd3fea6890bdbb11a1425d87bf1515831500d518f4223e9d72c", + "https://files.pythonhosted.org/packages/8d/87/013e1eed30ad46bec1eb68947bc9caf55ba2fd0d6aed04fe964e3b44c23b/multidict-6.9.1-cp314-cp314t-win_amd64.whl": "sha256:7c8d5882ba25ac0282258be435d8a05aa0cbcacfce15799154a338f847f159b9", + "https://files.pythonhosted.org/packages/90/bf/599ae2e6222822d88a247a8a7ae82fe6fd25d5700757b79603d5edafe6a0/multidict-6.9.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:35fc236507fb1b3138f0af5ecd5f94ed752d4d6d826248eae425f86204013eea", + "https://files.pythonhosted.org/packages/91/17/c2064aef64efc007bc89a571f843e5772f27946eb9bc018731bf8016e319/multidict-6.9.1-cp311-cp311-win_amd64.whl": "sha256:5f89dad732280e7a10b74d40b91364f88e13c3f2c08c2ef83a8cd42f7a61af2e", + "https://files.pythonhosted.org/packages/93/6c/d6cfe18e61010166d7237d7527c775eb9843e7078feadea45b7628751b60/multidict-6.9.1-cp313-cp313-macosx_10_13_x86_64.whl": "sha256:de7738b8c0bb74c4cc16bbd7fb49fc2bcf6430dba11b3432cd52768ae40933e8", + "https://files.pythonhosted.org/packages/93/7d/15468239920040d01c686e5ae669e6382f7bf31fc3e5e0a6b8f1c3b32d3b/multidict-6.9.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl": "sha256:6bc94fe17c3c56e5418f79515b786b101845f70609b0d19d0c1ba13448e5633a", + "https://files.pythonhosted.org/packages/93/f2/e06c8e42074d0a4b8419bfe92afbd1d262190b69549ecbcd2dffa4f103c2/multidict-6.9.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:7fd79c521f6290c69125fa2b85fa65d9e657e6a8ffaf722dc881b926bef4aa5c", + "https://files.pythonhosted.org/packages/94/cc/8aa34ae8d09498e8da003f485c03371b55cf1bc6d56cff861b3a7de61251/multidict-6.9.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl": "sha256:af1b5a92315048c3e36bbebfa7d4760a9c3e910bc4166f11b20d77d20d6bcfca", + "https://files.pythonhosted.org/packages/95/8e/71bd7f43c4883cba6c5f96db88bd2311d52e74ad7680be5915938490d56f/multidict-6.9.1-cp311-cp311-musllinux_1_2_s390x.whl": "sha256:87cc632c88ee5dc80e12681047839304d98ee5c9a708d686505767001c9b8b9a", + "https://files.pythonhosted.org/packages/97/4c/9f1b7945526905d58b4b2d422e2ea81326dda71f9bdc9c32c8002639234a/multidict-6.9.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:539c2cd5fed0947c135cd7eabaaac55f48300dfa1de0f3ca4edb5efa6606f471", + "https://files.pythonhosted.org/packages/97/8a/7741f7c23c211fae31ab546f0ba41569dae7671cf7ca30d5afb59e9d92aa/multidict-6.9.1-cp311-cp311-musllinux_1_2_i686.whl": "sha256:43124fe172ada86d03ac3c8dc8179091341f6724d5e5d5b160e1587e4cd3761b", + "https://files.pythonhosted.org/packages/98/05/0c86e9678e78f4596df0ed7f59d2aa755107da3f2a92f1b7fa150e94cbb8/multidict-6.9.1-cp311-cp311-musllinux_1_2_riscv64.whl": "sha256:7fc59e9ba821b220944ccfe0f89c9dc4745f6d097569992356eb03869f21e953", + "https://files.pythonhosted.org/packages/98/43/d7cf9ef4700e7c25244590d1b4f20cf12cbed86beba6c17be4d9e48c1099/multidict-6.9.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:1d804e4caf5d5da37d6dac1325da5629ebef1e27a294c2b568b295814aa36c7b", + "https://files.pythonhosted.org/packages/9b/07/cc9bc8a62651d2d53ab93ee4993b3a71b7cb78eb8ebfc9c757a5b6698617/multidict-6.9.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:95052e8777a86bae87c0bd0b5ab22d809e3d1d02bf69e3e66ddda5ba75a05805", + "https://files.pythonhosted.org/packages/9d/41/ed27d1d20ba91f4e13e8f7dcfaa592614ae0e1d5f45e03171d23c3b098ac/multidict-6.9.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:a313bad717dde740959d50850c315b75fd4eb0c5e6b4dc8535db0f1c369be125", + "https://files.pythonhosted.org/packages/a0/97/555aab000e03ecba85c0a1837fd5674d8bf10949490df7800da3a40660ce/multidict-6.9.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:989261c5f1735a165f2e4e87cf6d5f17ab734fa18f9ad0383d5adfcdaefce701", + "https://files.pythonhosted.org/packages/a2/2c/26bc1723592cfe965b575652a7749026474b0625b04b04564e1fba265dc5/multidict-6.9.1-cp315-cp315-android_24_x86_64.whl": "sha256:f04551dce5a7db8c9659f2e4245494c182d0663b83661803e08d46bfcae5eda1", + "https://files.pythonhosted.org/packages/a4/0c/ca62ae2882b89a4cfeb0bbca873a4afdb5fc32994c4f8a37a7cb52ede7a0/multidict-6.9.1-cp315-cp315t-win32.whl": "sha256:10083a8a0f4e1b26b599889e90b9802504ce5d3f7722f925bbb7ca47dd22a7c1", + "https://files.pythonhosted.org/packages/a7/9b/37f354562a8f82f9c1f63d3a94300fc82126d50320175f0702bbd544f87c/multidict-6.9.1-cp313-cp313-musllinux_1_2_i686.whl": "sha256:083735b7f395894e43adb278d5dae901448883a835ff8f1977e285fefdb10418", + "https://files.pythonhosted.org/packages/a8/32/c0972486f81a06c3bbb23063c85afaac53c51608f7e35bcb101a1006408b/multidict-6.9.1-cp315-cp315-musllinux_1_2_x86_64.whl": "sha256:ecc89dbd4155b2f8a47f4bbd89242a35ed15e8e0ec581cab5ac65fa38407329d", + "https://files.pythonhosted.org/packages/aa/57/89d2d3dedfae2558853c1770c7cbcdfd5211eb4c4090b1e8cb570544a490/multidict-6.9.1-cp315-cp315t-macosx_10_15_universal2.whl": "sha256:8879510a76940670517ea1cb589978da44b86e286ec3e50d664ef330817afce7", + "https://files.pythonhosted.org/packages/ac/72/c9dffcecccd1f8b9a58f960ec4eaecab62c4edb08d5bb984d4de67fe3fdb/multidict-6.9.1-cp315-cp315-macosx_10_15_universal2.whl": "sha256:006c4478de0a1876f4834e14255776286f09b9846b505fe63f67f9d173a9487c", + "https://files.pythonhosted.org/packages/ad/21/465a43c214d1d7e2d0c974e727d4b5935f8a0868838b5df9d0984c83c1dc/multidict-6.9.1-cp315-cp315t-musllinux_1_2_i686.whl": "sha256:f5844e7befc707367807586f550fa97e23dcfef0728f02b98c7bc498a961a5df", + "https://files.pythonhosted.org/packages/ad/2b/ab5bd3964691abe4d14b43bdbdb8a621b77cea2ca352dc93159ec0a4575b/multidict-6.9.1-cp313-cp313-musllinux_1_2_riscv64.whl": "sha256:ea999ae6e80e66ad5eea287860951b033d0104ca34d6d87c7b5125ebe0e12721", + "https://files.pythonhosted.org/packages/ae/18/10c008aac77297aa618631e8726ece31668f9dc9d9c848e4b5d2e68eb3d3/multidict-6.9.1-cp310-cp310-win_amd64.whl": "sha256:a32b78c1e52ebd8e247bb68300b90b233300d8816faa008ed0713bc539fb6af0", + "https://files.pythonhosted.org/packages/b1/b1/da73a58bef2613571902a824f1e11185207ba756215c99038f6d220bc167/multidict-6.9.1-cp310-cp310-win_arm64.whl": "sha256:ab64ace1a68682d191d9bedd9d4c939406ad86b1d9f628180410644249ad46c2", + "https://files.pythonhosted.org/packages/b3/3f/c66342f73ee5cd2c9b1dda6cfce89b5f348c48921b8c8b6e59aafbbfe31a/multidict-6.9.1-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:2c5d675da8f1cb5650271c8ad5e95c0a3e5a183c105e72d953b12877b1c8d0fd", + "https://files.pythonhosted.org/packages/b6/0c/8e912afafa70e944dbb8bec4b66ca6e008511395278c0d3dd0e89567536a/multidict-6.9.1-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:1a8adfcaf96f587ab138476eaddef95f29b8a2a8a9afbfea8d2fd62180995d02", + "https://files.pythonhosted.org/packages/b7/23/1ab8c7349adbb30c8cf41b88b0794740df8ea9f7de2e382da040a2f5bd8e/multidict-6.9.1-cp310-cp310-macosx_10_9_x86_64.whl": "sha256:1ca5ebe6d454f1e5496cf052386a559f1080bf2de75bf327ebca0a6003b79f19", + "https://files.pythonhosted.org/packages/b7/7f/c6b0896850b3ceb190ca302760d63148843371f027c5dde3d1d732343a08/multidict-6.9.1-cp314-cp314t-musllinux_1_2_x86_64.whl": "sha256:f2524ec55b3e65cbe235a8b3c36e2af3b635be02ed05e20c94e70c5c943c009e", + "https://files.pythonhosted.org/packages/b9/5c/a67817593019257a4ac8b0d1b4c426030e637c047b0692ef405439ecea7a/multidict-6.9.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl": "sha256:637f4ae36264bd7b8d9a60193acddc1d735ad52e8ed53a19931ea6d921fea8e5", + "https://files.pythonhosted.org/packages/ba/ee/a2bd133391204b1cec5a5caf327dc9a06710439b7403220860a8fb164560/multidict-6.9.1-cp315-cp315-musllinux_1_2_s390x.whl": "sha256:5ecace251ccfa705bf3d7d35c5032cf750f5c629809740405697bce5c118c4a4", + "https://files.pythonhosted.org/packages/bc/fc/c18b07100a6064573e49e538d13d47eb2b5221f48080512df78aef54ab04/multidict-6.9.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl": "sha256:a49ff5cdb33654cb7d6a3c377aa2a83ddefaa1db31eb10bcf3c180aa84f9af8a", + "https://files.pythonhosted.org/packages/bd/38/21f2305dd20ac5038fa581b5d7e0d8dbbd70dc6b50231c22ec173dacddda/multidict-6.9.1-cp315-cp315t-musllinux_1_2_armv7l.whl": "sha256:696477ad71385c4795e3b8e4cf10b0d2c28c2a1ca6a955e031cb1e62993e9ee3", + "https://files.pythonhosted.org/packages/bd/53/f65ed68b96eea2b4f6fa4f9031bdfccd8f3097c429e3d371c545d1c40ca4/multidict-6.9.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:d3b6e6840421c83ccb60398e333b44f910b0907bb409597685ab2eedd1e22eab", + "https://files.pythonhosted.org/packages/bd/c5/614d2eb9995232d066aae7f17d1d454060b6b5d882b22fbaf6150b05ef1d/multidict-6.9.1-cp315-cp315-ios_13_0_arm64_iphoneos.whl": "sha256:c0c88085affd35c33e124e36930c5ad96aff9294ce195eaa0fd9cec962b64a82", + "https://files.pythonhosted.org/packages/be/59/e26cb779be4c591d1a910f59d29aca9fba4de70349840a833beba2652371/multidict-6.9.1-py3-none-any.whl": "sha256:7bf6478188f4e47bf5686e8a33da4ae28bf43b1b2528d9ee144d28492bfac60b", + "https://files.pythonhosted.org/packages/be/78/1bac2987edac273a6b27fa50e9204bc3466c94a7b4f6a44828d730f8810f/multidict-6.9.1-cp313-cp313-win_amd64.whl": "sha256:ac51cd64bae51c462ea58ad2492c9b8209667a4ef60c45c4a304518b67598d5d", + "https://files.pythonhosted.org/packages/bf/f0/2480aef6b7d8e7ab89b064ae14f12ec069570dab3a5c13e0155912293247/multidict-6.9.1-cp314-cp314-musllinux_1_2_riscv64.whl": "sha256:37245ca4105386194dd1d292a6f2aae09bfe1bd7ac6f9ec25093e3cf8e9b143b", + "https://files.pythonhosted.org/packages/c3/7a/9906bf5f1fe20e8e755affccc1a69ecd8aebb079ac65386e5ffc8eefbe75/multidict-6.9.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:7c6eecfab7ce4cd9487ff8ba936fe38cdfd68c04faf3d5c710363c6a8e695659", + "https://files.pythonhosted.org/packages/c7/9f/c56e2fa223cb5d182660e1a09eec38880f96b7cd22769582f74447c60418/multidict-6.9.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl": "sha256:803f8b575a71b1b299d677c28db0653459c79b5308874efec813f17b7457c7f1", + "https://files.pythonhosted.org/packages/c8/df/0c2a28870181c1762f90952b897f6db46c934ce073efe0442604cbc276db/multidict-6.9.1-cp315-cp315t-macosx_10_15_x86_64.whl": "sha256:aec65b53a07f580606593f877eefbb29a45939bfc0d3fe6e6d9f42b41b749f68", + "https://files.pythonhosted.org/packages/ca/41/0bec327bc3a8271825376b6d8a469d1f80e3ba1e2e730e019836e29663c3/multidict-6.9.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:bb58ba73a3f96f9a3e46b1fab69929d7edbbddb3133ee74b5c3c54074a53c4f1", + "https://files.pythonhosted.org/packages/cd/0d/bf33cb097380252b08e1177b5ae0cab822c47ce80d236f3f724953c76721/multidict-6.9.1-cp315-cp315-musllinux_1_2_riscv64.whl": "sha256:03fac50ddfd8302175b77863a015eccfae76767cda5506eef86df559ba861e1f", + "https://files.pythonhosted.org/packages/ce/5f/278b5a2c99d6de27914b49158dd6f2a6481e53359142cc366dff04821a2f/multidict-6.9.1-cp310-cp310-musllinux_1_2_riscv64.whl": "sha256:e3b1aa25f01238886a6baed9e13b9a9240ed344346c79ae280ae65e8603b21d5", + "https://files.pythonhosted.org/packages/d0/36/ab0299a7abf53e38ff75d96c64480f1e2ff8edde985f93f7a1ad5e08bd94/multidict-6.9.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:81cdc537e0a42e3c0170752fcadbe450246d5c3b4b7231d6eb9672456605ac94", + "https://files.pythonhosted.org/packages/d0/95/59f4472ec512bc180fd207899594c7803ece96262ff9aaa3a4b6d7da6940/multidict-6.9.1-cp312-cp312-win_arm64.whl": "sha256:361f7206cf341ba94fb015688f5c8b480f8e63bd58a4c14a48aeca7851a241cc", + "https://files.pythonhosted.org/packages/d0/f1/ba67f668478f152bdfa18abe72e7588bd078bf8b42c172fcf542fcf45826/multidict-6.9.1-cp314-cp314-win32.whl": "sha256:e81ae656b9935ac4528a71f96bb7a14d949778ed1897c573d3e7ebb9187f8841", + "https://files.pythonhosted.org/packages/d3/69/7f2b3fafe064181669157ce872a097b08a0546fb6fd2481e8c5604b47ec3/multidict-6.9.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:8885e3808aedbd6725b921fb67dacaae0678933561ddd47c2b01315198c70e2e", + "https://files.pythonhosted.org/packages/d4/77/1fa118386deeae4e7a48870fa5cb073e748b0ac5265a6990651cefc48068/multidict-6.9.1-cp315-cp315-win_amd64.whl": "sha256:59c123d0e948d760a5f930f316cfefa07e8d632ab84327c0693ee6a88171154f", + "https://files.pythonhosted.org/packages/d6/14/f64bd05667343a7250cdd99f81bda2270e3959f00832441f10c7f904e1c1/multidict-6.9.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:fd882aa29bf402b62bf1fd7c19fd5df4b6528cf468a908864b39368572b662a9", + "https://files.pythonhosted.org/packages/d6/99/1d4d69c3512d0ddbfa3a1b69cfd9a151012ab2eb4eabbb096201b1f0b7d8/multidict-6.9.1.tar.gz": "sha256:0f06e60fa190aa7abd0914c2a766736fdc8e9f34878c4346338534b73d1b20e2", + "https://files.pythonhosted.org/packages/d7/2e/8c9c2591df01e5692ad1bf92febb082a17b1c6c3a19aa8b7ff49988fd989/multidict-6.9.1-cp312-cp312-win_amd64.whl": "sha256:a16a1dc8529f9e734a41c3b856f3eae7ebacdc061dde3f8a844e0c7889c97203", + "https://files.pythonhosted.org/packages/d7/5d/9ff39e7387f6fcc9a81af5dbf055fde08149849a04f8df10ca5b086b0d39/multidict-6.9.1-cp314-cp314-musllinux_1_2_i686.whl": "sha256:73bcafa21a78d0776b3ee7cd2a63c66f968eb7db8e8d594e32d7329950f6e828", + "https://files.pythonhosted.org/packages/d8/ac/7c1204406097bfc5c283d4a3287d61166807d189917567df4c1318484fc4/multidict-6.9.1-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:c148e8b596000dd3e4bfe206e70f3e666be18d72032e0012555f2373c52e35d6", + "https://files.pythonhosted.org/packages/d9/0d/4b5afb6d3e545c9af0cdfe2db8f6f4c6664568c23d863d888674e447e6a4/multidict-6.9.1-cp312-cp312-macosx_10_13_universal2.whl": "sha256:29138fef49828542e859828107e42e50d0e587c513b7eb4b2d92bade2b0860fe", + "https://files.pythonhosted.org/packages/d9/1c/08e5184df026b9d8e05a6dce5da22628e46bc4a7c7f03b8bf3c6939a8c46/multidict-6.9.1-cp314-cp314-musllinux_1_2_armv7l.whl": "sha256:95f273bea318a194f656527ee2ed19494327bc500b8e87d9358e3222579aa28d", + "https://files.pythonhosted.org/packages/da/b1/e37fbf769c567be277bcf32df6234035a4384677fcc1bd852752be3d6b93/multidict-6.9.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:b5f8771aaaed7f80e84a4e471d2f29ab6721e4595075e54d03ae1ed951b2000a", + "https://files.pythonhosted.org/packages/dc/14/04d155dd18528443cb9009f3a9f35f7417773797d072c95104ff17b8b9b7/multidict-6.9.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:dd9a137a4a9becda3094f3831cd026380f75f6855e051eefe4c73ade524f1cc3", + "https://files.pythonhosted.org/packages/dd/ee/51c45748acfce9cb69d89dcfcd09c874b385407fd6993e885d6905659865/multidict-6.9.1-cp315-cp315-win_arm64.whl": "sha256:31199204b3ced121ff5407a2c342326a5d27e3870abbf94bd80dbd2451b7bc8f", + "https://files.pythonhosted.org/packages/df/ef/51e79c2442b0f56ac4ac580108d713078b31297e028d468fc220971a305d/multidict-6.9.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:15db6a102cbaf1949cf028ecf080aac76d20bcd29ad4e092574db6c6b7af78a5", + "https://files.pythonhosted.org/packages/e0/89/b845535014a9ad50537ca50204aaf6351c5368822a3acd9da854fb2a5a34/multidict-6.9.1-cp310-cp310-macosx_11_0_arm64.whl": "sha256:02f6d0c4b70f783305e73f9944d8efe6be1022550f0974ba0ae9d8893c0350fa", + "https://files.pythonhosted.org/packages/e1/32/2a77ce19eea48cb9b3521a202b513ba3349aafa702c8317be0b645ffb74b/multidict-6.9.1-cp313-cp313-win_arm64.whl": "sha256:37a9ebe00c698279213d56e6c64e1962ab1e092918270649b397cac3dc196ca4", + "https://files.pythonhosted.org/packages/e1/e3/99591bf626613ea35779d2460949b45e59e589dc9058d6693c923eccd4e5/multidict-6.9.1-cp310-cp310-win32.whl": "sha256:66987aa68b0f7c2a1cc5f388ca962b8ed92b10f79de38d6d0d8c716154f519d9", + "https://files.pythonhosted.org/packages/e3/24/3823efc330630a1f132bcd0a9b182ddec3c53f452f551c8e8d3aaf5a2d20/multidict-6.9.1-cp311-cp311-macosx_10_9_universal2.whl": "sha256:910d4260512660484c0dc1588a316fbb35a40c081c36fc51d1225351af17cfe4", + "https://files.pythonhosted.org/packages/e8/63/0cdbfbbe36316b2ef4b8e011afaca2cf291a73fe4fabf34dd0b22e3ee48a/multidict-6.9.1-cp311-cp311-musllinux_1_2_ppc64le.whl": "sha256:b2f0adc22a4eb31e545221d93fc73a0f6a8cc2379d0f4309f71d1d17ba938b82", + "https://files.pythonhosted.org/packages/e9/3f/76542360e655cecdb7c158c7af88c69c4db0d2aac3421659d41214927229/multidict-6.9.1-cp315-cp315-macosx_10_15_x86_64.whl": "sha256:2784090c30a586d5b45197bd9c32f87fb927216cde302f6cfd76d76577e90f08", + "https://files.pythonhosted.org/packages/ea/a8/f6bc899f5aafaba755edc8e4bb934bc00b1e405f8d3fbc1dd10283738074/multidict-6.9.1-cp313-cp313-musllinux_1_2_s390x.whl": "sha256:095d900c242e00fbe5f321ee072e7278b4153e78c5ce9c1efde167d62c1e4771", + "https://files.pythonhosted.org/packages/eb/03/a8fc809ef364b8c231c065ea2ea2f97ae86d4f9a0e36b5721759fd606778/multidict-6.9.1-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:6441cc837aea58be7d9baef1b2383eb8311ab9303f500f99ac90b584cd78bb14", + "https://files.pythonhosted.org/packages/eb/1c/fb2114207afc7f00ab9897ae5beeee27de5ec58ea8b9623e879f2c56f003/multidict-6.9.1-cp310-cp310-macosx_10_9_universal2.whl": "sha256:aef74e9beabbd6c4aafc091dabff86d046ccf013ce1e4396c0fbb01b4cad9de8", + "https://files.pythonhosted.org/packages/eb/45/ddf7c76860f5f553a23ad3ca38463ccf5247081618977742c8dc4625355e/multidict-6.9.1-cp313-cp313-android_24_x86_64.whl": "sha256:d7bf9e43282d69561618e8a0ea33368d532ebef42f15c096f427090521dd74f3", + "https://files.pythonhosted.org/packages/ec/0f/c6041015aa2cdc11e1dff0cae58898ae5525d19e35efd65a4ecf3c6ea235/multidict-6.9.1-cp314-cp314-android_24_x86_64.whl": "sha256:fc0dcb22fa9aeabfe3fa4e0430099acff985ec5d77a851382f76cc6146e780e5", + "https://files.pythonhosted.org/packages/ed/5b/db08419c1e1f7c9d60cfd2787b2b517d7ae4ebbda8281b48a33eb5141467/multidict-6.9.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:976fd7689d69ec78d67d31d38d396d8adb562f7e8368279f76aed4aa451fa06d", + "https://files.pythonhosted.org/packages/ed/8f/212ed7e03282c7bc271e3796bf985b53d5727c2827361e3dd9c5ee6b093f/multidict-6.9.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl": "sha256:03731f6fc036180700c9dc2308205a48e5ca6f3ff03087739ab746f294022201", + "https://files.pythonhosted.org/packages/f2/27/32dde80245e2024e9bb7a6ca3c2fb7c695dc74014cba557cc35be6f91e24/multidict-6.9.1-cp313-cp313-win32.whl": "sha256:9c4880d017555d70dea367dd49271830842d48e3891c2da97da7ce8c4abcee40", + "https://files.pythonhosted.org/packages/f4/8c/abe55548f06f12878588f08eb803c5a391283f01243f784cb00adac79231/multidict-6.9.1-cp314-cp314-musllinux_1_2_x86_64.whl": "sha256:6b7e54fd883671d1a8810704851c044b7173287c552b9f5c3d9e0eb9f00ae194", + "https://files.pythonhosted.org/packages/f5/50/a05b1d36f6d3363a5a334cebbf11624c9c7a69d66fd23345eb53b1d43b7e/multidict-6.9.1-cp315-cp315-musllinux_1_2_ppc64le.whl": "sha256:0a5769559e3312dd96731fbe15b4abb6033368ac1cad5a98dadd21946a4c7d6c", + "https://files.pythonhosted.org/packages/f8/6b/35bf801b336fd960811207203ffdcdc24acc3558b3e7ff2e1c914b141e70/multidict-6.9.1-cp312-cp312-musllinux_1_2_i686.whl": "sha256:0f2ce963299d42fa3f22a90adc0fdf174792ffef5ff4c7ffb68260548fb05580", + "https://files.pythonhosted.org/packages/f8/84/6f319ee000f5ab3fa0055b194ad706fddd552c60c76a21d581c87db1d46c/multidict-6.9.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:b4da208a63434d21a3df64d29758e650fc4aa8cb05848554b76949c296539cca", + "https://files.pythonhosted.org/packages/f8/e5/8d54118bc228e64e1087f1729647b93bbea225eda4a3f914663a6f410bca/multidict-6.9.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:b69651732c64afb691e50cdc3387cae305e0eeff8804fe3e3ce203876494932a", + "https://files.pythonhosted.org/packages/f9/b4/8e6d950f02ca6ecc00ecf671f2ddb5dab7017671a8d197326f75621f5786/multidict-6.9.1-cp314-cp314-macosx_11_0_arm64.whl": "sha256:854fd2f1bc6e8a56b89910b5cd7261a8b40f13ebb31572da985ce59c7da0886d", + "https://files.pythonhosted.org/packages/fd/34/03f1d204d698c408f4754c969882609b6b7a902c0e3d16a7033f219cdeda/multidict-6.9.1-cp315-cp315t-win_arm64.whl": "sha256:501ed8b02a5990c67a91c732843609d43a6be1f7576fcdfc867331239f37fbd3", + "https://files.pythonhosted.org/packages/fe/4f/28ebb40a6f8e8aa7be78bcbe4bf9a1ac9518c40ef88accf2d4cd6ed7a7e0/multidict-6.9.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl": "sha256:8050e75af7e4c6e2d5260b84eeedb618f3e452e66473432e085b5d1b81429299", + "https://files.pythonhosted.org/packages/ff/c0/a70c32ea3299ebe00f44533740cb46905717c51faf29bbd3ce8bb5886d9d/multidict-6.9.1-cp312-cp312-win32.whl": "sha256:f9dad513626a33670f17cddc6078e30e311f444c957e8dbfc5b2b4603c8b4edb" + }, + "nh3": { + "https://files.pythonhosted.org/packages/09/a1/ea83abe738a3fbaa203dfdb836ca7cbab0e7e9609faaee4fe1d4652599c0/nh3-0.3.6-cp314-cp314t-musllinux_1_2_i686.whl": "sha256:edb2b4a1a27523e6cc7c417f8d21ce3d005243548b93e56b762b66b0c7f589f9", + "https://files.pythonhosted.org/packages/0a/13/6f1e302ca674ac74362e150848ad56a1be5145391204f74facdb8e94df12/nh3-0.3.6-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:455469a29951edc92bc48b47ac2281c3f2609e6c4f6a047056449f8c2c23facf", + "https://files.pythonhosted.org/packages/0e/24/a0d80182a18919665fefd19c1c06f1d1df1c9a6455d0252de40c034a0bc3/nh3-0.3.6-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:e6b7beece07525dc6e6b0fc2f104442de2ba328360ad00e50cbe2e1fd620447d", + "https://files.pythonhosted.org/packages/11/f9/3966c61455668c08853bf5e33b4bed93c421f3194ce4de896dc248d6f6ce/nh3-0.3.6-cp38-abi3-musllinux_1_2_armv7l.whl": "sha256:f5ed5fe84aee7f39db95c214a7421bf0499fbf500fec6d86a4e29bfc37971438", + "https://files.pythonhosted.org/packages/17/0c/6cdb5ee1e127be50dc8391e54bddc1f64e87bf4bfad0c55633320e2e02db/nh3-0.3.6-cp38-abi3-musllinux_1_2_x86_64.whl": "sha256:36d06341bd501240d320f5942481ed5e6846136b666e1ba4faf802b78ebc875f", + "https://files.pythonhosted.org/packages/19/d3/479cb4ae440424825735d60525b53e3c77fd60fd6e6afc0e984f00eb0178/nh3-0.3.6-cp38-abi3-musllinux_1_2_i686.whl": "sha256:082675ff87b9385ec430ffe6d5847ba7456cc39b73720cd4add472f9f4cffd56", + "https://files.pythonhosted.org/packages/25/bb/431615ba1d1d3eb63cde0f974f2114edf863a8a3f6049a12fed23fc241d3/nh3-0.3.6-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl": "sha256:44673b27010051ab5a5e438a86ec31bbda61d4a77d7e900af6b7be3037c1abae", + "https://files.pythonhosted.org/packages/30/a8/fb2c38845efb703a9173bffdfc745fc64d2b0e55cfc73a3647d2f028250c/nh3-0.3.6-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl": "sha256:2f90d9a0cfdbee218994fdaaeeb5a0fde62d08f35e4eef0378ec1e2200172fd0", + "https://files.pythonhosted.org/packages/36/ea/5542f3c45da4c00290d9d67a65e996702e23e613c4b627de3e09cb9fe357/nh3-0.3.6-cp314-cp314t-win_amd64.whl": "sha256:4713502748f564fee0633b37b3403783ce0a3af3a3d148ad91025a5bdadb7bc6", + "https://files.pythonhosted.org/packages/3c/a6/bfaa00046e58603507dcfc266c4778e3ab7adf68a5dedd73b6274b8d9314/nh3-0.3.6-cp38-abi3-manylinux_2_31_riscv64.whl": "sha256:25c733bee928530556b1db0ea46c52cf5aa686146e38e60a6fc7cb801ef91cec", + "https://files.pythonhosted.org/packages/41/21/e1084ab18eb589506335c7c7576f2d4643e9a0c0e33983ef0e549a256b96/nh3-0.3.6-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:e1b160831c9cdb06a6c79c2f9cdb11386602938f9af260d1c457a85add4f6f69", + "https://files.pythonhosted.org/packages/49/09/0d8e3101636d9ad88cdefb2914e764cb8e876ebdbb4286bfc251277d9c67/nh3-0.3.6-cp314-cp314t-musllinux_1_2_armv7l.whl": "sha256:889932a97fb4abb6f95fef1914c0d269ebfb60011e67121c1163059b9449dbb4", + "https://files.pythonhosted.org/packages/4b/4a/526f199626bfcb496bc01a268051b44737962005553b158e985ed7e64865/nh3-0.3.6-cp314-cp314t-musllinux_1_2_aarch64.whl": "sha256:f2f14b7ae1fca99c4a66c981aac3974e7fbc1ca30a12673d223ae1df76680917", + "https://files.pythonhosted.org/packages/59/62/5b6108bedaef2b2637fed04c87bdbcb5967b9961758b41f0e466ef22a022/nh3-0.3.6-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl": "sha256:34d2b0d934156b87ee114f599a3ba9b8b9e17b5d79652ba3a13fa50903de965e", + "https://files.pythonhosted.org/packages/5b/67/314f6151bad77a93d751978a344033e1fc890822f05f0416079338e34231/nh3-0.3.6-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:905f877dc66dd7aea4a76e54bcb26acb5ff8216f720c0017ccf63e0e6035698e", + "https://files.pythonhosted.org/packages/5e/1b/ef84624f14954d270f74060a19fc550dd4f06656399447569afb584d8c06/nh3-0.3.6.tar.gz": "sha256:f3736c9dd3d1856f80cd031715b84ca75cda2bbb1ac802c3da26bfce590838d7", + "https://files.pythonhosted.org/packages/66/35/26bd47e6af5915a628281dccdac354ddf4e32f7397047894270acd8c9870/nh3-0.3.6-cp314-cp314t-win_arm64.whl": "sha256:69bbb92865a693d909db3a700d3c01537533844d0948c1e9323561ce06ecda41", + "https://files.pythonhosted.org/packages/66/69/0654482b8635012fbae67826bd6c381abb05d841ac7388b9b4666300fdad/nh3-0.3.6-cp314-cp314t-musllinux_1_2_x86_64.whl": "sha256:43bc1ed3fa0716295fabee29ba42b2667e4a51d140b0a68e092170a765474fa6", + "https://files.pythonhosted.org/packages/68/17/06e72a18ee9b572914447338237ca7eb164c0df901f141bc10d1282247a2/nh3-0.3.6-cp38-abi3-musllinux_1_2_aarch64.whl": "sha256:82ca5bf427ad1b216b65ede1a2e2d87dc49bec417ceba0f297213107d3cd9d78", + "https://files.pythonhosted.org/packages/7b/e5/7cafee2f0413ca4cb0ef3bd111e94d408a48810008b283ad8aee00dd1809/nh3-0.3.6-cp38-abi3-win_arm64.whl": "sha256:69f365963f63a1e9bff53bdbb3c542c7c2efed3e163c9d5d83a772a2ac468c21", + "https://files.pythonhosted.org/packages/82/fa/2b5d684e3edf1e81bfd02d298c78c3e3da77ca1d8a2be3183a79544a7548/nh3-0.3.6-cp38-abi3-win_amd64.whl": "sha256:f338ac7d594c067679f1e99b4f5ec3906842979560f9d8f15d6bdfa39a353b10", + "https://files.pythonhosted.org/packages/99/3e/6506aa4f23dc7b7993a2d0a45dca3ce864ec48380adfe15a173e643c63e8/nh3-0.3.6-cp314-cp314t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl": "sha256:2411e8c3cee81a1ddd62c2a5d50585c28aa5566d373ad1db92536b95ddb24ef2", + "https://files.pythonhosted.org/packages/b0/94/f48d08e6f72a406300fa11d8acd929fea1a80d4bf750fa292cb10785f126/nh3-0.3.6-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl": "sha256:d14bf7982e7a77c0c775634c29c07ce08b38a046df73e1c1f139b3e82f18a38e", + "https://files.pythonhosted.org/packages/e3/e1/e96e7864a7a53bd6b6fab7e9632467382a2a2c1f3fed951918ad131542fb/nh3-0.3.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:e196fa70c2ff2eb4de7d3df3108f8f358c1d69dff20d45b11f20a5aa227ffb6d", + "https://files.pythonhosted.org/packages/e9/55/9de666ad975d6ccd77d799ea0add55ee2347aa81286ce21b2a97c070746b/nh3-0.3.6-cp38-abi3-win32.whl": "sha256:5276ef17bdba9ad8040575c74072008b13aae429436e9d0429e718bb5f90f4da", + "https://files.pythonhosted.org/packages/ed/a6/1f7285ffadc8307c4dbeb08d21b920536d5117785056d1079e998c4dfa44/nh3-0.3.6-cp314-cp314t-win32.whl": "sha256:597a8e843bea00b2eb5520658dc24a9bb032e7fc9e7c2c0c4cd29420220c9796", + "https://files.pythonhosted.org/packages/f3/ab/a7653bce9a3b204be6a6931767a9e23595807bb84790ce6685e4d7e5bd08/nh3-0.3.6-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl": "sha256:a43ebd7543555c3ac1bc353023d0794e75cb76f6f18f19c32e95441496c0cc25" + }, + "opentelemetry-api": { + "https://files.pythonhosted.org/packages/2b/6d/bbbf879826b7f3c89a45252010b5796fb1f1a0d45d9dc4709db0ef9a06c8/opentelemetry_api-1.30.0.tar.gz": "sha256:375893400c1435bf623f7dfb3bcd44825fe6b56c34d0667c542ea8257b1a1240", + "https://files.pythonhosted.org/packages/36/0a/eea862fae6413d8181b23acf8e13489c90a45f17986ee9cf4eab8a0b9ad9/opentelemetry_api-1.30.0-py3-none-any.whl": "sha256:d5f5284890d73fdf47f843dda3210edf37a38d66f44f2b5aedc1e89ed455dc09" + }, + "opentelemetry-exporter-prometheus": { + "https://files.pythonhosted.org/packages/36/6d/2a56355c00a8e225b0bbb85f2ca2e8fe963270d4314f9dee4576e49492fa/opentelemetry_exporter_prometheus-0.51b0.tar.gz": "sha256:25673d79d3b0b864133ee8df789fc6fb408c51e64b3cb775c20526c10bb93d05", + "https://files.pythonhosted.org/packages/6f/83/e2f5b986641cc13bae727598480d463140a2e1930c1bedb23ab60aea250c/opentelemetry_exporter_prometheus-0.51b0-py3-none-any.whl": "sha256:5c5c45b254e08c19564ab033f44a941a07fb6a33ea441b75ad203c70997a8f25" + }, + "opentelemetry-resourcedetector-gcp": { + "https://files.pythonhosted.org/packages/12/04/7e33228c88422a5518e1774a836c9ec68f10f51bde0f1d5dd5f3054e612a/opentelemetry_resourcedetector_gcp-1.9.0a0-py3-none-any.whl": "sha256:4e5a0822b0f0d7647b7ceb282d7aa921dd7f45466540bd0a24f954f90db8fde8", + "https://files.pythonhosted.org/packages/e1/86/f0693998817779802525a5bcc885a3cdb68d05b636bc6faae5c9ade4bee4/opentelemetry_resourcedetector_gcp-1.9.0a0.tar.gz": "sha256:6860a6649d1e3b9b7b7f09f3918cc16b72aa0c0c590d2a72ea6e42b67c9a42e7" + }, + "opentelemetry-sdk": { + "https://files.pythonhosted.org/packages/93/ee/d710062e8a862433d1be0b85920d0c653abe318878fef2d14dfe2c62ff7b/opentelemetry_sdk-1.30.0.tar.gz": "sha256:c9287a9e4a7614b9946e933a67168450b9ab35f08797eb9bc77d998fa480fa18", + "https://files.pythonhosted.org/packages/97/28/64d781d6adc6bda2260067ce2902bd030cf45aec657e02e28c5b4480b976/opentelemetry_sdk-1.30.0-py3-none-any.whl": "sha256:14fe7afc090caad881addb6926cec967129bd9260c4d33ae6a217359f6b61091" + }, + "opentelemetry-semantic-conventions": { + "https://files.pythonhosted.org/packages/1e/c0/0f9ef4605fea7f2b83d55dd0b0d7aebe8feead247cd6facd232b30907b4f/opentelemetry_semantic_conventions-0.51b0.tar.gz": "sha256:3fabf47f35d1fd9aebcdca7e6802d86bd5ebc3bc3408b7e3248dde6e87a18c47", + "https://files.pythonhosted.org/packages/2e/75/d7bdbb6fd8630b4cafb883482b75c4fc276b6426619539d266e32ac53266/opentelemetry_semantic_conventions-0.51b0-py3-none-any.whl": "sha256:fdc777359418e8d06c86012c3dc92c88a6453ba662e941593adb062e48c2eeae" + }, + "ordered-set": { + "https://files.pythonhosted.org/packages/33/55/af02708f230eb77084a299d7b08175cff006dea4f2721074b92cdb0296c0/ordered_set-4.1.0-py3-none-any.whl": "sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562", + "https://files.pythonhosted.org/packages/4c/ca/bfac8bc689799bcca4157e0e0ced07e70ce125193fc2e166d2e685b7e2fe/ordered-set-4.1.0.tar.gz": "sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8" + }, + "orjson": { + "https://files.pythonhosted.org/packages/01/55/e69188b939f77d5d32a9833745ace31ea5ccae3ab613a1ec185d3cd2c4fb/orjson-3.11.9-cp314-cp314-musllinux_1_2_armv7l.whl": "sha256:5b192c6cf397e4455b11523c5cf2b18ed084c1bbd61b6c0926344d2129481972", + "https://files.pythonhosted.org/packages/04/83/45fbb6d962e260807f99441db9613cee868ceda4baceda59b3720a563f97/orjson-3.11.9-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:9f78cf8fec5bd627f4082b8dfeac7871b43d7f3274904492a43dab39f18a19a0", + "https://files.pythonhosted.org/packages/05/94/b0d27090ea8a2095db3c2bd1b1c96f96f19bbb494d7fef33130e846e613d/orjson-3.11.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:03db380e3780fa0015ed776a90f20e8e20bb11dde13b216ce19e5718e3dfba62", + "https://files.pythonhosted.org/packages/06/69/850264ccf6d80f6b174620d30a87f65c9b1490aba33fe6b62798e618cad3/orjson-3.11.9-cp312-cp312-win32.whl": "sha256:2d057a602cdd19a0ad680417527c45b6961a095081c0f46fe0e03e304aac6470", + "https://files.pythonhosted.org/packages/09/d3/c5824260ca8b9d7ba82648d042a3f8f4815d18c15bb98a1f30edd1bb2d83/orjson-3.11.9-cp310-cp310-musllinux_1_2_armv7l.whl": "sha256:87e4d4ab280b0c87424d47695bec2182caf8cfc17879ea78dab76680194abc13", + "https://files.pythonhosted.org/packages/09/eb/75d50c29c05b8054013e221e598820a365c8e64065312e75e202ed880709/orjson-3.11.9-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:33d7d766701847dc6729846362dc27895d2f2d2251264f9d10e7cb9878194877", + "https://files.pythonhosted.org/packages/0b/ee/66154baf69f71c7164a268a5e888908aec5a0819d13c81d5e2755a257758/orjson-3.11.9-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:0b34789fa0da61cf7bef0546b09c738fb195331e017e477096d129e9105ab03d", + "https://files.pythonhosted.org/packages/0d/ba/a23b82a0a8d0ed7bed4e5f5035aae751cad4ff6a1e8d2ecd14d8860f5929/orjson-3.11.9-cp314-cp314-win32.whl": "sha256:e30ab17845bb9fa54ccf67fa4f9f5282652d54faa6d17452f47d0f369d038673", + "https://files.pythonhosted.org/packages/0d/bd/70b6ab193594d7abb875320c0a7c8335e846f28968c432c31042409c3c8d/orjson-3.11.9-cp311-cp311-win32.whl": "sha256:14ed654580c1ed2bc217352ec82f91b047aef82951aa71c7f64e0dcb03c0e180", + "https://files.pythonhosted.org/packages/0e/30/3178eb16f3221aeef068b6f1f1ebe05f656ea5c6dffe9f6c917329fe17a3/orjson-3.11.9-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:3513550321f8c8c811a7c3297b8a630e82dc08e4c10216d07703c997776236cd", + "https://files.pythonhosted.org/packages/0e/a4/82b7a2fe5d8a67a59ed831b24d59a3d46ea7d207b66e1602d376541d94a6/orjson-3.11.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:be4fa4f0af7fa18951f7ab3fc2148e223af211bf03f59e1c6034ec3f97f21d61", + "https://files.pythonhosted.org/packages/10/5d/b95ca542a001135cc250a49370f282f578c8f4e46cc8617d73775297eea8/orjson-3.11.9-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl": "sha256:135869ef917b8704ea0a94e01620e0c05021c15c52036e4663baffe75e72f8ce", + "https://files.pythonhosted.org/packages/11/d4/5bdb0626801230139987385554c5d4c42255218ac906525bf4347f22cd95/orjson-3.11.9-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:4fd66214623f1b17501df9f0543bef0b833979ab5b6ded1e1d123222866aa8c9", + "https://files.pythonhosted.org/packages/13/d8/5f0555e7638801323b7a75850f92e7dfa891bc84fe27a1ba4449170d1200/orjson-3.11.9-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:ea5c46eb2d3af39e806b986f4b09d5c2706a1f5afde3cbf7544ce6616127173c", + "https://files.pythonhosted.org/packages/16/21/5a3f1e8913103b703a436a5664238e5b965ec392b555fe68943ea3691e6b/orjson-3.11.9-cp314-cp314-win_arm64.whl": "sha256:eebdbdeef0094e4f5aefa20dcd4eb2368ab5e7a3b4edea27f1e7b2892e009cf9", + "https://files.pythonhosted.org/packages/16/64/bd815f5c610b3facc204f26ba94e87a9eb49b0d83de3d5fc1eee2402d91b/orjson-3.11.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:231742b4a11dad8d5380a435962c57e91b7c37b79be858f4ef1c0df1a259897e", + "https://files.pythonhosted.org/packages/16/6d/11867a3ffa3a3608d84a4de51ef4dd0896d6b5cc9132fbe1daf593e677bc/orjson-3.11.9-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl": "sha256:9ef6fe90aadef185c7b128859f40beb24720b4ecea95379fc9000931179c3a49", + "https://files.pythonhosted.org/packages/16/fa/9d54b07cb3f3b0bfd57841478e42d7a0ece4a9f49f9907eecf5a45461687/orjson-3.11.9-cp311-cp311-macosx_15_0_arm64.whl": "sha256:3ebca4179031ee716ed076ffadc29428e900512f6fccee8614c9983157fcf19c", + "https://files.pythonhosted.org/packages/1e/51/3fb9e65ae76ee97bd611869a503fa3fc0a6e81dd8b737cf3003f682df7ff/orjson-3.11.9-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl": "sha256:f01c4818b3fc9b0da8e096722a84318071eaa118df35f6ed2344da0e73a5444f", + "https://files.pythonhosted.org/packages/1f/7d/30e844b3dac3f74aed66b1f984daf9db3c98c0328c03d965a9e8dc06449e/orjson-3.11.9-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:53b50b0e14084b8f7e29c5ce84c5af0f1160169b30d8a6914231d97d2fe297d4", + "https://files.pythonhosted.org/packages/21/0f/c9ede0bf052f6b4051e64a7d4fa91b725cccf8321a6a786e86eb03519f00/orjson-3.11.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:ffe02797b5e9f3a9d8292ddcd289b474ad13e81ad83cd1891a240811f1d2cb81", + "https://files.pythonhosted.org/packages/24/75/05912954c8b288f34fcf5cd4b9b071cb4f6e77b9961e175e56ebb258089f/orjson-3.11.9-cp312-cp312-macosx_15_0_arm64.whl": "sha256:e5c9b8f28e726e97d97696c826bc7bea5d71cecd63576dba92924a32c1961291", + "https://files.pythonhosted.org/packages/2a/56/d54152b67b63a0b3e556cfc549d6ce84f74d7f425ddeadc6c8a74d913da7/orjson-3.11.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:71f3db16e69b667b132e0f305a833d5497da302d801508cbb051ed9a9819da47", + "https://files.pythonhosted.org/packages/2e/1a/b8a5a7ac527e80b9cb11d51e3f6689b709279183264b9ec5c7bc680bb8b5/orjson-3.11.9-cp314-cp314-musllinux_1_2_i686.whl": "sha256:ea407d4ccf5891d667d045fecae97a7a1e5e87b3b97f97ae1803c2e741130be0", + "https://files.pythonhosted.org/packages/31/6a/6cf69385a58208024fcb8c014e2141b8ce838aba6492b589f8acfff97fab/orjson-3.11.9-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:c2d3dc759490128c5c1711a53eeaa8ee1d437fd0038ffd2b6008abf46db3f882", + "https://files.pythonhosted.org/packages/32/33/93fcc25907235c344ae73122f8a4e01d2d393ef062b4af7d2e2487a32c37/orjson-3.11.9-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl": "sha256:4bab1b2d6141fe7b32ae71dac905666ece4f94936efbfb13d55bb7739a3a6021", + "https://files.pythonhosted.org/packages/3a/dc/7446c538590d55f455647e5f3c61fc33f7108714e7afcffa6a2a033f8350/orjson-3.11.9-cp312-cp312-musllinux_1_2_i686.whl": "sha256:cde1a448023ba7d5bb4c01c5afb48894380b5e4956e0627266526587ef4e535f", + "https://files.pythonhosted.org/packages/3d/57/1b30daf70f0d8180e9a73cefbfbdd99e4bf19eb020466502b01fba7e0e50/orjson-3.11.9-cp313-cp313-musllinux_1_2_i686.whl": "sha256:97db4c94a7db398a5bd636273324f0b3fd58b350bbbac8bb380ceb825a9b40f4", + "https://files.pythonhosted.org/packages/3f/17/1a1a228183d62d1b77e2c30d210f47dd4768b310ebe1607c63e3c0e3a71e/orjson-3.11.9-cp311-cp311-win_amd64.whl": "sha256:57ea77fb70a448ce87d18fca050193202a3da5e54598f6501ca5476fb66cfe02", + "https://files.pythonhosted.org/packages/49/bd/360686f39348aa88827cb6fbf7dc606fd41c831a35235e1abf1db8e3a9e6/orjson-3.11.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:147302878da387104b66bb4a8b0227d1d487e976ce41a8501916161072ed87b1", + "https://files.pythonhosted.org/packages/4e/61/73d49333bba660a075daccca10970dc6409ce1cf42ae4046646a19468aad/orjson-3.11.9-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl": "sha256:4da3c38a2083ca4aaf9c2a36776cce3e9328e6647b10d118948f3cfb4913ffe4", + "https://files.pythonhosted.org/packages/50/c7/375e83a76851b73b2e39f3bcf0e5a19e2b89bad13e5bca97d0b293d27f24/orjson-3.11.9-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:a8f5f8bc7ce7d59f08d9f99fa510c06496164a24cb5f3d34537dbd9ca30132e2", + "https://files.pythonhosted.org/packages/5a/5a/07d8aa117211a8ed7630bda80c8c0b14d04e0f8dcf99bcf49656e4a710eb/orjson-3.11.9-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:08f4d8ebb44925c794e535b2bebc507cebf32209df81de22ae285fb0d8d66de0", + "https://files.pythonhosted.org/packages/5f/cc/2d10025f9056d376e4127ec05a5808b218d46f035fdc08178a5411b34250/orjson-3.11.9-cp313-cp313-win32.whl": "sha256:d4087e5c0209a0a8efe4de3303c234b9c44d1174161dcd851e8eea07c7560b32", + "https://files.pythonhosted.org/packages/5f/f1/ff2f19ed0225f9680fafa42febca3570dd59444ebf190980738d376214c2/orjson-3.11.9-cp311-cp311-musllinux_1_2_armv7l.whl": "sha256:c5d001196b89fa9cf0a4ab79766cd835b991a166e4b621ba95089edc50c429ff", + "https://files.pythonhosted.org/packages/64/62/3e0e0c14c957133bcd855395c62b55ed4e3b0af23ffea11b032cb1dcbdb1/orjson-3.11.9-cp314-cp314-macosx_15_0_arm64.whl": "sha256:f36b7f32c7c0db4a719f1fc5824db4a9c6f8bd1a354debb91faf26ebf3a4c71e", + "https://files.pythonhosted.org/packages/64/cb/509c2e816fe4df641d93dc92f6a89adc8df3ada8ebdee2bd44aba3264c3c/orjson-3.11.9-cp310-cp310-musllinux_1_2_i686.whl": "sha256:ace6c58523302d3b97b6ac5c38a5298a54b473762b6be82726b4265c41029f92", + "https://files.pythonhosted.org/packages/66/60/52b0054c4c700d5aa7fc5b7ca96917400d8f061307778578e67a10e25852/orjson-3.11.9-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:8aff7da9952a5ad1cef8e68017724d96c7b9a66e99e91d6252e1b133d67a7b10", + "https://files.pythonhosted.org/packages/67/bd/2775ff28bfe883b9aa1ff348300542eb2ef1ee18d8ae0e3a49846817a865/orjson-3.11.9-cp313-cp313-win_amd64.whl": "sha256:051b102c93b4f634e89f3866b07b9a9a98915ada541f4ec30f177067b2694979", + "https://files.pythonhosted.org/packages/76/3e/c0b690253f0b82d86e99949af13533363acfb5432ecb5d53dd5b3bce9c34/orjson-3.11.9-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db", + "https://files.pythonhosted.org/packages/7e/0c/964746fcafbd16f8ff53219ad9f6b412b34f345c75f384ad434ceaadb538/orjson-3.11.9.tar.gz": "sha256:4fef17e1f8722c11587a6ef18e35902450221da0028e65dbaaa543619e68e48f", + "https://files.pythonhosted.org/packages/7f/7c/49d5d82a3d3097f641f094f552131f1e2723b0b8cb0fa2874ab65ecfffa6/orjson-3.11.9-cp312-cp312-musllinux_1_2_armv7l.whl": "sha256:4d7fde5501b944f83b3e665e1b31343ff6e154b15560a16b7130ea1e594a4206", + "https://files.pythonhosted.org/packages/80/01/be33fbff646e22f93398429ea645f20d2097aea1a6cdc1e6628e70125f83/orjson-3.11.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:115ab5f5f4a0f203cc2a5f0fb09aee503a3f771aa08392949ab5ca230c4fbdbd", + "https://files.pythonhosted.org/packages/88/b1/6ceafc2eefd0a553e3be77ce6c49d107e772485d9568629376171c50e634/orjson-3.11.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:48ee05097750de0ff69ed5b7bbcf0732182fd57a24043dcc2a1da780a5ead3a5", + "https://files.pythonhosted.org/packages/8e/eb/5da01e356015aee6ecfa1187ced87aef51364e306f5e695dd52719bf0e78/orjson-3.11.9-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl": "sha256:b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e", + "https://files.pythonhosted.org/packages/8f/27/b1e6dadb3c080313c03fdd8067b85e6a0460c7d8d6a1c3984ef77b904e4d/orjson-3.11.9-cp313-cp313-macosx_15_0_arm64.whl": "sha256:844417969855fc7a41be124aafe83dc424592a7f77cd4501900c67307122b92c", + "https://files.pythonhosted.org/packages/91/2b/d26799e580939e32a7da9a39531bc9e58e15ca32ffaa6a8cb3e9bb0d22cd/orjson-3.11.9-cp313-cp313-win_arm64.whl": "sha256:cce9127885941bd28f080cecf1f1d288336b7e0d812c345b08be88b572796254", + "https://files.pythonhosted.org/packages/97/4e/00503f64204bf859b37213a63927028f30fb6268cd8677fb0a5ad48155e1/orjson-3.11.9-cp314-cp314-musllinux_1_2_x86_64.whl": "sha256:5f63aaf97afd9f6dec5b1a68e1b8da12bfccb4cb9a9a65c3e0b6c847849e7586", + "https://files.pythonhosted.org/packages/9b/61/863bddf0da6e9e586765414debd54b4e58db05f560902b6d00658cb88636/orjson-3.11.9-cp311-cp311-musllinux_1_2_i686.whl": "sha256:16969c9d369c98eb084889c6e4d2d39b77c7eb38ceccf8da2a9fff62ae908980", + "https://files.pythonhosted.org/packages/9e/85/0ef63bcf1337f44031ce9b91b1919563f62a37527b3ea4368bb15a22e5d7/orjson-3.11.9-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:277fefe9d76ee17eb14debf399e3533d4d63b5f677a4d3719eb763536af1f4bd", + "https://files.pythonhosted.org/packages/a1/08/dca0082dd2a194acb93e5457e73455388e2e2ca464a2672449a9ddbb679d/orjson-3.11.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:4e39364e726a8fff737309aff059ff67d8a8c8d5b677be7bb49a8b3e84b7e218", + "https://files.pythonhosted.org/packages/ab/86/1c3a47df3bc8191ea9ac51603bbb872a95167a364320c269f2557911f406/orjson-3.11.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:26a473dbb4162108b27901492546f83c76fdcea3d0eadff00ae7a07e18dcce09", + "https://files.pythonhosted.org/packages/ae/d8/b64600f9083c7f151ad39717a5877fccbeb0ef6d7efcb55f971ce00b6bee/orjson-3.11.9-cp310-cp310-win_amd64.whl": "sha256:8697ab6a080a5c46edaad50e2bc5bd8c7ca5c66442d24104fa44ec74910a8244", + "https://files.pythonhosted.org/packages/b6/30/ed9860412a3603ceb3c5955bfd72d28b9d0e7ba6ed81add14f83d7114236/orjson-3.11.9-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:f5d89a2ed90731df3be64bab0aa44f78bff39fdc9d71c291f4a8023aa46425b7", + "https://files.pythonhosted.org/packages/b6/8a/4081492586d75b073d60c5271a8d0f05a0955cabf1e34c8473f6fcd84235/orjson-3.11.9-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:63e0efbc991250c0b3143488fa57d95affcabbfc63c99c48d625dd37779aafe2", + "https://files.pythonhosted.org/packages/b8/95/285de5fa296d09681ee9c546cd4a8aeb773b701cf343dc125994f4d52953/orjson-3.11.9-cp311-cp311-win_arm64.whl": "sha256:19b72ed11572a2ee51a67a903afbe5af504f84ed6f529c0fe44b0ab3fb5cc697", + "https://files.pythonhosted.org/packages/b9/d5/973a43fc9c55e20f2051e9830997649f669be0cb3ca52192087c0143f118/orjson-3.11.9-cp312-cp312-win_amd64.whl": "sha256:59e403b1cc5a676da8eaf31f6254801b7341b3e29efa85f92b48d272637e77be", + "https://files.pythonhosted.org/packages/c1/7a/bc82a0bb25e9faaf92dc4d9ef002732efc09737706af83e346788641d4a7/orjson-3.11.9-cp314-cp314-musllinux_1_2_aarch64.whl": "sha256:a028425d1b440c5d92a6be1e1a020739dfe67ea87d96c6dbe828c1b30041728b", + "https://files.pythonhosted.org/packages/c7/35/e744fd36c79b339d27beb06068b5a08a8882ef5418804d0ce545a31f718d/orjson-3.11.9-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:34fd2317602587321faab75ab76c623a0117e80841a6413654f04e47f339a8fb", + "https://files.pythonhosted.org/packages/d0/17/adc514dea7ac7c505527febf884934b815d34f0c7b8693c1a8b39c5c4a57/orjson-3.11.9-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:25e4aed0312d292c09f61af25bba34e0b2c88546041472b09088c39a4d828af1", + "https://files.pythonhosted.org/packages/d5/97/1e3dc2b2a28b7b2528f403d2fc1d79ec5f39af3bc143ab65d3ec26426385/orjson-3.11.9-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:4d4e98d6f3b8afed8bc8cd9718ec0cdf46661826beefb53fe8eafb37f2bf0362", + "https://files.pythonhosted.org/packages/d6/ec/4acaf21483e18aa945be74a474c74b434f284b549f275a0a39b9f98956e9/orjson-3.11.9-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl": "sha256:6cc7923789694fd58f001cbcac7e47abc13af4d560ebbfcf3b41a8b1a0748124", + "https://files.pythonhosted.org/packages/d7/7a/81fa3f2c7bef79b04cf2ab7838e5ac74b1f12511ceab979759b0275d6bb4/orjson-3.11.9-cp310-cp310-win32.whl": "sha256:b3afcf569c15577a9fe64627292daa3e6b3a70f4fb77a5df246a87ec21681b94", + "https://files.pythonhosted.org/packages/d7/cf/b33b5f3e695ae7d63feef9d915c37cc3b8f465493dcd4f8e0b4c697a2366/orjson-3.11.9-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl": "sha256:011382e2a60fda9d46f1cdee31068cfc52ffe952b587d683ec0463002802a0f4", + "https://files.pythonhosted.org/packages/db/b5/3ceae56d2e4962979eedb023ba6a46a4bb65f333960379be0ca470686220/orjson-3.11.9-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:97d0d932803c1b164fde11cb542a9efcb1e0f63b184537cca65887147906ff48", + "https://files.pythonhosted.org/packages/df/e5/4d2d8af06f788329b4f78f8cc3679bb395392fcaa1e4d8d3c33e85308fa4/orjson-3.11.9-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:71e63adb0e1f1ed5d9e168f50a91ceb93ae6420731d222dc7da5c69409aa47aa", + "https://files.pythonhosted.org/packages/e8/f8/0b1bd3e8f2efcdd376af5c8cfd79eaf13f018080c0089c80ebd724e3c7fb/orjson-3.11.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:d8ea516b3726d190e1b4297e6f4e7a8650347ae053868a18163b4dd3641d1fff", + "https://files.pythonhosted.org/packages/ea/76/f11311285324a40aab1e3031385c50b635a7cd0734fdaf60c7e89a696f60/orjson-3.11.9-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl": "sha256:a6082706765a95a6680d812e1daf1c0cfe8adec7831b3ff3b625693f3b461b1c", + "https://files.pythonhosted.org/packages/f3/59/dab79f61044c529d2c81aecdc589b1f833a1c8dec11ba3b1c2498a02ca7e/orjson-3.11.9-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:380cdce7ba24989af81d0a7013d0aaec5d0e2a21734c0e2681b1bc4f141957fe", + "https://files.pythonhosted.org/packages/f3/c3/0c6798456bade745c75c452342dabacce5798196483e77e643be1f53877d/orjson-3.11.9-cp314-cp314-win_amd64.whl": "sha256:32ef5f4283a3be81913947d19608eacb7c6608026851123790cd9cc8982af34b", + "https://files.pythonhosted.org/packages/fa/88/a21fb53b3ede6703aede6dce4710ed4111e5b201cfa6bbff5e544f9d47d7/orjson-3.11.9-cp313-cp313-musllinux_1_2_armv7l.whl": "sha256:8ecc30f10465fa1e0ce13fd01d9e22c316e5053a719a8d915d4545a09a5ff677", + "https://files.pythonhosted.org/packages/fc/39/31fbfe7850f2de32dee7e7e5c09f26d403ab01e440ac96001c6b01ad3c99/orjson-3.11.9-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:3a81d52442a7c99b3662333235b3adf96a1715864658b35bb797212be7bddb97", + "https://files.pythonhosted.org/packages/fd/26/d398e28048dc18205bbe812f2c88cb9b40313db2470778e25964796458fe/orjson-3.11.9-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl": "sha256:0e4eed3b200023042814d2fc8a5d2e880f13b52e1ed2485e83da4f3962f7dc1a", + "https://files.pythonhosted.org/packages/fe/ae/495470f0e4a18f73fa10b7f6b84b464ec4cc5291c4e0c7c2a6c400bef006/orjson-3.11.9-cp312-cp312-win_arm64.whl": "sha256:9af678d6488357948f1f84c6cd1c1d397c014e1ae2f98ae082a44eb48f602624" + }, + "packaging": { + "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl": "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", + "https://files.pythonhosted.org/packages/7d/fa/3944b40b07da9ce895c0e6303a5ab7d53da063554f534556b134a54d6093/packaging-26.3.tar.gz": "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", + "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz": "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", + "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl": "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e" + }, + "pathspec": { + "https://files.pythonhosted.org/packages/5a/82/42f767fc1c1143d6fd36efb827202a2d997a375e160a71eb2888a925aac1/pathspec-1.1.1.tar.gz": "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a", + "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl": "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189" + }, + "pelican": { + "https://files.pythonhosted.org/packages/6e/55/4adcce41a45f8f77e69d7e84ea447819dae1a78b4b9762a104599e5ec811/pelican-4.12.0-py3-none-any.whl": "sha256:3697230f56cfcca9e98d3ac9ac26f655bb20cad807f7eacf156601e241f69ad8", + "https://files.pythonhosted.org/packages/c4/8d/da26b77f0d9827d341bdedea357ccb5670717e3a9b4142e3e44c7f34db44/pelican-4.12.0.tar.gz": "sha256:3983b5d2dc84c7bdf967154359077a2b78c0bbd2f7dcc55292133a7779609458" + }, + "pelican-webassets": { + "https://files.pythonhosted.org/packages/42/d6/844e251c8da875d6ff4a86715394f43f8ad2141d70577f7e77e4058576b2/pelican_webassets-2.1.0-py3-none-any.whl": "sha256:9df6659ecb565af88df55df4aac27cafc948299ef3d4fc743f7385db2e274475", + "https://files.pythonhosted.org/packages/a1/22/6241f976879780ec6f89bf45df36952169f305cdddbaabcba2ae797e699e/pelican_webassets-2.1.0.tar.gz": "sha256:0a418b88ebd6d96efae4d666394552bcacc8d30d2f0abb5bb4db26064e8cfed0" + }, + "pep8-naming": { + "https://files.pythonhosted.org/packages/8d/59/c32862134635ba231d45f1711035550dc38246396c27269a4cde4bfe18d2/pep8_naming-0.15.1.tar.gz": "sha256:f6f4a499aba2deeda93c1f26ccc02f3da32b035c8b2db9696b730ef2c9639d29", + "https://files.pythonhosted.org/packages/a6/78/25281540f1121acaa78926f599a17ce102b8971bc20b096fa7fb6b5b59c1/pep8_naming-0.15.1-py3-none-any.whl": "sha256:eb63925e7fd9e028c7f7ee7b1e413ec03d1ee5de0e627012102ee0222c273c86" + }, + "platformdirs": { + "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz": "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", + "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl": "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb" + }, + "ply": { + "https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl": "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce", + "https://files.pythonhosted.org/packages/e5/69/882ee5c9d017149285cab114ebeab373308ef0f874fcdac9beb90e0ac4da/ply-3.11.tar.gz": "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3" + }, + "prometheus-client": { + "https://files.pythonhosted.org/packages/62/14/7d0f567991f3a9af8d1cd4f619040c93b68f09a02b6d0b6ab1b2d1ded5fe/prometheus_client-0.21.1.tar.gz": "sha256:252505a722ac04b0456be05c05f75f45d760c2911ffc45f2a06bcaed9f3ae3fb", + "https://files.pythonhosted.org/packages/ff/c2/ab7d37426c179ceb9aeb109a85cda8948bb269b7561a0be870cc656eefe4/prometheus_client-0.21.1-py3-none-any.whl": "sha256:594b45c410d6f4f8888940fe80b5cc2521b305a1fafe1c58609ef715a001f301" + }, + "propcache": { + "https://files.pythonhosted.org/packages/05/fc/cb52a0caf803caff9b95b0a99e7c9c87f15b7e34ba0feebfd2572b49013d/propcache-0.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:82de5da8c8893056603ac2d6a89eb8b4df49abf1a7c19d536984c8dd63f481d5", + "https://files.pythonhosted.org/packages/06/5d/3b921b9c60659ae464137508d3b4c2b3f52f592ceb1964aa2533b32fcf0b/propcache-0.3.1-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:71ebe3fe42656a2328ab08933d420df5f3ab121772eef78f2dc63624157f0ed9", + "https://files.pythonhosted.org/packages/07/c8/fdc6686a986feae3541ea23dcaa661bd93972d3940460646c6bb96e21c40/propcache-0.3.1.tar.gz": "sha256:40d980c33765359098837527e18eddefc9a24cea5b45e078a7f3bb5b032c6ecf", + "https://files.pythonhosted.org/packages/0a/06/0da53397c76a74271621807265b6eb61fb011451b1ddebf43213df763669/propcache-0.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:c2fe5c910f6007e716a06d269608d307b4f36e7babee5f36533722660e8c4a70", + "https://files.pythonhosted.org/packages/0d/f1/16e12c33e3dbe7f8b737809bad05719cff1dccb8df4dafbcff5575002c0e/propcache-0.3.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:5ced33d827625d0a589e831126ccb4f5c29dfdf6766cac441d23995a65825dcb", + "https://files.pythonhosted.org/packages/11/1a/ac0f757cc0babdc8217056fca85150066cf43bf11db9651e6b7d8e0646d6/propcache-0.3.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:27c6ac6aa9fc7bc662f594ef380707494cb42c22786a558d95fcdedb9aa5d035", + "https://files.pythonhosted.org/packages/11/1c/311326c3dfce59c58a6098388ba984b0e5fb0381ef2279ec458ef99bd547/propcache-0.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl": "sha256:9f64d91b751df77931336b5ff7bafbe8845c5770b06630e27acd5dbb71e1931c", + "https://files.pythonhosted.org/packages/15/43/0b8eb2a55753c4a574fc0899885da504b521068d3b08ca56774cad0bea2b/propcache-0.3.1-cp310-cp310-macosx_11_0_arm64.whl": "sha256:730178f476ef03d3d4d255f0c9fa186cb1d13fd33ffe89d39f2cda4da90ceb71", + "https://files.pythonhosted.org/packages/17/76/9632254479c55516f51644ddbf747a45f813031af5adcb8db91c0b824375/propcache-0.3.1-cp310-cp310-musllinux_1_2_i686.whl": "sha256:9979643ffc69b799d50d3a7b72b5164a2e97e117009d7af6dfdd2ab906cb72cd", + "https://files.pythonhosted.org/packages/18/6d/a008e07ad7b905011253adbbd97e5b5375c33f0b961355ca0a30377504ac/propcache-0.3.1-cp313-cp313-musllinux_1_2_armv7l.whl": "sha256:05543250deac8e61084234d5fc54f8ebd254e8f2b39a16b1dce48904f45b744b", + "https://files.pythonhosted.org/packages/18/c6/9a39b2646a71321815d8d616e890851af9fb327af7d1b9fdce7d2d8377ca/propcache-0.3.1-cp39-cp39-macosx_10_9_x86_64.whl": "sha256:668ddddc9f3075af019f784456267eb504cb77c2c4bd46cc8402d723b4d200bf", + "https://files.pythonhosted.org/packages/19/3b/6c44fa59d6418f4239d5db8b1ece757351e85d6f3ca126dfe37d427020c8/propcache-0.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:9e64e948ab41411958670f1093c0a57acfdc3bee5cf5b935671bbd5313bcf229", + "https://files.pythonhosted.org/packages/19/7e/2237dad1dbffdd2162de470599fa1a1d55df493b16b71e5d25a0ac1c1543/propcache-0.3.1-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:2d219b0dbabe75e15e581fc1ae796109b07c8ba7d25b9ae8d650da582bed01b0", + "https://files.pythonhosted.org/packages/1a/d8/f0c17c44d1cda0ad1979af2e593ea290defdde9eaeb89b08abbe02a5e8e1/propcache-0.3.1-cp312-cp312-macosx_10_13_x86_64.whl": "sha256:89498dd49c2f9a026ee057965cdf8192e5ae070ce7d7a7bd4b66a8e257d0c976", + "https://files.pythonhosted.org/packages/1d/3a/8a68dd867da9ca2ee9dfd361093e9cb08cb0f37e5ddb2276f1b5177d7731/propcache-0.3.1-cp311-cp311-win_amd64.whl": "sha256:9532ea0b26a401264b1365146c440a6d78269ed41f83f23818d4b79497aeabe7", + "https://files.pythonhosted.org/packages/20/56/e27c136101addf877c8291dbda1b3b86ae848f3837ce758510a0d806c92f/propcache-0.3.1-cp310-cp310-macosx_10_9_universal2.whl": "sha256:f27785888d2fdd918bc36de8b8739f2d6c791399552333721b58193f68ea3e98", + "https://files.pythonhosted.org/packages/23/a9/2a2f8d93d8f526c35dd8dbbc4a1ac22a106712cd821e15e2a6530aea8931/propcache-0.3.1-cp39-cp39-musllinux_1_2_aarch64.whl": "sha256:b303b194c2e6f171cfddf8b8ba30baefccf03d36a4d9cab7fd0bb68ba476a3d7", + "https://files.pythonhosted.org/packages/24/bb/3b1b01da5dd04c77a204c84e538ff11f624e31431cfde7201d9110b092b1/propcache-0.3.1-cp312-cp312-win_amd64.whl": "sha256:88c423efef9d7a59dae0614eaed718449c09a5ac79a5f224a8b9664d603f04a3", + "https://files.pythonhosted.org/packages/31/0a/49ff7e5056c17dfba62cbdcbb90a29daffd199c52f8e65e5cb09d5f53a57/propcache-0.3.1-cp310-cp310-win_amd64.whl": "sha256:47ef24aa6511e388e9894ec16f0fbf3313a53ee68402bc428744a367ec55b833", + "https://files.pythonhosted.org/packages/35/36/0bbabaacdcc26dac4f8139625e930f4311864251276033a52fd52ff2a274/propcache-0.3.1-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:5a0a9898fdb99bf11786265468571e628ba60af80dc3f6eb89a3545540c6b0ef", + "https://files.pythonhosted.org/packages/39/e6/d51601342e53cc7582449e6a3c14a0479fab2f0750c1f4d22302e34219c6/propcache-0.3.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:5aed8d8308215089c0734a2af4f2e95eeb360660184ad3912686c181e500b2e7", + "https://files.pythonhosted.org/packages/3b/4c/f72c9e1022b3b043ec7dc475a0f405d4c3e10b9b1d378a7330fecf0652da/propcache-0.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:563f9d8c03ad645597b8d010ef4e9eab359faeb11a0a2ac9f7b4bc8c28ebef25", + "https://files.pythonhosted.org/packages/3b/4d/be5f1a90abc1881884aa5878989a1acdafd379a91d9c7e5e12cef37ec0d7/propcache-0.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:6d8e309ff9a0503ef70dc9a0ebd3e69cf7b3894c9ae2ae81fc10943c37762458", + "https://files.pythonhosted.org/packages/3e/2f/854e653c96ad1161f96194c6678a41bbb38c7947d17768e8811a77635a08/propcache-0.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:3e584b6d388aeb0001d6d5c2bd86b26304adde6d9bb9bfa9c4889805021b96de", + "https://files.pythonhosted.org/packages/3e/66/2e90547d6b60180fb29e23dc87bd8c116517d4255240ec6d3f7dc23d1926/propcache-0.3.1-cp313-cp313t-win32.whl": "sha256:359e81a949a7619802eb601d66d37072b79b79c2505e6d3fd8b945538411400d", + "https://files.pythonhosted.org/packages/3e/a2/018b9f2ed876bf5091e60153f727e8f9073d97573f790ff7cdf6bc1d1fb8/propcache-0.3.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:4114c4ada8f3181af20808bedb250da6bae56660e4b8dfd9cd95d4549c0962f7", + "https://files.pythonhosted.org/packages/3e/c3/a90b773cf639bd01d12a9e20c95be0ae978a5a8abe6d2d343900ae76cd71/propcache-0.3.1-cp310-cp310-musllinux_1_2_ppc64le.whl": "sha256:4cf9e93a81979f1424f1a3d155213dc928f1069d697e4353edb8a5eba67c6259", + "https://files.pythonhosted.org/packages/40/8d/090955e13ed06bc3496ba4a9fb26c62e209ac41973cb0d6222de20c6868f/propcache-0.3.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:8a17583515a04358b034e241f952f1715243482fc2c2945fd99a1b03a0bd77d6", + "https://files.pythonhosted.org/packages/41/aa/ca78d9be314d1e15ff517b992bebbed3bdfef5b8919e85bf4940e57b6137/propcache-0.3.1-cp312-cp312-macosx_10_13_universal2.whl": "sha256:f78eb8422acc93d7b69964012ad7048764bb45a54ba7a39bb9e146c72ea29723", + "https://files.pythonhosted.org/packages/45/5f/3faee66fc930dfb5da509e34c6ac7128870631c0e3582987fad161fcb4b1/propcache-0.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:975af16f406ce48f1333ec5e912fe11064605d5c5b3f6746969077cc3adeb120", + "https://files.pythonhosted.org/packages/4a/1f/ecd9ce27710021ae623631c0146719280a929d895a095f6d85efb6a0be2e/propcache-0.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl": "sha256:17d1c688a443355234f3c031349da69444be052613483f3e4158eef751abcd8a", + "https://files.pythonhosted.org/packages/4b/74/91939924b0385e54dc48eb2e4edd1e4903ffd053cf1916ebc5347ac227f7/propcache-0.3.1-cp313-cp313t-musllinux_1_2_armv7l.whl": "sha256:19a06db789a4bd896ee91ebc50d059e23b3639c25d58eb35be3ca1cbe967c3bf", + "https://files.pythonhosted.org/packages/4d/e5/5ef30eb2cd81576256d7b6caaa0ce33cd1d2c2c92c8903cccb1af1a4ff2f/propcache-0.3.1-cp313-cp313t-macosx_10_13_x86_64.whl": "sha256:0fbe94666e62ebe36cd652f5fc012abfbc2342de99b523f8267a678e4dfdee3c", + "https://files.pythonhosted.org/packages/53/1b/d3406629a2c8a5666d4674c50f757a77be119b113eedd47b0375afdf1b42/propcache-0.3.1-cp313-cp313-musllinux_1_2_ppc64le.whl": "sha256:f3bbecd2f34d0e6d3c543fdb3b15d6b60dd69970c2b4c822379e5ec8f6f621d5", + "https://files.pythonhosted.org/packages/54/6e/30a11f4417d9266b5a464ac5a8c5164ddc9dd153dfa77bf57918165eb4ae/propcache-0.3.1-cp311-cp311-win32.whl": "sha256:58aa11f4ca8b60113d4b8e32d37e7e78bd8af4d1a5b5cb4979ed856a45e62005", + "https://files.pythonhosted.org/packages/57/2b/8f61b998c7ea93a2b7eca79e53f3e903db1787fca9373af9e2cf8dc22f9d/propcache-0.3.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:b655032b202028a582d27aeedc2e813299f82cb232f969f87a4fde491a233f11", + "https://files.pythonhosted.org/packages/58/60/f645cc8b570f99be3cf46714170c2de4b4c9d6b827b912811eff1eb8a412/propcache-0.3.1-cp313-cp313-macosx_10_13_universal2.whl": "sha256:f1528ec4374617a7a753f90f20e2f551121bb558fcb35926f99e3c42367164b8", + "https://files.pythonhosted.org/packages/58/70/2117780ed7edcd7ba6b8134cb7802aada90b894a9810ec56b7bb6018bee7/propcache-0.3.1-cp313-cp313t-musllinux_1_2_s390x.whl": "sha256:e474fc718e73ba5ec5180358aa07f6aded0ff5f2abe700e3115c37d75c947e18", + "https://files.pythonhosted.org/packages/59/f9/4c0a5cf6974c2c43b1a6810c40d889769cc8f84cea676cbe1e62766a45f8/propcache-0.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:f6f1324db48f001c2ca26a25fa25af60711e09b9aaf4b28488602776f4f9a744", + "https://files.pythonhosted.org/packages/5a/a8/0a4fd2f664fc6acc66438370905124ce62e84e2e860f2557015ee4a61c7e/propcache-0.3.1-cp313-cp313t-macosx_10_13_universal2.whl": "sha256:a444192f20f5ce8a5e52761a031b90f5ea6288b1eef42ad4c7e64fef33540b8f", + "https://files.pythonhosted.org/packages/61/73/d64abb7bb5d18880ecfac152247c0f1a5807256ea21e4737ce3019afffeb/propcache-0.3.1-cp39-cp39-win_amd64.whl": "sha256:603f1fe4144420374f1a69b907494c3acbc867a581c2d49d4175b0de7cc64566", + "https://files.pythonhosted.org/packages/62/1e/a0d5ebda5da7ff34d2f5259a3e171a94be83c41eb1e7cd21a2105a84a02e/propcache-0.3.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:a34aa3a1abc50740be6ac0ab9d594e274f59960d3ad253cd318af76b996dd654", + "https://files.pythonhosted.org/packages/62/37/fc357e345bc1971e21f76597028b059c3d795c5ca7690d7a8d9a03c9708a/propcache-0.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:d249609e547c04d190e820d0d4c8ca03ed4582bcf8e4e160a6969ddfb57b62e5", + "https://files.pythonhosted.org/packages/63/bd/88e98836544c4f04db97eefd23b037c2002fa173dd2772301c61cd3085f9/propcache-0.3.1-cp310-cp310-macosx_10_9_x86_64.whl": "sha256:d4e89cde74154c7b5957f87a355bb9c8ec929c167b59c83d90654ea36aeb6180", + "https://files.pythonhosted.org/packages/67/0c/3e82563af77d1f8731132166da69fdfd95e71210e31f18edce08a1eb11ea/propcache-0.3.1-cp312-cp312-musllinux_1_2_ppc64le.whl": "sha256:e4fe2a6d5ce975c117a6bb1e8ccda772d1e7029c1cca1acd209f91d30fa72815", + "https://files.pythonhosted.org/packages/67/3f/0dd87220f61598b61b590a8b3562142ae475a9c0f694ee32bf97e4e41d44/propcache-0.3.1-cp39-cp39-musllinux_1_2_x86_64.whl": "sha256:8638f99dca15b9dff328fb6273e09f03d1c50d9b6512f3b65a4154588a7595fe", + "https://files.pythonhosted.org/packages/6f/4e/c8ec771731f1b1e7d07bd8875f1d13c1564b5d60f7483624d021eaef5687/propcache-0.3.1-cp39-cp39-musllinux_1_2_i686.whl": "sha256:a461959ead5b38e2581998700b26346b78cd98540b5524796c175722f18b0294", + "https://files.pythonhosted.org/packages/6f/d4/c1adbf3901537582e65cf90fd9c26fde1298fde5a2c593f987112c0d0798/propcache-0.3.1-cp313-cp313-macosx_10_13_x86_64.whl": "sha256:dc1915ec523b3b494933b5424980831b636fe483d7d543f7afb7b3bf00f0c10f", + "https://files.pythonhosted.org/packages/72/c6/fdb9e8ba161a4e12c75a7415cb99314cad195d3b8ae9d770783cec54001e/propcache-0.3.1-cp39-cp39-musllinux_1_2_s390x.whl": "sha256:ef2e4e91fb3945769e14ce82ed53007195e616a63aa43b40fb7ebaaf907c8d4c", + "https://files.pythonhosted.org/packages/79/dd/71aae9dec59333064cfdd7eb31a63fa09f64181b979802a67a90b2abfcba/propcache-0.3.1-cp310-cp310-win32.whl": "sha256:1f6cc0ad7b4560e5637eb2c994e97b4fa41ba8226069c9277eb5ea7101845b42", + "https://files.pythonhosted.org/packages/7a/fd/5283e5ed8a82b00c7a989b99bb6ea173db1ad750bf0bf8dff08d3f4a4e28/propcache-0.3.1-cp311-cp311-musllinux_1_2_ppc64le.whl": "sha256:e861ad82892408487be144906a368ddbe2dc6297074ade2d892341b35c59844a", + "https://files.pythonhosted.org/packages/7b/4e/e332164372af66992c07b470448beb7e36ce7dba6a06c6c2b6131f112e74/propcache-0.3.1-cp39-cp39-win32.whl": "sha256:6f173bbfe976105aaa890b712d1759de339d8a7cef2fc0a1714cc1a1e1c47f64", + "https://files.pythonhosted.org/packages/7c/9c/3b3942b302badd589ad6b672da3ca7b660a6c2f505cafd058133ddc73918/propcache-0.3.1-cp312-cp312-musllinux_1_2_armv7l.whl": "sha256:050b571b2e96ec942898f8eb46ea4bfbb19bd5502424747e83badc2d4a99a44e", + "https://files.pythonhosted.org/packages/7c/e4/4aeb95a1cd085e0558ab0de95abfc5187329616193a1012a6c4c930e9f7a/propcache-0.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:319fa8765bfd6a265e5fa661547556da381e53274bc05094fc9ea50da51bfd46", + "https://files.pythonhosted.org/packages/83/c0/ea5133dda43e298cd2010ec05c2821b391e10980e64ee72c0a76cdbb813a/propcache-0.3.1-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:4d0dfdd9a2ebc77b869a0b04423591ea8823f791293b527dc1bb896c1d6f1136", + "https://files.pythonhosted.org/packages/87/9a/87091ceb048efeba4d28e903c0b15bcc84b7c0bf27dc0261e62335d9b7b8/propcache-0.3.1-cp313-cp313t-macosx_11_0_arm64.whl": "sha256:f011f104db880f4e2166bcdcf7f58250f7a465bc6b068dc84c824a3d4a5c94dc", + "https://files.pythonhosted.org/packages/89/2d/5f52d9c579f67b8ee1edd9ec073c91b23cc5b7ff7951a1e449e04ed8fdf3/propcache-0.3.1-cp311-cp311-musllinux_1_2_i686.whl": "sha256:b0313e8b923b3814d1c4a524c93dfecea5f39fa95601f6a9b1ac96cd66f89ea0", + "https://files.pythonhosted.org/packages/8e/66/acb88e1f30ef5536d785c283af2e62931cb934a56a3ecf39105887aa8905/propcache-0.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:b23c11c2c9e6d4e7300c92e022046ad09b91fd00e36e83c44483df4afa990073", + "https://files.pythonhosted.org/packages/90/0f/5a5319ee83bd651f75311fcb0c492c21322a7fc8f788e4eef23f44243427/propcache-0.3.1-cp311-cp311-macosx_10_9_universal2.whl": "sha256:7f30241577d2fef2602113b70ef7231bf4c69a97e04693bde08ddab913ba0ce5", + "https://files.pythonhosted.org/packages/90/38/ab17d75938ef7ac87332c588857422ae126b1c76253f0f5b1242032923ca/propcache-0.3.1-cp311-cp311-musllinux_1_2_s390x.whl": "sha256:61014615c1274df8da5991a1e5da85a3ccb00c2d4701ac6f3383afd3ca47ab0a", + "https://files.pythonhosted.org/packages/92/0a/0cf77d0e984b7058019ffa5385b3efd6962cbd5340a8f278ae103032863a/propcache-0.3.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:64a956dff37080b352c1c40b2966b09defb014347043e740d420ca1eb7c9b908", + "https://files.pythonhosted.org/packages/98/37/02c9343ffe59e590e0e56dc5c97d0da2b8b19fa747ebacf158310f97a79a/propcache-0.3.1-cp313-cp313-musllinux_1_2_i686.whl": "sha256:5cb5918253912e088edbf023788de539219718d3b10aef334476b62d2b53de53", + "https://files.pythonhosted.org/packages/98/a1/75f6355f9ad039108ff000dfc2e19962c8dea0430da9a1428e7975cf24b2/propcache-0.3.1-cp312-cp312-musllinux_1_2_i686.whl": "sha256:e1c4d24b804b3a87e9350f79e2371a705a188d292fd310e663483af6ee6718ee", + "https://files.pythonhosted.org/packages/98/b8/eb977e28138f9e22a5a789daf608d36e05ed93093ef12a12441030da800a/propcache-0.3.1-cp311-cp311-musllinux_1_2_armv7l.whl": "sha256:bd39c92e4c8f6cbf5f08257d6360123af72af9f4da75a690bef50da77362d25f", + "https://files.pythonhosted.org/packages/9a/8a/e6e1c77394088f4cfdace4a91a7328e398ebed745d59c2f6764135c5342d/propcache-0.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:5b9145c35cc87313b5fd480144f8078716007656093d23059e8993d3a8fa730f", + "https://files.pythonhosted.org/packages/a4/bc/a82c5878eb3afb5c88da86e2cf06e1fe78b7875b26198dbb70fe50a010dc/propcache-0.3.1-cp310-cp310-musllinux_1_2_armv7l.whl": "sha256:cd6a55f65241c551eb53f8cf4d2f4af33512c39da5d9777694e9d9c60872f519", + "https://files.pythonhosted.org/packages/a6/2c/a54614d61895ba6dd7ac8f107e2b2a0347259ab29cbf2ecc7b94fa38c4dc/propcache-0.3.1-cp313-cp313-win_amd64.whl": "sha256:813fbb8b6aea2fc9659815e585e548fe706d6f663fa73dff59a1677d4595a037", + "https://files.pythonhosted.org/packages/a9/02/ccbcf3e1c604c16cc525309161d57412c23cf2351523aedbb280eb7c9094/propcache-0.3.1-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:ec314cde7314d2dd0510c6787326bbffcbdc317ecee6b7401ce218b3099075a7", + "https://files.pythonhosted.org/packages/aa/bf/7b8c9fd097d511638fa9b6af3d986adbdf567598a567b46338c925144c1b/propcache-0.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:1eb34d90aac9bfbced9a58b266f8946cb5935869ff01b164573a7634d39fbcb5", + "https://files.pythonhosted.org/packages/aa/e1/4a782cdc7ebc42dfb44224dabf93b481395a0b6cbc9f0149785edbbab19c/propcache-0.3.1-cp39-cp39-macosx_10_9_universal2.whl": "sha256:ed5f6d2edbf349bd8d630e81f474d33d6ae5d07760c44d33cd808e2f5c8f4ae6", + "https://files.pythonhosted.org/packages/ad/6c/d01f9dfbbdc613305e0a831016844987a1fb4861dd221cd4c69b1216b43f/propcache-0.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:967a8eec513dbe08330f10137eacb427b2ca52118769e82ebcfcab0fba92a649", + "https://files.pythonhosted.org/packages/ae/7e/3e3b36854e96be2e881bc6e87293d59c74dd734dd038dd4981474be44e26/propcache-0.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:83be47aa4e35b87c106fc0c84c0fc069d3f9b9b06d3c494cd404ec6747544894", + "https://files.pythonhosted.org/packages/ae/bd/c1e37265910752e6e5e8a4c1605d0129e5b7933c3dc3cf1b9b48ed83b364/propcache-0.3.1-cp312-cp312-macosx_11_0_arm64.whl": "sha256:09400e98545c998d57d10035ff623266927cb784d13dd2b31fd33b8a5316b85b", + "https://files.pythonhosted.org/packages/b7/d5/ba91702207ac61ae6f1c2da81c5d0d6bf6ce89e08a2b4d44e411c0bbe867/propcache-0.3.1-cp313-cp313t-musllinux_1_2_ppc64le.whl": "sha256:87380fb1f3089d2a0b8b00f006ed12bd41bd858fabfa7330c954c70f50ed8757", + "https://files.pythonhosted.org/packages/b8/d3/c3cb8f1d6ae3b37f83e1de806713a9b3642c5895f0215a62e1a4bd6e5e34/propcache-0.3.1-py3-none-any.whl": "sha256:9a8ecf38de50a7f518c21568c80f985e776397b902f1ce0b01f799aba1608b40", + "https://files.pythonhosted.org/packages/c2/d7/e6079af45136ad325c5337f5dd9ef97ab5dc349e0ff362fe5c5db95e2454/propcache-0.3.1-cp313-cp313t-musllinux_1_2_i686.whl": "sha256:bef100c88d8692864651b5f98e871fb090bd65c8a41a1cb0ff2322db39c96c27", + "https://files.pythonhosted.org/packages/c4/42/817289120c6b9194a44f6c3e6b2c3277c5b70bbad39e7df648f177cc3634/propcache-0.3.1-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:1c5c7ab7f2bb3f573d1cb921993006ba2d39e8621019dffb1c5bc94cdbae81e8", + "https://files.pythonhosted.org/packages/c5/b8/bdfcb1170a7b8504226064d7c0b4deb61acbcc6bb2e754ee25fb36c1b72a/propcache-0.3.1-cp39-cp39-musllinux_1_2_ppc64le.whl": "sha256:069e7212890b0bcf9b2be0a03afb0c2d5161d91e1bf51569a64f629acc7defbf", + "https://files.pythonhosted.org/packages/cb/8f/50ad8599399d1861b4d2b6b45271f0ef6af1b09b0a2386a46dbaf19c9535/propcache-0.3.1-cp313-cp313t-win_amd64.whl": "sha256:e7fb9a84c9abbf2b2683fa3e7b0d7da4d8ecf139a1c635732a8bda29c5214b0e", + "https://files.pythonhosted.org/packages/cc/27/4e0ef21084b53bd35d4dae1634b6d0bad35e9c58ed4f032511acca9d4d26/propcache-0.3.1-cp313-cp313-win32.whl": "sha256:3a02a28095b5e63128bcae98eb59025924f121f048a62393db682f049bf4ac24", + "https://files.pythonhosted.org/packages/cd/a7/3664756cf50ce739e5f3abd48febc0be1a713b1f389a502ca819791a6b69/propcache-0.3.1-cp313-cp313-musllinux_1_2_s390x.whl": "sha256:aca63103895c7d960a5b9b044a83f544b233c95e0dcff114389d64d762017af7", + "https://files.pythonhosted.org/packages/ce/84/3db5537e0879942783e2256616ff15d870a11d7ac26541336fe1b673c818/propcache-0.3.1-cp311-cp311-macosx_10_9_x86_64.whl": "sha256:43593c6772aa12abc3af7784bff4a41ffa921608dd38b77cf1dfd7f5c4e71371", + "https://files.pythonhosted.org/packages/d1/b5/fe752b2e63f49f727c6c1c224175d21b7d1727ce1d4873ef1c24c9216830/propcache-0.3.1-cp313-cp313-macosx_11_0_arm64.whl": "sha256:a110205022d077da24e60b3df8bcee73971be9575dec5573dd17ae5d81751111", + "https://files.pythonhosted.org/packages/d4/b0/911eda0865f90c0c7e9f0415d40a5bf681204da5fd7ca089361a64c16b28/propcache-0.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:aa8efd8c5adc5a2c9d3b952815ff8f7710cefdcaf5f2c36d26aff51aeca2f12f", + "https://files.pythonhosted.org/packages/da/6a/29fa75de1cbbb302f1e1d684009b969976ca603ee162282ae702287b6621/propcache-0.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:c66d8ccbc902ad548312b96ed8d5d266d0d2c6d006fd0f66323e9d8f2dd49be7", + "https://files.pythonhosted.org/packages/db/19/e777227545e09ca1e77a6e21274ae9ec45de0f589f0ce3eca2a41f366220/propcache-0.3.1-cp312-cp312-win32.whl": "sha256:7d2d5a0028d920738372630870e7d9644ce437142197f8c827194fca404bf03b", + "https://files.pythonhosted.org/packages/db/a0/d72da3f61ceab126e9be1f3bc7844b4e98c6e61c985097474668e7e52152/propcache-0.3.1-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:9cec3239c85ed15bfaded997773fdad9fb5662b0a7cbc854a43f291eb183179e", + "https://files.pythonhosted.org/packages/e2/c8/b649ed972433c3f0d827d7f0cf9ea47162f4ef8f4fe98c5f3641a0bc63ff/propcache-0.3.1-cp311-cp311-macosx_11_0_arm64.whl": "sha256:a75801768bbe65499495660b777e018cbe90c7980f07f8aa57d6be79ea6f71da", + "https://files.pythonhosted.org/packages/e5/fc/b1d1fdffbe1e0278ab535f8d21fc6b030889417714a545755bdd5ebe9bb0/propcache-0.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:0c3c3a203c375b08fd06a20da3cf7aac293b834b6f4f4db71190e8422750cca5", + "https://files.pythonhosted.org/packages/e7/64/66f2f4d1b4f0007c6e9078bd95b609b633d3957fe6dd23eac33ebde4b584/propcache-0.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:5cdb0f3e1eb6dfc9965d19734d8f9c481b294b5274337a8cb5cb01b462dcb7e0", + "https://files.pythonhosted.org/packages/e8/fd/970ca0e22acc829f1adf5de3724085e778c1ad8a75bec010049502cb3a86/propcache-0.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:fb6e0faf8cb6b4beea5d6ed7b5a578254c6d7df54c36ccd3d8b3eb00d6770277", + "https://files.pythonhosted.org/packages/ed/ec/ad5a952cdb9d65c351f88db7c46957edd3d65ffeee72a2f18bd6341433e0/propcache-0.3.1-cp310-cp310-musllinux_1_2_s390x.whl": "sha256:2fce1df66915909ff6c824bbb5eb403d2d15f98f1518e583074671a30fe0c21e", + "https://files.pythonhosted.org/packages/ef/71/5247a264b95e8d4ba86757cf9ad6a523d764bd4579a2d80007a2d4d2b0ad/propcache-0.3.1-cp39-cp39-musllinux_1_2_armv7l.whl": "sha256:916cd229b0150129d645ec51614d38129ee74c03293a9f3f17537be0029a9641", + "https://files.pythonhosted.org/packages/f1/eb/13090e05bf6b963fc1653cdc922133ced467cb4b8dab53158db5a37aa21e/propcache-0.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:a0ab8cf8cdd2194f8ff979a43ab43049b1df0b37aa64ab7eca04ac14429baeb7", + "https://files.pythonhosted.org/packages/f3/e2/88ad1c4c42861dd09b45924e468c42a1beb2c5267cb960b7a9f6af67dd04/propcache-0.3.1-cp39-cp39-macosx_11_0_arm64.whl": "sha256:0c86e7ceea56376216eba345aa1fc6a8a6b27ac236181f840d1d7e6a1ea9ba5c", + "https://files.pythonhosted.org/packages/f5/f9/233ddb05ffdcaee4448508ee1d70aa7deff21bb41469ccdfcc339f871427/propcache-0.3.1-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:3e19ea4ea0bf46179f8a3652ac1426e6dcbaf577ce4b4f65be581e237340420d", + "https://files.pythonhosted.org/packages/f7/50/9fb7cca01532a08c4d5186d7bb2da6c4c587825c0ae134b89b47c7d62628/propcache-0.3.1-cp312-cp312-musllinux_1_2_s390x.whl": "sha256:feccd282de1f6322f56f6845bf1207a537227812f0a9bf5571df52bb418d79d5", + "https://files.pythonhosted.org/packages/fa/c9/e85aeeeaae83358e2a1ef32d6ff50a483a5d5248bc38510d030a6f4e2816/propcache-0.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:f35c7070eeec2cdaac6fd3fe245226ed2a6292d3ee8c938e5bb645b434c5f256" + }, + "protobuf": { + "https://files.pythonhosted.org/packages/0a/19/8d0cb6f20a1ef7b18f1c8986ad5783f22f84cce39c6ce9a6e645ea55192e/protobuf-7.35.1-cp310-abi3-win_amd64.whl": "sha256:230a75ddfc2de4806e56696ce9640c1cdfdb6543b7cfce98d42a4c0a0e7bdb87", + "https://files.pythonhosted.org/packages/0f/58/dc12f2cd484951524af6e3382c785869b9b3fb5e52ee95ae23add53ee8f9/protobuf-7.35.1-cp310-abi3-manylinux2014_s390x.whl": "sha256:b73f9489a4b8b1c9cb1f8ed951c736392592edb24b9d6819f36d2e10b171d5b4", + "https://files.pythonhosted.org/packages/10/03/8aeeb7458d22546bf64b5250ca1daeb5ff757d900e8e4a7476c6f0db843e/protobuf-7.35.1-cp310-abi3-macosx_10_9_universal2.whl": "sha256:24f857477359a85c0c235261b8ba905fd51b2562f4a64ca1df5473f29850cbf6", + "https://files.pythonhosted.org/packages/19/c7/5f7c636ec43e0c545e28d1f1db71990108306f7bdcb89f069ba97e428e7f/protobuf-7.35.1-py3-none-any.whl": "sha256:4bc97768d8fe4ad6743c8a19403e314511ed9f6d13205b687e52421c023ac1b9", + "https://files.pythonhosted.org/packages/37/4b/dfb89eb0e652a1ff073c39a59fb5e3a83cfe9b57a2c83fa6d78270101767/protobuf-7.35.1-cp310-abi3-manylinux2014_aarch64.whl": "sha256:11d6b0ec246892d85215b0a13ca6e0233cf5284b68f0ac02646427f4ff88a799", + "https://files.pythonhosted.org/packages/43/29/d09e70352e4e88c9c7a198d5645d7277811448d76c23b00345670f7c8a38/protobuf-5.29.5.tar.gz": "sha256:bc1463bafd4b0929216c35f437a8e28731a2b7fe3d98bb77a600efced5a15c84", + "https://files.pythonhosted.org/packages/5f/11/6e40e9fc5bba02988a214c07cf324595789ca7820160bfd1f8be96e48539/protobuf-5.29.5-cp310-abi3-win32.whl": "sha256:3f1c6468a2cfd102ff4703976138844f78ebd1fb45f49011afc5139e9e283079", + "https://files.pythonhosted.org/packages/6c/04/98f6f8cf5b07ab1294c13f34b4e69b3722bb609c5b701d6c169828f9f8aa/protobuf-5.29.5-cp38-abi3-manylinux2014_aarch64.whl": "sha256:fa18533a299d7ab6c55a238bf8629311439995f2e7eca5caaff08663606e9015", + "https://files.pythonhosted.org/packages/7e/cc/7e77861000a0691aeea8f4566e5d3aa716f2b1dece4a24439437e41d3d25/protobuf-5.29.5-py3-none-any.whl": "sha256:6cf42630262c59b2d8de33954443d94b746c952b01434fc58a417fdbd2e84bd5", + "https://files.pythonhosted.org/packages/81/7f/73cefb093e1a2a7c3ffd839e6f9fcafb7a427d300c7f8aef9c64405d8ac6/protobuf-5.29.5-cp310-abi3-win_amd64.whl": "sha256:3f76e3a3675b4a4d867b52e4a5f5b78a2ef9565549d4037e06cf7b0942b1d3fc", + "https://files.pythonhosted.org/packages/85/e4/07c80521879c2d15f321465ac24c70efe2381378c00bf5e56a0f4fbac8cd/protobuf-5.29.5-cp38-abi3-manylinux2014_x86_64.whl": "sha256:63848923da3325e1bf7e9003d680ce6e14b07e55d0473253a690c3a8b8fd6e61", + "https://files.pythonhosted.org/packages/96/8b/2c62731fe3e92ddbbeca0174f78f0f8739197cdeb7c75ceb5aad3706963b/protobuf-5.29.5-cp39-cp39-win_amd64.whl": "sha256:470f3af547ef17847a28e1f47200a1cbf0ba3ff57b7de50d22776607cd2ea353", + "https://files.pythonhosted.org/packages/a2/bb/9a6e6ec4a99bccd35e326e8e5eab30ca42f3df987c13ca6522b8b4fbd5ff/protobuf-5.29.5-cp38-cp38-win_amd64.whl": "sha256:7318608d56b6402d2ea7704ff1e1e4597bee46d760e7e4dd42a3d45e24b87f2e", + "https://files.pythonhosted.org/packages/b1/24/dc0e489944b3cba0403f26223c0cc552a222af91a42257cbd25ef968b0c0/protobuf-5.29.5-cp38-cp38-win32.whl": "sha256:ef91363ad4faba7b25d844ef1ada59ff1604184c0bcd8b39b8a6bef15e1af238", + "https://files.pythonhosted.org/packages/d8/bc/6d6c7ba8709c85f8f2c390b2b118d6fb08a783676a572271851bf45a7d22/protobuf-7.35.1-cp310-abi3-win32.whl": "sha256:353652e4efd0bca5b5fc2656abf8307ef351f0cf938c9eba09f0e09c20a25c30", + "https://files.pythonhosted.org/packages/da/01/9ef0afd7999eb9badb3a768b4aedd78c86d4c65cfaf1958ab276199e76b4/protobuf-7.35.1.tar.gz": "sha256:ce115a26fe0c39a2c29973d914d327e516a6455464489fe3cd1e51a1b354f81a", + "https://files.pythonhosted.org/packages/dd/73/10e1661c21f139f2c6ad9b23040ff36fee624310dc28fba20d33fdae124c/protobuf-5.29.5-cp38-abi3-macosx_10_9_universal2.whl": "sha256:e38c5add5a311f2a6eb0340716ef9b039c1dfa428b28f25a7838ac329204a671", + "https://files.pythonhosted.org/packages/e4/be/5b3cfe508bfab6761414ff944e3366eb13be4fd71efcd69450f89ba39f43/protobuf-7.35.1-cp310-abi3-manylinux2014_x86_64.whl": "sha256:74758715c53d7158fb76caf4f0cfdacc5329a4b1bb994f865d6cf302d413a1c4", + "https://files.pythonhosted.org/packages/e5/59/ca89678bb0352f094fc92f2b358daa40e3acc91a93aa8f922b24762bf841/protobuf-5.29.5-cp39-cp39-win32.whl": "sha256:6f642dc9a61782fa72b90878af134c5afe1917c89a568cd3476d758d3c3a0736" + }, + "pyasn1": { + "https://files.pythonhosted.org/packages/9a/3b/6163796d69c3977d1e4287bea4a6979161cbbdd170ebb430511e8e1999ce/pyasn1-0.6.4-py3-none-any.whl": "sha256:deda9277cfd454080ec40b207fb6df82206a3a2688735233cdcd8d3d565f088b", + "https://files.pythonhosted.org/packages/a4/9a/23310166d960def5897e91fe20e5b724601b02a22e84ba1f94232c0b7f67/pyasn1-0.6.4.tar.gz": "sha256:9c447d8431c947fe4c8febc4ed9e760bc29011a5b01e5c74b67025bd9fb8ce81", + "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz": "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", + "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl": "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629" + }, + "pyasn1-modules": { + "https://files.pythonhosted.org/packages/1d/67/6afbf0d507f73c32d21084a79946bfcfca5fbc62a72057e9c23797a737c9/pyasn1_modules-0.4.1.tar.gz": "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c", + "https://files.pythonhosted.org/packages/77/89/bc88a6711935ba795a679ea6ebee07e128050d6382eaa35a0a47c8032bdc/pyasn1_modules-0.4.1-py3-none-any.whl": "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd" + }, + "pycodestyle": { + "https://files.pythonhosted.org/packages/11/e0/abfd2a0d2efe47670df87f3e3a0e2edda42f055053c85361f19c0e2c1ca8/pycodestyle-2.14.0.tar.gz": "sha256:c4b5b517d278089ff9d0abdec919cd97262a3367449ea1c8b49b91529167b783", + "https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl": "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d" + }, + "pycparser": { + "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl": "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", + "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl": "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", + "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz": "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", + "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz": "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", + "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl": "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", + "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz": "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2" + }, + "pyflakes": { + "https://files.pythonhosted.org/packages/45/dc/fd034dc20b4b264b3d015808458391acbf9df40b1e54750ef175d39180b1/pyflakes-3.4.0.tar.gz": "sha256:b24f96fafb7d2ab0ec5075b7350b3d2d2218eab42003821c06344973d3ea2f58", + "https://files.pythonhosted.org/packages/c2/2f/81d580a0fb83baeb066698975cb14a618bdbed7720678566f1b046a95fe8/pyflakes-3.4.0-py2.py3-none-any.whl": "sha256:f742a7dbd0d9cb9ea41e9a24a918996e8170c799fa528688d40dd582c8265f4f" + }, + "pygithub": { + "https://files.pythonhosted.org/packages/91/71/f314841697a1d52af3e1ea7c5e1c3f09685b64ae4c58ff16b605a866255d/pygithub-2.10.0-py3-none-any.whl": "sha256:192ada2a76e4afc7d6b37e500c9bfeba1731e6506697445a5ba1c4af8bf0b924", + "https://files.pythonhosted.org/packages/e1/9b/195603d5371861005a3467c5e4afd02fd0698795a2aa36dc41498b9d879d/pygithub-2.10.0.tar.gz": "sha256:90ff24ef1cd1bd57124c2a3869cafee9d7b066909129ecdaba2c2d1903bc118d" + }, + "pygments": { + "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz": "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", + "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz": "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", + "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl": "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", + "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl": "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176" + }, + "pyjwt": { + "https://files.pythonhosted.org/packages/43/ea/5194e52748b0da83d71e082d75496eaec6e58f419f5e184786ded517e6a9/pyjwt-2.15.1.tar.gz": "sha256:4f259e80cdfb6b3fc18a7de51fd1ef9ec79652f25019bae68975ca2468a34df8", + "https://files.pythonhosted.org/packages/50/ca/44de4e75f8aadc457f0634be3b542815078ded46dca30efb960edeecad6e/pyjwt-2.15.1-py3-none-any.whl": "sha256:42d59d631f7768a1028a64c7ff581a9bf7519804daf91fc5b6c56e30eec5e193" + }, + "pylsqpack": { + "https://files.pythonhosted.org/packages/04/30/dc13ed88ad762d9fbb8351064a4c1e137a2574155deb6f88e8ca9c90cf5e/pylsqpack-0.3.18-cp38-abi3-macosx_10_9_x86_64.whl": "sha256:1f415d2e03c779261ac7ed421a009a4c752eef6f1ef7b5a34c4a463a5e17fbad", + "https://files.pythonhosted.org/packages/0f/ca/37bf35c8315756a338372841854baeb1b61f3d0bd66bb0099b4307b2e4b1/pylsqpack-0.3.18-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:005ddce84bdcbf5c3cf99f764504208e1aa0a91a8331bf47108f2708f2a315e6", + "https://files.pythonhosted.org/packages/27/ba/8dd7356bf101f70b77c553010a8f62690531608e0d8116f7c04f6d0545b2/pylsqpack-0.3.18-pp38-pypy38_pp73-macosx_10_9_x86_64.whl": "sha256:ae628cd359ecb466dd85f151ea1ad53de3114e5a9ae0f0ac1408fb43a4318032", + "https://files.pythonhosted.org/packages/36/8a/8a9df4bfccd08e762fdb3a2edcebb60355601fc45da9f413bfeb81982108/pylsqpack-0.3.18-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:e1054b0b44f6141a99e84a9aa6a27c9df028e9223747b893e8e37cdc95b602f1", + "https://files.pythonhosted.org/packages/82/42/1c8fb200785bee0bd9d87c554ede22669ac0dc368be9d55ed6cf2e3ec090/pylsqpack-0.3.18-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:75042b442a0a7a283b5adc21045e6583f3c817d40ccec769837bf2f90b79c494", + "https://files.pythonhosted.org/packages/83/6b/e62ec15297e3516e7b1c898cb94bd856781903ad9eb59fd84e23aaa7fe03/pylsqpack-0.3.18-cp38-abi3-win_amd64.whl": "sha256:40465d025b946bca195bdaed74b3b79fe3f7f419ab1d4bc4109dca34ba9881d7", + "https://files.pythonhosted.org/packages/8e/fb/010f792c4b862fdf03063dfa402165f3aa404955e3e9266cf9333e1b1e9e/pylsqpack-0.3.18-cp38-abi3-win32.whl": "sha256:a2798e1c08bd36875f77a1ebec0f130fdf9e27eebdb0499a764201d55ef78770", + "https://files.pythonhosted.org/packages/93/1d/3f400f2e7413caec3cd58a9718bcab97d6e66ffb037af79cb45f06ac8813/pylsqpack-0.3.18.tar.gz": "sha256:45ae55e721877505f4d5ccd49591d69353f2a548a8673dfafb251d385b3c097f", + "https://files.pythonhosted.org/packages/9d/10/8942570003b118dcfc83c258bca3a649c73e61f2669db408c43daa001bec/pylsqpack-0.3.18-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:3dd664354422d4cd51c189febb5f5d22bf3d8c453cc25517c04ce01a57478060", + "https://files.pythonhosted.org/packages/b3/ba/3087e5ce2d5bd65770a2d499f2729db3336fbdd0af43b45b426e58ea1136/pylsqpack-0.3.18-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:8b5fd04bb27180286811f8e1659974e6e5e854a882de3f2aba8caefc1bb9ab81", + "https://files.pythonhosted.org/packages/bc/98/633d4d6432f0f4064edd17ddab90bdbbd2fb534cab7c094d4b4a13537126/pylsqpack-0.3.18-pp39-pypy39_pp73-macosx_10_9_x86_64.whl": "sha256:8ea75152e8cb8b8c7cfef11c3aa5ebe5b226bd850889f56ff70a688e9680acbf", + "https://files.pythonhosted.org/packages/c0/e8/abdb782df25edb20abd874fe844d0b14d7c771f054948fec3c468facb436/pylsqpack-0.3.18-pp39-pypy39_pp73-win_amd64.whl": "sha256:711f3aa645f72a928e22606c1f026cde905de23efc07028fe1bc7429f73ec8ee", + "https://files.pythonhosted.org/packages/c1/15/244bc828a81e2a0bcf5bcf4a8199840c4c278c3d1c95e957b9b0c7ef9a71/pylsqpack-0.3.18-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:3c4cccfd91afd589994f844fd1dbae0acdb58a8ab929d8edeadb25339deb6590", + "https://files.pythonhosted.org/packages/c4/b3/516ba15668ad15b82164d00c0984fb1e101745f9676b4d929dd31c3946b5/pylsqpack-0.3.18-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:4a248be29d9ca1fa2ebd7ef4b8ac166d17df0d8d4631b4499c8c566e221d4e5b", + "https://files.pythonhosted.org/packages/cc/5b/29e9b02f84393b4acbe0584f38916722be70402e85efcc71187695d2a224/pylsqpack-0.3.18-cp38-abi3-macosx_11_0_arm64.whl": "sha256:c84e6d4dcb708d766a50bfd16579d8a0bff4eb4e5f5dff9f3df4018454d4013b", + "https://files.pythonhosted.org/packages/d3/fb/3e55e084f94bb61a6df06d99c34068f8ed0ea9ce7304afcf2666303d6b85/pylsqpack-0.3.18-pp38-pypy38_pp73-win_amd64.whl": "sha256:c003eb882f41e4dbd093243c67b97c8634209b4d5ba7edd16163b1ff37306254", + "https://files.pythonhosted.org/packages/de/f8/89c953c742c49e9fe51056a52261f0d9297edcc4e9bb74c17165f843b0d3/pylsqpack-0.3.18-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:06e1bbe47514b83cd03158e5558ef8cc44f578169c1820098be9f3cc4137f16a", + "https://files.pythonhosted.org/packages/ea/48/b3099486580ffd36cddda413ff00f54b19413ceafe811c5ee2a7874a900f/pylsqpack-0.3.18-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:bac5f2dc255ae70e5a14033e769769b38bd4c980b365dacd88665610f245e36f" + }, + "pynacl": { + "https://files.pythonhosted.org/packages/06/ea/43fe2f7eab5f200e40fb10d305bf6f87ea31b3bbc83443eac37cd34a9e1e/pynacl-1.6.2-cp314-cp314t-musllinux_1_2_x86_64.whl": "sha256:2fef529ef3ee487ad8113d287a593fa26f48ee3620d92ecc6f1d09ea38e0709b", + "https://files.pythonhosted.org/packages/1e/b4/e927e0653ba63b02a4ca5b4d852a8d1d678afbf69b3dbf9c4d0785ac905c/pynacl-1.6.2-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:8845c0631c0be43abdd865511c41eab235e0be69c81dc66a50911594198679b0", + "https://files.pythonhosted.org/packages/29/7d/5945b5af29534641820d3bd7b00962abbbdfee84ec7e19f0d5b3175f9a31/pynacl-1.6.2-cp38-abi3-win_arm64.whl": "sha256:834a43af110f743a754448463e8fd61259cd4ab5bbedcf70f9dabad1d28a394c", + "https://files.pythonhosted.org/packages/33/33/7873dc161c6a06f43cda13dec67b6fe152cb2f982581151956fa5e5cdb47/pynacl-1.6.2-cp314-cp314t-win_arm64.whl": "sha256:d29bfe37e20e015a7d8b23cfc8bd6aa7909c92a1b8f41ee416bbb3e79ef182b2", + "https://files.pythonhosted.org/packages/3e/d0/f301f83ac8dbe53442c5a43f6a39016f94f754d7a9815a875b65e218a307/pynacl-1.6.2-cp38-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl": "sha256:8a66d6fb6ae7661c58995f9c6435bda2b1e68b54b598a6a10247bfcdadac996c", + "https://files.pythonhosted.org/packages/41/ad/334600e8cacc7d86587fe5f565480fde569dfb487389c8e1be56ac21d8ac/pynacl-1.6.2-cp38-abi3-win_amd64.whl": "sha256:62985f233210dee6548c223301b6c25440852e13d59a8b81490203c3227c5ba0", + "https://files.pythonhosted.org/packages/48/47/e761c254f410c023a469284a9bc210933e18588ca87706ae93002c05114c/pynacl-1.6.2-cp38-abi3-win32.whl": "sha256:5811c72b473b2f38f7e2a3dc4f8642e3a3e9b5e7317266e4ced1fba85cae41aa", + "https://files.pythonhosted.org/packages/4b/79/0e3c34dc3c4671f67d251c07aa8eb100916f250ee470df230b0ab89551b4/pynacl-1.6.2-cp314-cp314t-macosx_10_10_universal2.whl": "sha256:622d7b07cc5c02c666795792931b50c91f3ce3c2649762efb1ef0d5684c81594", + "https://files.pythonhosted.org/packages/4d/54/c9ea116412788629b1347e415f72195c25eb2f3809b2d3e7b25f5c79f13a/pynacl-1.6.2-cp314-cp314t-win32.whl": "sha256:a84bf1c20339d06dc0c85d9aea9637a24f718f375d861b2668b2f9f96fa51145", + "https://files.pythonhosted.org/packages/55/ad/6efc57ab75ee4422e96b5f2697d51bbcf6cdcc091e66310df91fbdc144a8/pynacl-1.6.2-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl": "sha256:44081faff368d6c5553ccf55322ef2819abb40e25afaec7e740f159f74813634", + "https://files.pythonhosted.org/packages/68/f7/322f2f9915c4ef27d140101dd0ed26b479f7e6f5f183590fd32dfc48c4d3/pynacl-1.6.2-cp38-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl": "sha256:46065496ab748469cdd999246d17e301b2c24ae2fdf739132e580a0e94c94a87", + "https://files.pythonhosted.org/packages/78/b7/928ee9c4779caa0a915844311ab9fb5f99585621c5d6e4574538a17dca07/pynacl-1.6.2-cp314-cp314t-manylinux_2_34_aarch64.whl": "sha256:a9f9932d8d2811ce1a8ffa79dcbdf3970e7355b5c8eb0c1a881a57e7f7d96e88", + "https://files.pythonhosted.org/packages/7f/81/d60984052df5c97b1d24365bc1e30024379b42c4edcd79d2436b1b9806f2/pynacl-1.6.2-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:22de65bb9010a725b0dac248f353bb072969c94fa8d6b1f34b87d7953cf7bbe4", + "https://files.pythonhosted.org/packages/85/42/fe60b5f4473e12c72f977548e4028156f4d340b884c635ec6b063fe7e9a5/pynacl-1.6.2-cp38-abi3-musllinux_1_2_aarch64.whl": "sha256:68be3a09455743ff9505491220b64440ced8973fe930f270c8e07ccfa25b1f9e", + "https://files.pythonhosted.org/packages/87/74/8d4b718f8a22aea9e8dcc8b95deb76d4aae380e2f5b570cc70b5fd0a852d/pynacl-1.6.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:fe9847ca47d287af41e82be1dd5e23023d3c31a951da134121ab02e42ac218c9", + "https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl": "sha256:c949ea47e4206af7c8f604b8278093b674f7c79ed0d4719cc836902bf4517465", + "https://files.pythonhosted.org/packages/c4/58/fc6e649762b029315325ace1a8c6be66125e42f67416d3dbd47b69563d61/pynacl-1.6.2-cp38-abi3-manylinux_2_34_aarch64.whl": "sha256:26bfcd00dcf2cf160f122186af731ae30ab120c18e8375684ec2670dccd28130", + "https://files.pythonhosted.org/packages/c9/a8/b917096b1accc9acd878819a49d3d84875731a41eb665f6ebc826b1af99e/pynacl-1.6.2-cp38-abi3-manylinux_2_34_x86_64.whl": "sha256:c8a231e36ec2cab018c4ad4358c386e36eede0319a0c41fed24f840b1dac59f6", + "https://files.pythonhosted.org/packages/ce/04/64e9d76646abac2dccf904fccba352a86e7d172647557f35b9fe2a5ee4a1/pynacl-1.6.2-cp314-cp314t-win_amd64.whl": "sha256:320ef68a41c87547c91a8b58903c9caa641ab01e8512ce291085b5fe2fcb7590", + "https://files.pythonhosted.org/packages/d9/9a/4019b524b03a13438637b11538c82781a5eda427394380381af8f04f467a/pynacl-1.6.2.tar.gz": "sha256:018494d6d696ae03c7e656e5e74cdfd8ea1326962cc401bcf018f1ed8436811c", + "https://files.pythonhosted.org/packages/eb/1c/23a26e931736e13b16483795c8a6b2f641bf6a3d5238c22b070a5112722c/pynacl-1.6.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:d071c6a9a4c94d79eb665db4ce5cedc537faf74f2355e4d502591d850d3913c0", + "https://files.pythonhosted.org/packages/f3/2f/5e7ea8d85f9f3ea5b6b87db1d8388daa3587eed181bdeb0306816fdbbe79/pynacl-1.6.2-cp314-cp314t-musllinux_1_2_aarch64.whl": "sha256:3bffb6d0f6becacb6526f8f42adfb5efb26337056ee0831fb9a7044d1a964444", + "https://files.pythonhosted.org/packages/f7/a9/1bdba746a2be20f8809fee75c10e3159d75864ef69c6b0dd168fc60e485d/pynacl-1.6.2-cp314-cp314t-manylinux_2_34_x86_64.whl": "sha256:bc4a36b28dd72fb4845e5d8f9760610588a96d5a51f01d84d8c6ff9849968c14", + "https://files.pythonhosted.org/packages/fa/f9/e40e318c604259301cc091a2a63f237d9e7b424c4851cafaea4ea7c4834e/pynacl-1.6.2-cp38-abi3-musllinux_1_2_x86_64.whl": "sha256:8b097553b380236d51ed11356c953bf8ce36a29a3e596e934ecabe76c985a577", + "https://files.pythonhosted.org/packages/fd/73/be4fdd3a6a87fe8a4553380c2b47fbd1f7f58292eb820902f5c8ac7de7b0/pynacl-1.6.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl": "sha256:04316d1fc625d860b6c162fff704eb8426b1a8bcd3abacea11142cbd99a6b574" + }, + "pyopenssl": { + "https://files.pythonhosted.org/packages/3f/e8/7325d258199b159eb2c03fe32107533e2832e70e63f4fb88a6aa00023201/pyopenssl-26.4.0.tar.gz": "sha256:28dfcce0162b9211413e26dfbfdf1d24317fbeba18fc93c12400a1856b2a0bc7", + "https://files.pythonhosted.org/packages/51/ad/2cf6d3fa2fae5c79e1ed9960c0d42badd0f94d81dd12b50604cdc839e648/pyopenssl-26.4.0-py3-none-any.whl": "sha256:f0eb0cb2d581d3ad2b9c489468485e7f2ab6727d08401bcf9d824c3caddf3c1c" + }, + "python-dateutil": { + "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz": "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", + "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl": "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" + }, + "python-gnupg": { + "https://files.pythonhosted.org/packages/98/2c/6cd2c7cff4bdbb434be5429ef6b8e96ee6b50155551361f30a1bb2ea3c1d/python_gnupg-0.5.6.tar.gz": "sha256:5743e96212d38923fc19083812dc127907e44dbd3bcf0db4d657e291d3c21eac", + "https://files.pythonhosted.org/packages/d2/ab/0ea9de971caf3cd2e268d2b05dfe9883b21cfe686a59249bd2dccb4bae33/python_gnupg-0.5.6-py2.py3-none-any.whl": "sha256:b5050a55663d8ab9fcc8d97556d229af337a87a3ebebd7054cbd8b7e2043394a" + }, + "pytz": { + "https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl": "sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126", + "https://files.pythonhosted.org/packages/ff/46/dd499ec9038423421951e4fad73051febaa13d2df82b4064f87af8b8c0c3/pytz-2026.2.tar.gz": "sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a" + }, + "pywin32-ctypes": { + "https://files.pythonhosted.org/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz": "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755", + "https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl": "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8" + }, + "pyyaml": { + "https://files.pythonhosted.org/packages/02/72/d972384252432d57f248767556ac083793292a4adf4e2d85dfe785ec2659/PyYAML-6.0.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4", + "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", + "https://files.pythonhosted.org/packages/05/14/52d505b5c59ce73244f59c7a50ecf47093ce4765f116cdb98286a71eeca2/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl": "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956", + "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz": "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", + "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", + "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", + "https://files.pythonhosted.org/packages/0d/a2/09f67a3589cb4320fb5ce90d3fd4c9752636b8b6ad8f34b54d76c5a54693/PyYAML-6.0.3-cp38-cp38-macosx_10_13_x86_64.whl": "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f", + "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", + "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl": "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", + "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl": "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", + "https://files.pythonhosted.org/packages/1f/15/2bc9c8faf6450a8b3c9fc5448ed869c599c0a74ba2669772b1f3a0040180/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69", + "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl": "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", + "https://files.pythonhosted.org/packages/25/a2/b725b61ac76a75583ae7104b3209f75ea44b13cfd026aa535ece22b7f22e/PyYAML-6.0.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6", + "https://files.pythonhosted.org/packages/29/3d/6f5e0d58bd924fb0d06c3a6bad00effbdae2de5adb5cda5648006ffbd8d3/pyyaml-6.0.3-cp39-cp39-win32.whl": "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0", + "https://files.pythonhosted.org/packages/2a/fa/926c003379b19fca39dd4634818b00dec6c62d87faf628d1394e137354d4/pyyaml-6.0.3-cp310-cp310-win_amd64.whl": "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c", + "https://files.pythonhosted.org/packages/2f/3a/61b9db1d28f00f8fd0ae760459a5c4bf1b941baf714e207b6eb0657d2578/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198", + "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", + "https://files.pythonhosted.org/packages/43/f7/0e6a5ae5599c838c696adb4e6330a59f463265bfa1e116cfd1fbb0abaaae/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8", + "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl": "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", + "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", + "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl": "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", + "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", + "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", + "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl": "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", + "https://files.pythonhosted.org/packages/6f/b0/b2227677b2d1036d84f5ee95eb948e7af53d59fe3e4328784e4d290607e0/PyYAML-6.0.3-cp38-cp38-musllinux_1_2_x86_64.whl": "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369", + "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", + "https://files.pythonhosted.org/packages/73/b9/793686b2d54b531203c160ef12bec60228a0109c79bae6c1277961026770/pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a", + "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl": "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", + "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", + "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl": "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", + "https://files.pythonhosted.org/packages/76/b2/2b69cee94c9eb215216fc05778675c393e3aa541131dc910df8e52c83776/PyYAML-6.0.3-cp38-cp38-win_amd64.whl": "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b", + "https://files.pythonhosted.org/packages/7a/1e/7acc4f0e74c4b3d9531e24739e0ab832a5edf40e64fbae1a9c01941cabd7/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b", + "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", + "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl": "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", + "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl": "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", + "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", + "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl": "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", + "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", + "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", + "https://files.pythonhosted.org/packages/8b/ef/abd085f06853af0cd59fa5f913d61a8eab65d7639ff2a658d18a25d6a89d/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0", + "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", + "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl": "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", + "https://files.pythonhosted.org/packages/99/a5/718a8ea22521e06ef19f91945766a892c5ceb1855df6adbde67d997ea7ed/PyYAML-6.0.3-cp38-cp38-win32.whl": "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295", + "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl": "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", + "https://files.pythonhosted.org/packages/9f/62/67fc8e68a75f738c9200422bf65693fb79a4cd0dc5b23310e5202e978090/pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl": "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da", + "https://files.pythonhosted.org/packages/a3/00/531e92e88c00f4333ce359e50c19b8d1de9fe8d581b1534e35ccfbc5f393/pyyaml-6.0.3-cp310-cp310-win32.whl": "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e", + "https://files.pythonhosted.org/packages/a7/3b/6c58ac0fa7c4e1b35e48024eb03d00817438310447f93ef4431673c24138/PyYAML-6.0.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3", + "https://files.pythonhosted.org/packages/a9/86/a137b39a611def2ed78b0e66ce2fe13ee701a07c07aebe55c340ed2a050e/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl": "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926", + "https://files.pythonhosted.org/packages/ae/92/861f152ce87c452b11b9d0977952259aa7df792d71c1053365cc7b09cc08/pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl": "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917", + "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl": "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", + "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", + "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl": "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", + "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", + "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl": "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", + "https://files.pythonhosted.org/packages/d0/cd/f0cfc8c74f8a030017a2b9c771b7f47e5dd702c3e28e5b2071374bda2948/pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9", + "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl": "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", + "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl": "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", + "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl": "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", + "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl": "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", + "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl": "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", + "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl": "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", + "https://files.pythonhosted.org/packages/dd/62/71c27c94f457cf4418ef8ccc71735324c549f7e3ea9d34aba50874563561/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl": "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7", + "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", + "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl": "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", + "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", + "https://files.pythonhosted.org/packages/ef/b2/18f2bd28cd2055a79a46c9b0895c0b3d987ce40ee471cecf58a1a0199805/pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5", + "https://files.pythonhosted.org/packages/f0/0c/25113e0b5e103d7f1490c0e947e303fe4a696c10b501dea7a9f49d4e876c/pyyaml-6.0.3-cp39-cp39-win_amd64.whl": "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007", + "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl": "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", + "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl": "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", + "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", + "https://files.pythonhosted.org/packages/f4/a0/39350dd17dd6d6c6507025c0e53aef67a9293a6d37d3511f23ea510d5800/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl": "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b", + "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl": "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", + "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6" + }, + "readme-renderer": { + "https://files.pythonhosted.org/packages/02/51/d3a6ea424652c60f05600d8c2e01a55c913755e7cdad64afabbd1aa16f44/readme_renderer-45.0.tar.gz": "sha256:030a8fac74904f8fba11ad1bb6964e3f76e896dc7e5e71f16af190c9056696d1", + "https://files.pythonhosted.org/packages/97/1b/295bf2fa3e740131778065e5ffa2c481f0e7210182d408e9a2c244ff5b0c/readme_renderer-45.0-py3-none-any.whl": "sha256:3385ed220117104a2bceb4a9dac8c5fdf6d1f96890d7ea2a9c7174fd5c84091f" + }, + "requests": { + "https://files.pythonhosted.org/packages/34/64/8860370b167a9721e8956ae116825caff829224fbca0ca6e7bf8ddef8430/requests-2.33.0.tar.gz": "sha256:c7ebc5e8b0f21837386ad0e1c8fe8b829fa5f544d8df3b2253bff14ef29d7652", + "https://files.pythonhosted.org/packages/56/5d/c814546c2333ceea4ba42262d8c4d55763003e767fa169adc693bd524478/requests-2.33.0-py3-none-any.whl": "sha256:3324635456fa185245e24865e810cecec7b4caf933d7eb133dcde67d48cee69b", + "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz": "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl": "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", + "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz": "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", + "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl": "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" + }, + "requests-toolbelt": { + "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl": "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", + "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz": "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6" + }, + "rfc3986": { + "https://files.pythonhosted.org/packages/85/40/1520d68bfa07ab5a6f065a186815fb6610c86fe957bc065754e47f7b0840/rfc3986-2.0.0.tar.gz": "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c", + "https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl": "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd" + }, + "rich": { + "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl": "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", + "https://files.pythonhosted.org/packages/87/67/a37f6214d0e9fe57f6ae54b2956d550ca8365857f42a1ce0392bb21d9410/rich-13.7.1-py3-none-any.whl": "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222", + "https://files.pythonhosted.org/packages/b3/01/c954e134dc440ab5f96952fe52b4fdc64225530320a910473c1fe270d9aa/rich-13.7.1.tar.gz": "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432", + "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz": "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36" + }, + "rsa": { + "https://files.pythonhosted.org/packages/49/97/fa78e3d2f65c02c8e1268b9aba606569fe97f6c8f7c2d74394553347c145/rsa-4.9-py3-none-any.whl": "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", + "https://files.pythonhosted.org/packages/aa/65/7d973b89c4d2351d7fb232c2e452547ddfa243e93131e7cfa766da627b52/rsa-4.9.tar.gz": "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21" + }, + "secretstorage": { + "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz": "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", + "https://files.pythonhosted.org/packages/b7/46/f5af3402b579fd5e11573ce652019a67074317e18c1935cc0b4ba9b35552/secretstorage-3.5.0-py3-none-any.whl": "sha256:0ce65888c0725fcb2c5bc0fdb8e5438eece02c523557ea40ce0703c266248137" + }, + "service-identity": { + "https://files.pythonhosted.org/packages/38/d2/2ac20fd05f1b6fce31986536da4caeac51ed2e1bb25d4a7d73ca4eccdfab/service_identity-24.1.0.tar.gz": "sha256:6829c9d62fb832c2e1c435629b0a8c476e1929881f28bee4d20bc24161009221", + "https://files.pythonhosted.org/packages/3b/92/44669afe6354a7bed9968013862118c401690d8b5a805bab75ac1764845f/service_identity-24.1.0-py3-none-any.whl": "sha256:a28caf8130c8a5c1c7a6f5293faaf239bbfb7751e4862436920ee6f2616f568a" + }, + "setuptools": { + "https://files.pythonhosted.org/packages/40/50/bc3d02829a3babd70b7f1414c93cf6acd198976f0469a07d0e7b813c5002/setuptools-77.0.1-py3-none-any.whl": "sha256:81a234dff81a82bb52e522c8aef145d0dd4de1fd6de4d3b196d0f77dc2fded26", + "https://files.pythonhosted.org/packages/6d/44/f5da03a8ef95d369145c5bb53050e7877c9f3d312e128605fd9504829143/setuptools-84.0.0.tar.gz": "sha256:f4695c21257f0d9b537ec2692c941d02ee143b7cc1276941349a546573b2ef73", + "https://files.pythonhosted.org/packages/95/9c/c510029fc6ef33a6275cd2c5d3cecd6613dfd6aa401d57c54f1c18852ccf/setuptools-84.0.0-py3-none-any.whl": "sha256:51a52592b3b99e102b609654876bd65f19f999935166d1352678931132b0c670", + "https://files.pythonhosted.org/packages/ea/df/9f719dc48f64284be8bd99e2e0bb0dd6e9f8e2c2c3c7bf7a685bc5adf2c7/setuptools-77.0.1.tar.gz": "sha256:a1246a1b4178c66d7cf50c9fc6d530fac3f89bc284cf803c7fa878c41b1a03b2" + }, + "six": { + "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz": "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl": "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + }, + "slack-sdk": { + "https://files.pythonhosted.org/packages/13/75/a4964eb771a0c74d79ee7a3bee6fb5d9718909dd1b675e80d62a6a0ad90a/slack_sdk-3.43.0.tar.gz": "sha256:0553152e46c4259eb69f7464cdadc35ba4802ca10f9f5a849c92cf03d6c2ba07", + "https://files.pythonhosted.org/packages/e4/55/42141b8338d46323d5b3c6095201b044c670c20f898643b322ea9b1543a1/slack_sdk-3.43.0-py2.py3-none-any.whl": "sha256:4b6557c65577fc172f685af218b811f9f3b4909e24cddd839ada09565f10c585" + }, + "smmap": { + "https://files.pythonhosted.org/packages/88/04/b5bf6d21dc4041000ccba7eb17dd3055feb237e7ffc2c20d3fae3af62baa/smmap-5.0.1.tar.gz": "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", + "https://files.pythonhosted.org/packages/a7/a5/10f97f73544edcdef54409f1d839f6049a0d79df68adbc1ceb24d1aaca42/smmap-5.0.1-py3-none-any.whl": "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da" + }, + "tomli": { + "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl": "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", + "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl": "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", + "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", + "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", + "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz": "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", + "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl": "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", + "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", + "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl": "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", + "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl": "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", + "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl": "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", + "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl": "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", + "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl": "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", + "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", + "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", + "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl": "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", + "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl": "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", + "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl": "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", + "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", + "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", + "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", + "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", + "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", + "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", + "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", + "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl": "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", + "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl": "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", + "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl": "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", + "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl": "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", + "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", + "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", + "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl": "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", + "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a" + }, + "trycast": { + "https://files.pythonhosted.org/packages/4c/9e/078254410a17331b258b8cba56e97c4b7d53fa0a764d33cc6b193496d9ea/trycast-1.3.0.tar.gz": "sha256:09ba60415234b033bb80756db154056e95519edc35f4973a267c63e9e0d848c9", + "https://files.pythonhosted.org/packages/a0/3d/ec36412efd3b194964687a095b1d5f1d0528f079a05c7ef78402e6777327/trycast-1.3.0-py3-none-any.whl": "sha256:e02f15c4e375b3b958017ba111a51dc0587756536f0228f4385e9548b69fae84" + }, + "twine": { + "https://files.pythonhosted.org/packages/92/3c/58f808a359700f39a967dffede33efeac809262c03303fa3eec6afff8f49/twine-7.0.0.tar.gz": "sha256:85cdb29c518efef867360ae4acd4b0dfd61c8654a22fca08e6f8539f05022177", + "https://files.pythonhosted.org/packages/96/08/ddcdc06225eaad6de0e48e1002b06d919dbde20582d0662c7af51308e5d6/twine-7.0.0-py3-none-any.whl": "sha256:b854164df26db268af05f49aa5c0344b10e27a494343ff05b1e0bad3b135f5a7" + }, + "twisted": { + "https://files.pythonhosted.org/packages/70/53/a50654eb9c63da0df2b5dca8ec27656a88b7edd798de5ffad55353203874/twisted-24.11.0-py3-none-any.whl": "sha256:fe403076c71f04d5d2d789a755b687c5637ec3bcd3b2b8252d76f2ba65f54261", + "https://files.pythonhosted.org/packages/77/1c/e07af0df31229250ab58a943077e4adbd5e227d9f2ac826920416b3e5fa2/twisted-24.11.0.tar.gz": "sha256:695d0556d5ec579dcc464d2856b634880ed1319f45b10d19043f2b57eb0115b5" + }, + "typeguard": { + "https://files.pythonhosted.org/packages/70/60/8cd6a3d78d00ceeb2193c02b7ed08f063d5341ccdfb24df88e61f383048e/typeguard-4.4.2.tar.gz": "sha256:a6f1065813e32ef365bc3b3f503af8a96f9dd4e0033a02c28c4a4983de8c6c49", + "https://files.pythonhosted.org/packages/cf/4b/9a77dc721aa0b7f74440a42e4ef6f9a4fae7324e17f64f88b96f4c25cc05/typeguard-4.4.2-py3-none-any.whl": "sha256:77a78f11f09777aeae7fa08585f33b5f4ef0e7335af40005b0c422ed398ff48c" + }, + "typing-extensions": { + "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl": "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", + "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl": "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", + "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz": "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", + "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz": "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5" + }, + "tzdata": { + "https://files.pythonhosted.org/packages/5e/a7/c202b344c5ca7daf398f3b8a477eeb205cf3b6f32e7ec3a6bac0629ca975/tzdata-2025.3.tar.gz": "sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7", + "https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl": "sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1" + }, + "unidecode": { + "https://files.pythonhosted.org/packages/84/b7/6ec57841fb67c98f52fc8e4a2d96df60059637cba077edc569a302a8ffc7/Unidecode-1.3.8-py3-none-any.whl": "sha256:d130a61ce6696f8148a3bd8fe779c99adeb4b870584eeb9526584e9aa091fd39", + "https://files.pythonhosted.org/packages/f7/89/19151076a006b9ac0dd37b1354e031f5297891ee507eb624755e58e10d3e/Unidecode-1.3.8.tar.gz": "sha256:cfdb349d46ed3873ece4586b96aa75258726e2fa8ec21d6f00a591d98806c2f4" + }, + "uritemplate": { + "https://files.pythonhosted.org/packages/81/c0/7461b49cd25aeece13766f02ee576d1db528f1c37ce69aee300e075b485b/uritemplate-4.1.1-py2.py3-none-any.whl": "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e", + "https://files.pythonhosted.org/packages/d2/5a/4742fdba39cd02a56226815abfa72fe0aa81c33bed16ed045647d6000eba/uritemplate-4.1.1.tar.gz": "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0" + }, + "urllib3": { + "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz": "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", + "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl": "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", + "https://files.pythonhosted.org/packages/92/9d/c4e665119135114480843e7ab388fa94d8480650450e6f8e26b70d323a4c/urllib3-2.8.0-py3-none-any.whl": "sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3", + "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl": "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", + "https://files.pythonhosted.org/packages/e3/05/b17359e1cefb4f909b5e40b1b90a496d987258916dbbf88e842c729f510e/urllib3-2.8.0.tar.gz": "sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63", + "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz": "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" + }, + "uvloop": { + "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl": "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", + "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz": "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", + "https://files.pythonhosted.org/packages/09/bd/3667151ad0702282a1f4d5d29288fce8a13c8b6858bf0978c219cd52b231/uvloop-0.22.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:ac33ed96229b7790eb729702751c0e93ac5bc3bcf52ae9eccbff30da09194b86", + "https://files.pythonhosted.org/packages/09/e0/604f61d004ded805f24974c87ddd8374ef675644f476f01f1df90e4cdf72/uvloop-0.22.1-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:a592b043a47ad17911add5fbd087c76716d7c9ccc1d64ec9249ceafd735f03c2", + "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl": "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", + "https://files.pythonhosted.org/packages/14/39/615af1a05a4010b67ff2061ce22b8df7944acccb79cfed7f9483f4742c04/uvloop-0.22.1-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:c3e5c6727a57cb6558592a95019e504f605d1c54eb86463ee9f7a2dbd411c820", + "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", + "https://files.pythonhosted.org/packages/24/68/a6ac446820273e71aa762fa21cdcc09861edd3536ff47c5cd3b7afb10eeb/uvloop-0.22.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:700e674a166ca5778255e0e1dc4e9d79ab2acc57b9171b79e65feba7184b3370", + "https://files.pythonhosted.org/packages/36/b2/9d69c9253fefd1ea40e139562ecec65579606709f3433871b51c35fa5fc7/uvloop-0.22.1-cp38-cp38-macosx_10_9_x86_64.whl": "sha256:017bd46f9e7b78e81606329d07141d3da446f8798c6baeec124260e22c262772", + "https://files.pythonhosted.org/packages/3d/ff/7f72e8170be527b4977b033239a83a68d5c881cc4775fca255c677f7ac5d/uvloop-0.22.1-cp312-cp312-macosx_10_13_universal2.whl": "sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42", + "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", + "https://files.pythonhosted.org/packages/43/cb/dc8bbe4058a641d31bf457771e8088fb79b4b222c3b6a48a0e35f37c3701/uvloop-0.22.1-cp38-cp38-musllinux_1_2_x86_64.whl": "sha256:4a968a72422a097b09042d5fa2c5c590251ad484acf910a651b4b620acd7f193", + "https://files.pythonhosted.org/packages/5f/6f/e62b4dfc7ad6518e7eff2516f680d02a0f6eb62c0c212e152ca708a0085e/uvloop-0.22.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:7b5b1ac819a3f946d3b2ee07f09149578ae76066d70b44df3fa990add49a82e4", + "https://files.pythonhosted.org/packages/74/4f/256aca690709e9b008b7108bc85fba619a2bc37c6d80743d18abad16ee09/uvloop-0.22.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:56a2d1fae65fd82197cb8c53c367310b3eabe1bbb9fb5a04d28e3e3520e4f702", + "https://files.pythonhosted.org/packages/75/be/f8e590fe61d18b4a92070905497aec4c0e64ae1761498cad09023f3f4b3e/uvloop-0.22.1-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:535cc37b3a04f6cd2c1ef65fa1d370c9a35b6695df735fcff5427323f2cd5473", + "https://files.pythonhosted.org/packages/76/ee/3fdfeaa9776c0fd585d358c92b1dbca669720ffa476f0bbe64ed8f245bd7/uvloop-0.22.1-cp39-cp39-musllinux_1_2_x86_64.whl": "sha256:286322a90bea1f9422a470d5d2ad82d38080be0a29c4dd9b3e6384320a4d11e7", + "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl": "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", + "https://files.pythonhosted.org/packages/7f/74/03c05ae4737e871923d21a76fe28b6aad57f5c03b6e6bfcfa5ad616013e4/uvloop-0.22.1-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:40631b049d5972c6755b06d0bfe8233b1bd9a8a6392d9d1c45c10b6f9e9b2733", + "https://files.pythonhosted.org/packages/83/fb/bee1eb11cc92bd91f76d97869bb6a816e80d59fd73721b0a3044dc703d9c/uvloop-0.22.1-cp39-cp39-musllinux_1_2_aarch64.whl": "sha256:05e4b5f86e621cf3927631789999e697e58f0d2d32675b67d9ca9eb0bca55743", + "https://files.pythonhosted.org/packages/86/94/9fb7fad2f824d25f8ecac0d70b94d0d48107ad5ece03769a9c543444f78a/uvloop-0.22.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:53c85520781d84a4b8b230e24a5af5b0778efdb39142b424990ff1ef7c48ba21", + "https://files.pythonhosted.org/packages/87/ed/863fe9bf180d420c005eaa6b0b368674956b3046384805563da3437770df/uvloop-0.22.1-cp38-cp38-musllinux_1_2_aarch64.whl": "sha256:55502bc2c653ed2e9692e8c55cb95b397d33f9f2911e929dc97c4d6b26d04242", + "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl": "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", + "https://files.pythonhosted.org/packages/90/60/97362554ac21e20e81bcef1150cb2a7e4ffdaf8ea1e5b2e8bf7a053caa18/uvloop-0.22.1-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:e047cc068570bac9866237739607d1313b9253c3051ad84738cbb095be0537b2", + "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl": "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", + "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl": "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", + "https://files.pythonhosted.org/packages/99/39/6b3f7d234ba3964c428a6e40006340f53ba37993f46ed6e111c6e9141d18/uvloop-0.22.1-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:512fec6815e2dd45161054592441ef76c830eddaad55c8aa30952e6fe1ed07c0", + "https://files.pythonhosted.org/packages/9e/91/2c84f00bdbe3c51023cc83b027bac1fe959ba4a552e970da5ef0237f7945/uvloop-0.22.1-cp39-cp39-macosx_10_9_x86_64.whl": "sha256:ea721dd3203b809039fcc2983f14608dae82b212288b346e0bfe46ec2fab0b7c", + "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", + "https://files.pythonhosted.org/packages/a8/73/c4e271b3bce59724e291465cc936c37758886a4868787da0278b3b56b905/uvloop-0.22.1-cp311-cp311-macosx_10_9_x86_64.whl": "sha256:3b7f102bf3cb1995cfeaee9321105e8f5da76fdb104cdad8986f85461a1b7b77", + "https://files.pythonhosted.org/packages/b3/f6/21657bb3beb5f8c57ce8be3b83f653dd7933c2fd00545ed1b092d464799a/uvloop-0.22.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:481c990a7abe2c6f4fc3d98781cc9426ebd7f03a9aaa7eb03d3bfc68ac2a46bd", + "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", + "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", + "https://files.pythonhosted.org/packages/ba/ae/6f6f9af7f590b319c94532b9567409ba11f4fa71af1148cab1bf48a07048/uvloop-0.22.1-cp310-cp310-macosx_10_9_x86_64.whl": "sha256:7cd375a12b71d33d46af85a3343b35d98e8116134ba404bd657b3b1d15988792", + "https://files.pythonhosted.org/packages/bb/ce/8491fd370b0230deb5eac69c7aae35b3be527e25a911c0acdffb922dc1cd/uvloop-0.22.1-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:1489cf791aa7b6e8c8be1c5a080bae3a672791fcb4e9e12249b05862a2ca9cec", + "https://files.pythonhosted.org/packages/bd/1b/6fbd611aeba01ef802c5876c94d7be603a9710db055beacbad39e75a31aa/uvloop-0.22.1-cp39-cp39-macosx_10_9_universal2.whl": "sha256:b45649628d816c030dba3c80f8e2689bab1c89518ed10d426036cdc47874dfc4", + "https://files.pythonhosted.org/packages/bf/75/cd9bd5e2ac7d5e6906769f6d5b656b3554266c5748ef23117827fbd07d7b/uvloop-0.22.1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:57df59d8b48feb0e613d9b1f5e57b7532e97cbaf0d61f7aa9aa32221e84bc4b6", + "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", + "https://files.pythonhosted.org/packages/c3/c6/e5d433f88fd54d81ef4be58b2b7b0cea13c442454a1db703a1eea0db1a59/uvloop-0.22.1-cp312-cp312-macosx_10_13_x86_64.whl": "sha256:51eb9bd88391483410daad430813d982010f9c9c89512321f5b60e2cddbdddd6", + "https://files.pythonhosted.org/packages/c7/d5/69900f7883235562f1f50d8184bb7dd84a2fb61e9ec63f3782546fdbd057/uvloop-0.22.1-cp311-cp311-macosx_10_9_universal2.whl": "sha256:c60ebcd36f7b240b30788554b6f0782454826a0ed765d8430652621b5de674b9", + "https://files.pythonhosted.org/packages/cc/10/76aec83886d41a88aca5681db6a2c0601622d0d2cb66cd0d200587f962ad/uvloop-0.22.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:0ae676de143db2b2f60a9696d7eca5bb9d0dd6cc3ac3dad59a8ae7e95f9e1b54", + "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl": "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", + "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", + "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl": "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", + "https://files.pythonhosted.org/packages/d5/9a/733fcb815d345979fc54d3cdc3eb50bc75a47da3e4003ea7ada58e6daa65/uvloop-0.22.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:17d4e97258b0172dfa107b89aa1eeba3016f4b1974ce85ca3ef6a66b35cbf659", + "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl": "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", + "https://files.pythonhosted.org/packages/eb/14/ecceb239b65adaaf7fde510aa8bd534075695d1e5f8dadfa32b5723d9cfb/uvloop-0.22.1-cp310-cp310-macosx_10_9_universal2.whl": "sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c", + "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl": "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", + "https://files.pythonhosted.org/packages/f2/82/8a4a6785b53ee42f9235e9d7aacab8b691204e96554c80135a8806a940d4/uvloop-0.22.1-cp38-cp38-macosx_10_9_universal2.whl": "sha256:80eee091fe128e425177fbd82f8635769e2f32ec9daf6468286ec57ec0313efa", + "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad" + }, + "validate-email": { + "https://files.pythonhosted.org/packages/84/a0/cb53fb64b52123513d04f9b913b905f3eb6fda7264e639b4573cc715c29f/validate_email-1.3.tar.gz": "sha256:784719dc5f780be319cdd185dc85dd93afebdb6ebb943811bc4c7c5f9c72aeaf" + }, + "verboselogs": { + "https://files.pythonhosted.org/packages/29/15/90ffe9bdfdd1e102bc6c21b1eea755d34e69772074b6e706cab741b9b698/verboselogs-1.7.tar.gz": "sha256:e33ddedcdfdafcb3a174701150430b11b46ceb64c2a9a26198c76a156568e427", + "https://files.pythonhosted.org/packages/b8/9d/c5c3cb0093642042fd604b53928ac65e7650fdc5a8a97814288e29beab84/verboselogs-1.7-py2.py3-none-any.whl": "sha256:d63f23bf568295b95d3530c6864a0b580cec70e7ff974177dead1e4ffbc6ff49" + }, + "watchfiles": { + "https://files.pythonhosted.org/packages/00/24/1c089457e39a0e6a142df8cb795a690b71f05c948bc60df4ec12359956b8/watchfiles-0.23.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:fd257f98cff9c6cb39eee1a83c7c3183970d8a8d23e8cf4f47d9a21329285cee", + "https://files.pythonhosted.org/packages/03/31/c1b5ea92100d9774f5a8a89115a43ef1c4fb169b643b6cc930e0cd2c5728/watchfiles-0.23.0-cp311-none-win_amd64.whl": "sha256:46f1d8069a95885ca529645cdbb05aea5837d799965676e1b2b1f95a4206313e", + "https://files.pythonhosted.org/packages/03/f1/fdacfdbffb0635a7d0140ecca6ef7b5bce6566a085f76a65eb796ee54ddd/watchfiles-0.23.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:0e01bcb8d767c58865207a6c2f2792ad763a0fe1119fb0a430f444f5b02a5ea0", + "https://files.pythonhosted.org/packages/06/9c/46e0d17853b62b5d4bf8095e7b9bb0b0ad4babb6c6133138929473f161f3/watchfiles-0.23.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:b8d3c5cd327dd6ce0edfc94374fb5883d254fe78a5e9d9dfc237a1897dc73cd1", + "https://files.pythonhosted.org/packages/07/85/0d231295071443fb82f2d57a786ae9b2d935c7a168724b74a8de0c07d53e/watchfiles-0.23.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl": "sha256:a96ac14e184aa86dc43b8a22bb53854760a58b2966c2b41580de938e9bf26ed0", + "https://files.pythonhosted.org/packages/09/47/8287b6757a094988eb762837a8ad814525c966c2d156cd0e486d1d6ac8d5/watchfiles-0.23.0-cp39-cp39-musllinux_1_1_aarch64.whl": "sha256:8ada449e22198c31fb013ae7e9add887e8d2bd2335401abd3cbc55f8c5083647", + "https://files.pythonhosted.org/packages/09/79/f9e6dca8a48766f3186b9610f77055f80e81fd5cb2371c55d13d6a84d19e/watchfiles-0.23.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl": "sha256:aba037c1310dd108411d27b3d5815998ef0e83573e47d4219f45753c710f969f", + "https://files.pythonhosted.org/packages/0b/07/f5b54afa8b7c33386c5778d92e681562939900f4ee1c6de9bffc49e7221f/watchfiles-0.23.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:02b7ba9d4557149410747353e7325010d48edcfe9d609a85cb450f17fd50dc3d", + "https://files.pythonhosted.org/packages/14/5f/787386438d895145099e1415d1fbd3ff047a4f5e329134fd30677fe83f1f/watchfiles-0.23.0-cp311-cp311-macosx_10_12_x86_64.whl": "sha256:e397b64f7aaf26915bf2ad0f1190f75c855d11eb111cc00f12f97430153c2eab", + "https://files.pythonhosted.org/packages/1a/c6/bf3b8cbe6944499fbe0d400175560a200cdecadccbacc8ace74486565d74/watchfiles-0.23.0-cp313-none-win_amd64.whl": "sha256:f449afbb971df5c6faeb0a27bca0427d7b600dd8f4a068492faec18023f0dcff", + "https://files.pythonhosted.org/packages/1d/b9/09e6918eac8d6f9e178adfa8b99b4f955001e670086cf4778e4e1daf973e/watchfiles-0.23.0-cp38-none-win_amd64.whl": "sha256:c846884b2e690ba62a51048a097acb6b5cd263d8bd91062cd6137e2880578472", + "https://files.pythonhosted.org/packages/20/08/c0a09fc63a6b75fccd3e99b21f07ddb812e64a78da10703397b39653263e/watchfiles-0.23.0-cp310-cp310-macosx_10_12_x86_64.whl": "sha256:bee8ce357a05c20db04f46c22be2d1a2c6a8ed365b325d08af94358e0688eeb4", + "https://files.pythonhosted.org/packages/20/5e/a97417a6544615b21c7960a45aeea13e3b42779e0ed3ebdd2d76ad62ab50/watchfiles-0.23.0-cp312-cp312-macosx_11_0_arm64.whl": "sha256:62d2b18cb1edaba311fbbfe83fb5e53a858ba37cacb01e69bc20553bb70911b8", + "https://files.pythonhosted.org/packages/22/ec/c756c012b174ccf5f2ee32202603e66b33b93a54cf16c69a7440c764d7f9/watchfiles-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:8f48c917ffd36ff9a5212614c2d0d585fa8b064ca7e66206fb5c095015bc8207", + "https://files.pythonhosted.org/packages/22/ee/06a0a6cbde8ac6fff57c33da9e428f42dd0989e60a6ad72ca6534f650a47/watchfiles-0.23.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:37fd826dac84c6441615aa3f04077adcc5cac7194a021c9f0d69af20fb9fa788", + "https://files.pythonhosted.org/packages/23/9c/810ede8d4dff7e65393b50cbb1a3ef10b6cdb1312a97d8106712175355c8/watchfiles-0.23.0-cp311-none-win_arm64.whl": "sha256:e495ed2a7943503766c5d1ff05ae9212dc2ce1c0e30a80d4f0d84889298fa304", + "https://files.pythonhosted.org/packages/28/24/060b064f28083866d916052fcced5c3547c5081a8e27b0702434666aa9a0/watchfiles-0.23.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl": "sha256:dd41d5c72417b87c00b1b635738f3c283e737d75c5fa5c3e1c60cd03eac3af77", + "https://files.pythonhosted.org/packages/28/8a/6d00aa4aa9a9938de645c1d411e3af82e74db8d25a0c05427b7a88b4d8d3/watchfiles-0.23.0-cp313-cp313-musllinux_1_1_aarch64.whl": "sha256:109a61763e7318d9f821b878589e71229f97366fa6a5c7720687d367f3ab9eef", + "https://files.pythonhosted.org/packages/29/46/f41defd581154c4022c04ef41f812e6fd1633e75444e7b12147fdb0b7364/watchfiles-0.23.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl": "sha256:7ca6b71dcc50d320c88fb2d88ecd63924934a8abc1673683a242a7ca7d39e781", + "https://files.pythonhosted.org/packages/2c/35/a683945181a527083a1146620997b5d6ffe06d716c4497d388bfea813f0c/watchfiles-0.23.0-cp312-cp312-musllinux_1_1_x86_64.whl": "sha256:bd3e2d64500a6cad28bcd710ee6269fbeb2e5320525acd0cfab5f269ade68581", + "https://files.pythonhosted.org/packages/2c/ff/e891b230bcf3a648352a00b920d4a1142a938f0b97c9e8e27c2eaaeda221/watchfiles-0.23.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:9ff785af8bacdf0be863ec0c428e3288b817e82f3d0c1d652cd9c6d509020dd0", + "https://files.pythonhosted.org/packages/2f/bd/6ac26a36b16182e2b6df21ac7a86c647979ae43acb6dd03eab14bee66bd8/watchfiles-0.23.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:1733b9bc2c8098c6bdb0ff7a3d7cb211753fecb7bd99bdd6df995621ee1a574b", + "https://files.pythonhosted.org/packages/32/17/819ab060ff4f948c419d0d6e3a7c3d49bc19e6b75fc9afeb155395049d7a/watchfiles-0.23.0-cp38-cp38-macosx_10_12_x86_64.whl": "sha256:2dddc2487d33e92f8b6222b5fb74ae2cfde5e8e6c44e0248d24ec23befdc5366", + "https://files.pythonhosted.org/packages/34/2c/c279de01628f467d16b444bdcedf9c4ce3bc5242cb23f9bfb8fbff8522ee/watchfiles-0.23.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:d1aa4cc85202956d1a65c88d18c7b687b8319dbe6b1aec8969784ef7a10e7d1a", + "https://files.pythonhosted.org/packages/39/ba/d361135dac6cd0fb4449f4f058c053eb9b42f70ff4d9a13767808e18851c/watchfiles-0.23.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl": "sha256:c5e7803a65eb2d563c73230e9d693c6539e3c975ccfe62526cadde69f3fda0cf", + "https://files.pythonhosted.org/packages/3b/25/ec3676b140a93ac256d058a6f82810cf5e0e42fd444b948c62bc56f57f52/watchfiles-0.23.0-cp313-none-win32.whl": "sha256:f46c6f0aec8d02a52d97a583782d9af38c19a29900747eb048af358a9c1d8e5b", + "https://files.pythonhosted.org/packages/3b/cc/85dac96249b3fb93178d8111befed7ab517bdabec9793296c39400189235/watchfiles-0.23.0-cp38-none-win32.whl": "sha256:aafea64a3ae698695975251f4254df2225e2624185a69534e7fe70581066bc1b", + "https://files.pythonhosted.org/packages/3d/02/f223537cd0e3c22df45629710b27b7f89fdf4114be2f3399b83faedf1446/watchfiles-0.23.0-cp311-none-win32.whl": "sha256:1d636c8aeb28cdd04a4aa89030c4b48f8b2954d8483e5f989774fa441c0ed57b", + "https://files.pythonhosted.org/packages/3f/b5/1faa511755b72dfd0eecf2230113a55318e11d2080f659326e7f758b3b0f/watchfiles-0.23.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:532e1f2c491274d1333a814e4c5c2e8b92345d41b12dc806cf07aaff786beb66", + "https://files.pythonhosted.org/packages/43/cf/747f412b75ea4bb5419e659ae8b2713a327b6f879e3f2e0695c7d7275cf3/watchfiles-0.23.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:fb02d41c33be667e6135e6686f1bb76104c88a312a18faa0ef0262b5bf7f1a0f", + "https://files.pythonhosted.org/packages/4b/d1/dab28bed3bc9172d44100e5fae8107bd01ef85fc6bddb80d223d0d9f709f/watchfiles-0.23.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl": "sha256:6b1a950ab299a4a78fd6369a97b8763732bfb154fdb433356ec55a5bce9515c1", + "https://files.pythonhosted.org/packages/4b/dd/fab40f60fcfd868e000315983b996a97bb12977f2de347c1e7a40a5d1c7d/watchfiles-0.23.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:f18de0f82c62c4197bea5ecf4389288ac755896aac734bd2cc44004c56e4ac47", + "https://files.pythonhosted.org/packages/54/29/e5052c455ff0d8fa9625b99b11877f804bb68150d2c8b82a4b2d871fd23d/watchfiles-0.23.0-cp39-none-win_amd64.whl": "sha256:d2d42254b189a346249424fb9bb39182a19289a2409051ee432fb2926bad966a", + "https://files.pythonhosted.org/packages/57/65/f3e854c5b8912d76c8fefc7c891b3df628b9110907b968faadcb8142347e/watchfiles-0.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:18e2de19801b0eaa4c5292a223effb7cfb43904cb742c5317a0ac686ed604765", + "https://files.pythonhosted.org/packages/5a/d9/120d212d2952342e2c9673096f5c17cd48e90a7c9ff203ab1ad2f974befe/watchfiles-0.23.0-cp313-cp313-musllinux_1_1_x86_64.whl": "sha256:9f8e6bb5ac007d4a4027b25f09827ed78cbbd5b9700fd6c54429278dacce05d1", + "https://files.pythonhosted.org/packages/5c/25/6511ed7bc826ddc2a4e879cf469621a1184719e97d63e7f723e95991ebd3/watchfiles-0.23.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl": "sha256:9f02a259fcbbb5fcfe7a0805b1097ead5ba7a043e318eef1db59f93067f0b49b", + "https://files.pythonhosted.org/packages/5e/7f/bdf0d159141d2926432331a0eb33ae2a4978b9ad89912ce9297711cbc43e/watchfiles-0.23.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:a8f195338a5a7b50a058522b39517c50238358d9ad8284fd92943643144c0c03", + "https://files.pythonhosted.org/packages/61/52/85cdf326a53f1ae3fbe5dcab13f5729ca91ec2d61140e095a2a4cdf6a9ca/watchfiles-0.23.0-cp312-cp312-macosx_10_12_x86_64.whl": "sha256:1db691bad0243aed27c8354b12d60e8e266b75216ae99d33e927ff5238d270b5", + "https://files.pythonhosted.org/packages/62/c9/94f91ad2f88f4d84a0ccea6628d47f51007f03d5e4be6718f208c55cd1f5/watchfiles-0.23.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:02ff5d7bd066c6a7673b17c8879cd8ee903078d184802a7ee851449c43521bdd", + "https://files.pythonhosted.org/packages/67/38/6a24bf5724ce3d6e9087a7f9b7faf33760dfa5616974eda1ed35ba9ef41b/watchfiles-0.23.0-cp39-cp39-macosx_11_0_arm64.whl": "sha256:6bb91fa4d0b392f0f7e27c40981e46dda9eb0fbc84162c7fb478fe115944f491", + "https://files.pythonhosted.org/packages/6a/a1/d7aa3f23c78b2c9cac5d1cf46fed5f74340d0ffd47c0f485b76419ec6597/watchfiles-0.23.0-cp310-none-win_amd64.whl": "sha256:4ea756e425ab2dfc8ef2a0cb87af8aa7ef7dfc6fc46c6f89bcf382121d4fff75", + "https://files.pythonhosted.org/packages/73/d3/00d561a66aa000251ed598f576e8bfd1c4102f9956fc06310e9b53258d3e/watchfiles-0.23.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:1ebaebb53b34690da0936c256c1cdb0914f24fb0e03da76d185806df9328abed", + "https://files.pythonhosted.org/packages/76/6f/3075cd9c69fdce2544fb13cb9e3c8ad51424cb2c552b019514799a14966e/watchfiles-0.23.0-cp311-cp311-macosx_11_0_arm64.whl": "sha256:b4ac73b02ca1824ec0a7351588241fd3953748d3774694aa7ddb5e8e46aef3e3", + "https://files.pythonhosted.org/packages/78/94/97ac8d7a19f5439ab5cc28d0b5d648760358e43097f6acb8cb7165c4c1b7/watchfiles-0.23.0-cp310-cp310-musllinux_1_1_aarch64.whl": "sha256:9d183e3888ada88185ab17064079c0db8c17e32023f5c278d7bf8014713b1b5b", + "https://files.pythonhosted.org/packages/8c/ff/2b338016e96ab592e8d9cece0260b9fca54d8bed7b36940c46112eda2e49/watchfiles-0.23.0-cp310-cp310-macosx_11_0_arm64.whl": "sha256:4ccd3011cc7ee2f789af9ebe04745436371d36afe610028921cab9f24bb2987b", + "https://files.pythonhosted.org/packages/91/6c/f099be35e763bae70190c8b9ce269f94745cb181711bdf023c1f1796a9f0/watchfiles-0.23.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:efadd40fca3a04063d40c4448c9303ce24dd6151dc162cfae4a2a060232ebdcb", + "https://files.pythonhosted.org/packages/93/41/dcfbc67472a42480f4376124b52238cc8b6b84d9b2b0316cc037feaa4b22/watchfiles-0.23.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl": "sha256:20b423b58f5fdde704a226b598a2d78165fe29eb5621358fe57ea63f16f165c4", + "https://files.pythonhosted.org/packages/98/e1/76ad010c0a2bb6efbb80383c0bba56db065238f12b0da6e6026b4e69f6aa/watchfiles-0.23.0-cp313-cp313-macosx_11_0_arm64.whl": "sha256:85042ab91814fca99cec4678fc063fb46df4cbb57b4835a1cc2cb7a51e10250e", + "https://files.pythonhosted.org/packages/9e/1a/b06613ef620d7f5ca712a3d4928ec1c07182159a64277fcdf7738edb0b32/watchfiles-0.23.0.tar.gz": "sha256:9338ade39ff24f8086bb005d16c29f8e9f19e55b18dcb04dfa26fcbc09da497b", + "https://files.pythonhosted.org/packages/9e/9b/ec2eabc996e5332fc89c633fbe762e08a58a7df6b5e595dd458c5f7778a4/watchfiles-0.23.0-cp312-none-win32.whl": "sha256:eb99c954291b2fad0eff98b490aa641e128fbc4a03b11c8a0086de8b7077fb75", + "https://files.pythonhosted.org/packages/a1/13/d2d59d545b84fd3cf4f08b69da358209b4276c2c932d060d94a421015074/watchfiles-0.23.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:24655e8c1c9c114005c3868a3d432c8aa595a786b8493500071e6a52f3d09217", + "https://files.pythonhosted.org/packages/a1/2c/0d86bd0b9239f7d72f96848357eb082baed2d70b5cc257593d1ad39e06cd/watchfiles-0.23.0-cp38-cp38-musllinux_1_1_x86_64.whl": "sha256:a8323daae27ea290ba3350c70c836c0d2b0fb47897fa3b0ca6a5375b952b90d3", + "https://files.pythonhosted.org/packages/a3/b6/243c1dd351ac9b8258a3ea99c33d04ecdc9766e6c7f13a43452883e92a7a/watchfiles-0.23.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:48a1b05c0afb2cd2f48c1ed2ae5487b116e34b93b13074ed3c22ad5c743109f0", + "https://files.pythonhosted.org/packages/a4/9f/a3c9f1fbcd1099554e4f707e14473ff23f0e05013d553755b98c2d86716d/watchfiles-0.23.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:87f889f6e58849ddb7c5d2cb19e2e074917ed1c6e3ceca50405775166492cca8", + "https://files.pythonhosted.org/packages/a4/b8/992e478c6732ab75bf97d691f2ae7bf9f0aac4e269b2ac776ed79a65ef3a/watchfiles-0.23.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:ee1f5fcbf5bc33acc0be9dd31130bcba35d6d2302e4eceafafd7d9018c7755ab", + "https://files.pythonhosted.org/packages/ab/6b/cd4faa27088a8b612ffdfa25e3d413e676a6173b8b02a33e7fec152d75ca/watchfiles-0.23.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:130a896d53b48a1cecccfa903f37a1d87dbb74295305f865a3e816452f6e49e4", + "https://files.pythonhosted.org/packages/ae/8d/fdf4efc0235dcf158e8e1e91a3f74ff2db7492c94397cdba463c0e5e6293/watchfiles-0.23.0-cp39-cp39-musllinux_1_1_x86_64.whl": "sha256:3af1b05361e1cc497bf1be654a664750ae61f5739e4bb094a2be86ec8c6db9b6", + "https://files.pythonhosted.org/packages/b0/c5/d6a3c0001e116063b85382308770eaf2235decd2fbae3c67178e45fc07b0/watchfiles-0.23.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:524fcb8d59b0dbee2c9b32207084b67b2420f6431ed02c18bd191e6c575f5c48", + "https://files.pythonhosted.org/packages/b1/32/86f0d012d344168ed30746c04cac7ce3292ef5220fa4823ad73ca5f1f1db/watchfiles-0.23.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:b1f67312efa3902a8e8496bfa9824d3bec096ff83c4669ea555c6bdd213aa516", + "https://files.pythonhosted.org/packages/b1/64/a80f51cb55c967629930682bf120d5ca9d1c65077c38328be635ed0d567c/watchfiles-0.23.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:7f7252f52a09f8fa5435dc82b6af79483118ce6bd51eb74e6269f05ee22a7b9f", + "https://files.pythonhosted.org/packages/b3/e4/2647ca9aaa072e139a4cc6c83c8a15d2f8fa6740913903ab998917a5ed97/watchfiles-0.23.0-cp311-cp311-musllinux_1_1_x86_64.whl": "sha256:857af85d445b9ba9178db95658c219dbd77b71b8264e66836a6eba4fbf49c320", + "https://files.pythonhosted.org/packages/b4/45/d97e61c893fc59d4b0c4154fdf26449e103a3783db4d981bb8e7301af532/watchfiles-0.23.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:ecf2be4b9eece4f3da8ba5f244b9e51932ebc441c0867bd6af46a3d97eb068d6", + "https://files.pythonhosted.org/packages/b4/dd/8214a88b94fd0ed559e3f38b973a01bb3b48e9365dcb1d1966438dce816d/watchfiles-0.23.0-cp39-cp39-macosx_10_12_x86_64.whl": "sha256:a753993635eccf1ecb185dedcc69d220dab41804272f45e4aef0a67e790c3eb3", + "https://files.pythonhosted.org/packages/b6/00/ac760f3fa8d8975dbeaef9af99b21077e7c38898ac5051c8601649d86d99/watchfiles-0.23.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:1e5f3ca0ff47940ce0a389457b35d6df601c317c1e1a9615981c474452f98de1", + "https://files.pythonhosted.org/packages/b9/f0/76ad5227da9461b1190de2f9dd21fece09660a9a44607de9c728f3d3e93f/watchfiles-0.23.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:ee7db6e36e7a2c15923072e41ea24d9a0cf39658cb0637ecc9307b09d28827e1", + "https://files.pythonhosted.org/packages/bc/82/537945ed624af6248c9820a99cbfd5902bb5e6a71a01a5b3de0c00f1872e/watchfiles-0.23.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:e087e8fdf1270d000913c12e6eca44edd02aad3559b3e6b8ef00f0ce76e0636f", + "https://files.pythonhosted.org/packages/c4/ee/6fc9552ad1a68e68ea8209166916dc8c5824bef80c325ec36c5362277d24/watchfiles-0.23.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl": "sha256:556347b0abb4224c5ec688fc58214162e92a500323f50182f994f3ad33385dcb", + "https://files.pythonhosted.org/packages/c6/64/07f4c50883f1406e5a4187651b4d3d2495582df9f70d320ee3c9e7ed19be/watchfiles-0.23.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl": "sha256:7cf12ac34c444362f3261fb3ff548f0037ddd4c5bb85f66c4be30d2936beb3c5", + "https://files.pythonhosted.org/packages/ca/da/dffc4fc9a38a0189c91c502856d7d828b8ad6ecdecbeeb81022b301b5b03/watchfiles-0.23.0-cp38-cp38-musllinux_1_1_aarch64.whl": "sha256:0eff099a4df36afaa0eea7a913aa64dcf2cbd4e7a4f319a73012210af4d23810", + "https://files.pythonhosted.org/packages/d1/23/89b2bef692c350de8a4c2bde501fdf6087889a55f52a3201f0c53b616087/watchfiles-0.23.0-cp312-cp312-musllinux_1_1_aarch64.whl": "sha256:8e56fbcdd27fce061854ddec99e015dd779cae186eb36b14471fc9ae713b118c", + "https://files.pythonhosted.org/packages/d3/aa/33c470ba209a236865a6a6cc0c027e5b9e08b3420a3fb431e17c6d981fe1/watchfiles-0.23.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:b98732ec893975455708d6fc9a6daab527fc8bbe65be354a3861f8c450a632a4", + "https://files.pythonhosted.org/packages/d6/8b/8f868c420aa6afb19a40c20c2bceef879bf45b15c67a9d9b8ddb9cf28365/watchfiles-0.23.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:2537ef60596511df79b91613a5bb499b63f46f01a11a81b0a2b0dedf645d0a9c", + "https://files.pythonhosted.org/packages/d7/34/606577c1c99ed184edda555ce37728f6f3da90865e4dcfd98020c1f23fc1/watchfiles-0.23.0-cp39-none-win32.whl": "sha256:486bda18be5d25ab5d932699ceed918f68eb91f45d018b0343e3502e52866e5e", + "https://files.pythonhosted.org/packages/d8/e9/4af3cfb2eb161003ce79518eb0cbfd014313e30dc842209776fbee3a64e6/watchfiles-0.23.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:a0b2c25040a3c0ce0e66c7779cc045fdfbbb8d59e5aabfe033000b42fe44b53e", + "https://files.pythonhosted.org/packages/e0/3a/62add8d90070f4b17f8bbfd66c9eaa9e08af3bc4020c07a9400d1b959aaf/watchfiles-0.23.0-cp312-none-win_amd64.whl": "sha256:dccc858372a56080332ea89b78cfb18efb945da858fabeb67f5a44fa0bcb4ebb", + "https://files.pythonhosted.org/packages/e1/15/daf4361e0a6e6b27f516aaaacbb16baa8d1a266657b2314862fc73f2deaf/watchfiles-0.23.0-cp311-cp311-musllinux_1_1_aarch64.whl": "sha256:2368c5371c17fdcb5a2ea71c5c9d49f9b128821bfee69503cc38eae00feb3220", + "https://files.pythonhosted.org/packages/e4/63/9c5c902a041d4b742ab83220137e9c7570a829db6b0a9a41b751ac5937d0/watchfiles-0.23.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl": "sha256:1cf7f486169986c4b9d34087f08ce56a35126600b6fef3028f19ca16d5889071", + "https://files.pythonhosted.org/packages/e8/9a/2792d4c24105104bfaf959bffefb09e02d14050913a83242ce4eb1e3f2ff/watchfiles-0.23.0-cp312-none-win_arm64.whl": "sha256:6c21a5467f35c61eafb4e394303720893066897fca937bade5b4f5877d350ff8", + "https://files.pythonhosted.org/packages/ec/bf/77bc430ede44c217f3e6a68c1f55a8304dc1cd82d32623cacaedc2e122b2/watchfiles-0.23.0-cp38-cp38-macosx_11_0_arm64.whl": "sha256:e75695cc952e825fa3e0684a7f4a302f9128721f13eedd8dbd3af2ba450932b8", + "https://files.pythonhosted.org/packages/f2/55/7266cd63e736abbde902cbd99fb70a8eddfac7e0e52ed52fbbee6eed5f95/watchfiles-0.23.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl": "sha256:40cb8fa00028908211eb9f8d47744dca21a4be6766672e1ff3280bee320436f1", + "https://files.pythonhosted.org/packages/f6/5b/1a1d9bca4eae8cf191e74b62cd970f4a010f56f897c11dd2e6caef3ce7e3/watchfiles-0.23.0-cp313-cp313-macosx_10_12_x86_64.whl": "sha256:ba31c32f6b4dceeb2be04f717811565159617e28d61a60bb616b6442027fd4b9", + "https://files.pythonhosted.org/packages/f7/52/2f7bbedc5f524d2ba0e9d792dab01ef4418d0f5045a9f5f4e5aca142a30d/watchfiles-0.23.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl": "sha256:6991e3a78f642368b8b1b669327eb6751439f9f7eaaa625fae67dd6070ecfa0b", + "https://files.pythonhosted.org/packages/f7/7c/135a60260dd055227eb3b38f0be5fc16409ad58c5c6636467b27991fd863/watchfiles-0.23.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl": "sha256:6a9265cf87a5b70147bfb2fec14770ed5b11a5bb83353f0eee1c25a81af5abfe", + "https://files.pythonhosted.org/packages/fa/2c/ba3e9d54c17a4014996555a0b31f4be1c8920fdfe067942f60873ac8931a/watchfiles-0.23.0-cp310-none-win32.whl": "sha256:296e0b29ab0276ca59d82d2da22cbbdb39a23eed94cca69aed274595fb3dfe42", + "https://files.pythonhosted.org/packages/fc/c9/568a54e07245a068819572a7d51c7d2f6ff8e7018102e956156fadae408c/watchfiles-0.23.0-cp310-cp310-musllinux_1_1_x86_64.whl": "sha256:9837edf328b2805346f91209b7e660f65fb0e9ca18b7459d075d58db082bf981", + "https://files.pythonhosted.org/packages/fd/36/bf01f9d2f16609f8a9564c9001895df821212a14cda6e1cc25d4295c8c61/watchfiles-0.23.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:2aec5c29915caf08771d2507da3ac08e8de24a50f746eb1ed295584ba1820330", + "https://files.pythonhosted.org/packages/fd/df/af2a1c7b19eb4927bcd7edf75ed64ed6eb7208921adc14a11cdede1b3225/watchfiles-0.23.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:11698bb2ea5e991d10f1f4f83a39a02f91e44e4bd05f01b5c1ec04c9342bf63c" + }, + "wrapt": { + "https://files.pythonhosted.org/packages/00/ad/5d2c1b34ba3202cd833d9221833e74d6500ce66730974993a8dc9a94fb8c/wrapt-1.17.2-cp39-cp39-win_amd64.whl": "sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb", + "https://files.pythonhosted.org/packages/09/28/2e45a4f4771fcfb109e244d5dbe54259e970362a311b67a965555ba65026/wrapt-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82", + "https://files.pythonhosted.org/packages/09/5e/1655cf481e079c1f22d0cabdd4e51733679932718dc23bf2db175f329b76/wrapt-1.17.2-cp313-cp313t-win_amd64.whl": "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c", + "https://files.pythonhosted.org/packages/09/99/c0c844a5ccde0fe5761d4305485297f91d67cf2a1a824c5f282e661ec7ff/wrapt-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000", + "https://files.pythonhosted.org/packages/0c/66/95b9e90e6e1274999b183c9c3f984996d870e933ca9560115bd1cd1d6f77/wrapt-1.17.2-cp38-cp38-macosx_10_9_universal2.whl": "sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9", + "https://files.pythonhosted.org/packages/0d/21/09573d2443916705c57fdab85d508f592c0a58d57becc53e15755d67fba2/wrapt-1.17.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2", + "https://files.pythonhosted.org/packages/0f/77/0576d841bf84af8579124a93d216f55d6f74374e4445264cb378a6ed33eb/wrapt-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72", + "https://files.pythonhosted.org/packages/15/06/1dbf478ea45c03e78a6a8c4be4fdc3c3bddea5c8de8a93bc971415e47f0f/wrapt-1.17.2-cp312-cp312-win_amd64.whl": "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991", + "https://files.pythonhosted.org/packages/17/27/4fe749a54e7fae6e7146f1c7d914d28ef599dacd4416566c055564080fe2/wrapt-1.17.2-cp312-cp312-win32.whl": "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9", + "https://files.pythonhosted.org/packages/1b/7b/13369d42651b809389c1a7153baa01d9700430576c81a2f5c5e460df0ed9/wrapt-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl": "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22", + "https://files.pythonhosted.org/packages/25/cb/7262bc1b0300b4b64af50c2720ef958c2c1917525238d661c3e9a2b71b7b/wrapt-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b", + "https://files.pythonhosted.org/packages/27/70/0f6e0679845cbf8b165e027d43402a55494779295c4b08414097b258ac87/wrapt-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c", + "https://files.pythonhosted.org/packages/2a/5a/04cde32b07a7431d4ed0553a76fdb7a61270e78c5fd5a603e190ac389f14/wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98", + "https://files.pythonhosted.org/packages/2b/49/364a615a0cc0872685646c495c7172e4fc7bf1959e3b12a1807a03014e05/wrapt-1.17.2-cp39-cp39-win32.whl": "sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb", + "https://files.pythonhosted.org/packages/2d/21/cf0bd85ae66f92600829ea1de8e1da778e5e9f6e574ccbe74b66db0d95db/wrapt-1.17.2-cp39-cp39-musllinux_1_2_i686.whl": "sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8", + "https://files.pythonhosted.org/packages/2d/82/f56956041adef78f849db6b289b282e72b55ab8045a75abad81898c28d19/wrapt-1.17.2-py3-none-any.whl": "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", + "https://files.pythonhosted.org/packages/32/98/4ed894cf012b6d6aae5f5cc974006bdeb92f0241775addad3f8cd6ab71c8/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb", + "https://files.pythonhosted.org/packages/34/0c/85af70d291f44659c422416f0272046109e785bf6db8c081cfeeae5715c5/wrapt-1.17.2-cp38-cp38-musllinux_1_2_x86_64.whl": "sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f", + "https://files.pythonhosted.org/packages/36/89/0aae34c10fe524cce30fe5fc433210376bce94cf74d05b0d68344c8ba46e/wrapt-1.17.2-cp313-cp313-macosx_11_0_arm64.whl": "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5", + "https://files.pythonhosted.org/packages/37/14/bd210faf0a66faeb8529d42b6b45a25d6aa6ce25ddfc19168e4161aed227/wrapt-1.17.2-cp38-cp38-musllinux_1_2_i686.whl": "sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04", + "https://files.pythonhosted.org/packages/39/35/0282c0d8789c0dc9bcc738911776c762a701f95cfe113fb8f0b40e45c2b9/wrapt-1.17.2-cp311-cp311-musllinux_1_2_i686.whl": "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662", + "https://files.pythonhosted.org/packages/3b/24/11c4510de906d77e0cfb5197f1b1445d4fec42c9a39ea853d482698ac681/wrapt-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8", + "https://files.pythonhosted.org/packages/3c/70/1d259c6b1ad164eb23ff70e3e452dd1950f96e6473f72b7207891d0fd1f0/wrapt-1.17.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9", + "https://files.pythonhosted.org/packages/3d/bc/30f903f891a82d402ffb5fda27ec1d621cc97cb74c16fea0b6141f1d4e87/wrapt-1.17.2-cp313-cp313t-macosx_10_13_universal2.whl": "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192", + "https://files.pythonhosted.org/packages/45/ce/700e17a852dd5dec894e241c72973ea82363486bcc1fb05d47b4fbd1d683/wrapt-1.17.2-cp38-cp38-musllinux_1_2_aarch64.whl": "sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a", + "https://files.pythonhosted.org/packages/47/f8/fb1773491a253cbc123c5d5dc15c86041f746ed30416535f2a8df1f4a392/wrapt-1.17.2-cp311-cp311-win_amd64.whl": "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3", + "https://files.pythonhosted.org/packages/48/2a/97928387d6ed1c1ebbfd4efc4133a0633546bec8481a2dd5ec961313a1c7/wrapt-1.17.2-cp312-cp312-macosx_11_0_arm64.whl": "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40", + "https://files.pythonhosted.org/packages/4a/98/de07243751f1c4a9b15c76019250210dd3486ce098c3d80d5f729cba029c/wrapt-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504", + "https://files.pythonhosted.org/packages/4b/0d/9d4b5219ae4393f718699ca1c05f5ebc0c40d076f7e65fd48f5f693294fb/wrapt-1.17.2-cp310-cp310-win32.whl": "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563", + "https://files.pythonhosted.org/packages/4e/ca/3b7afa1eae3a9e7fefe499db9b96813f41828b9fdb016ee836c4c379dadb/wrapt-1.17.2-cp313-cp313t-macosx_11_0_arm64.whl": "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0", + "https://files.pythonhosted.org/packages/4f/6d/90c9fd2c3c6fee181feecb620d95105370198b6b98a0770cba090441a828/wrapt-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72", + "https://files.pythonhosted.org/packages/50/ff/149aba8365fdacef52b31a258c4dc1c57c79759c335eff0b3316a2664a64/wrapt-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl": "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda", + "https://files.pythonhosted.org/packages/52/27/3dd9ad5f1097b33c95d05929e409cc86d7c765cb5437b86694dc8f8e9af0/wrapt-1.17.2-cp38-cp38-win_amd64.whl": "sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3", + "https://files.pythonhosted.org/packages/53/18/75ddc64c3f63988f5a1d7e10fb204ffe5762bc663f8023f18ecaf31a332e/wrapt-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl": "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392", + "https://files.pythonhosted.org/packages/53/f8/c3f6b2cf9b9277fb0813418e1503e68414cd036b3b099c823379c9575e6d/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_i686.whl": "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6", + "https://files.pythonhosted.org/packages/5a/d1/1daec934997e8b160040c78d7b31789f19b122110a75eca3d4e8da0049e1/wrapt-1.17.2-cp310-cp310-macosx_10_9_universal2.whl": "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984", + "https://files.pythonhosted.org/packages/5d/a4/c8472fe2568978b5532df84273c53ddf713f689d408a4335717ab89547e0/wrapt-1.17.2-cp38-cp38-macosx_11_0_arm64.whl": "sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6", + "https://files.pythonhosted.org/packages/62/bf/e0105016f907c30b4bd9e377867c48c34dc9c6c0c104556c9c9126bd89ed/wrapt-1.17.2-cp310-cp310-macosx_11_0_arm64.whl": "sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7", + "https://files.pythonhosted.org/packages/65/46/5a917ce85b5c3b490d35c02bf71aedaa9f2f63f2d15d9949cc4ba56e8ba9/wrapt-1.17.2-cp311-cp311-macosx_11_0_arm64.whl": "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438", + "https://files.pythonhosted.org/packages/6a/e1/0122853035b40b3f333bbb25f1939fc1045e21dd518f7f0922b60c156f7c/wrapt-1.17.2-cp313-cp313t-win32.whl": "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555", + "https://files.pythonhosted.org/packages/6d/16/112d25e9092398a0dd6fec50ab7ac1b775a0c19b428f049785096067ada9/wrapt-1.17.2-cp39-cp39-musllinux_1_2_x86_64.whl": "sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9", + "https://files.pythonhosted.org/packages/6f/54/f170dfb278fe1c30d0ff864513cff526d624ab8de3254b20abb9cffedc24/wrapt-1.17.2-cp313-cp313-musllinux_1_2_i686.whl": "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b", + "https://files.pythonhosted.org/packages/71/d7/cfcf842291267bf455b3e266c0c29dcb675b5540ee8b50ba1699abf3af45/wrapt-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6", + "https://files.pythonhosted.org/packages/72/6a/c5a83e8f61aec1e1aeef939807602fb880e5872371e95df2137142f5c58e/wrapt-1.17.2-cp310-cp310-win_amd64.whl": "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f", + "https://files.pythonhosted.org/packages/73/54/3bfe5a1febbbccb7a2f77de47b989c0b85ed3a6a41614b104204a788c20e/wrapt-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d", + "https://files.pythonhosted.org/packages/75/56/05d000de894c4cfcb84bcd6b1df6214297b8089a7bd324c21a4765e49b14/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_aarch64.whl": "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6", + "https://files.pythonhosted.org/packages/77/99/77b06b3c3c410dbae411105bf22496facf03a5496bfaca8fbcf9da381889/wrapt-1.17.2-cp39-cp39-musllinux_1_2_aarch64.whl": "sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f", + "https://files.pythonhosted.org/packages/7e/09/dccf68fa98e862df7e6a60a61d43d644b7d095a5fc36dbb591bbd4a1c7b2/wrapt-1.17.2-cp310-cp310-musllinux_1_2_i686.whl": "sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c", + "https://files.pythonhosted.org/packages/80/4e/eb8b353e36711347893f502ce91c770b0b0929f8f0bed2670a6856e667a9/wrapt-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9", + "https://files.pythonhosted.org/packages/89/be/7c1baed43290775cb9030c774bc53c860db140397047cc49aedaf0a15477/wrapt-1.17.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306", + "https://files.pythonhosted.org/packages/8a/04/c97273eb491b5f1c918857cd26f314b74fc9b29224521f5b83f872253725/wrapt-1.17.2-cp313-cp313t-macosx_10_13_x86_64.whl": "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b", + "https://files.pythonhosted.org/packages/8a/f4/6ed2b8f6f1c832933283974839b88ec7c983fd12905e01e97889dadf7559/wrapt-1.17.2-cp39-cp39-macosx_10_9_universal2.whl": "sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a", + "https://files.pythonhosted.org/packages/8f/fa/9fb6e594f2ce03ef03eddbdb5f4f90acb1452221a5351116c7c4708ac865/wrapt-1.17.2-cp311-cp311-win32.whl": "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317", + "https://files.pythonhosted.org/packages/90/ec/00759565518f268ed707dcc40f7eeec38637d46b098a1f5143bff488fe97/wrapt-1.17.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061", + "https://files.pythonhosted.org/packages/9d/4b/71996e62d543b0a0bd95dda485219856def3347e3e9380cc0d6cf10cfb2f/wrapt-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b", + "https://files.pythonhosted.org/packages/a1/bd/ab55f849fd1f9a58ed7ea47f5559ff09741b25f00c191231f9f059c83949/wrapt-1.17.2-cp312-cp312-macosx_10_13_universal2.whl": "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925", + "https://files.pythonhosted.org/packages/a2/a9/712a53f8f4f4545768ac532619f6e56d5d0364a87b2212531685e89aeef8/wrapt-1.17.2-cp39-cp39-macosx_10_9_x86_64.whl": "sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061", + "https://files.pythonhosted.org/packages/a4/b6/6eced5e2db5924bf6d9223d2bb96b62e00395aae77058e6a9e11bf16b3bd/wrapt-1.17.2-cp38-cp38-macosx_10_9_x86_64.whl": "sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119", + "https://files.pythonhosted.org/packages/a5/51/a42757dd41032afd6d8037617aa3bc6803ba971850733b24dfb7d5c627c4/wrapt-1.17.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f", + "https://files.pythonhosted.org/packages/a7/b1/0bb11e29aa5139d90b770ebbfa167267b1fc548d2302c30c8f7572851738/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_x86_64.whl": "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f", + "https://files.pythonhosted.org/packages/a7/d3/8e17bb70f6ae25dabc1aaf990f86824e4fd98ee9cadf197054e068500d27/wrapt-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2", + "https://files.pythonhosted.org/packages/a9/68/6b83367e1afb8de91cbea4ef8e85b58acdf62f034f05d78c7b82afaa23d8/wrapt-1.17.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a", + "https://files.pythonhosted.org/packages/b4/b0/9fc566b0fe08b282c850063591a756057c3247b2362b9286429ec5bf1721/wrapt-1.17.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6", + "https://files.pythonhosted.org/packages/b7/8e/067021fa3c8814952c5e228d916963c1115b983e21393289de15128e867e/wrapt-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62", + "https://files.pythonhosted.org/packages/bf/ae/743f16ef8c2e3628df3ddfd652b7d4c555d12c84b53f3d8218498f4ade9b/wrapt-1.17.2-cp313-cp313-win_amd64.whl": "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845", + "https://files.pythonhosted.org/packages/bf/bb/d552bfe47db02fcfc950fc563073a33500f8108efa5f7b41db2f83a59028/wrapt-1.17.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b", + "https://files.pythonhosted.org/packages/c0/ef/8be90a0b7e73c32e550c73cfb2fa09db62234227ece47b0e80a05073b375/wrapt-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl": "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998", + "https://files.pythonhosted.org/packages/c3/fc/e91cc220803d7bc4db93fb02facd8461c37364151b8494762cc88b0fbcef/wrapt-1.17.2.tar.gz": "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3", + "https://files.pythonhosted.org/packages/c6/d2/dcb56bf5f32fcd4bd9aacc77b50a539abdd5b6536872413fd3f428b21bed/wrapt-1.17.2-cp312-cp312-musllinux_1_2_i686.whl": "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae", + "https://files.pythonhosted.org/packages/ca/74/336c918d2915a4943501c77566db41d1bd6e9f4dbc317f356b9a244dfe83/wrapt-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a", + "https://files.pythonhosted.org/packages/cd/f7/a2aab2cbc7a665efab072344a8949a71081eed1d2f451f7f7d2b966594a2/wrapt-1.17.2-cp311-cp311-macosx_10_9_universal2.whl": "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58", + "https://files.pythonhosted.org/packages/ce/b9/0ffd557a92f3b11d4c5d5e0c5e4ad057bd9eb8586615cdaf901409920b14/wrapt-1.17.2-cp313-cp313-macosx_10_13_universal2.whl": "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125", + "https://files.pythonhosted.org/packages/cf/cb/7a07b51762dcd59bdbe07aa97f87b3169766cadf240f48d1cbe70a1be9db/wrapt-1.17.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9", + "https://files.pythonhosted.org/packages/d5/66/5d973e9f3e7370fd686fb47a9af3319418ed925c27d72ce16b791231576d/wrapt-1.17.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc", + "https://files.pythonhosted.org/packages/ea/fd/0c30f2301ca94e655e5e057012e83284ce8c545df7661a78d8bfca2fac7a/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681", + "https://files.pythonhosted.org/packages/f8/1e/b215068e824878f69ea945804fa26c176f7c2735a3ad5367d78930bd076a/wrapt-1.17.2-cp38-cp38-win32.whl": "sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7", + "https://files.pythonhosted.org/packages/f8/5a/7cffd26b1c607b0b0c8a9ca9d75757ad7620c9c0a9b4a25d3f8a1480fafc/wrapt-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2", + "https://files.pythonhosted.org/packages/f9/f0/13925f4bd6548013038cdeb11ee2cbd4e37c30f8bfd5db9e5a2a370d6e20/wrapt-1.17.2-cp313-cp313-win32.whl": "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a", + "https://files.pythonhosted.org/packages/fa/9b/e172c8f28a489a2888df18f953e2f6cb8d33b1a2e78c9dfc52d8bf6a5ead/wrapt-1.17.2-cp39-cp39-macosx_11_0_arm64.whl": "sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82" + }, + "yamllint": { + "https://files.pythonhosted.org/packages/05/92/aed08e68de6e6a3d7c2328ce7388072cd6affc26e2917197430b646aed02/yamllint-1.38.0-py3-none-any.whl": "sha256:fc394a5b3be980a4062607b8fdddc0843f4fa394152b6da21722f5d59013c220", + "https://files.pythonhosted.org/packages/28/a0/8fc2d68e132cf918f18273fdc8a1b8432b60d75ac12fdae4b0ef5c9d2e8d/yamllint-1.38.0.tar.gz": "sha256:09e5f29531daab93366bb061e76019d5e91691ef0a40328f04c927387d1d364d" + }, + "yapf": { + "https://files.pythonhosted.org/packages/23/97/b6f296d1e9cc1ec25c7604178b48532fa5901f721bcf1b8d8148b13e5588/yapf-0.43.0.tar.gz": "sha256:00d3aa24bfedff9420b2e0d5d9f5ab6d9d4268e72afbf59bb3fa542781d5218e", + "https://files.pythonhosted.org/packages/37/81/6acd6601f61e31cfb8729d3da6d5df966f80f374b78eff83760714487338/yapf-0.43.0-py3-none-any.whl": "sha256:224faffbc39c428cb095818cf6ef5511fdab6f7430a10783fdfb292ccf2852ca" + }, + "yarl": { + "https://files.pythonhosted.org/packages/00/fd/7e1c66efad35e1649114fa13f17485f62881ad58edeeb7f49f8c5e748bf9/yarl-1.23.0-cp313-cp313-win_arm64.whl": "sha256:fb4948814a2a98e3912505f09c9e7493b1506226afb1f881825368d6fb776ee3", + "https://files.pythonhosted.org/packages/08/1f/6f65f59e72d54aa467119b63fc0b0b1762eff0232db1f4720cd89e2f4a17/yarl-1.23.0-cp313-cp313-musllinux_1_2_s390x.whl": "sha256:39004f0ad156da43e86aa71f44e033de68a44e5a31fc53507b36dd253970054a", + "https://files.pythonhosted.org/packages/0a/e6/5c744a9b54f4e8007ad35bce96fbc9218338e84812d36f3390cea616881a/yarl-1.23.0-cp314-cp314-musllinux_1_2_riscv64.whl": "sha256:3650dc2480f94f7116c364096bc84b1d602f44224ef7d5c7208425915c0475dd", + "https://files.pythonhosted.org/packages/0a/ff/7196790538f31debe3341283b5b0707e7feb947620fc5e8236ef28d44f72/yarl-1.23.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:bd654fad46d8d9e823afbb4f87c79160b5a374ed1ff5bde24e542e6ba8f41434", + "https://files.pythonhosted.org/packages/0c/23/e3bfc188d0b400f025bc49d99793d02c9abe15752138dcc27e4eaf0c4a9e/yarl-1.23.0-cp314-cp314-musllinux_1_2_s390x.whl": "sha256:f40e782d49630ad384db66d4d8b73ff4f1b8955dc12e26b09a3e3af064b3b9d6", + "https://files.pythonhosted.org/packages/0c/f1/dab7ac5e7306fb79c0190766a3c00b4cb8d09a1f390ded68c85a5934faf5/yarl-1.23.0-cp314-cp314t-macosx_11_0_arm64.whl": "sha256:394906945aa8b19fc14a61cf69743a868bb8c465efe85eee687109cc540b98f4", + "https://files.pythonhosted.org/packages/15/61/74bb1182cf79c9bbe4eb6b1f14a57a22d7a0be5e9cedf8e2d5c2086474c3/yarl-1.23.0-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:3ceb13c5c858d01321b5d9bb65e4cf37a92169ea470b70fec6f236b2c9dd7e34", + "https://files.pythonhosted.org/packages/18/6a/530e16aebce27c5937920f3431c628a29a4b6b430fab3fd1c117b26ff3f6/yarl-1.23.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:c7f8dc16c498ff06497c015642333219871effba93e4a2e8604a06264aca5c5c", + "https://files.pythonhosted.org/packages/19/2a/725ecc166d53438bc88f76822ed4b1e3b10756e790bafd7b523fe97c322d/yarl-1.23.0-cp312-cp312-macosx_11_0_arm64.whl": "sha256:13a563739ae600a631c36ce096615fe307f131344588b0bc0daec108cdb47b25", + "https://files.pythonhosted.org/packages/19/90/d56967f61a29d8498efb7afb651e0b2b422a1e9b47b0ab5f4e40a19b699b/yarl-1.23.0-cp314-cp314t-musllinux_1_2_armv7l.whl": "sha256:d38c1e8231722c4ce40d7593f28d92b5fc72f3e9774fe73d7e800ec32299f63a", + "https://files.pythonhosted.org/packages/19/ff/33009a39d3ccf4b94d7d7880dfe17fb5816c5a4fe0096d9b56abceea9ac7/yarl-1.23.0-cp314-cp314t-macosx_10_15_x86_64.whl": "sha256:2803ed8b21ca47a43da80a6fd1ed3019d30061f7061daa35ac54f63933409412", + "https://files.pythonhosted.org/packages/1c/07/61c9dd8ba8f86473263b4036f70fb594c09e99c0d9737a799dfd8bc85651/yarl-1.23.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:5023346c4ee7992febc0068e7593de5fa2bf611848c08404b35ebbb76b1b0512", + "https://files.pythonhosted.org/packages/23/6e/beb1beec874a72f23815c1434518bfc4ed2175065173fb138c3705f658d4/yarl-1.23.0.tar.gz": "sha256:53b1ea6ca88ebd4420379c330aea57e258408dd0df9af0992e5de2078dc9f5d5", + "https://files.pythonhosted.org/packages/23/9c/42c2e2dd91c1a570402f51bdf066bfdb1241c2240ba001967bad778e77b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_ppc64le.whl": "sha256:ead11956716a940c1abc816b7df3fa2b84d06eaed8832ca32f5c5e058c65506b", + "https://files.pythonhosted.org/packages/24/84/e237607faf4e099dbb8a4f511cfd5efcb5f75918baad200ff7380635631b/yarl-1.23.0-cp311-cp311-macosx_10_9_x86_64.whl": "sha256:cbb0fef01f0c6b38cb0f39b1f78fc90b807e0e3c86a7ff3ce74ad77ce5c7880c", + "https://files.pythonhosted.org/packages/24/f9/e8242b68362bffe6fb536c8db5076861466fc780f0f1b479fc4ffbebb128/yarl-1.23.0-cp314-cp314-macosx_11_0_arm64.whl": "sha256:23f371bd662cf44a7630d4d113101eafc0cfa7518a2760d20760b26021454719", + "https://files.pythonhosted.org/packages/28/ec/5498c4e3a6d5f1003beb23405671c2eb9cdbf3067d1c80f15eeafe301010/yarl-1.23.0-cp314-cp314t-musllinux_1_2_x86_64.whl": "sha256:e09fd068c2e169a7070d83d3bde728a4d48de0549f975290be3c108c02e499b4", + "https://files.pythonhosted.org/packages/2d/86/ed7a73ab85ef00e8bb70b0cb5421d8a2a625b81a333941a469a6f4022828/yarl-1.23.0-cp314-cp314t-musllinux_1_2_aarch64.whl": "sha256:041b1a4cefacf65840b4e295c6985f334ba83c30607441ae3cf206a0eed1a2e4", + "https://files.pythonhosted.org/packages/2f/0c/b3ceacf82c3fe21183ce35fa2acf5320af003d52bc1fcf5915077681142e/yarl-1.23.0-cp312-cp312-musllinux_1_2_riscv64.whl": "sha256:8419ebd326430d1cbb7efb5292330a2cf39114e82df5cc3d83c9a0d5ebeaf2f2", + "https://files.pythonhosted.org/packages/34/92/6a7be9239f2347234e027284e7a5f74b1140cc86575e7b469d13fba1ebfe/yarl-1.23.0-cp310-cp310-musllinux_1_2_s390x.whl": "sha256:80e6d33a3d42a7549b409f199857b4fb54e2103fc44fb87605b6663b7a7ff750", + "https://files.pythonhosted.org/packages/38/0f/0b4e3edcec794a86b853b0c6396c0a888d72dfce19b2d88c02ac289fb6c1/yarl-1.23.0-cp310-cp310-win32.whl": "sha256:debe9c4f41c32990771be5c22b56f810659f9ddf3d63f67abfdcaa2c6c9c5c1d", + "https://files.pythonhosted.org/packages/38/69/912e6c5e146793e5d4b5fe39ff5b00f4d22463dfd5a162bec565ac757673/yarl-1.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl": "sha256:0e40111274f340d32ebcc0a5668d54d2b552a6cca84c9475859d364b380e3222", + "https://files.pythonhosted.org/packages/39/54/bc2b45559f86543d163b6e294417a107bb87557609007c007ad889afec18/yarl-1.23.0-cp314-cp314-macosx_10_15_x86_64.whl": "sha256:85610b4f27f69984932a7abbe52703688de3724d9f72bceb1cca667deff27474", + "https://files.pythonhosted.org/packages/42/2b/fef67d616931055bf3d6764885990a3ac647d68734a2d6a9e1d13de437a2/yarl-1.23.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:1c57676bdedc94cd3bc37724cf6f8cd2779f02f6aba48de45feca073e714fe52", + "https://files.pythonhosted.org/packages/43/68/8c5b36aa5178900b37387937bc2c2fe0e9505537f713495472dcf6f6fccc/yarl-1.23.0-cp313-cp313t-win_amd64.whl": "sha256:dd00607bffbf30250fe108065f07453ec124dbf223420f57f5e749b04295e090", + "https://files.pythonhosted.org/packages/49/fb/c438fb5108047e629f6282a371e6e91cf3f97ee087c4fb748a1f32ceef55/yarl-1.23.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:aafe5dcfda86c8af00386d7781d4c2181b5011b7be3f2add5e99899ea925df05", + "https://files.pythonhosted.org/packages/50/12/95a1d33f04a79c402664070d43b8b9f72dc18914e135b345b611b0b1f8cc/yarl-1.23.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:31c9921eb8bd12633b41ad27686bbb0b1a2a9b8452bfdf221e34f311e9942ed4", + "https://files.pythonhosted.org/packages/50/93/e88f3c80971b42cfc83f50a51b9d165a1dbf154b97005f2994a79f212a07/yarl-1.23.0-cp313-cp313t-macosx_11_0_arm64.whl": "sha256:cde9a2ecd91668bcb7f077c4966d8ceddb60af01b52e6e3e2680e4cf00ad1a59", + "https://files.pythonhosted.org/packages/51/47/3fa2286c3cb162c71cdb34c4224d5745a1ceceb391b2bd9b19b668a8d724/yarl-1.23.0-cp314-cp314t-win_arm64.whl": "sha256:44bb7bef4ea409384e3f8bc36c063d77ea1b8d4a5b2706956c0d6695f07dcc25", + "https://files.pythonhosted.org/packages/51/8a/882c0e7bc8277eb895b31bce0138f51a1ba551fc2e1ec6753ffc1e7c1377/yarl-1.23.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:a82836cab5f197a0514235aaf7ffccdc886ccdaa2324bc0aafdd4ae898103039", + "https://files.pythonhosted.org/packages/52/07/0b7179101fe5f8385ec6c6bb5d0cb9f76bd9fb4a769591ab6fb5cdbfc69a/yarl-1.23.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:4a59ba56f340334766f3a4442e0efd0af895fae9e2b204741ef885c446b3a1a8", + "https://files.pythonhosted.org/packages/56/11/1ed91d42bd9e73c13dc9e7eb0dd92298d75e7ac4dd7f046ad0c472e231cd/yarl-1.23.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:f514f6474e04179d3d33175ed3f3e31434d3130d42ec153540d5b157deefd735", + "https://files.pythonhosted.org/packages/56/38/12730c05e5ad40a76374d440ed8b0899729a96c250516d91c620a6e38fc2/yarl-1.23.0-cp310-cp310-musllinux_1_2_riscv64.whl": "sha256:75e3026ab649bf48f9a10c0134512638725b521340293f202a69b567518d94e0", + "https://files.pythonhosted.org/packages/58/80/c7c8244fc3e5bc483dc71a09560f43b619fab29301a0f0a8f936e42865c7/yarl-1.23.0-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:dbf507e9ef5688bada447a24d68b4b58dd389ba93b7afc065a2ba892bea54769", + "https://files.pythonhosted.org/packages/59/97/35ca6767524687ad64e5f5c31ad54bc76d585585a9fcb40f649e7e82ffed/yarl-1.23.0-cp311-cp311-musllinux_1_2_riscv64.whl": "sha256:4764a6a7588561a9aef92f65bda2c4fb58fe7c675c0883862e6df97559de0bfb", + "https://files.pythonhosted.org/packages/5e/81/4aebccfa9376bd98b9d8bfad20621a57d3e8cfc5b8631c1fa5f62cdd03f4/yarl-1.23.0-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:5ec2f42d41ccbd5df0270d7df31618a8ee267bfa50997f5d720ddba86c4a83a6", + "https://files.pythonhosted.org/packages/5e/c6/31e28f3a6ba2869c43d124f37ea5260cac9c9281df803c354b31f4dd1f3c/yarl-1.23.0-cp313-cp313-musllinux_1_2_riscv64.whl": "sha256:e0fd068364a6759bc794459f0a735ab151d11304346332489c7972bacbe9e72b", + "https://files.pythonhosted.org/packages/62/e2/a4980481071791bc83bce2b7a1a1f7adcabfa366007518b4b845e92eeee3/yarl-1.23.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:531ef597132086b6cf96faa7c6c1dcd0361dd5f1694e5cc30375907b9b7d3ea9", + "https://files.pythonhosted.org/packages/63/6e/904c4f476471afdbad6b7e5b70362fb5810e35cd7466529a97322b6f5556/yarl-1.23.0-cp313-cp313-musllinux_1_2_armv7l.whl": "sha256:609d3614d78d74ebe35f54953c5bbd2ac647a7ddb9c30a5d877580f5e86b22f2", + "https://files.pythonhosted.org/packages/66/3e/868e5c3364b6cee19ff3e1a122194fa4ce51def02c61023970442162859e/yarl-1.23.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:a3d2bff8f37f8d0f96c7ec554d16945050d54462d6e95414babaa18bfafc7f51", + "https://files.pythonhosted.org/packages/66/fe/b1e10b08d287f518994f1e2ff9b6d26f0adeecd8dd7d533b01bab29a3eda/yarl-1.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:34b6cf500e61c90f305094911f9acc9c86da1a05a7a3f5be9f68817043f486e4", + "https://files.pythonhosted.org/packages/67/b6/8925d68af039b835ae876db5838e82e76ec87b9782ecc97e192b809c4831/yarl-1.23.0-cp313-cp313-macosx_10_13_x86_64.whl": "sha256:4a42e651629dafb64fd5b0286a3580613702b5809ad3f24934ea87595804f2c5", + "https://files.pythonhosted.org/packages/68/03/093f4055ed4cae649ac53bca3d180bd37102e9e11d048588e9ab0c0108d0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_aarch64.whl": "sha256:e7b0460976dc75cb87ad9cc1f9899a4b97751e7d4e77ab840fc9b6d377b8fd24", + "https://files.pythonhosted.org/packages/68/2e/c5a2234238f8ce37a8312b52801ee74117f576b1539eec8404a480434acc/yarl-1.23.0-cp310-cp310-macosx_11_0_arm64.whl": "sha256:2a6940a074fb3c48356ed0158a3ca5699c955ee4185b4d7d619be3c327143e05", + "https://files.pythonhosted.org/packages/69/68/c8739671f5699c7dc470580a4f821ef37c32c4cb0b047ce223a7f115757f/yarl-1.23.0-py3-none-any.whl": "sha256:a2df6afe50dea8ae15fa34c9f824a3ee958d785fd5d089063d960bae1daa0a3f", + "https://files.pythonhosted.org/packages/69/7f/cd5ef733f2550de6241bd8bd8c3febc78158b9d75f197d9c7baa113436af/yarl-1.23.0-cp312-cp312-win32.whl": "sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d", + "https://files.pythonhosted.org/packages/6a/3f/6c6c8a0fe29c26fb2db2e8d32195bb84ec1bfb8f1d32e7f73b787fcf349b/yarl-1.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl": "sha256:0e1fdaa14ef51366d7757b45bde294e95f6c8c049194e793eedb8387c86d5993", + "https://files.pythonhosted.org/packages/6f/54/5b0db00d2cb056922356104468019c0a132e89c8d3ab67d8ede9f4483d2a/yarl-1.23.0-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:877b0738624280e34c55680d6054a307aa94f7d52fa0e3034a9cc6e790871da7", + "https://files.pythonhosted.org/packages/72/00/8b8f76909259f56647adb1011d7ed8b321bcf97e464515c65016a47ecdf0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_ppc64le.whl": "sha256:d53834e23c015ee83a99377db6e5e37d8484f333edb03bd15b4bc312cc7254fb", + "https://files.pythonhosted.org/packages/72/32/0abe4a76d59adf2081dcb0397168553ece4616ada1c54d1c49d8936c74f8/yarl-1.23.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:50f9d8d531dfb767c565f348f33dd5139a6c43f5cbdf3f67da40d54241df93f6", + "https://files.pythonhosted.org/packages/72/42/f0505f949a90b3f8b7a363d6cbdf398f6e6c58946d85c6d3a3bc70595b26/yarl-1.23.0-cp314-cp314-musllinux_1_2_x86_64.whl": "sha256:94f8575fbdf81749008d980c17796097e645574a3b8c28ee313931068dad14fe", + "https://files.pythonhosted.org/packages/72/59/c5b8d94b14e3d3c2a9c20cb100119fd534ab5a14b93673ab4cc4a4141ea5/yarl-1.23.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:d7504f2b476d21653e4d143f44a175f7f751cd41233525312696c76aa3dbb23f", + "https://files.pythonhosted.org/packages/74/05/1bcd60a8a0a914d462c305137246b6f9d167628d73568505fce3f1cb2e65/yarl-1.23.0-cp313-cp313t-musllinux_1_2_riscv64.whl": "sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6", + "https://files.pythonhosted.org/packages/74/3f/bbd8ff36fb038622797ffbaf7db314918bb4d76f1cc8a4f9ca7a55fe5195/yarl-1.23.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:ed5f69ce7be7902e5c70ea19eb72d20abf7d725ab5d49777d696e32d4fc1811d", + "https://files.pythonhosted.org/packages/76/0a/8b08aac08b50682e65759f7f8dde98ae8168f72487e7357a5d684c581ef9/yarl-1.23.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:53ad387048f6f09a8969631e4de3f1bf70c50e93545d64af4f751b2498755072", + "https://files.pythonhosted.org/packages/76/40/cc22d1d7714b717fde2006fad2ced5efe5580606cb059ae42117542122f3/yarl-1.23.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:a31de1613658308efdb21ada98cbc86a97c181aa050ba22a808120bb5be3ab94", + "https://files.pythonhosted.org/packages/77/04/9516bc4e269d2a3ec9c6779fcdeac51ce5b3a9b0156f06ac7152e5bba864/yarl-1.23.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:389871e65468400d6283c0308e791a640b5ab5c83bcee02a2f51295f95e09748", + "https://files.pythonhosted.org/packages/77/4f/96976cb54cbfc5c9fd73ed4c51804f92f209481d1fb190981c0f8a07a1d7/yarl-1.23.0-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:578110dd426f0d209d1509244e6d4a3f1a3e9077655d98c5f22583d63252a08a", + "https://files.pythonhosted.org/packages/7a/35/5a553687c5793df5429cd1db45909d4f3af7eee90014888c208d086a44f0/yarl-1.23.0-cp310-cp310-macosx_10_9_x86_64.whl": "sha256:e4c53f8347cd4200f0d70a48ad059cabaf24f5adc6ba08622a23423bc7efa10d", + "https://files.pythonhosted.org/packages/7a/84/266e8da36879c6edcd37b02b547e2d9ecdfea776be49598e75696e3316e1/yarl-1.23.0-cp313-cp313-win_amd64.whl": "sha256:baaf55442359053c7d62f6f8413a62adba3205119bcb6f49594894d8be47e5e3", + "https://files.pythonhosted.org/packages/80/25/a3892b46182c586c202629fc2159aa13975d3741d52ebd7347fd501d48d5/yarl-1.23.0-cp313-cp313t-win32.whl": "sha256:93a784271881035ab4406a172edb0faecb6e7d00f4b53dc2f55919d6c9688595", + "https://files.pythonhosted.org/packages/85/59/cd98e556fbb2bf8fab29c1a722f67ad45c5f3447cac798ab85620d1e70af/yarl-1.23.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:f2af5c81a1f124609d5f33507082fc3f739959d4719b56877ab1ee7e7b3d602b", + "https://files.pythonhosted.org/packages/85/fb/115b16f22c37ea4437d323e472945bea97301c8ec6089868fa560abab590/yarl-1.23.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:4c41e021bc6d7affb3364dc1e1e5fa9582b470f283748784bd6ea0558f87f42c", + "https://files.pythonhosted.org/packages/86/65/91a0285f51321369fd1a8308aa19207520c5f0587772cfc2e03fc2467e90/yarl-1.23.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:5f10fd85e4b75967468af655228fbfd212bdf66db1c0d135065ce288982eda26", + "https://files.pythonhosted.org/packages/86/e7/71ca9cc9ca79c0b7d491216177d1aed559d632947b8ffb0ee60f7d8b23e3/yarl-1.23.0-cp310-cp310-musllinux_1_2_armv7l.whl": "sha256:85e9beda1f591bc73e77ea1c51965c68e98dafd0fec72cdd745f77d727466716", + "https://files.pythonhosted.org/packages/86/fc/4118c5671ea948208bdb1492d8b76bdf1453d3e73df051f939f563e7dcc5/yarl-1.23.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:e9d9a4d06d3481eab79803beb4d9bd6f6a8e781ec078ac70d7ef2dcc29d1bea5", + "https://files.pythonhosted.org/packages/88/08/93749219179a45e27b036e03260fda05190b911de8e18225c294ac95bbc9/yarl-1.23.0-cp314-cp314-musllinux_1_2_aarch64.whl": "sha256:5ee586fb17ff8f90c91cf73c6108a434b02d69925f44f5f8e0d7f2f260607eae", + "https://files.pythonhosted.org/packages/88/8a/94615bc31022f711add374097ad4144d569e95ff3c38d39215d07ac153a0/yarl-1.23.0-cp312-cp312-macosx_10_13_universal2.whl": "sha256:1932b6b8bba8d0160a9d1078aae5838a66039e8832d41d2992daa9a3a08f7860", + "https://files.pythonhosted.org/packages/8b/0d/9cc638702f6fc3c7a3685bcc8cf2a9ed7d6206e932a49f5242658047ef51/yarl-1.23.0-cp310-cp310-macosx_10_9_universal2.whl": "sha256:cff6d44cb13d39db2663a22b22305d10855efa0fa8015ddeacc40bc59b9d8107", + "https://files.pythonhosted.org/packages/8c/6c/4a90d59c572e46b270ca132aca66954f1175abd691f74c1ef4c6711828e2/yarl-1.23.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:b2c6b50c7b0464165472b56b42d4c76a7b864597007d9c085e8b63e185cf4a7a", + "https://files.pythonhosted.org/packages/8e/db/4f9b838f4d8bdd6f0f385aed8bbf21c71ed11a0b9983305c302cbd557815/yarl-1.23.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:8c4fe09e0780c6c3bf2b7d4af02ee2394439d11a523bbcf095cf4747c2932007", + "https://files.pythonhosted.org/packages/8f/0d/476c38e85ddb4c6ec6b20b815bdd779aa386a013f3d8b85516feee55c8dc/yarl-1.23.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:fb1e8b8d66c278b21d13b0a7ca22c41dd757a7c209c6b12c313e445c31dd3b28", + "https://files.pythonhosted.org/packages/8f/54/f5b870b5505663911dba950a8e4776a0dbd51c9c54c0ae88e823e4b874a0/yarl-1.23.0-cp313-cp313-win32.whl": "sha256:1b6b572edd95b4fa8df75de10b04bc81acc87c1c7d16bcdd2035b09d30acc957", + "https://files.pythonhosted.org/packages/90/98/b85a038d65d1b92c3903ab89444f48d3cee490a883477b716d7a24b1a78c/yarl-1.23.0-cp314-cp314-macosx_10_15_universal2.whl": "sha256:21d1b7305a71a15b4794b5ff22e8eef96ff4a6d7f9657155e5aa419444b28912", + "https://files.pythonhosted.org/packages/90/b2/f52381aac396d6778ce516b7bc149c79e65bfc068b5de2857ab69eeea3b7/yarl-1.23.0-cp313-cp313t-musllinux_1_2_s390x.whl": "sha256:a0e317df055958a0c1e79e5d2aa5a5eaa4a6d05a20d4b0c9c3f48918139c9fc6", + "https://files.pythonhosted.org/packages/93/22/b85eca6fa2ad9491af48c973e4c8cf6b103a73dbb271fe3346949449fca0/yarl-1.23.0-cp311-cp311-win_amd64.whl": "sha256:bf49a3ae946a87083ef3a34c8f677ae4243f5b824bfc4c69672e72b3d6719d46", + "https://files.pythonhosted.org/packages/93/95/07e3553fe6f113e6864a20bdc53a78113cda3b9ced8784ee52a52c9f80d8/yarl-1.23.0-cp311-cp311-win_arm64.whl": "sha256:b39cb32a6582750b6cc77bfb3c49c0f8760dc18dc96ec9fb55fbb0f04e08b928", + "https://files.pythonhosted.org/packages/99/30/58260ed98e6ff7f90ba84442c1ddd758c9170d70327394a6227b310cd60f/yarl-1.23.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:9cbf44c5cb4a7633d078788e1b56387e3d3cf2b8139a3be38040b22d6c3221c8", + "https://files.pythonhosted.org/packages/9a/4b/a0a6e5d0ee8a2f3a373ddef8a4097d74ac901ac363eea1440464ccbe0898/yarl-1.23.0-cp313-cp313-macosx_10_13_universal2.whl": "sha256:16c6994ac35c3e74fb0ae93323bf8b9c2a9088d55946109489667c510a7d010e", + "https://files.pythonhosted.org/packages/9a/64/c53487d9f4968045b8afa51aed7ca44f58b2589e772f32745f3744476c82/yarl-1.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:99c8a9ed30f4164bc4c14b37a90208836cbf50d4ce2a57c71d0f52c7fb4f7598", + "https://files.pythonhosted.org/packages/9c/fc/119dd07004f17ea43bb91e3ece6587759edd7519d6b086d16bfbd3319982/yarl-1.23.0-cp313-cp313t-macosx_10_13_universal2.whl": "sha256:aecfed0b41aa72b7881712c65cf764e39ce2ec352324f5e0837c7048d9e6daaa", + "https://files.pythonhosted.org/packages/9d/40/acfcdb3b5f9d68ef499e39e04d25e141fe90661f9d54114556cf83be8353/yarl-1.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl": "sha256:4966242ec68afc74c122f8459abd597afd7d8a60dc93d695c1334c5fd25f762f", + "https://files.pythonhosted.org/packages/9d/e0/12900edd28bdab91a69bd2554b85ad7b151f64e8b521fe16f9ad2f56477a/yarl-1.23.0-cp312-cp312-musllinux_1_2_s390x.whl": "sha256:be61f6fff406ca40e3b1d84716fde398fc08bc63dd96d15f3a14230a0973ed86", + "https://files.pythonhosted.org/packages/9e/c0/b39770b56d4a9f0bb5f77e2f1763cd2d75cc2f6c0131e3b4c360348fcd65/yarl-1.23.0-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:6b41389c19b07c760c7e427a3462e8ab83c4bb087d127f0e854c706ce1b9215c", + "https://files.pythonhosted.org/packages/9e/e9/f9ff8ceefba599eac6abddcfb0b3bee9b9e636e96dbf54342a8577252379/yarl-1.23.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:d1009abedb49ae95b136a8904a3f71b342f849ffeced2d3747bf29caeda218c4", + "https://files.pythonhosted.org/packages/a0/71/ad95c33da18897e4c636528bbc24a1dd23fe16797de8bc4ec667b8db0ba4/yarl-1.23.0-cp310-cp310-win_amd64.whl": "sha256:ab5f043cb8a2d71c981c09c510da013bc79fd661f5c60139f00dd3c3cc4f2ffb", + "https://files.pythonhosted.org/packages/a2/aa/60da938b8f0997ba3a911263c40d82b6f645a67902a490b46f3355e10fae/yarl-1.23.0-cp311-cp311-macosx_10_9_universal2.whl": "sha256:b35d13d549077713e4414f927cdc388d62e543987c572baee613bf82f11a4b99", + "https://files.pythonhosted.org/packages/a3/c4/18b178a69935f9e7a338127d5b77d868fdc0f0e49becd286d51b3a18c61d/yarl-1.23.0-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:e5723c01a56c5028c807c701aa66722916d2747ad737a046853f6c46f4875543", + "https://files.pythonhosted.org/packages/a4/b8/35c0750fcd5a3f781058bfd954515dd4b1eab45e218cbb85cf11132215f1/yarl-1.23.0-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:170e26584b060879e29fac213e4228ef063f39128723807a312e5c7fec28eff2", + "https://files.pythonhosted.org/packages/a9/5b/9b92f54c784c26e2a422e55a8d2607ab15b7ea3349e28359282f84f01d43/yarl-1.23.0-cp314-cp314-win_amd64.whl": "sha256:63e92247f383c85ab00dd0091e8c3fa331a96e865459f5ee80353c70a4a42d70", + "https://files.pythonhosted.org/packages/aa/65/b39290f1d892a9dd671d1c722014ca062a9c35d60885d57e5375db0404b5/yarl-1.23.0-cp314-cp314-win32.whl": "sha256:c8aa34a5c864db1087d911a0b902d60d203ea3607d91f615acd3f3108ac32169", + "https://files.pythonhosted.org/packages/aa/b1/08e95f3caee1fad6e65017b9f26c1d79877b502622d60e517de01e72f95d/yarl-1.23.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:71d006bee8397a4a89f469b8deb22469fe7508132d3c17fa6ed871e79832691c", + "https://files.pythonhosted.org/packages/ac/e2/cab11b126fb7d440281b7df8e9ddbe4851e70a4dde47a202b6642586b8d9/yarl-1.23.0-cp314-cp314t-musllinux_1_2_riscv64.whl": "sha256:2e27c8841126e017dd2a054a95771569e6070b9ee1b133366d8b31beb5018a41", + "https://files.pythonhosted.org/packages/ae/50/06d511cc4b8e0360d3c94af051a768e84b755c5eb031b12adaaab6dec6e5/yarl-1.23.0-cp313-cp313-macosx_11_0_arm64.whl": "sha256:7c6b9461a2a8b47c65eef63bb1c76a4f1c119618ffa99ea79bc5bb1e46c5821b", + "https://files.pythonhosted.org/packages/b2/0d/71ceabc14c146ba8ee3804ca7b3d42b1664c8440439de5214d366fec7d3a/yarl-1.23.0-cp311-cp311-macosx_11_0_arm64.whl": "sha256:dc52310451fc7c629e13c4e061cbe2dd01684d91f2f8ee2821b083c58bd72432", + "https://files.pythonhosted.org/packages/b7/35/7b30f4810fba112f60f5a43237545867504e15b1c7647a785fbaf588fac2/yarl-1.23.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:575aa4405a656e61a540f4a80eaa5260f2a38fff7bfdc4b5f611840d76e9e277", + "https://files.pythonhosted.org/packages/b9/28/4c75ebb108f322aa8f917ae10a8ffa4f07cae10a8a627b64e578617df6a0/yarl-1.23.0-cp313-cp313t-musllinux_1_2_armv7l.whl": "sha256:115136c4a426f9da976187d238e84139ff6b51a20839aa6e3720cd1026d768de", + "https://files.pythonhosted.org/packages/bc/d2/8ae2e6cd77d0805f4526e30ec43b6f9a3dfc542d401ac4990d178e4bf0cf/yarl-1.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl": "sha256:1c3a3598a832590c5a3ce56ab5576361b5688c12cb1d39429cf5dba30b510760", + "https://files.pythonhosted.org/packages/c0/cc/6409f9018864a6aa186c61175b977131f373f1988e198e031236916e87e4/yarl-1.23.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl": "sha256:62694e275c93d54f7ccedcfef57d42761b2aad5234b6be1f3e3026cae4001cd4", + "https://files.pythonhosted.org/packages/c1/56/25d58c3eddde825890a5fe6aa1866228377354a3c39262235234ab5f616b/yarl-1.23.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:682bae25f0a0dd23a056739f23a134db9f52a63e2afd6bfb37ddc76292bbd723", + "https://files.pythonhosted.org/packages/c2/9b/2c893e16bfc50e6b2edf76c1a9eb6cb0c744346197e74c65e99ad8d634d0/yarl-1.23.0-cp314-cp314t-musllinux_1_2_s390x.whl": "sha256:76855800ac56f878847a09ce6dba727c93ca2d89c9e9d63002d26b916810b0a2", + "https://files.pythonhosted.org/packages/c4/f4/4e30b250927ffdab4db70da08b9b8d2194d7c7b400167b8fbeca1e4701ca/yarl-1.23.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:2569b67d616eab450d262ca7cb9f9e19d2f718c70a8b88712859359d0ab17035", + "https://files.pythonhosted.org/packages/c6/cc/d79ba8292f51f81f4dc533a8ccfb9fc6992cabf0998ed3245de7589dc07c/yarl-1.23.0-cp313-cp313t-win_arm64.whl": "sha256:ac09d42f48f80c9ee1635b2fcaa819496a44502737660d3c0f2ade7526d29144", + "https://files.pythonhosted.org/packages/c7/63/88802d1f6b1cb1fc67d67a58cd0cf8a1790de4ce7946e434240f1d60ab4a/yarl-1.23.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:dda608c88cf709b1d406bdfcd84d8d63cff7c9e577a403c6108ce8ce9dcc8764", + "https://files.pythonhosted.org/packages/cd/9b/30ea5239a61786f18fd25797151a17fbb3be176977187a48d541b5447dd4/yarl-1.23.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:95451e6ce06c3e104556d73b559f5da6c34a069b6b62946d3ad66afcd51642ea", + "https://files.pythonhosted.org/packages/ce/c9/74e44e056a23fbc33aca71779ef450ca648a5bc472bdad7a82339918f818/yarl-1.23.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:fda207c815b253e34f7e1909840fd14299567b1c0eb4908f8c2ce01a41265401", + "https://files.pythonhosted.org/packages/cf/26/9c89acf82f08a52cb52d6d39454f8d18af15f9d386a23795389d1d423823/yarl-1.23.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:c75eb09e8d55bceb4367e83496ff8ef2bc7ea6960efb38e978e8073ea59ecb67", + "https://files.pythonhosted.org/packages/d2/35/aeab955d6c425b227d5b7247eafb24f2653fedc32f95373a001af5dfeb9e/yarl-1.23.0-cp312-cp312-win_arm64.whl": "sha256:6e87a6e8735b44816e7db0b2fbc9686932df473c826b0d9743148432e10bb9b9", + "https://files.pythonhosted.org/packages/d3/1c/1a3387ee6d73589f6f2a220ae06f2984f6c20b40c734989b0a44f5987308/yarl-1.23.0-cp311-cp311-musllinux_1_2_s390x.whl": "sha256:03214408cfa590df47728b84c679ae4ef00be2428e11630277be0727eba2d7cc", + "https://files.pythonhosted.org/packages/d3/8a/36d82869ab5ec829ca8574dfcb92b51286fcfb1e9c7a73659616362dc880/yarl-1.23.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:803a3c3ce4acc62eaf01eaca1208dcf0783025ef27572c3336502b9c232005e7", + "https://files.pythonhosted.org/packages/d9/13/d269aa1aed3e4f50a5a103f96327210cc5fa5dd2d50882778f13c7a14606/yarl-1.23.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:9ee33b875f0b390564c1fb7bc528abf18c8ee6073b201c6ae8524aca778e2d83", + "https://files.pythonhosted.org/packages/d9/cf/ea424a004969f5d81a362110a6ac1496d79efdc6d50c2c4b2e3ea0fc2519/yarl-1.23.0-cp314-cp314-musllinux_1_2_armv7l.whl": "sha256:17235362f580149742739cc3828b80e24029d08cbb9c4bda0242c7b5bc610a8e", + "https://files.pythonhosted.org/packages/dd/8d/d2fad34b1c08aa161b74394183daa7d800141aaaee207317e82c790b418d/yarl-1.23.0-cp314-cp314t-macosx_10_15_universal2.whl": "sha256:9a18d6f9359e45722c064c97464ec883eb0e0366d33eda61cb19a244bf222679", + "https://files.pythonhosted.org/packages/e0/7d/8a84dc9381fd4412d5e7ff04926f9865f6372b4c2fd91e10092e65d29eb8/yarl-1.23.0-cp314-cp314-win_arm64.whl": "sha256:70efd20be968c76ece7baa8dafe04c5be06abc57f754d6f36f3741f7aa7a208e", + "https://files.pythonhosted.org/packages/e1/19/3774d162f6732d1cfb0b47b4140a942a35ca82bb19b6db1f80e9e7bdc8f8/yarl-1.23.0-cp314-cp314t-win_amd64.whl": "sha256:4503053d296bc6e4cbd1fad61cf3b6e33b939886c4f249ba7c78b602214fabe2", + "https://files.pythonhosted.org/packages/e2/14/dfa369523c79bccf9c9c746b0a63eb31f65db9418ac01275f7950962e504/yarl-1.23.0-cp310-cp310-win_arm64.whl": "sha256:263cd4f47159c09b8b685890af949195b51d1aa82ba451c5847ca9bc6413c220", + "https://files.pythonhosted.org/packages/e2/b7/14341481fe568e2b0408bcf1484c652accafe06a0ade9387b5d3fd9df446/yarl-1.23.0-cp314-cp314-musllinux_1_2_ppc64le.whl": "sha256:0793e2bd0cf14234983bbb371591e6bea9e876ddf6896cdcc93450996b0b5c85", + "https://files.pythonhosted.org/packages/e3/6f/c6554045d59d64052698add01226bc867b52fe4a12373415d7991fdca95d/yarl-1.23.0-cp312-cp312-macosx_10_13_x86_64.whl": "sha256:411225bae281f114067578891bc75534cfb3d92a3b4dfef7a6ca78ba354e6069", + "https://files.pythonhosted.org/packages/e5/1c/9a1979aec4a81896d597bcb2177827f2dbee3f5b7cc48b2d0dadb644b41d/yarl-1.23.0-cp311-cp311-win32.whl": "sha256:51430653db848d258336cfa0244427b17d12db63d42603a55f0d4546f50f25b5", + "https://files.pythonhosted.org/packages/e5/1e/304a00cf5f6100414c4b5a01fc7ff9ee724b62158a08df2f8170dfc72a2d/yarl-1.23.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl": "sha256:88f9fb0116fbfcefcab70f85cf4b74a2b6ce5d199c41345296f49d974ddb4123", + "https://files.pythonhosted.org/packages/e5/e8/638bae5bbf1113a659b2435d8895474598afe38b4a837103764f603aba56/yarl-1.23.0-cp313-cp313t-musllinux_1_2_x86_64.whl": "sha256:6f0fd84de0c957b2d280143522c4f91a73aada1923caee763e24a2b3fda9f8a5", + "https://files.pythonhosted.org/packages/e6/0d/9f2348502fbb3af409e8f47730282cd6bc80dec6630c1e06374d882d6eb2/yarl-1.23.0-cp313-cp313t-macosx_10_13_x86_64.whl": "sha256:a41bcf68efd19073376eb8cf948b8d9be0af26256403e512bb18f3966f1f9120", + "https://files.pythonhosted.org/packages/e7/64/6980f99ab00e1f0ff67cb84766c93d595b067eed07439cfccfc8fb28c1a6/yarl-1.23.0-cp311-cp311-musllinux_1_2_armv7l.whl": "sha256:1dc702e42d0684f42d6519c8d581e49c96cefaaab16691f03566d30658ee8788", + "https://files.pythonhosted.org/packages/ea/d8/d1cb2378c81dd729e98c716582b1ccb08357e8488e4c24714658cc6630e8/yarl-1.23.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:c4a80f77dc1acaaa61f0934176fccca7096d9b1ff08c8ba9cddf5ae034a24319", + "https://files.pythonhosted.org/packages/eb/78/0231bfcc5d4c8eec220bc2f9ef82cb4566192ea867a7c5b4148f44f6cbcd/yarl-1.23.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:a8d00f29b42f534cc8aa3931cfe773b13b23e561e10d2b26f27a8d309b0e82a1", + "https://files.pythonhosted.org/packages/f5/be/25216a49daeeb7af2bec0db22d5e7df08ed1d7c9f65d78b14f3b74fd72fc/yarl-1.23.0-cp312-cp312-win_amd64.whl": "sha256:f69f57305656a4852f2a7203efc661d8c042e6cc67f7acd97d8667fb448a426e", + "https://files.pythonhosted.org/packages/f6/40/10fa93811fd439341fad7e0718a86aca0de9548023bbb403668d6555acab/yarl-1.23.0-cp312-cp312-musllinux_1_2_armv7l.whl": "sha256:b5405bb8f0e783a988172993cfc627e4d9d00432d6bbac65a923041edacf997d", + "https://files.pythonhosted.org/packages/fe/c3/cd737e2d45e70717907f83e146f6949f20cc23cd4bf7b2688727763aa458/yarl-1.23.0-cp314-cp314t-win32.whl": "sha256:73309162a6a571d4cbd3b6a1dcc703c7311843ae0d1578df6f09be4e98df38d4" + }, + "zipp": { + "https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl": "sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f", + "https://files.pythonhosted.org/packages/54/bf/5c0000c44ebc80123ecbdddba1f5dcd94a5ada602a9c225d84b5aaa55e86/zipp-3.20.2.tar.gz": "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29", + "https://files.pythonhosted.org/packages/62/8b/5ba542fa83c90e09eac972fc9baca7a88e7e7ca4b221a89251954019308b/zipp-3.20.2-py3-none-any.whl": "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", + "https://files.pythonhosted.org/packages/b9/d8/eab98a517c14134c0b2eb4e2387bc5f457334293ec5d2dd3857ec2966802/zipp-4.1.0.tar.gz": "sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602" + }, + "zope-event": { + "https://files.pythonhosted.org/packages/46/c2/427f1867bb96555d1d34342f1dd97f8c420966ab564d58d18469a1db8736/zope.event-5.0.tar.gz": "sha256:bac440d8d9891b4068e2b5a2c5e2c9765a9df762944bda6955f96bb9b91e67cd", + "https://files.pythonhosted.org/packages/fe/42/f8dbc2b9ad59e927940325a22d6d3931d630c3644dae7e2369ef5d9ba230/zope.event-5.0-py3-none-any.whl": "sha256:2832e95014f4db26c47a13fdaef84cef2f4df37e66b59d8f1f4a8f319a632c26" + }, + "zope-interface": { + "https://files.pythonhosted.org/packages/07/a8/106ca4c2add440728e382f1b16c7d886563602487bdd90004788d45eb310/zope.interface-7.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:f6dd02ec01f4468da0f234da9d9c8545c5412fef80bc590cc51d8dd084138a89", + "https://files.pythonhosted.org/packages/0a/2f/1bccc6f4cc882662162a1158cda1a7f616add2ffe322b28c99cb031b4ffc/zope.interface-7.2-cp313-cp313-win_amd64.whl": "sha256:4893395d5dd2ba655c38ceb13014fd65667740f09fa5bb01caa1e6284e48c0cd", + "https://files.pythonhosted.org/packages/11/b1/627384b745310d082d29e3695db5f5a9188186676912c14b61a78bbc6afe/zope.interface-7.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:802176a9f99bd8cc276dcd3b8512808716492f6f557c11196d42e26c01a69a4c", + "https://files.pythonhosted.org/packages/28/ea/fdd9813c1eafd333ad92464d57a4e3a82b37ae57c19497bcffa42df673e4/zope.interface-7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:550f1c6588ecc368c9ce13c44a49b8d6b6f3ca7588873c679bd8fd88a1b557b6", + "https://files.pythonhosted.org/packages/2a/dd/fcd313ee216ad0739ae00e6126bc22a0af62a74f76a9ca668d16cd276222/zope.interface-7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:52e446f9955195440e787596dccd1411f543743c359eeb26e9b2c02b077b0519", + "https://files.pythonhosted.org/packages/30/93/9210e7606be57a2dfc6277ac97dcc864fd8d39f142ca194fdc186d596fda/zope.interface-7.2.tar.gz": "sha256:8b49f1a3d1ee4cdaf5b32d2e738362c7f5e40ac8b46dd7d1a65e82a4872728fe", + "https://files.pythonhosted.org/packages/36/22/b1abd91854c1be03f5542fe092e6a745096d2eca7704d69432e119100583/zope.interface-7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:72cd1790b48c16db85d51fbbd12d20949d7339ad84fd971427cf00d990c1f137", + "https://files.pythonhosted.org/packages/3b/d3/0000a4d497ef9fbf4f66bb6828b8d0a235e690d57c333be877bec763722f/zope.interface-7.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:0ef9e2f865721553c6f22a9ff97da0f0216c074bd02b25cf0d3af60ea4d6931d", + "https://files.pythonhosted.org/packages/3e/e5/0b359e99084f033d413419eff23ee9c2bd33bca2ca9f4e83d11856f22d10/zope.interface-7.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:27f926f0dcb058211a3bb3e0e501c69759613b17a553788b2caeb991bed3b61d", + "https://files.pythonhosted.org/packages/49/65/78e7cebca6be07c8fc4032bfbb123e500d60efdf7b86727bb8a071992108/zope.interface-7.2-cp313-cp313-macosx_11_0_arm64.whl": "sha256:15398c000c094b8855d7d74f4fdc9e73aa02d4d0d5c775acdef98cdb1119768d", + "https://files.pythonhosted.org/packages/49/b4/451f19448772b4a1159519033a5f72672221e623b0a1bd2b896b653943d8/zope.interface-7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:033b3923b63474800b04cba480b70f6e6243a62208071fc148354f3f89cc01b7", + "https://files.pythonhosted.org/packages/52/db/7e5f4226bef540f6d55acfd95cd105782bc6ee044d9b5587ce2c95558a5e/zope.interface-7.2-cp310-cp310-macosx_11_0_arm64.whl": "sha256:05b910a5afe03256b58ab2ba6288960a2892dfeef01336dc4be6f1b9ed02ab0a", + "https://files.pythonhosted.org/packages/5f/c7/3c67562e03b3752ba4ab6b23355f15a58ac2d023a6ef763caaca430f91f2/zope.interface-7.2-cp312-cp312-win_amd64.whl": "sha256:29caad142a2355ce7cfea48725aa8bcf0067e2b5cc63fcf5cd9f97ad12d6afb5", + "https://files.pythonhosted.org/packages/65/94/5aa4461c10718062c8f8711161faf3249d6d3679c24a0b81dd6fc8ba1dd3/zope.interface-7.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:a102424e28c6b47c67923a1f337ede4a4c2bba3965b01cf707978a801fc7442c", + "https://files.pythonhosted.org/packages/68/0b/c7516bc3bad144c2496f355e35bd699443b82e9437aa02d9867653203b4a/zope.interface-7.2-cp312-cp312-macosx_10_9_x86_64.whl": "sha256:086ee2f51eaef1e4a52bd7d3111a0404081dadae87f84c0ad4ce2649d4f708b7", + "https://files.pythonhosted.org/packages/69/da/c9cfb384c18bd3a26d9fc6a9b5f32ccea49ae09444f097eaa5ca9814aff9/zope.interface-7.2-cp39-cp39-win_amd64.whl": "sha256:1090c60116b3da3bfdd0c03406e2f14a1ff53e5771aebe33fec1edc0a350175d", + "https://files.pythonhosted.org/packages/76/71/e6177f390e8daa7e75378505c5ab974e0bf59c1d3b19155638c7afbf4b2d/zope.interface-7.2-cp310-cp310-macosx_10_9_x86_64.whl": "sha256:ce290e62229964715f1011c3dbeab7a4a1e4971fd6f31324c4519464473ef9f2", + "https://files.pythonhosted.org/packages/7b/90/12d50b95f40e3b2fc0ba7f7782104093b9fd62806b13b98ef4e580f2ca61/zope.interface-7.2-cp310-cp310-win_amd64.whl": "sha256:144964649eba4c5e4410bb0ee290d338e78f179cdbfd15813de1a664e7649b3b", + "https://files.pythonhosted.org/packages/7c/a3/c4e9d23ca87d3f922e38ba4f4edcbf6114c10ff9ee0b7b4d5023b0f1f3f5/zope.interface-7.2-cp38-cp38-win_amd64.whl": "sha256:7dc5016e0133c1a1ec212fc87a4f7e7e562054549a99c73c8896fa3a9e80cbc7", + "https://files.pythonhosted.org/packages/88/d4/4ba1569b856870527cec4bf22b91fe704b81a3c1a451b2ccf234e9e0666f/zope.interface-7.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:2ad9913fd858274db8dd867012ebe544ef18d218f6f7d1e3c3e6d98000f14b75", + "https://files.pythonhosted.org/packages/8a/cd/f1e8303b81151cd6ba6e229db5fe601f9867a7b29f24a95eeba255970099/zope.interface-7.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:baf95683cde5bc7d0e12d8e7588a3eb754d7c4fa714548adcd96bdf90169f021", + "https://files.pythonhosted.org/packages/8c/2c/1f49dc8b4843c4f0848d8e43191aed312bad946a1563d1bf9e46cf2816ee/zope.interface-7.2-cp39-cp39-macosx_10_9_x86_64.whl": "sha256:7bd449c306ba006c65799ea7912adbbfed071089461a19091a228998b82b1fdb", + "https://files.pythonhosted.org/packages/96/08/2103587ebc989b455cf05e858e7fbdfeedfc3373358320e9c513428290b1/zope.interface-7.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:cab15ff4832580aa440dc9790b8a6128abd0b88b7ee4dd56abacbc52f212209d", + "https://files.pythonhosted.org/packages/98/7d/2e8daf0abea7798d16a58f2f3a2bf7588872eee54ac119f99393fdd47b65/zope.interface-7.2-cp311-cp311-macosx_10_9_x86_64.whl": "sha256:1909f52a00c8c3dcab6c4fad5d13de2285a4b3c7be063b239b8dc15ddfb73bd2", + "https://files.pythonhosted.org/packages/9e/dd/5505c6fa2dd3a6b76176c07bc85ad0c24f218a3e7c929272384a5eb5f18a/zope.interface-7.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:224b7b0314f919e751f2bca17d15aad00ddbb1eadf1cb0190fa8175edb7ede62", + "https://files.pythonhosted.org/packages/9f/aa/1a28c02815fe1ca282b54f6705b9ddba20328fabdc37b8cf73fc06b172f0/zope.interface-7.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:25e6a61dcb184453bb00eafa733169ab6d903e46f5c2ace4ad275386f9ab327a", + "https://files.pythonhosted.org/packages/a0/2a/0c03c7170fe61d0d371e4c7ea5b62b8cb79b095b3d630ca16719bf8b7b18/zope.interface-7.2-cp311-cp311-macosx_11_0_arm64.whl": "sha256:80ecf2451596f19fd607bb09953f426588fc1e79e93f5968ecf3367550396b22", + "https://files.pythonhosted.org/packages/a2/e9/1463036df1f78ff8c45a02642a7bf6931ae4a38a4acd6a8e07c128e387a7/zope.interface-7.2-cp312-cp312-macosx_11_0_arm64.whl": "sha256:21328fcc9d5b80768bf051faa35ab98fb979080c18e6f84ab3f27ce703bce465", + "https://files.pythonhosted.org/packages/a7/2c/82028f121d27c7e68632347fe04f4a6e0466e77bb36e104c8b074f3d7d7b/zope.interface-7.2-cp311-cp311-win_amd64.whl": "sha256:3f6771d1647b1fc543d37640b45c06b34832a943c80d1db214a37c31161a93f1", + "https://files.pythonhosted.org/packages/b6/66/ac05b741c2129fdf668b85631d2268421c5cd1a9ff99be1674371139d665/zope.interface-7.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl": "sha256:a71a5b541078d0ebe373a81a3b7e71432c61d12e660f1d67896ca62d9628045b", + "https://files.pythonhosted.org/packages/b8/f6/54548df6dc73e30ac6c8a7ff1da73ac9007ba38f866397091d5a82237bd3/zope.interface-7.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:eb23f58a446a7f09db85eda09521a498e109f137b85fb278edb2e34841055398", + "https://files.pythonhosted.org/packages/c6/3b/e309d731712c1a1866d61b5356a069dd44e5b01e394b6cb49848fa2efbff/zope.interface-7.2-cp313-cp313-macosx_10_9_x86_64.whl": "sha256:3e0350b51e88658d5ad126c6a57502b19d5f559f6cb0a628e3dc90442b53dd98", + "https://files.pythonhosted.org/packages/e6/0f/4e296d4b36ceb5464b671443ac4084d586d47698610025c4731ff2d30eae/zope.interface-7.2-cp38-cp38-macosx_10_9_x86_64.whl": "sha256:d3a8ffec2a50d8ec470143ea3d15c0c52d73df882eef92de7537e8ce13475e8a", + "https://files.pythonhosted.org/packages/ed/7d/83ddbfc8424c69579a90fc8edc2b797223da2a8083a94d8dfa0e374c5ed4/zope.interface-7.2-cp39-cp39-macosx_11_0_arm64.whl": "sha256:a19a6cc9c6ce4b1e7e3d319a473cf0ee989cbbe2b39201d7c19e214d2dfb80c7", + "https://files.pythonhosted.org/packages/f5/8c/49548aaa4f691615d703b5bee88ea67f68eac8f94c9fb6f1b2f4ae631354/zope.interface-7.2-cp38-cp38-macosx_11_0_arm64.whl": "sha256:31d06db13a30303c08d61d5fb32154be51dfcbdb8438d2374ae27b4e069aac40", + "https://files.pythonhosted.org/packages/fc/ca/57286866285f4b8a4634c12ca1957c24bdac06eae28fd4a3a578e30cf906/zope.interface-7.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl": "sha256:8e7da17f53e25d1a3bde5da4601e026adc9e8071f9f6f936d0fe3fe84ace6d54", + "https://files.pythonhosted.org/packages/fe/f9/5a66f98f8c21d644d94f95b9484564f76e175034de3a57a45ba72238ce10/zope.interface-7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl": "sha256:e204937f67b28d2dca73ca936d3039a144a081fc47a07598d44854ea2a106239" + }, + "zstandard": { + "https://files.pythonhosted.org/packages/08/b3/206883dd25b8d1591a1caa44b54c2aad84badccf2f1de9e2d60a446f9a25/zstandard-0.25.0-cp312-cp312-musllinux_1_1_x86_64.whl": "sha256:aaf21ba8fb76d102b696781bddaa0954b782536446083ae3fdaa6f16b25a1c4b", + "https://files.pythonhosted.org/packages/0a/1d/58635ae6104df96671076ac7d4ae7816838ce7debd94aecf83e30b7121b0/zstandard-0.25.0-cp310-cp310-musllinux_1_2_aarch64.whl": "sha256:3756b3e9da9b83da1796f8809dd57cb024f838b9eeafde28f3cb472012797ac1", + "https://files.pythonhosted.org/packages/0f/67/354d1555575bc2490435f90d67ca4dd65238ff2f119f30f72d5cde09c2ad/zstandard-0.25.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:06acb75eebeedb77b69048031282737717a63e71e4ae3f77cc0c3b9508320df6", + "https://files.pythonhosted.org/packages/12/56/354fe655905f290d3b147b33fe946b0f27e791e4b50a5f004c802cb3eb7b/zstandard-0.25.0-cp311-cp311-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl": "sha256:0bbc9a0c65ce0eea3c34a691e3c4b6889f5f3909ba4822ab385fab9057099431", + "https://files.pythonhosted.org/packages/12/9b/3fb626390113f272abd0799fd677ea33d5fc3ec185e62e6be534493c4b60/zstandard-0.25.0-cp311-cp311-musllinux_1_2_aarch64.whl": "sha256:6c0e5a65158a7946e7a7affa6418878ef97ab66636f13353b8502d7ea03c8097", + "https://files.pythonhosted.org/packages/14/0d/d0a405dad6ab6f9f759c26d866cca66cb209bff6f8db656074d662a953dd/zstandard-0.25.0-cp39-cp39-macosx_10_9_x86_64.whl": "sha256:b9af1fe743828123e12b41dd8091eca1074d0c1569cc42e6e1eee98027f2bbd0", + "https://files.pythonhosted.org/packages/18/e1/97680c664a1bf9a247a280a053d98e251424af51f1b196c6d52f117c9720/zstandard-0.25.0-cp312-cp312-musllinux_1_2_i686.whl": "sha256:809c5bcb2c67cd0ed81e9229d227d4ca28f82d0f778fc5fea624a9def3963f91", + "https://files.pythonhosted.org/packages/1b/c0/59e912a531d91e1c192d3085fc0f6fb2852753c301a812d856d857ea03c6/zstandard-0.25.0-cp314-cp314-musllinux_1_2_ppc64le.whl": "sha256:f67e8f1a324a900e75b5e28ffb152bcac9fbed1cc7b43f99cd90f395c4375344", + "https://files.pythonhosted.org/packages/1e/15/efef5a2f204a64bdb5571e6161d49f7ef0fffdbca953a615efbec045f60f/zstandard-0.25.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:6dffecc361d079bb48d7caef5d673c88c8988d3d33fb74ab95b7ee6da42652ea", + "https://files.pythonhosted.org/packages/1e/73/316e4010de585ac798e154e88fd81bb16afc5c5cb1a72eeb16dd37e8024a/zstandard-0.25.0-cp312-cp312-musllinux_1_2_ppc64le.whl": "sha256:f27662e4f7dbf9f9c12391cb37b4c4c3cb90ffbd3b1fb9284dadbbb8935fa708", + "https://files.pythonhosted.org/packages/21/88/5ba550f797ca953a52d708c8e4f380959e7e3280af029e38fbf47b55916e/zstandard-0.25.0-cp311-cp311-musllinux_1_1_aarch64.whl": "sha256:bfd06b1c5584b657a2892a6014c2f4c20e0db0208c159148fa78c65f7e0b0277", + "https://files.pythonhosted.org/packages/27/22/503347aa08d073993f25109c36c8d9f029c7d5949198050962cb568dfa5e/zstandard-0.25.0-cp311-cp311-musllinux_1_2_s390x.whl": "sha256:22a086cff1b6ceca18a8dd6096ec631e430e93a8e70a9ca5efa7561a00f826fa", + "https://files.pythonhosted.org/packages/2a/83/c3ca27c363d104980f1c9cee1101cc8ba724ac8c28a033ede6aab89585b1/zstandard-0.25.0-cp311-cp311-macosx_10_9_x86_64.whl": "sha256:933b65d7680ea337180733cf9e87293cc5500cc0eb3fc8769f4d3c88d724ec5c", + "https://files.pythonhosted.org/packages/2b/95/fc5531d9c618a679a20ff6c29e2b3ef1d1f4ad66c5e161ae6ff847d102a9/zstandard-0.25.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:fd7a5004eb1980d3cefe26b2685bcb0b17989901a70a1040d1ac86f1d898c551", + "https://files.pythonhosted.org/packages/31/dc/cc50210e11e465c975462439a492516a73300ab8caa8f5e0902544fd748b/zstandard-0.25.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl": "sha256:e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0", + "https://files.pythonhosted.org/packages/35/0b/8df9c4ad06af91d39e94fa96cc010a24ac4ef1378d3efab9223cc8593d40/zstandard-0.25.0-cp313-cp313-macosx_10_13_x86_64.whl": "sha256:ec996f12524f88e151c339688c3897194821d7f03081ab35d31d1e12ec975e94", + "https://files.pythonhosted.org/packages/3a/43/241f9615bcf8ba8903b3f0432da069e857fc4fd1783bd26183db53c4804b/zstandard-0.25.0-cp314-cp314-win_amd64.whl": "sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2", + "https://files.pythonhosted.org/packages/3b/13/2b7ed68bd85e69a2069bcc72141d378f22cae5a0f3b353a2c8f50ef30c1b/zstandard-0.25.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:01582723b3ccd6939ab7b3a78622c573799d5d8737b534b86d0e06ac18dbde4a", + "https://files.pythonhosted.org/packages/3d/5c/f8923b595b55fe49e30612987ad8bf053aef555c14f05bb659dd5dbe3e8a/zstandard-0.25.0-cp314-cp314-macosx_10_13_x86_64.whl": "sha256:e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3", + "https://files.pythonhosted.org/packages/3f/06/9ae96a3e5dcfd119377ba33d4c42a7d89da1efabd5cb3e366b156c45ff4d/zstandard-0.25.0-cp313-cp313-macosx_11_0_arm64.whl": "sha256:a1a4ae2dec3993a32247995bdfe367fc3266da832d82f8438c8570f989753de1", + "https://files.pythonhosted.org/packages/41/b5/bc7a92c116e2ef32dc8061c209d71e97ff6df37487d7d39adb51a343ee89/zstandard-0.25.0-cp39-cp39-win_amd64.whl": "sha256:37daddd452c0ffb65da00620afb8e17abd4adaae6ce6310702841760c2c26860", + "https://files.pythonhosted.org/packages/43/a3/c6155f5c1cce691cb80dfd38627046e50af3ee9ddc5d0b45b9b063bfb8c9/zstandard-0.25.0-cp311-cp311-win_amd64.whl": "sha256:daab68faadb847063d0c56f361a289c4f268706b598afbf9ad113cbe5c38b6b2", + "https://files.pythonhosted.org/packages/46/c0/ca3e533b4fa03112facbe7fbe7779cb1ebec215688e5df576fe5429172e0/zstandard-0.25.0-cp311-cp311-musllinux_1_1_x86_64.whl": "sha256:f373da2c1757bb7f1acaf09369cdc1d51d84131e50d5fa9863982fd626466313", + "https://files.pythonhosted.org/packages/4e/d5/ba05ed95c6b8ec30bd468dfeab20589f2cf709b5c940483e31d991f2ca58/zstandard-0.25.0-cp313-cp313-musllinux_1_1_aarch64.whl": "sha256:3a39c94ad7866160a4a46d772e43311a743c316942037671beb264e395bdd611", + "https://files.pythonhosted.org/packages/50/d5/870aa06b3a76c73eced65c044b92286a3c4e00554005ff51962deef28e28/zstandard-0.25.0-cp313-cp313-musllinux_1_1_x86_64.whl": "sha256:172de1f06947577d3a3005416977cce6168f2261284c02080e7ad0185faeced3", + "https://files.pythonhosted.org/packages/53/60/7be26e610767316c028a2cbedb9a3beabdbe33e2182c373f71a1c0b88f36/zstandard-0.25.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:5a56ba0db2d244117ed744dfa8f6f5b366e14148e00de44723413b2f3938a902", + "https://files.pythonhosted.org/packages/53/6c/288c3f0bd9fcfe9ca41e2c2fbfd17b2097f6af57b62a81161941f09afa76/zstandard-0.25.0-cp312-cp312-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl": "sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64", + "https://files.pythonhosted.org/packages/53/f6/2a37931023f737fd849c5c28def57442bbafadb626da60cf9ed58461fe24/zstandard-0.25.0-cp39-cp39-musllinux_1_2_aarch64.whl": "sha256:53f94448fe5b10ee75d246497168e5825135d54325458c4bfffbaafabcc0a577", + "https://files.pythonhosted.org/packages/56/7a/28efd1d371f1acd037ac64ed1c5e2b41514a6cc937dd6ab6a13ab9f0702f/zstandard-0.25.0-cp310-cp310-macosx_10_9_x86_64.whl": "sha256:e59fdc271772f6686e01e1b3b74537259800f57e24280be3f29c8a0deb1904dd", + "https://files.pythonhosted.org/packages/58/08/a8522c28c08031a9521f27abc6f78dbdee7312a7463dd2cfc658b813323b/zstandard-0.25.0-cp310-cp310-musllinux_1_2_s390x.whl": "sha256:e7360eae90809efd19b886e59a09dad07da4ca9ba096752e61a2e03c8aca188e", + "https://files.pythonhosted.org/packages/5b/60/dd0f8cfa8129c5a0ce3ea6b7f70be5b33d2618013a161e1ff26c2b39787c/zstandard-0.25.0-cp312-cp312-musllinux_1_2_s390x.whl": "sha256:99c0c846e6e61718715a3c9437ccc625de26593fea60189567f0118dc9db7512", + "https://files.pythonhosted.org/packages/5c/71/e14820b61a1c137966b7667b400b72fa4a45c836257e443f3d77607db268/zstandard-0.25.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:3b870ce5a02d4b22286cf4944c628e0f0881b11b3f14667c1d62185a99e04f53", + "https://files.pythonhosted.org/packages/5d/35/398dc2ffc89d304d59bc12f0fdd931b4ce455bddf7038a0a67733a25f550/zstandard-0.25.0-cp313-cp313-musllinux_1_2_aarch64.whl": "sha256:3c83b0188c852a47cd13ef3bf9209fb0a77fa5374958b8c53aaa699398c6bd7b", + "https://files.pythonhosted.org/packages/5d/7c/8b6b71b1ddd517f68ffb55e10834388d4f793c49c6b83effaaa05785b0b4/zstandard-0.25.0-cp314-cp314-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl": "sha256:f604efd28f239cc21b3adb53eb061e2a205dc164be408e553b41ba2ffe0ca15c", + "https://files.pythonhosted.org/packages/61/b3/b637faea43677eb7bd42ab204dfb7053bd5c4582bfe6b1baefa80ac0c47b/zstandard-0.25.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl": "sha256:ca54090275939dc8ec5dea2d2afb400e0f83444b2fc24e07df7fdef677110859", + "https://files.pythonhosted.org/packages/63/4b/e3678b4e776db00f9f7b2fe58e547e8928ef32727d7a1ff01dea010f3f13/zstandard-0.25.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:8e735494da3db08694d26480f1493ad2cf86e99bdd53e8e9771b2752a5c0246a", + "https://files.pythonhosted.org/packages/6d/db/ddb11011826ed7db9d0e485d13df79b58586bfdec56e5c84a928a9a78c1c/zstandard-0.25.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:bfc4e20784722098822e3eee42b8e576b379ed72cca4a7cb856ae733e62192ea", + "https://files.pythonhosted.org/packages/6f/11/4c91411805c3f7b6f31c60e78ce347ca48f6f16d552fc659af6ec3b73202/zstandard-0.25.0-cp310-cp310-musllinux_1_2_x86_64.whl": "sha256:75ffc32a569fb049499e63ce68c743155477610532da1eb38e7f24bf7cd29e74", + "https://files.pythonhosted.org/packages/70/e8/2ec6b6fb7358b2ec0113ae202647ca7c0e9d15b61c005ae5225ad0995df5/zstandard-0.25.0-cp313-cp313-musllinux_1_2_ppc64le.whl": "sha256:0be7622c37c183406f3dbf0cba104118eb16a4ea7359eeb5752f0794882fc250", + "https://files.pythonhosted.org/packages/73/28/a44bdece01bca027b079f0e00be3b6bd89a4df180071da59a3dd7381665b/zstandard-0.25.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl": "sha256:e05ab82ea7753354bb054b92e2f288afb750e6b439ff6ca78af52939ebbc476d", + "https://files.pythonhosted.org/packages/75/71/c2e9234643dcfbd6c5e975e9a2b0050e1b2afffda6c3a959e1b87997bc80/zstandard-0.25.0-cp39-cp39-musllinux_1_2_s390x.whl": "sha256:51526324f1b23229001eb3735bc8c94f9c578b1bd9e867a0a646a3b17109f388", + "https://files.pythonhosted.org/packages/75/d6/57e9cb0a9983e9a229dd8fd2e6e96593ef2aa82a3907188436f22b111ccd/zstandard-0.25.0-cp310-cp310-musllinux_1_2_i686.whl": "sha256:81dad8d145d8fd981b2962b686b2241d3a1ea07733e76a2f15435dfb7fb60150", + "https://files.pythonhosted.org/packages/79/3b/fa54d9015f945330510cb5d0b0501e8253c127cca7ebe8ba46a965df18c5/zstandard-0.25.0-cp312-cp312-win_amd64.whl": "sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01", + "https://files.pythonhosted.org/packages/7a/59/edd117dedb97a768578b49fb2f1156defb839d1aa5b06200a62be943667f/zstandard-0.25.0-cp39-cp39-musllinux_1_2_ppc64le.whl": "sha256:07b527a69c1e1c8b5ab1ab14e2afe0675614a09182213f21a0717b62027b5936", + "https://files.pythonhosted.org/packages/7b/01/b5f4d4dbc59ef193e870495c6f1275f5b2928e01ff5a81fecb22a06e22fb/zstandard-0.25.0-cp313-cp313-musllinux_1_2_s390x.whl": "sha256:5f5e4c2a23ca271c218ac025bd7d635597048b366d6f31f420aaeb715239fc98", + "https://files.pythonhosted.org/packages/7b/a3/732893eab0a3a7aecff8b99052fecf9f605cf0fb5fb6d0290e36beee47a4/zstandard-0.25.0-cp311-cp311-win32.whl": "sha256:f5aeea11ded7320a84dcdd62a3d95b5186834224a9e55b92ccae35d21a8b63d4", + "https://files.pythonhosted.org/packages/82/fc/f26eb6ef91ae723a03e16eddb198abcfce2bc5a42e224d44cc8b6765e57e/zstandard-0.25.0-cp312-cp312-macosx_10_13_x86_64.whl": "sha256:7b3c3a3ab9daa3eed242d6ecceead93aebbb8f5f84318d82cee643e019c4b73b", + "https://files.pythonhosted.org/packages/85/c7/3483ad9ff0662623f3648479b0380d2de5510abf00990468c286c6b04017/zstandard-0.25.0-cp312-cp312-musllinux_1_1_aarch64.whl": "sha256:10ef2a79ab8e2974e2075fb984e5b9806c64134810fac21576f0668e7ea19f8f", + "https://files.pythonhosted.org/packages/86/b2/fc50c58271a1ead0e5a0a0e6311f4b221f35954dce438ce62751b3af9b68/zstandard-0.25.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:53e08b2445a6bc241261fea89d065536f00a581f02535f8122eba42db9375530", + "https://files.pythonhosted.org/packages/88/cd/2cf6d476131b509cc122d25d3416a2d0aa17687ddbada7599149f9da620e/zstandard-0.25.0-cp39-cp39-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl": "sha256:a51ff14f8017338e2f2e5dab738ce1ec3b5a851f23b18c1ae1359b1eecbee6df", + "https://files.pythonhosted.org/packages/8b/67/f92e64e748fd6aaffe01e2b75a083c0c4fd27abe1c8747fee4555fcee7dd/zstandard-0.25.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:2b6bd67528ee8b5c5f10255735abc21aa106931f0dbaf297c7be0c886353c3d0", + "https://files.pythonhosted.org/packages/8c/3e/8945ab86a0820cc0e0cdbf38086a92868a9172020fdab8a03ac19662b0e5/zstandard-0.25.0-cp311-cp311-win_arm64.whl": "sha256:22a06c5df3751bb7dc67406f5374734ccee8ed37fc5981bf1ad7041831fa1137", + "https://files.pythonhosted.org/packages/8c/a7/bb5a0c1c0f3f4b5e9d5b55198e39de91e04ba7c205cc46fcb0f95f0383c1/zstandard-0.25.0-cp311-cp311-musllinux_1_2_ppc64le.whl": "sha256:98750a309eb2f020da61e727de7d7ba3c57c97cf6213f6f6277bb7fb42a8e065", + "https://files.pythonhosted.org/packages/8d/09/d0a2a14fc3439c5f874042dca72a79c70a532090b7ba0003be73fee37ae2/zstandard-0.25.0-cp314-cp314-macosx_11_0_arm64.whl": "sha256:05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f", + "https://files.pythonhosted.org/packages/8e/e0/69a553d2047f9a2c7347caa225bb3a63b6d7704ad74610cb7823baa08ed7/zstandard-0.25.0-cp313-cp313-win32.whl": "sha256:7030defa83eef3e51ff26f0b7bfb229f0204b66fe18e04359ce3474ac33cbc09", + "https://files.pythonhosted.org/packages/93/90/96d50ad417a8ace5f841b3228e93d1bb13e6ad356737f42e2dde30d8bd68/zstandard-0.25.0-cp310-cp310-win_amd64.whl": "sha256:ea9d54cc3d8064260114a0bbf3479fc4a98b21dffc89b3459edd506b69262f6e", + "https://files.pythonhosted.org/packages/96/34/ef34ef77f1ee38fc8e4f9775217a613b452916e633c4f1d98f31db52c4a5/zstandard-0.25.0-cp310-cp310-macosx_11_0_arm64.whl": "sha256:4d441506e9b372386a5271c64125f72d5df6d2a8e8a2a45a0ae09b03cb781ef7", + "https://files.pythonhosted.org/packages/98/cf/c899f2d6df0840d5e384cf4c4121458c72802e8bda19691f3b16619f51e9/zstandard-0.25.0-cp314-cp314-musllinux_1_2_i686.whl": "sha256:a4089a10e598eae6393756b036e0f419e8c1d60f44a831520f9af41c14216cf2", + "https://files.pythonhosted.org/packages/9a/5c/36ba1e5507d56d2213202ec2b05e8541734af5f2ce378c5d1ceaf4d88dc4/zstandard-0.25.0-cp313-cp313-musllinux_1_2_i686.whl": "sha256:1673b7199bbe763365b81a4f3252b8e80f44c9e323fc42940dc8843bfeaf9851", + "https://files.pythonhosted.org/packages/9d/1b/4fdb2c12eb58f31f28c4d28e8dc36611dd7205df8452e63f52fb6261d13e/zstandard-0.25.0-cp310-cp310-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl": "sha256:ab85470ab54c2cb96e176f40342d9ed41e58ca5733be6a893b730e7af9c40550", + "https://files.pythonhosted.org/packages/9d/31/76c0779101453e6c117b0ff22565865c54f48f8bd807df2b00c2c404b8e0/zstandard-0.25.0-cp312-cp312-musllinux_1_2_aarch64.whl": "sha256:1869da9571d5e94a85a5e8d57e4e8807b175c9e4a6294e3b66fa4efb074d90f6", + "https://files.pythonhosted.org/packages/a0/1d/7e31db1240de2df22a58e2ea9a93fc6e38cc29353e660c0272b6735d6669/zstandard-0.25.0-cp314-cp314-musllinux_1_2_s390x.whl": "sha256:9654dbc012d8b06fc3d19cc825af3f7bf8ae242226df5f83936cb39f5fdc846c", + "https://files.pythonhosted.org/packages/a4/86/a48e56320d0a17189ab7a42645387334fba2200e904ee47fc5a26c1fd8ca/zstandard-0.25.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl": "sha256:223415140608d0f0da010499eaa8ccdb9af210a543fac54bce15babbcfc78439", + "https://files.pythonhosted.org/packages/aa/1c/d920d64b22f8dd028a8b90e2d756e431a5d86194caa78e3819c7bf53b4b3/zstandard-0.25.0-cp312-cp312-macosx_11_0_arm64.whl": "sha256:913cbd31a400febff93b564a23e17c3ed2d56c064006f54efec210d586171c00", + "https://files.pythonhosted.org/packages/ac/4d/e66465c5411a7cf4866aeadc7d108081d8ceba9bc7abe6b14aa21c671ec3/zstandard-0.25.0-cp311-cp311-macosx_11_0_arm64.whl": "sha256:a3f79487c687b1fc69f19e487cd949bf3aae653d181dfb5fde3bf6d18894706f", + "https://files.pythonhosted.org/packages/b2/e5/fbd822d5c6f427cf158316d012c5a12f233473c2f9c5fe5ab1ae5d21f3d8/zstandard-0.25.0-cp313-cp313-musllinux_1_2_x86_64.whl": "sha256:4f187a0bb61b35119d1926aee039524d1f93aaf38a9916b8c4b78ac8514a0aaf", + "https://files.pythonhosted.org/packages/b3/87/d3ee185e3d1aa0133399893697ae91f221fda79deb61adbe998a7235c43f/zstandard-0.25.0-cp310-cp310-musllinux_1_1_x86_64.whl": "sha256:25f8f3cd45087d089aef5ba3848cd9efe3ad41163d3400862fb42f81a3a46701", + "https://files.pythonhosted.org/packages/b5/52/ca76ed6dbfd8845a5563d3af4e972da3b9da8a9308ca6b56b0b929d93e23/zstandard-0.25.0-cp39-cp39-musllinux_1_2_i686.whl": "sha256:c2ba942c94e0691467ab901fc51b6f2085ff48f2eea77b1a48240f011e8247c7", + "https://files.pythonhosted.org/packages/b7/37/a6ce629ffdb43959e92e87ebdaeebb5ac81c944b6a75c9c47e300f85abdf/zstandard-0.25.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:7149623bba7fdf7e7f24312953bcf73cae103db8cae49f8154dd1eadc8a29ecb", + "https://files.pythonhosted.org/packages/b8/e9/29cc59d4a9d51b3fd8b477d858d0bd7ab627f700908bf1517f46ddd470ae/zstandard-0.25.0-cp39-cp39-win32.whl": "sha256:1cd5da4d8e8ee0e88be976c294db744773459d51bb32f707a0f166e5ad5c8649", + "https://files.pythonhosted.org/packages/bb/1f/e9cfd801a3f9190bf3e759c422bbfd2247db9d7f3d54a56ecde70137791a/zstandard-0.25.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:9300d02ea7c6506f00e627e287e0492a5eb0371ec1670ae852fefffa6164b072", + "https://files.pythonhosted.org/packages/c2/38/f249a2050ad1eea0bb364046153942e34abba95dd5520af199aed86fbb49/zstandard-0.25.0-cp314-cp314-win32.whl": "sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12", + "https://files.pythonhosted.org/packages/c9/ae/56523ae9c142f0c08efd5e868a6da613ae76614eca1305259c3bf6a0ed43/zstandard-0.25.0-cp314-cp314-musllinux_1_2_aarch64.whl": "sha256:a9ec8c642d1ec73287ae3e726792dd86c96f5681eb8df274a757bf62b750eae7", + "https://files.pythonhosted.org/packages/c9/dd/fdaf0674f4b10d92cb120ccff58bbb6626bf8368f00ebfd2a41ba4a0dc99/zstandard-0.25.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:5f1ad7bf88535edcf30038f6919abe087f606f62c00a87d7e33e7fc57cb69fcc", + "https://files.pythonhosted.org/packages/ca/aa/ceb8d79cbad6dabd4cb1178ca853f6a4374d791c5e0241a0988173e2a341/zstandard-0.25.0-cp39-cp39-macosx_11_0_arm64.whl": "sha256:4b14abacf83dfb5c25eb4e4a79520de9e7e205f72c9ee7702f91233ae57d33a2", + "https://files.pythonhosted.org/packages/cb/d3/23094a6b6a4b1343b27ae68249daa17ae0651fcfec9ed4de09d14b940285/zstandard-0.25.0-cp311-cp311-musllinux_1_2_i686.whl": "sha256:c8e167d5adf59476fa3e37bee730890e389410c354771a62e3c076c86f9f7778", + "https://files.pythonhosted.org/packages/d1/a9/ee891e5edf33a6ebce0a028726f0bbd8567effe20fe3d5808c42323e8542/zstandard-0.25.0-cp310-cp310-musllinux_1_2_ppc64le.whl": "sha256:a5a419712cf88862a45a23def0ae063686db3d324cec7edbe40509d1a79a0aab", + "https://files.pythonhosted.org/packages/d2/20/5f72d6ba970690df90fdd37195c5caa992e70cb6f203f74cc2bcc0b8cf30/zstandard-0.25.0-cp39-cp39-musllinux_1_1_aarch64.whl": "sha256:1f3689581a72eaba9131b1d9bdbfe520ccd169999219b41000ede2fca5c1bfdb", + "https://files.pythonhosted.org/packages/d4/57/60c3c01243bb81d381c9916e2a6d9e149ab8627c0c7d7abb2d73384b3c0c/zstandard-0.25.0-cp313-cp313-win_arm64.whl": "sha256:85304a43f4d513f5464ceb938aa02c1e78c2943b29f44a750b48b25ac999a049", + "https://files.pythonhosted.org/packages/d7/83/41939e60d8d7ebfe2b747be022d0806953799140a702b90ffe214d557638/zstandard-0.25.0-cp310-cp310-musllinux_1_1_aarch64.whl": "sha256:9174f4ed06f790a6869b41cba05b43eeb9a35f8993c4422ab853b705e8112bbd", + "https://files.pythonhosted.org/packages/d9/14/933d27204c2bd404229c69f445862454dcc101cd69ef8c6068f15aaec12c/zstandard-0.25.0-cp313-cp313-manylinux2010_i686.manylinux2014_i686.manylinux_2_12_i686.manylinux_2_17_i686.whl": "sha256:e96594a5537722fdfb79951672a2a63aec5ebfb823e7560586f7484819f2a08f", + "https://files.pythonhosted.org/packages/d9/82/b9c06c870f3bd8767c201f1edbdf9e8dc34be5b0fbc5682c4f80fe948475/zstandard-0.25.0-cp313-cp313-win_amd64.whl": "sha256:1f830a0dac88719af0ae43b8b2d6aef487d437036468ef3c2ea59c51f9d55fd5", + "https://files.pythonhosted.org/packages/db/00/87466ea3f99599d02a5238498b87bf84a6348290c19571051839ca943777/zstandard-0.25.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:457ed498fc58cdc12fc48f7950e02740d4f7ae9493dd4ab2168a47c93c31298e", + "https://files.pythonhosted.org/packages/e2/be/94267dc6ee64f0f8ba2b2ae7c7a2df934a816baaa7291db9e1aa77394c3c/zstandard-0.25.0-cp311-cp311-musllinux_1_2_x86_64.whl": "sha256:72d35d7aa0bba323965da807a462b0966c91608ef3a48ba761678cb20ce5d8b7", + "https://files.pythonhosted.org/packages/e3/79/2bf870b3abeb5c070fe2d670a5a8d1057a8270f125ef7676d29ea900f496/zstandard-0.25.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:6a573a35693e03cf1d67799fd01b50ff578515a8aeadd4595d2a7fa9f3ec002a", + "https://files.pythonhosted.org/packages/e4/f1/131a0382b8b8d11e84690574645f528f5c5b9343e06cefd77f5fd730cd2b/zstandard-0.25.0-cp39-cp39-musllinux_1_1_x86_64.whl": "sha256:d8c56bb4e6c795fc77d74d8e8b80846e1fb8292fc0b5060cd8131d522974b751", + "https://files.pythonhosted.org/packages/e9/74/68341185a4f32b274e0fc3410d5ad0750497e1acc20bd0f5b5f64ce17785/zstandard-0.25.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:78228d8a6a1c177a96b94f7e2e8d012c55f9c760761980da16ae7546a15a8e9b", + "https://files.pythonhosted.org/packages/ea/6b/8b51697e5319b1f9ac71087b0af9a40d8a6288ff8025c36486e0c12abcc4/zstandard-0.25.0-cp312-cp312-win_arm64.whl": "sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9", + "https://files.pythonhosted.org/packages/ef/d6/8c4bd38a3b24c4c7676a7a3d8de85d6ee7a983602a734b9f9cdefb04a5d6/zstandard-0.25.0-cp310-cp310-win32.whl": "sha256:106281ae350e494f4ac8a80470e66d1fe27e497052c8d9c3b95dc4cf1ade81aa", + "https://files.pythonhosted.org/packages/f0/ef/da163ce2450ed4febf6467d77ccb4cd52c4c30ab45624bad26ca0a27260c/zstandard-0.25.0-cp314-cp314-win_arm64.whl": "sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d", + "https://files.pythonhosted.org/packages/f2/1b/402cab5edcfe867465daf869d5ac2a94930931c0989633bc01d6a7d8bd68/zstandard-0.25.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl": "sha256:19796b39075201d51d5f5f790bf849221e58b48a39a5fc74837675d8bafc7362", + "https://files.pythonhosted.org/packages/f5/93/8ebc19f0a31c44ea0e7348f9b0d4b326ed413b6575a3c6ff4ed50222abb6/zstandard-0.25.0-cp39-cp39-musllinux_1_2_x86_64.whl": "sha256:89c4b48479a43f820b749df49cd7ba2dbc2b1b78560ecb5ab52985574fd40b27", + "https://files.pythonhosted.org/packages/f6/49/fac46df5ad353d50535e118d6983069df68ca5908d4d65b8c466150a4ff1/zstandard-0.25.0-cp314-cp314-musllinux_1_2_x86_64.whl": "sha256:4203ce3b31aec23012d3a4cf4a2ed64d12fea5269c49aed5e4c3611b938e4088", + "https://files.pythonhosted.org/packages/f8/ad/eb659984ee2c0a779f9d06dbfe45e2dc39d99ff40a319895df2d3d9a48e5/zstandard-0.25.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl": "sha256:2e54296a283f3ab5a26fc9b8b5d4978ea0532f37b231644f367aa588930aa043", + "https://files.pythonhosted.org/packages/f9/ce/26dc5a6fa956be41d0e984909224ed196ee6f91d607f0b3fd84577741a77/zstandard-0.25.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl": "sha256:05353cef599a7b0b98baca9b068dd36810c3ef0f42bf282583f438caf6ddcee3", + "https://files.pythonhosted.org/packages/fc/5f/75aafd4b9d11b5407b641b8e41a57864097663699f23e9ad4dbb91dc6bfe/zstandard-0.25.0-cp312-cp312-musllinux_1_2_x86_64.whl": "sha256:474d2596a2dbc241a556e965fb76002c1ce655445e4e3bf38e5477d413165ffa", + "https://files.pythonhosted.org/packages/fd/aa/3e0508d5a5dd96529cdc5a97011299056e14c6505b678fd58938792794b1/zstandard-0.25.0.tar.gz": "sha256:7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b", + "https://files.pythonhosted.org/packages/fd/e5/6d36f92a197c3c17729a2125e29c169f460538a7d939a27eaaa6dcfcba8e/zstandard-0.25.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl": "sha256:4b6d83057e713ff235a12e73916b6d356e3084fd3d14ced499d84240f3eecee0", + "https://files.pythonhosted.org/packages/ff/8d/0309daffea4fcac7981021dbf21cdb2e3427a9e76bafbcdbdf5392ff99a4/zstandard-0.25.0-cp312-cp312-win32.whl": "sha256:23ebc8f17a03133b4426bcc04aabd68f8236eb78c3760f12783385171b0fd8bd" + } + } + }, + "fact_version": "v2" + } + }, + "factsVersions": {} +} diff --git a/Makefile b/Makefile index 5d087fa3f..dd8657d72 100644 --- a/Makefile +++ b/Makefile @@ -14,13 +14,10 @@ include Makefile.defs -MIN_CLANG_VERSION := 18.1.8 -COMPILER_DEP := clang.bazelrc - ENVOY_BINS = cilium-envoy bazel-bin/cilium-envoy cilium-envoy-starter bazel-bin/cilium-envoy-starter cilium-envoy-healthcheck bazel-bin/bin/cilium-envoy-healthcheck ENVOY_TESTS = bazel-bin/tests/*_test -BUILD_DEP_FILES = ENVOY_VERSION WORKSPACE .bazelrc envoy.bazelrc bazel/toolchains/BUILD bazel/toolchains/cc_toolchain_config.bzl +BUILD_DEP_FILES = ENVOY_VERSION MODULE.bazel MODULE.bazel.lock .bazelrc envoy.bazelrc SHELL=/bin/bash -o pipefail BAZEL ?= $(QUIET) bazel @@ -54,19 +51,14 @@ endif # Extra opts are passed to docker targets, which will choose the bazel platform themselves EXTRA_BAZEL_BUILD_OPTS := $(BAZEL_BUILD_OPTS) -BAZEL_ASAN_BUILD_OPTS ?= $(EXTRA_BAZEL_BUILD_OPTS) -c dbg --config=asan --config=clang-asan +BAZEL_ASAN_BUILD_OPTS ?= $(EXTRA_BAZEL_BUILD_OPTS) -c dbg --config=asan BAZEL_ASAN_TEST_OPTS ?= --jobs=HOST_RAM*.0001 --test_timeout=600 --local_test_jobs=2 --flaky_test_attempts=1 --test_output=errors BAZEL_MSAN_BUILD_OPTS ?= --config=msan $(EXTRA_BAZEL_BUILD_OPTS) -c dbg BAZEL_MSAN_TEST_OPTS ?= --jobs=HOST_RAM*.00005 --test_timeout=900 --local_test_jobs=1 --flaky_test_attempts=1 --test_output=errors -PROXYLIB_MSAN_CC ?= clang -PROXYLIB_MSAN_GO_BUILD_FLAGS ?= -msan -buildvcs=false BAZEL_TSAN_BUILD_OPTS ?= --config=tsan $(EXTRA_BAZEL_BUILD_OPTS) -c dbg BAZEL_TSAN_TEST_OPTS ?= --jobs=HOST_RAM*.00005 --test_timeout=900 --local_test_jobs=1 --flaky_test_attempts=1 --test_output=errors -PROXYLIB_TSAN_CC ?= clang -PROXYLIB_TSAN_CGO_CFLAGS ?= -fsanitize=thread -PROXYLIB_TSAN_GO_BUILD_FLAGS ?= -installsuffix=tsan -buildvcs=false ifdef DEBUG BAZEL_BUILD_OPTS += -c dbg @@ -91,10 +83,6 @@ ifdef PKG_BUILD .PHONY: install-bazelisk install-bazelisk: echo "Bazel assumed to be installed in the builder image" - - define install_clang - echo "Clang assumed to be installed in the builder image" - endef else ifneq ($(TARGETARCH),$(BUILDARCH)) $(error local cross-builds are not supported: BUILDARCH=$(BUILDARCH), TARGETARCH=$(TARGETARCH)) @@ -108,26 +96,6 @@ else .PHONY: install-bazelisk install-bazelisk: tools/install_bazelisk.sh - - # Install clang if needed - define install_clang - add_llvm_source() { \ - if [ ! -f /etc/apt/trusted.gpg.d/apt.llvm.org.asc ]; then \ - $(SUDO) wget -q -O /etc/apt/trusted.gpg.d/apt.llvm.org.asc https://apt.llvm.org/llvm-snapshot.gpg.key; \ - fi; \ - local CODENAME=$$(lsb_release -cs); \ - apt_source="deb http://apt.llvm.org/$$CODENAME/ llvm-toolchain-$$CODENAME-18 main" && \ - $(SUDO) apt-add-repository -y "$${apt_source}" && \ - $(SUDO) apt update; \ - }; \ - version="$$(dpkg-query -W -f='$${Version}' clang-18 2>/dev/null || echo 0)"; \ - if dpkg --compare-versions "$$version" ge 1:$(MIN_CLANG_VERSION)~ && [ -x /usr/lib/llvm-18/bin/llvm-config ]; then \ - echo "clang-18 $$version satisfies minimum $(MIN_CLANG_VERSION); skipping apt install"; \ - else \ - add_llvm_source; \ - $(SUDO) apt install -y clang-18 clangd-18 llvm-18-dev lld-18 lldb-18 clang-format-18 clang-tools-18 clang-tidy-18 libc++-18-dev libc++abi-18-dev; \ - fi - endef endif include Makefile.dev @@ -135,24 +103,8 @@ include Makefile.dev BUILD_DEP_HASHES: $(BUILD_DEP_FILES) sha256sum $^ >$@ -clang.bazelrc: bazel/setup_clang.sh - @$(call install_clang) - bazel/setup_clang.sh /usr/lib/llvm-18 - echo "# Use system LLVM instead of hermetic download to avoid libtinfo.so.5 mismatch" >> $@ - echo "build:clang-local --repo_env=BAZEL_LLVM_PATH=/usr/lib/llvm-18" >> $@ - echo "# Disable module_maps/layering_check — abseil module maps are incompatible with system clang" >> $@ - echo "build:clang-local --features=-module_maps --features=-layering_check" >> $@ - echo "build:clang-local --host_features=-module_maps --host_features=-layering_check" >> $@ - echo "build --config=clang-local" >> $@ - -.PHONY: cargo-repin -cargo-repin: install-bazelisk - @$(ECHO_BAZEL) - test -e bazel/envoy_dynamic_modules_rust_sdk.Cargo.Bazel.lock || touch bazel/envoy_dynamic_modules_rust_sdk.Cargo.Bazel.lock - CARGO_BAZEL_REPIN=workspace CARGO_BAZEL_REPIN_ONLY=envoy_rust_crate_index bazel $(BAZEL_OPTS) sync --only=envoy_rust_crate_index - .PHONY: bazel-bin/cilium-envoy -bazel-bin/cilium-envoy: $(COMPILER_DEP) SOURCE_VERSION install-bazelisk +bazel-bin/cilium-envoy: SOURCE_VERSION install-bazelisk @$(ECHO_BAZEL) $(BAZEL) $(BAZEL_OPTS) build $(BAZEL_BUILD_OPTS) //:cilium-envoy $(BAZEL_FILTER) @@ -162,7 +114,7 @@ cilium-envoy: bazel-bin/cilium-envoy chmod 0755 $@ .PHONY: bazel-bin/cilium-envoy-starter -bazel-bin/cilium-envoy-starter: $(COMPILER_DEP) SOURCE_VERSION install-bazelisk +bazel-bin/cilium-envoy-starter: SOURCE_VERSION install-bazelisk @$(ECHO_BAZEL) $(BAZEL) $(BAZEL_OPTS) build $(BAZEL_BUILD_OPTS) //:cilium-envoy-starter $(BAZEL_FILTER) @@ -215,16 +167,13 @@ clean: force @$(ECHO_CLEAN) $(notdir $(shell pwd)) -$(QUIET) rm -f $(ENVOY_BINS) $(ENVOY_TESTS) -proxylib/libcilium.so: - make -C proxylib - .PHONY: envoy-test-deps -envoy-test-deps: $(COMPILER_DEP) SOURCE_VERSION proxylib/libcilium.so +envoy-test-deps: SOURCE_VERSION @$(ECHO_BAZEL) $(BAZEL) $(BAZEL_OPTS) build $(BAZEL_BUILD_OPTS) $(BAZEL_TEST_OPTS) //tests/... @envoy//test/integration:tcp_proxy_integration_test $(BAZEL_FILTER) .PHONY: envoy-tests -envoy-tests: $(COMPILER_DEP) SOURCE_VERSION proxylib/libcilium.so +envoy-tests: SOURCE_VERSION @$(ECHO_BAZEL) # Upstream tcp_proxy_integration_test included to validate that our custom patches # didn't break anything @@ -234,20 +183,12 @@ envoy-tests: $(COMPILER_DEP) SOURCE_VERSION proxylib/libcilium.so envoy-asan-tests: $(MAKE) envoy-tests BAZEL_BUILD_OPTS="$(BAZEL_ASAN_BUILD_OPTS)" BAZEL_TEST_OPTS="$(BAZEL_ASAN_TEST_OPTS)" -.PHONY: proxylib-msan -proxylib-msan: - $(MAKE) -C proxylib all CC="$(PROXYLIB_MSAN_CC)" GO_BUILD_FLAGS="$(PROXYLIB_MSAN_GO_BUILD_FLAGS)" - .PHONY: envoy-msan-tests -envoy-msan-tests: proxylib-msan +envoy-msan-tests: $(MAKE) envoy-tests BAZEL_BUILD_OPTS="$(BAZEL_MSAN_BUILD_OPTS)" BAZEL_TEST_OPTS="$(BAZEL_MSAN_TEST_OPTS)" -.PHONY: proxylib-tsan -proxylib-tsan: - $(MAKE) -C proxylib all CC="$(PROXYLIB_TSAN_CC)" CGO_CFLAGS="$(PROXYLIB_TSAN_CGO_CFLAGS)" GO_BUILD_FLAGS="$(PROXYLIB_TSAN_GO_BUILD_FLAGS)" - .PHONY: envoy-tsan-tests -envoy-tsan-tests: proxylib-tsan +envoy-tsan-tests: $(MAKE) envoy-tests BAZEL_BUILD_OPTS="$(BAZEL_TSAN_BUILD_OPTS)" BAZEL_TEST_OPTS="$(BAZEL_TSAN_TEST_OPTS)" .PHONY: \ diff --git a/Makefile.api b/Makefile.api index 54d55a4e4..ea678a183 100644 --- a/Makefile.api +++ b/Makefile.api @@ -16,18 +16,19 @@ include Makefile.quiet # Depends on Envoy dependencies, Envoy API & protoc must be built first -PROTOC ?= bazel-out/host/bin/external/com_google_protobuf/protoc +PROTOC ?= bazel-out/host/bin/external/protobuf+/protoc -ENVOY_API_PROTO_PATH = bazel-proxy/external/envoy_api +# Bazel module repositories are checked out under their canonical names ("+"). +ENVOY_API_PROTO_PATH = bazel-proxy/external/envoy_api+ CILIUM_PROTO_PATH = . PROTO_DEPS = \ - -I bazel-proxy/external/com_google_protobuf/src \ - -I bazel-proxy/external/com_google_googleapis \ - -I bazel-proxy/external/com_envoyproxy_protoc_gen_validate \ - -I bazel-proxy/external/opentelemetry-proto \ - -I bazel-proxy/external/prometheus_metrics_model \ - -I bazel-proxy/external/xds \ - -I bazel-proxy/external/dev_cel/proto + -I bazel-proxy/external/protobuf+/src \ + -I bazel-proxy/external/googleapis+ \ + -I bazel-proxy/external/protoc-gen-validate+ \ + -I bazel-proxy/external/opentelemetry-proto+ \ + -I bazel-proxy/external/prometheus-metrics-model+ \ + -I bazel-proxy/external/xds+ \ + -I bazel-proxy/external/cel-spec+/proto GO_OUT = go GO_MODULE = module=github.com/cilium/proxy/go diff --git a/Makefile.dev b/Makefile.dev index 291ffa3bc..b61091f18 100644 --- a/Makefile.dev +++ b/Makefile.dev @@ -19,7 +19,7 @@ BAZEL_ARCHIVE ?= ~/bazel-cache.tar.bz2 # @envoy_api//:v3_protos must be built before invoking Makefile.api API_DEPS = @envoy_api//:v3_protos -PROTOC_TARGET = @com_google_protobuf//:protoc +PROTOC_TARGET = @protobuf//:protoc api: force-non-root Makefile.api install-bazelisk PROTOC=`$(BAZEL) cquery --output=starlark --starlark:expr=target.files_to_run.executable.path $(PROTOC_TARGET) | grep "fastbuild.*/bin/external"`; \ $(BAZEL) build $(PROTOC_TARGET) $(API_DEPS); \ @@ -32,7 +32,7 @@ api-clean: mkdir -p go/contrib/envoy mkdir go/envoy -$(CHECK_FORMAT): force-non-root SOURCE_VERSION install-bazelisk clang.bazelrc +$(CHECK_FORMAT): force-non-root SOURCE_VERSION install-bazelisk $(BAZEL) $(BAZEL_OPTS) build $(BAZEL_BUILD_OPTS) //:check_format.py veryclean: force-non-root clean @@ -42,19 +42,16 @@ veryclean: force-non-root clean precheck: force-non-root tools/check_repositories.sh -FORMAT_EXCLUDED_PREFIXES = "./linux/" "./proxylib/" "./starter/" "./vendor/" "./go/" "./envoy_build_config/" "./work/" "./bin/" "./.cache/" +FORMAT_EXCLUDED_PREFIXES = "./linux/" "./starter/" "./vendor/" "./go/" "./envoy_build_config/" "./work/" "./bin/" "./.cache/" # The default set of sources assumes all relevant sources are dependecies of some tests! TIDY_SOURCES ?= $(shell bazel query 'kind("source file", deps(//tests/...))' 2>/dev/null | sed -n "s/\/\/cilium:/cilium\//p; s/\/\/tests:/tests\//p") COMPILATION_DATABASE_DEPS = \ - WORKSPACE \ + MODULE.bazel \ .bazelrc \ envoy.bazelrc \ bazel/BUILD \ - bazel/local_llvm.bzl \ - bazel/toolchains/BUILD \ - bazel/toolchains/cc_toolchain_config.bzl \ cilium/BUILD \ cilium/api/BUILD \ envoy_build_config/BUILD \ @@ -75,36 +72,45 @@ compile_commands.json: $(COMPILATION_DATABASE_DEPS) force-non-root # Default number of jobs, derived from available memory TIDY_JOBS ?= $$(( $(shell sed -n "s/^MemAvailable: *\([0-9]*\).*\$$/\1/p" /proc/meminfo) / 4500000 )) -# tidy uses run-clang-tidy, .clang-tidy must be present in the project directory and configured to -# ignore the same headers as .clangd. Unfortunately the configuration format is different. -tidy: $(COMPILER_DEP) compile_commands.json force-non-root - run-clang-tidy -quiet -extra-arg="-Wno-unknown-pragmas" -checks=misc-include-cleaner -j $(TIDY_JOBS) $(TIDY_SOURCES) || echo "clang-tidy check failed, run 'make tidy-fix' locally to fix tidy errors." - -tidy-fix: $(COMPILER_DEP) compile_commands.json force-non-root +# clang-tidy and clang-apply-replacements come from the hermetic LLVM toolchain that Bazel +# downloads for Envoy (@llvm_minimal_linux_ from @envoy_toolshed, planted in the execroot under +# its canonical repository name by the compilation database build above). That toolchain does not ship LLVM's run-clang-tidy driver, +# tools/run_clang_tidy.sh stands in for it. +# Bazel names the execroot symlink after the workspace directory (bazel-proxy here, bazel-b in the +# CI containers), so derive it rather than hardcoding it. +LLVM_HOST_ARCH := $(subst aarch64,arm64,$(subst x86_64,x64,$(shell uname -m))) +LLVM_TOOLS_BIN = bazel-$(notdir $(CURDIR))/external/envoy_toolshed++llvm_minimal_extension+llvm_minimal_linux_$(LLVM_HOST_ARCH)/bin +RUN_CLANG_TIDY = CLANG_TIDY=$(LLVM_TOOLS_BIN)/clang-tidy CLANG_APPLY_REPLACEMENTS=$(LLVM_TOOLS_BIN)/clang-apply-replacements tools/run_clang_tidy.sh + +# .clang-tidy must be present in the project directory and configured to ignore the same headers +# as .clangd. Unfortunately the configuration format is different. +tidy: compile_commands.json force-non-root + $(RUN_CLANG_TIDY) -quiet -extra-arg="-Wno-unknown-pragmas" -checks=misc-include-cleaner -j $(TIDY_JOBS) $(TIDY_SOURCES) || echo "clang-tidy check failed, run 'make tidy-fix' locally to fix tidy errors." + +tidy-fix: compile_commands.json force-non-root echo "clang-tidy fix results can contain duplicate or misplaced includes, check before committing!" - run-clang-tidy -fix -format -style=file -quiet -extra-arg="-Wno-unknown-pragmas" -checks=misc-include-cleaner -j $(TIDY_JOBS) $(TIDY_SOURCES) || echo "clang-tidy fix produced changes, please commit them." + $(RUN_CLANG_TIDY) -fix -format -style=file -quiet -extra-arg="-Wno-unknown-pragmas" -checks=misc-include-cleaner -j $(TIDY_JOBS) $(TIDY_SOURCES) || echo "clang-tidy fix produced changes, please commit them." -tidy-fix-head: $(COMPILER_DEP) compile_commands.json force-non-root +tidy-fix-head: compile_commands.json force-non-root echo "clang-tidy fix results can contain duplicate or misplaced includes, check before committing!" - run-clang-tidy -fix -format -style=file -quiet -extra-arg="-Wno-unknown-pragmas" -checks=misc-include-cleaner -j $(TIDY_JOBS) $(shell git diff-tree --no-commit-id --name-only -r --diff-filter=d HEAD) || echo "clang-tidy fix produced changes, please commit them." + $(RUN_CLANG_TIDY) -fix -format -style=file -quiet -extra-arg="-Wno-unknown-pragmas" -checks=misc-include-cleaner -j $(TIDY_JOBS) $(shell git diff-tree --no-commit-id --name-only -r --diff-filter=d HEAD) || echo "clang-tidy fix produced changes, please commit them." -format: $(COMPILER_DEP) force-non-root +format: force-non-root $(BAZEL) $(BAZEL_OPTS) run $(BAZEL_BUILD_OPTS) @envoy//tools/code_format:check_format -- --path "$(PWD)" --skip_envoy_build_rule_check --add-excluded-prefixes $(FORMAT_EXCLUDED_PREFIXES) --bazel_tools_check_excluded_paths="./" --build_fixer_check_excluded_paths="./" check || echo "Format check failed, run 'make format-fix' locally to fix formatting errors." -format-fix: $(COMPILER_DEP) force-non-root +format-fix: force-non-root $(BAZEL) $(BAZEL_OPTS) run $(BAZEL_BUILD_OPTS) @envoy//tools/code_format:check_format -- --path "$(PWD)" --skip_envoy_build_rule_check --add-excluded-prefixes $(FORMAT_EXCLUDED_PREFIXES) --bazel_tools_check_excluded_paths="." --build_fixer_check_excluded_paths="./" fix # Run tests without debug by default. -tests: $(COMPILER_DEP) force-non-root SOURCE_VERSION proxylib/libcilium.so install-bazelisk +tests: force-non-root SOURCE_VERSION install-bazelisk $(BAZEL) $(BAZEL_OPTS) test $(BAZEL_BUILD_OPTS) //:envoy_binary_test $(BAZEL_FILTER) $(BAZEL) $(BAZEL_OPTS) test $(BAZEL_BUILD_OPTS) $(BAZEL_TEST_OPTS) //tests/... $(BAZEL_FILTER) $(GO) test -mod=vendor ./go/... - $(MAKE) -C proxylib test -unstripped-tests: $(COMPILER_DEP) force-non-root SOURCE_VERSION proxylib/libcilium.so install-bazelisk +unstripped-tests: force-non-root SOURCE_VERSION install-bazelisk $(BAZEL) $(BAZEL_OPTS) test $(BAZEL_BUILD_OPTS) --config=release_debug --fission=no --features=-per_object_debug_info //:envoy_binary_test $(BAZEL_FILTER) $(BAZEL) $(BAZEL_OPTS) test $(BAZEL_BUILD_OPTS) --config=release_debug --fission=no --features=-per_object_debug_info $(BAZEL_TEST_OPTS) //tests/... $(BAZEL_FILTER) -debug-tests: $(COMPILER_DEP) force-non-root SOURCE_VERSION install-bazelisk +debug-tests: force-non-root SOURCE_VERSION install-bazelisk $(BAZEL) $(BAZEL_OPTS) test $(BAZEL_BUILD_OPTS) -c dbg --fission=no --features=-per_object_debug_info $(BAZEL_TEST_OPTS) //:envoy_binary_test $(BAZEL_FILTER) $(BAZEL) $(BAZEL_OPTS) test $(BAZEL_BUILD_OPTS) -c dbg --fission=no --features=-per_object_debug_info $(BAZEL_TEST_OPTS) //tests/... $(BAZEL_FILTER) diff --git a/Makefile.docker b/Makefile.docker index 2e7f651f0..d66ab649c 100644 --- a/Makefile.docker +++ b/Makefile.docker @@ -91,12 +91,8 @@ BRANCH_TAG := $(shell echo $(BRANCH_NAME) | tr -c '[:alnum:]_.\n-' '-') BUILDER_ARCHIVE_TAG ?= main-archive-latest TESTS_ARCHIVE_TAG ?= test-main-archive-latest -BUILDER_DOCKER_HASH=$(shell git ls-tree --full-tree HEAD -- ./Dockerfile.builder | awk '{ print $$3 }') -BUILDER_BASE_TAG ?= $(BUILDER_DOCKER_HASH) -BUILDER_BASE ?= $(DOCKER_DEV_ACCOUNT)/cilium-envoy-builder:$(BUILDER_BASE_TAG) - -BUILD_IMAGE_OPTS := --build-arg BUILDER_BASE="$(BUILDER_BASE)" -TESTS_IMAGE_OPTS := --build-arg BUILDER_BASE="$(BUILDER_BASE)" +BUILD_IMAGE_OPTS := +TESTS_IMAGE_OPTS := ifdef DEBUG BUILD_IMAGE_OPTS += --build-arg DEBUG=$(DEBUG) @@ -134,16 +130,6 @@ ifdef TESTS_ARCHIVE_IMAGE TESTS_IMAGE_OPTS += --build-arg ARCHIVE_IMAGE=$(TESTS_ARCHIVE_IMAGE) endif -# Builder image consists only of build tools, so it only needs .bazelversion -Dockerfile.builder.dockerignore: - echo "*" >$@ - echo "!/.bazelversion" >>$@ - -# Builder image for tests consists only of build tools, so it only needs .bazelversion -Dockerfile.builder.tests.dockerignore: - echo "*" >$@ - echo "!/.bazelversion" >>$@ - # Release does not need Go API or test files Dockerfile.dockerignore: .dockerignore Makefile.docker cp $< $@ @@ -176,10 +162,6 @@ GIT_IGNORE_FILES := $(shell find -H . -not -path "./_build*" -not -path "./vendo echo "/Makefile.docker" >>$@ echo "/README*" >>$@ -.PHONY: docker-image-builder -docker-image-builder: Dockerfile.builder SOURCE_VERSION Dockerfile.builder.dockerignore - $(DOCKER) build $(DOCKER_BUILD_OPTS) --build-arg BAZEL_BUILD_OPTS="$(EXTRA_BAZEL_BUILD_OPTS)" --build-arg BUILDER_BASE="$(BUILDER_BASE)" -f $< -t $(DOCKER_DEV_ACCOUNT)/cilium-envoy-builder:$(BUILDER_BASE_TAG) . - .PHONY: docker-builder-archive docker-builder-archive: Dockerfile SOURCE_VERSION Dockerfile.dockerignore $(DOCKER) build --target builder-archive $(DOCKER_BUILD_OPTS) $(DOCKER_CACHE_OPTS) $(BUILD_IMAGE_OPTS) --build-arg BAZEL_BUILD_OPTS="$(EXTRA_BAZEL_BUILD_OPTS)" --build-arg COPY_CACHE_EXT=.new -t $(DOCKER_DEV_ACCOUNT)/cilium-envoy-builder:$(BUILDER_ARCHIVE_TAG) . diff --git a/README.md b/README.md index c7efa92a6..8179f8221 100644 --- a/README.md +++ b/README.md @@ -47,10 +47,10 @@ Note: The below table is updated by script `tools/update_version_matrix.sh` ## Building -Cilium proxy is best built with the provided build containers. For a -local host build consult [the builder -Dockerfile](https://github.com/cilium/proxy/blob/main/Dockerfile.builder) -for the required dependencies. +Cilium proxy is best built with the provided build containers. Bazel +downloads the compiler toolchain itself, so a local host build only needs +the tools installed by the `builder-base` stage of the +[Dockerfile](https://github.com/cilium/proxy/blob/main/Dockerfile). Container builds require Docker Buildkit and optionally Buildx for multi-arch builds. Builds are currently only supported for amd64 and @@ -201,38 +201,6 @@ significantly. To do this you should update Envoy version in ARCH=multi NO_CACHE=1 NO_ARCHIVE=1 BUILDER_ARCHIVE_TAG=main-archive-latest make docker-builder-archive ``` -If the Envoy update changes the dynamic modules Rust SDK dependencies, -refresh the Cilium-owned crate-universe lockfile with `make cargo-repin` -and commit the resulting -`bazel/envoy_dynamic_modules_rust_sdk.Cargo.Bazel.lock` update together -with the Envoy bump. Normal builds use this checked-in lockfile and do -not need to run Cargo repinning first. - - -## Updating the builder image - -The required Bazel version typically changes from one Envoy release to -another. To create a new builder image first update the required Bazel -version at `.bazelversion` and then run: - -``` -ARCH=multi NO_CACHE=1 NO_ARCHIVE=1 make docker-image-builder -``` - -The builder can not be cross-compiled as native build tools are needed -for native arm64 builds. This means that for non-native builds QEMU -CPU emulation is used instead of cross-compilation. If you have an -arm64 machine you can create a Docker buildx builder to use it for -native builds. - -The builder image is tagged as -"quay.io/cilium/cilium-envoy-builder:bazel-". Change the -BUILDER_BASE ARG in `Dockerfile` to use the new builder and commit the -result. - -For testing purposes you can define `DOCKER_DEV_ACCOUNT` as explained -above to push the builder into a different registry or account. - ## Running integration tests diff --git a/UPGRADE_ENVOY.md b/UPGRADE_ENVOY.md index 7fe4fdaf8..a4f01ff76 100644 --- a/UPGRADE_ENVOY.md +++ b/UPGRADE_ENVOY.md @@ -15,20 +15,13 @@ the upgrade automatically. New Envoy minor version might require new Bazel version. 1. Update `.bazelversion` file. -2. Sync up `WORKSPACE` file with upstream. +2. Sync up `MODULE.bazel` with upstream: the `bazel_dep` versions it shares with Envoy, and the + overrides, dev dependencies and toolchains Envoy only sets up when it is the root module. 3. Sync up `envoy.bazelrc` file with upstream. -```shell -# Building a new builder image locally with your own docker account -$ DOCKER_DEV_ACCOUNT=docker.io/sayboras ARCH=multi NO_CACHE=1 make docker-image-builder - -# Export the builder image environment variable for later use -$ export BUILDER=docker.io/sayboras/cilium-envoy-builder:6.3.2-35ff82a25ab6321721eba727a1cc23fe7c240d5f@sha256:028da98e1c815d12250cc32327f3511016a859a027c0136d1ac7a4a178fbfe41 -``` - ### Update Envoy release commit hash 1. Bump version in `ENVOY_VERSION` file. -2. Update git hash from Envoy official release in `WORKSPACE`. +2. Update git hash from Envoy official release (`ENVOY_SHA`) in `MODULE.bazel`. 3. Sync up `envoy_build_config/extensions_build_config.bzl` with upstream. ### Adjust Cilium custom patches @@ -59,7 +52,7 @@ easiest way is to just run the compilation and fix any issues coming up. ```shell # Please refer to main README.md for the details of how to build. -$ DOCKER_DEV_ACCOUNT=docker.io/sayboras BUILDER_BASE=$BUILDER ARCH=multi NO_CACHE=1 make docker-image-envoy +$ DOCKER_DEV_ACCOUNT=docker.io/sayboras ARCH=multi NO_CACHE=1 make docker-image-envoy ``` ### Update Envoy API diff --git a/Vagrantfile b/Vagrantfile index da75251c5..ffd6668f3 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -25,17 +25,8 @@ apt-get update && \ apt-get upgrade -y --no-install-recommends && \ apt-get install -y --no-install-recommends \ ca-certificates \ - gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross binutils-aarch64-linux-gnu \ - gcc-x86-64-linux-gnu g++-x86-64-linux-gnu libc6-dev-amd64-cross binutils-x86-64-linux-gnu \ - libc6-dev \ autoconf automake cmake coreutils curl git libtool make ninja-build patch patchelf \ - python3 python-is-python3 unzip virtualenv wget zip \ - software-properties-common && \ - wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc && \ - apt-add-repository -y "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-18 main" && \ - apt-get update && \ - apt-get install -y --no-install-recommends \ - clang-18 clangd-18 llvm-18-dev lld-18 lldb-18 clang-format-18 clang-tools-18 clang-tidy-18 libc++-18-dev libc++abi-18-dev && \ + python3 python-is-python3 unzip virtualenv wget zip && \ apt-get purge --auto-remove && \ apt-get clean SCRIPT diff --git a/WORKSPACE b/WORKSPACE deleted file mode 100644 index ce1ed958e..000000000 --- a/WORKSPACE +++ /dev/null @@ -1,160 +0,0 @@ -workspace(name = "cilium") - -ENVOY_PROJECT = "envoyproxy" - -ENVOY_REPO = "envoy" - -# Envoy GIT commit SHA of release -# -# We grep for the following line to generate SOURCE_VERSION file for non-git -# distribution builds. This line must start with the string ENVOY_SHA followed by -# an equals sign and a git SHA in double quotes. -# -# No other line in this file may have ENVOY_SHA followed by an equals sign! -# -# renovate: datasource=github-releases depName=envoyproxy/envoy digestVersion=v1.39.3 -ENVOY_SHA = "6eb0d2d97489ec1b4e1584a004f5de443d97a41b" - -# // clang-format off: unexpected @bazel_tools reference, please indirect via a definition in //bazel -load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") -# // clang-format on - -local_repository( - name = "envoy_build_config", - path = "envoy_build_config", -) - -# This is a local repository for local development instead of git repository for faster feedback loop -#local_repository( -# name = "envoy", -# # Update the path to point to your local Envoy repository. -# path = "/home/tammach/go/src/github.com/envoyproxy/envoy", -#) - -git_repository( - name = "envoy", - commit = ENVOY_SHA, - # Use Bazel's native patch implementation. `patch_tool = "git"` must not be - # used: since Bazel 8, `git_repository` carries a `patch_strip` attribute and - # prepends its `-pN` to `patch_args`, which `git apply` rejects as an unknown - # global option. - patch_strip = 1, - patches = [ - "@//patches:0001-network-Add-callback-for-upstream-authorization.patch", - "@//patches:0002-listener-add-socket-options.patch", - "@//patches:0003-original_dst_cluster-Avoid-multiple-hosts-for-the-sa.patch", - "@//patches:0004-thread_local-reset-slot-in-worker-threads-first.patch", - "@//patches:0005-http-header-expose-attribute.patch", - "@//patches:0006-config-add-grpc-mux-stream-event-callback.patch", - "@//patches:0007-network-Allow-write-filters-to-consume-data-after-e.patch", - "@//patches:0008-tcp_proxy-Allow-filters-to-wait-for-upstream-close.patch", - ], - # // clang-format off: Envoy's format check: Only repository_locations.bzl may contains URL references - remote = "https://github.com/envoyproxy/envoy.git", - # // clang-format on -) - -# -# Bazel does not do transitive dependencies, so we must basically -# include all of Envoy's WORKSPACE file below, with the following -# changes: -# - Skip the 'workspace(name = "envoy")' line as we already defined -# the workspace above. -# - loads of "//..." need to be renamed as "@envoy//..." -# - -load("@envoy//bazel:api_binding.bzl", "envoy_api_binding") - -envoy_api_binding() - -load("@envoy//bazel:api_repositories.bzl", "envoy_api_dependencies") - -envoy_api_dependencies() - -load("@envoy//bazel:repositories.bzl", "envoy_dependencies") - -envoy_dependencies() - -load("@envoy//bazel:bazel_deps.bzl", "envoy_bazel_dependencies") - -envoy_bazel_dependencies() - -load("@envoy//bazel:repositories_extra.bzl", "envoy_dependencies_extra") - -envoy_dependencies_extra() - -load("@envoy//bazel:python_dependencies.bzl", "envoy_python_dependencies") - -envoy_python_dependencies() - -load("@bazel_gazelle//:deps.bzl", "go_repository") -load("@envoy//bazel:dependency_imports.bzl", "envoy_dependency_imports") - -go_repository( - name = "org_golang_x_text", - build_external = "external", - importpath = "golang.org/x/text", - sum = "h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=", - version = "v0.33.0", -) - -go_repository( - name = "org_golang_x_tools", - build_external = "external", - importpath = "golang.org/x/tools", - sum = "h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=", - version = "v0.41.0", -) - -go_repository( - name = "org_golang_x_net", - build_external = "external", - importpath = "golang.org/x/net", - sum = "h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=", - version = "v0.49.0", -) - -go_repository( - name = "org_golang_x_sys", - build_external = "external", - importpath = "golang.org/x/sys", - sum = "h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=", - version = "v0.42.0", -) - -go_repository( - name = "org_golang_x_mod", - build_external = "external", - importpath = "golang.org/x/mod", - sum = "h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=", - version = "v0.32.0", -) - -# rules_rust hashes the crate manifest label into the crate_universe lockfile, so -# Envoy's own Cargo.Bazel.lock never matches when Envoy is embedded as @envoy. -# Point the crate index at a Cilium-owned lockfile instead. Refresh it with -# `make cargo-repin` whenever Envoy changes its Rust dependencies. -envoy_dependency_imports( - cargo_bazel_lockfile = "@//bazel:envoy_dynamic_modules_rust_sdk.Cargo.Bazel.lock", -) - -load("@envoy//bazel:repo.bzl", "envoy_repo") - -envoy_repo() - -# Pre-create @llvm_toolchain_llvm from the local LLVM (BAZEL_LLVM_PATH) BEFORE -# envoy_toolchains(). envoy_toolchains() (and toolchains_llvm's llvm_toolchain()) -# only create @llvm_toolchain_llvm when it does not already exist, and the repo -# envoy would create lacks the //:clang-format target that the format check needs. -# Providing a complete repo here makes both compilation and the format check work. -load("//bazel:local_llvm.bzl", "local_llvm_repo") - -local_llvm_repo(name = "llvm_toolchain_llvm") - -load("@envoy//bazel:toolchains.bzl", "envoy_toolchains") - -envoy_toolchains() - -load("@envoy//bazel:dependency_imports_extra.bzl", "envoy_dependency_imports_extra") - -envoy_dependency_imports_extra() diff --git a/bazel/BUILD b/bazel/BUILD index 969fc1995..0a693023c 100644 --- a/bazel/BUILD +++ b/bazel/BUILD @@ -1,18 +1,6 @@ -constraint_setting( - name = "cilium_target_platform", - visibility = ["//visibility:public"], -) - -constraint_value( - name = "cilium_target_platform_enabled", - constraint_setting = ":cilium_target_platform", - visibility = ["//visibility:public"], -) - platform( name = "linux_aarch64", constraint_values = [ - ":cilium_target_platform_enabled", "@platforms//cpu:aarch64", "@platforms//os:linux", ], @@ -21,10 +9,7 @@ platform( platform( name = "linux_x86_64", constraint_values = [ - ":cilium_target_platform_enabled", "@platforms//cpu:x86_64", "@platforms//os:linux", ], ) - -exports_files(["envoy_dynamic_modules_rust_sdk.Cargo.Bazel.lock"]) diff --git a/bazel/envoy_dynamic_modules_rust_sdk.Cargo.Bazel.lock b/bazel/envoy_dynamic_modules_rust_sdk.Cargo.Bazel.lock deleted file mode 100644 index b94a9991e..000000000 --- a/bazel/envoy_dynamic_modules_rust_sdk.Cargo.Bazel.lock +++ /dev/null @@ -1,13076 +0,0 @@ -{ - "checksum": "ab1bf27b6172ab6ff094cc63e1db922d26015dc64095d0fb29443ca48168cf20", - "crates": { - "aho-corasick 1.1.4": { - "name": "aho-corasick", - "version": "1.1.4", - "package_url": "https://github.com/BurntSushi/aho-corasick", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/aho-corasick/1.1.4/download", - "sha256": "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" - } - }, - "targets": [ - { - "Library": { - "crate_name": "aho_corasick", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "aho_corasick", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "1.1.4" - }, - "license": "Unlicense OR MIT", - "license_ids": [ - "MIT", - "Unlicense" - ], - "license_file": "LICENSE-MIT" - }, - "anstyle 1.0.14": { - "name": "anstyle", - "version": "1.0.14", - "package_url": "https://github.com/rust-cli/anstyle.git", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/anstyle/1.0.14/download", - "sha256": "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" - } - }, - "targets": [ - { - "Library": { - "crate_name": "anstyle", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "anstyle", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "edition": "2021", - "version": "1.0.14" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "anyhow 1.0.102": { - "name": "anyhow", - "version": "1.0.102", - "package_url": "https://github.com/dtolnay/anyhow", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/anyhow/1.0.102/download", - "sha256": "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" - } - }, - "targets": [ - { - "Library": { - "crate_name": "anyhow", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "anyhow", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "anyhow 1.0.102", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.0.102" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "async-trait 0.1.89": { - "name": "async-trait", - "version": "0.1.89", - "package_url": "https://github.com/dtolnay/async-trait", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/async-trait/0.1.89/download", - "sha256": "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "async_trait", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "async_trait", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.1.89" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "atomic-waker 1.1.2": { - "name": "atomic-waker", - "version": "1.1.2", - "package_url": "https://github.com/smol-rs/atomic-waker", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/atomic-waker/1.1.2/download", - "sha256": "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - } - }, - "targets": [ - { - "Library": { - "crate_name": "atomic_waker", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "atomic_waker", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2018", - "version": "1.1.2" - }, - "license": "Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "autocfg 1.5.0": { - "name": "autocfg", - "version": "1.5.0", - "package_url": "https://github.com/cuviper/autocfg", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/autocfg/1.5.0/download", - "sha256": "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - } - }, - "targets": [ - { - "Library": { - "crate_name": "autocfg", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "autocfg", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2015", - "version": "1.5.0" - }, - "license": "Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "bindgen 0.70.1": { - "name": "bindgen", - "version": "0.70.1", - "package_url": "https://github.com/rust-lang/rust-bindgen", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/bindgen/0.70.1/download", - "sha256": "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" - } - }, - "targets": [ - { - "Library": { - "crate_name": "bindgen", - "crate_root": "lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "bindgen", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "logging", - "prettyplease", - "runtime" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "bindgen 0.70.1", - "target": "build_script_build" - }, - { - "id": "bitflags 2.11.0", - "target": "bitflags" - }, - { - "id": "cexpr 0.6.0", - "target": "cexpr" - }, - { - "id": "clang-sys 1.8.1", - "target": "clang_sys" - }, - { - "id": "itertools 0.13.0", - "target": "itertools" - }, - { - "id": "log 0.4.29", - "target": "log" - }, - { - "id": "prettyplease 0.2.37", - "target": "prettyplease" - }, - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "regex 1.12.3", - "target": "regex" - }, - { - "id": "rustc-hash 1.1.0", - "target": "rustc_hash" - }, - { - "id": "shlex 1.3.0", - "target": "shlex" - }, - { - "id": "syn 2.0.117", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.70.1" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ], - "link_deps": { - "common": [ - { - "id": "clang-sys 1.8.1", - "target": "clang_sys" - }, - { - "id": "prettyplease 0.2.37", - "target": "prettyplease" - } - ], - "selects": {} - } - }, - "license": "BSD-3-Clause", - "license_ids": [ - "BSD-3-Clause" - ], - "license_file": "LICENSE" - }, - "bitflags 2.11.0": { - "name": "bitflags", - "version": "2.11.0", - "package_url": "https://github.com/bitflags/bitflags", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/bitflags/2.11.0/download", - "sha256": "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" - } - }, - "targets": [ - { - "Library": { - "crate_name": "bitflags", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "bitflags", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "2.11.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "bumpalo 3.20.2": { - "name": "bumpalo", - "version": "3.20.2", - "package_url": "https://github.com/fitzgen/bumpalo", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/bumpalo/3.20.2/download", - "sha256": "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" - } - }, - "targets": [ - { - "Library": { - "crate_name": "bumpalo", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "bumpalo", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default" - ], - "selects": {} - }, - "edition": "2021", - "version": "3.20.2" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "bytes 1.11.1": { - "name": "bytes", - "version": "1.11.1", - "package_url": "https://github.com/tokio-rs/bytes", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/bytes/1.11.1/download", - "sha256": "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" - } - }, - "targets": [ - { - "Library": { - "crate_name": "bytes", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "bytes", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "edition": "2021", - "version": "1.11.1" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "cc 1.2.57": { - "name": "cc", - "version": "1.2.57", - "package_url": "https://github.com/rust-lang/cc-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/cc/1.2.57/download", - "sha256": "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" - } - }, - "targets": [ - { - "Library": { - "crate_name": "cc", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "cc", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "find-msvc-tools 0.1.9", - "target": "find_msvc_tools" - }, - { - "id": "shlex 1.3.0", - "target": "shlex" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "1.2.57" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "cexpr 0.6.0": { - "name": "cexpr", - "version": "0.6.0", - "package_url": "https://github.com/jethrogb/rust-cexpr", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/cexpr/0.6.0/download", - "sha256": "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" - } - }, - "targets": [ - { - "Library": { - "crate_name": "cexpr", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "cexpr", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "nom 7.1.3", - "target": "nom" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.6.0" - }, - "license": "Apache-2.0/MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "cfg-if 1.0.4": { - "name": "cfg-if", - "version": "1.0.4", - "package_url": "https://github.com/rust-lang/cfg-if", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/cfg-if/1.0.4/download", - "sha256": "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - } - }, - "targets": [ - { - "Library": { - "crate_name": "cfg_if", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "cfg_if", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2018", - "version": "1.0.4" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "chacha20 0.10.0": { - "name": "chacha20", - "version": "0.10.0", - "package_url": "https://github.com/RustCrypto/stream-ciphers", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/chacha20/0.10.0/download", - "sha256": "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" - } - }, - "targets": [ - { - "Library": { - "crate_name": "chacha20", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "chacha20", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "rng" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "cfg-if 1.0.4", - "target": "cfg_if" - }, - { - "id": "rand_core 0.10.1", - "target": "rand_core" - } - ], - "selects": { - "cfg(any(target_arch = \"x86_64\", target_arch = \"x86\"))": [ - { - "id": "cpufeatures 0.3.0", - "target": "cpufeatures" - } - ] - } - }, - "edition": "2024", - "version": "0.10.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "clang-sys 1.8.1": { - "name": "clang-sys", - "version": "1.8.1", - "package_url": "https://github.com/KyleMayes/clang-sys", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/clang-sys/1.8.1/download", - "sha256": "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" - } - }, - "targets": [ - { - "Library": { - "crate_name": "clang_sys", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "clang_sys", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "clang_3_5", - "clang_3_6", - "clang_3_7", - "clang_3_8", - "clang_3_9", - "clang_4_0", - "clang_5_0", - "clang_6_0", - "libloading", - "runtime" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "clang-sys 1.8.1", - "target": "build_script_build" - }, - { - "id": "glob 0.3.3", - "target": "glob" - }, - { - "id": "libc 0.2.183", - "target": "libc" - }, - { - "id": "libloading 0.8.9", - "target": "libloading" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.8.1" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "glob 0.3.3", - "target": "glob" - } - ], - "selects": {} - }, - "links": "clang" - }, - "license": "Apache-2.0", - "license_ids": [ - "Apache-2.0" - ], - "license_file": "LICENSE.txt" - }, - "combine 4.6.7": { - "name": "combine", - "version": "4.6.7", - "package_url": "https://github.com/Marwes/combine", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/combine/4.6.7/download", - "sha256": "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" - } - }, - "targets": [ - { - "Library": { - "crate_name": "combine", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "combine", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "memchr 2.8.0", - "target": "memchr" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "4.6.7" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "core-foundation 0.9.4": { - "name": "core-foundation", - "version": "0.9.4", - "package_url": "https://github.com/servo/core-foundation-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/core-foundation/0.9.4/download", - "sha256": "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" - } - }, - "targets": [ - { - "Library": { - "crate_name": "core_foundation", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "core_foundation", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "link" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "core-foundation-sys 0.8.7", - "target": "core_foundation_sys" - }, - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.9.4" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "core-foundation-sys 0.8.7": { - "name": "core-foundation-sys", - "version": "0.8.7", - "package_url": "https://github.com/servo/core-foundation-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/core-foundation-sys/0.8.7/download", - "sha256": "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - } - }, - "targets": [ - { - "Library": { - "crate_name": "core_foundation_sys", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "core_foundation_sys", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "link" - ], - "selects": {} - }, - "edition": "2018", - "version": "0.8.7" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "cpufeatures 0.3.0": { - "name": "cpufeatures", - "version": "0.3.0", - "package_url": "https://github.com/RustCrypto/utils", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/cpufeatures/0.3.0/download", - "sha256": "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" - } - }, - "targets": [ - { - "Library": { - "crate_name": "cpufeatures", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "cpufeatures", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [], - "selects": { - "cfg(all(target_arch = \"aarch64\", target_os = \"android\"))": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(all(target_arch = \"aarch64\", target_os = \"linux\"))": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(all(target_arch = \"aarch64\", target_vendor = \"apple\"))": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(all(target_arch = \"loongarch64\", target_os = \"linux\"))": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ] - } - }, - "edition": "2024", - "version": "0.3.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "critical-section 1.2.0": { - "name": "critical-section", - "version": "1.2.0", - "package_url": "https://github.com/rust-embedded/critical-section", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/critical-section/1.2.0/download", - "sha256": "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" - } - }, - "targets": [ - { - "Library": { - "crate_name": "critical_section", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "critical_section", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2018", - "version": "1.2.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "crossbeam-channel 0.5.15": { - "name": "crossbeam-channel", - "version": "0.5.15", - "package_url": "https://github.com/crossbeam-rs/crossbeam", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/crossbeam-channel/0.5.15/download", - "sha256": "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" - } - }, - "targets": [ - { - "Library": { - "crate_name": "crossbeam_channel", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "crossbeam_channel", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "crossbeam-utils 0.8.21", - "target": "crossbeam_utils" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.5.15" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "crossbeam-epoch 0.9.18": { - "name": "crossbeam-epoch", - "version": "0.9.18", - "package_url": "https://github.com/crossbeam-rs/crossbeam", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/crossbeam-epoch/0.9.18/download", - "sha256": "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" - } - }, - "targets": [ - { - "Library": { - "crate_name": "crossbeam_epoch", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "crossbeam_epoch", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "default", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "crossbeam-utils 0.8.21", - "target": "crossbeam_utils" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.9.18" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "crossbeam-utils 0.8.21": { - "name": "crossbeam-utils", - "version": "0.8.21", - "package_url": "https://github.com/crossbeam-rs/crossbeam", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/crossbeam-utils/0.8.21/download", - "sha256": "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - } - }, - "targets": [ - { - "Library": { - "crate_name": "crossbeam_utils", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "crossbeam_utils", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "crossbeam-utils 0.8.21", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.8.21" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "data-encoding 2.10.0": { - "name": "data-encoding", - "version": "2.10.0", - "package_url": "https://github.com/ia0/data-encoding", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/data-encoding/2.10.0/download", - "sha256": "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" - } - }, - "targets": [ - { - "Library": { - "crate_name": "data_encoding", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "data_encoding", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "std" - ], - "selects": {} - }, - "edition": "2018", - "version": "2.10.0" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "deranged 0.5.8": { - "name": "deranged", - "version": "0.5.8", - "package_url": "https://github.com/jhpratt/deranged", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/deranged/0.5.8/download", - "sha256": "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" - } - }, - "targets": [ - { - "Library": { - "crate_name": "deranged", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "deranged", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "powerfmt" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "powerfmt 0.2.0", - "target": "powerfmt" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.5.8" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-Apache" - }, - "displaydoc 0.2.5": { - "name": "displaydoc", - "version": "0.2.5", - "package_url": "https://github.com/yaahc/displaydoc", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/displaydoc/0.2.5/download", - "sha256": "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "displaydoc", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "displaydoc", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.2.5" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "downcast 0.11.0": { - "name": "downcast", - "version": "0.11.0", - "package_url": "https://github.com/fkoep/downcast-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/downcast/0.11.0/download", - "sha256": "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" - } - }, - "targets": [ - { - "Library": { - "crate_name": "downcast", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "downcast", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "edition": "2018", - "version": "0.11.0" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE-MIT" - }, - "either 1.15.0": { - "name": "either", - "version": "1.15.0", - "package_url": "https://github.com/rayon-rs/either", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/either/1.15.0/download", - "sha256": "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - } - }, - "targets": [ - { - "Library": { - "crate_name": "either", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "either", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "edition": "2021", - "version": "1.15.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "envoy-dynamic-modules-builtin-extensions 0.1.0": { - "name": "envoy-dynamic-modules-builtin-extensions", - "version": "0.1.0", - "package_url": "https://github.com/envoyproxy/envoy", - "repository": null, - "targets": [], - "library_target_name": null, - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "hickory-resolver 0.26.1", - "target": "hickory_resolver" - }, - { - "id": "serde 1.0.228", - "target": "serde" - }, - { - "id": "serde_json 1.0.149", - "target": "serde_json" - }, - { - "id": "time 0.3.47", - "target": "time" - }, - { - "id": "tokio 1.50.0", - "target": "tokio" - }, - { - "id": "url 2.5.8", - "target": "url" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.1.0" - }, - "license": "Apache-2.0", - "license_ids": [ - "Apache-2.0" - ], - "license_file": null - }, - "envoy-proxy-dynamic-modules-rust-sdk 0.1.0": { - "name": "envoy-proxy-dynamic-modules-rust-sdk", - "version": "0.1.0", - "package_url": "https://github.com/envoyproxy/envoy", - "repository": null, - "targets": [ - { - "Library": { - "crate_name": "envoy_proxy_dynamic_modules_rust_sdk", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "envoy_proxy_dynamic_modules_rust_sdk", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "envoy-proxy-dynamic-modules-rust-sdk 0.1.0", - "target": "build_script_build" - }, - { - "id": "mockall 0.13.1", - "target": "mockall" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.1.0" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "bindgen 0.70.1", - "target": "bindgen" - } - ], - "selects": {} - } - }, - "license": "Apache-2.0", - "license_ids": [ - "Apache-2.0" - ], - "license_file": null - }, - "equivalent 1.0.2": { - "name": "equivalent", - "version": "1.0.2", - "package_url": "https://github.com/indexmap-rs/equivalent", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/equivalent/1.0.2/download", - "sha256": "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - } - }, - "targets": [ - { - "Library": { - "crate_name": "equivalent", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "equivalent", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2015", - "version": "1.0.2" - }, - "license": "Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "find-msvc-tools 0.1.9": { - "name": "find-msvc-tools", - "version": "0.1.9", - "package_url": "https://github.com/rust-lang/cc-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/find-msvc-tools/0.1.9/download", - "sha256": "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - } - }, - "targets": [ - { - "Library": { - "crate_name": "find_msvc_tools", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "find_msvc_tools", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2018", - "version": "0.1.9" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "fnv 1.0.7": { - "name": "fnv", - "version": "1.0.7", - "package_url": "https://github.com/servo/rust-fnv", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/fnv/1.0.7/download", - "sha256": "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - } - }, - "targets": [ - { - "Library": { - "crate_name": "fnv", - "crate_root": "lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "fnv", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "edition": "2015", - "version": "1.0.7" - }, - "license": "Apache-2.0 / MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "foldhash 0.1.5": { - "name": "foldhash", - "version": "0.1.5", - "package_url": "https://github.com/orlp/foldhash", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/foldhash/0.1.5/download", - "sha256": "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - } - }, - "targets": [ - { - "Library": { - "crate_name": "foldhash", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "foldhash", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "0.1.5" - }, - "license": "Zlib", - "license_ids": [ - "Zlib" - ], - "license_file": "LICENSE" - }, - "form_urlencoded 1.2.2": { - "name": "form_urlencoded", - "version": "1.2.2", - "package_url": "https://github.com/servo/rust-url", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/form_urlencoded/1.2.2/download", - "sha256": "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" - } - }, - "targets": [ - { - "Library": { - "crate_name": "form_urlencoded", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "form_urlencoded", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "percent-encoding 2.3.2", - "target": "percent_encoding" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "1.2.2" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "fragile 2.0.1": { - "name": "fragile", - "version": "2.0.1", - "package_url": "https://github.com/mitsuhiko/fragile", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/fragile/2.0.1/download", - "sha256": "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" - } - }, - "targets": [ - { - "Library": { - "crate_name": "fragile", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "fragile", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2018", - "version": "2.0.1" - }, - "license": "Apache-2.0", - "license_ids": [ - "Apache-2.0" - ], - "license_file": "LICENSE" - }, - "futures-channel 0.3.32": { - "name": "futures-channel", - "version": "0.3.32", - "package_url": "https://github.com/rust-lang/futures-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/futures-channel/0.3.32/download", - "sha256": "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" - } - }, - "targets": [ - { - "Library": { - "crate_name": "futures_channel", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "futures_channel", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "futures-core 0.3.32", - "target": "futures_core" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.3.32" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "futures-core 0.3.32": { - "name": "futures-core", - "version": "0.3.32", - "package_url": "https://github.com/rust-lang/futures-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/futures-core/0.3.32/download", - "sha256": "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" - } - }, - "targets": [ - { - "Library": { - "crate_name": "futures_core", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "futures_core", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "default", - "std" - ], - "selects": {} - }, - "edition": "2018", - "version": "0.3.32" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "futures-io 0.3.32": { - "name": "futures-io", - "version": "0.3.32", - "package_url": "https://github.com/rust-lang/futures-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/futures-io/0.3.32/download", - "sha256": "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" - } - }, - "targets": [ - { - "Library": { - "crate_name": "futures_io", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "futures_io", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "std" - ], - "selects": {} - }, - "edition": "2018", - "version": "0.3.32" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "futures-macro 0.3.32": { - "name": "futures-macro", - "version": "0.3.32", - "package_url": "https://github.com/rust-lang/futures-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/futures-macro/0.3.32/download", - "sha256": "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "futures_macro", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "futures_macro", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.3.32" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "futures-sink 0.3.32": { - "name": "futures-sink", - "version": "0.3.32", - "package_url": "https://github.com/rust-lang/futures-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/futures-sink/0.3.32/download", - "sha256": "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" - } - }, - "targets": [ - { - "Library": { - "crate_name": "futures_sink", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "futures_sink", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "default", - "std" - ], - "selects": {} - }, - "edition": "2018", - "version": "0.3.32" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "futures-task 0.3.32": { - "name": "futures-task", - "version": "0.3.32", - "package_url": "https://github.com/rust-lang/futures-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/futures-task/0.3.32/download", - "sha256": "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" - } - }, - "targets": [ - { - "Library": { - "crate_name": "futures_task", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "futures_task", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "std" - ], - "selects": {} - }, - "edition": "2018", - "version": "0.3.32" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "futures-util 0.3.32": { - "name": "futures-util", - "version": "0.3.32", - "package_url": "https://github.com/rust-lang/futures-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/futures-util/0.3.32/download", - "sha256": "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" - } - }, - "targets": [ - { - "Library": { - "crate_name": "futures_util", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "futures_util", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "async-await", - "async-await-macro", - "futures-macro", - "slab", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "futures-core 0.3.32", - "target": "futures_core" - }, - { - "id": "futures-task 0.3.32", - "target": "futures_task" - }, - { - "id": "pin-project-lite 0.2.17", - "target": "pin_project_lite" - }, - { - "id": "slab 0.4.12", - "target": "slab" - } - ], - "selects": {} - }, - "edition": "2018", - "proc_macro_deps": { - "common": [ - { - "id": "futures-macro 0.3.32", - "target": "futures_macro" - } - ], - "selects": {} - }, - "version": "0.3.32" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "getrandom 0.2.17": { - "name": "getrandom", - "version": "0.2.17", - "package_url": "https://github.com/rust-random/getrandom", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/getrandom/0.2.17/download", - "sha256": "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" - } - }, - "targets": [ - { - "Library": { - "crate_name": "getrandom", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "getrandom", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "cfg-if 1.0.4", - "target": "cfg_if" - } - ], - "selects": { - "cfg(target_os = \"wasi\")": [ - { - "id": "wasi 0.11.1+wasi-snapshot-preview1", - "target": "wasi" - } - ], - "cfg(unix)": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ] - } - }, - "edition": "2018", - "version": "0.2.17" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "getrandom 0.4.2": { - "name": "getrandom", - "version": "0.4.2", - "package_url": "https://github.com/rust-random/getrandom", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/getrandom/0.4.2/download", - "sha256": "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" - } - }, - "targets": [ - { - "Library": { - "crate_name": "getrandom", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "getrandom", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "std", - "sys_rng" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "cfg-if 1.0.4", - "target": "cfg_if" - }, - { - "id": "getrandom 0.4.2", - "target": "build_script_build" - }, - { - "id": "rand_core 0.10.1", - "target": "rand_core" - } - ], - "selects": { - "cfg(all(any(target_os = \"linux\", target_os = \"android\"), not(any(all(target_os = \"linux\", target_env = \"\"), getrandom_backend = \"custom\", getrandom_backend = \"linux_raw\", getrandom_backend = \"rdrand\", getrandom_backend = \"rndr\"))))": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(all(target_arch = \"wasm32\", target_os = \"wasi\", target_env = \"p2\"))": [ - { - "id": "wasip2 1.0.2+wasi-0.2.9", - "target": "wasip2" - } - ], - "cfg(all(target_arch = \"wasm32\", target_os = \"wasi\", target_env = \"p3\"))": [ - { - "id": "wasip3 0.4.0+wasi-0.3.0-rc-2026-01-06", - "target": "wasip3" - } - ], - "cfg(all(target_os = \"uefi\", getrandom_backend = \"efi_rng\"))": [ - { - "id": "r-efi 6.0.0", - "target": "r_efi" - } - ], - "cfg(any(target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"hurd\", target_os = \"illumos\", target_os = \"cygwin\", all(target_os = \"horizon\", target_arch = \"arm\")))": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(any(target_os = \"haiku\", target_os = \"redox\", target_os = \"nto\", target_os = \"aix\"))": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(any(target_os = \"ios\", target_os = \"visionos\", target_os = \"watchos\", target_os = \"tvos\"))": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(any(target_os = \"macos\", target_os = \"openbsd\", target_os = \"vita\", target_os = \"emscripten\"))": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(target_os = \"netbsd\")": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(target_os = \"solaris\")": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(target_os = \"vxworks\")": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ] - } - }, - "edition": "2024", - "version": "0.4.2" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "glob 0.3.3": { - "name": "glob", - "version": "0.3.3", - "package_url": "https://github.com/rust-lang/glob", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/glob/0.3.3/download", - "sha256": "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - } - }, - "targets": [ - { - "Library": { - "crate_name": "glob", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "glob", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2015", - "version": "0.3.3" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "h2 0.4.13": { - "name": "h2", - "version": "0.4.13", - "package_url": "https://github.com/hyperium/h2", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/h2/0.4.13/download", - "sha256": "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" - } - }, - "targets": [ - { - "Library": { - "crate_name": "h2", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "h2", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "stream" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "atomic-waker 1.1.2", - "target": "atomic_waker" - }, - { - "id": "bytes 1.11.1", - "target": "bytes" - }, - { - "id": "fnv 1.0.7", - "target": "fnv" - }, - { - "id": "futures-core 0.3.32", - "target": "futures_core" - }, - { - "id": "futures-sink 0.3.32", - "target": "futures_sink" - }, - { - "id": "http 1.4.0", - "target": "http" - }, - { - "id": "indexmap 2.13.0", - "target": "indexmap" - }, - { - "id": "slab 0.4.12", - "target": "slab" - }, - { - "id": "tokio 1.50.0", - "target": "tokio" - }, - { - "id": "tokio-util 0.7.18", - "target": "tokio_util" - }, - { - "id": "tracing 0.1.44", - "target": "tracing" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.4.13" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "hashbrown 0.15.5": { - "name": "hashbrown", - "version": "0.15.5", - "package_url": "https://github.com/rust-lang/hashbrown", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/hashbrown/0.15.5/download", - "sha256": "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" - } - }, - "targets": [ - { - "Library": { - "crate_name": "hashbrown", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "hashbrown", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default-hasher" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "foldhash 0.1.5", - "target": "foldhash" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.15.5" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "hashbrown 0.16.1": { - "name": "hashbrown", - "version": "0.16.1", - "package_url": "https://github.com/rust-lang/hashbrown", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/hashbrown/0.16.1/download", - "sha256": "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" - } - }, - "targets": [ - { - "Library": { - "crate_name": "hashbrown", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "hashbrown", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "0.16.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "heck 0.5.0": { - "name": "heck", - "version": "0.5.0", - "package_url": "https://github.com/withoutboats/heck", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/heck/0.5.0/download", - "sha256": "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - } - }, - "targets": [ - { - "Library": { - "crate_name": "heck", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "heck", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "0.5.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "hickory-net 0.26.1": { - "name": "hickory-net", - "version": "0.26.1", - "package_url": "https://github.com/hickory-dns/hickory-dns", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/hickory-net/0.26.1/download", - "sha256": "e2295ed2f9c31e471e1428a8f88a3f0e1f4b27c15049592138d1eebe9c35b183" - } - }, - "targets": [ - { - "Library": { - "crate_name": "hickory_net", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "hickory_net", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "__dnssec", - "__https", - "__tls", - "dnssec-ring", - "https-ring", - "tls-ring", - "tokio", - "webpki-roots" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "bitflags 2.11.0", - "target": "bitflags" - }, - { - "id": "bytes 1.11.1", - "target": "bytes" - }, - { - "id": "cfg-if 1.0.4", - "target": "cfg_if" - }, - { - "id": "data-encoding 2.10.0", - "target": "data_encoding" - }, - { - "id": "futures-channel 0.3.32", - "target": "futures_channel" - }, - { - "id": "futures-io 0.3.32", - "target": "futures_io" - }, - { - "id": "futures-util 0.3.32", - "target": "futures_util" - }, - { - "id": "h2 0.4.13", - "target": "h2" - }, - { - "id": "hickory-proto 0.26.1", - "target": "hickory_proto" - }, - { - "id": "http 1.4.0", - "target": "http" - }, - { - "id": "idna 1.1.0", - "target": "idna" - }, - { - "id": "ipnet 2.12.0", - "target": "ipnet" - }, - { - "id": "lru-cache 0.1.2", - "target": "lru_cache" - }, - { - "id": "parking_lot 0.12.5", - "target": "parking_lot" - }, - { - "id": "rand 0.10.1", - "target": "rand" - }, - { - "id": "ring 0.17.14", - "target": "ring" - }, - { - "id": "rustls 0.23.37", - "target": "rustls" - }, - { - "id": "rustls-pki-types 1.14.0", - "target": "rustls_pki_types" - }, - { - "id": "thiserror 2.0.18", - "target": "thiserror" - }, - { - "id": "time 0.3.47", - "target": "time" - }, - { - "id": "tinyvec 1.11.0", - "target": "tinyvec" - }, - { - "id": "tokio 1.50.0", - "target": "tokio" - }, - { - "id": "tokio-rustls 0.26.4", - "target": "tokio_rustls" - }, - { - "id": "tracing 0.1.44", - "target": "tracing" - }, - { - "id": "url 2.5.8", - "target": "url" - }, - { - "id": "webpki-roots 1.0.6", - "target": "webpki_roots" - } - ], - "selects": { - "cfg(target_os = \"android\")": [ - { - "id": "jni 0.22.4", - "target": "jni" - } - ] - } - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "async-trait 0.1.89", - "target": "async_trait" - } - ], - "selects": {} - }, - "version": "0.26.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "hickory-proto 0.26.1": { - "name": "hickory-proto", - "version": "0.26.1", - "package_url": "https://github.com/hickory-dns/hickory-dns", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/hickory-proto/0.26.1/download", - "sha256": "0bab31817bfb44672a252e97fe81cd0c18d1b2cf892108922f6818820df8c643" - } - }, - "targets": [ - { - "Library": { - "crate_name": "hickory_proto", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "hickory_proto", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "__dnssec", - "access-control", - "dnssec-ring", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "bitflags 2.11.0", - "target": "bitflags" - }, - { - "id": "data-encoding 2.10.0", - "target": "data_encoding" - }, - { - "id": "idna 1.1.0", - "target": "idna" - }, - { - "id": "ipnet 2.12.0", - "target": "ipnet" - }, - { - "id": "once_cell 1.21.4", - "target": "once_cell" - }, - { - "id": "prefix-trie 0.8.3", - "target": "prefix_trie" - }, - { - "id": "rand 0.10.1", - "target": "rand" - }, - { - "id": "ring 0.17.14", - "target": "ring" - }, - { - "id": "rustls-pki-types 1.14.0", - "target": "rustls_pki_types" - }, - { - "id": "thiserror 2.0.18", - "target": "thiserror" - }, - { - "id": "time 0.3.47", - "target": "time" - }, - { - "id": "tinyvec 1.11.0", - "target": "tinyvec" - }, - { - "id": "tracing 0.1.44", - "target": "tracing" - }, - { - "id": "url 2.5.8", - "target": "url" - } - ], - "selects": { - "cfg(target_os = \"android\")": [ - { - "id": "jni 0.22.4", - "target": "jni" - } - ] - } - }, - "edition": "2021", - "version": "0.26.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "hickory-resolver 0.26.1": { - "name": "hickory-resolver", - "version": "0.26.1", - "package_url": "https://github.com/hickory-dns/hickory-dns", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/hickory-resolver/0.26.1/download", - "sha256": "f0d58d28879ceecde6607729660c2667a081ccdc082e082675042793960f178c" - } - }, - "targets": [ - { - "Library": { - "crate_name": "hickory_resolver", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "hickory_resolver", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "__dnssec", - "__https", - "__tls", - "default", - "dnssec-ring", - "https-ring", - "system-config", - "tls-ring", - "tokio", - "webpki-roots" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "cfg-if 1.0.4", - "target": "cfg_if" - }, - { - "id": "futures-util 0.3.32", - "target": "futures_util" - }, - { - "id": "hickory-net 0.26.1", - "target": "hickory_net" - }, - { - "id": "hickory-proto 0.26.1", - "target": "hickory_proto" - }, - { - "id": "ipnet 2.12.0", - "target": "ipnet" - }, - { - "id": "moka 0.12.15", - "target": "moka" - }, - { - "id": "once_cell 1.21.4", - "target": "once_cell" - }, - { - "id": "parking_lot 0.12.5", - "target": "parking_lot" - }, - { - "id": "rand 0.10.1", - "target": "rand" - }, - { - "id": "resolv-conf 0.7.6", - "target": "resolv_conf" - }, - { - "id": "rustls 0.23.37", - "target": "rustls" - }, - { - "id": "smallvec 1.15.1", - "target": "smallvec" - }, - { - "id": "thiserror 2.0.18", - "target": "thiserror" - }, - { - "id": "tokio 1.50.0", - "target": "tokio" - }, - { - "id": "tokio-rustls 0.26.4", - "target": "tokio_rustls" - }, - { - "id": "tracing 0.1.44", - "target": "tracing" - }, - { - "id": "webpki-roots 1.0.6", - "target": "webpki_roots" - } - ], - "selects": { - "aarch64-apple-darwin": [ - { - "id": "system-configuration 0.7.0", - "target": "system_configuration" - } - ], - "x86_64-pc-windows-msvc": [ - { - "id": "ipconfig 0.3.4", - "target": "ipconfig" - } - ] - } - }, - "edition": "2021", - "version": "0.26.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "http 1.4.0": { - "name": "http", - "version": "1.4.0", - "package_url": "https://github.com/hyperium/http", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/http/1.4.0/download", - "sha256": "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" - } - }, - "targets": [ - { - "Library": { - "crate_name": "http", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "http", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "bytes 1.11.1", - "target": "bytes" - }, - { - "id": "itoa 1.0.18", - "target": "itoa" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.4.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "icu_collections 2.1.1": { - "name": "icu_collections", - "version": "2.1.1", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/icu_collections/2.1.1/download", - "sha256": "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" - } - }, - "targets": [ - { - "Library": { - "crate_name": "icu_collections", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "icu_collections", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "potential_utf 0.1.4", - "target": "potential_utf" - }, - { - "id": "yoke 0.8.1", - "target": "yoke" - }, - { - "id": "zerofrom 0.1.6", - "target": "zerofrom" - }, - { - "id": "zerovec 0.11.5", - "target": "zerovec" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "displaydoc 0.2.5", - "target": "displaydoc" - } - ], - "selects": {} - }, - "version": "2.1.1" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "icu_locale_core 2.1.1": { - "name": "icu_locale_core", - "version": "2.1.1", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/icu_locale_core/2.1.1/download", - "sha256": "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" - } - }, - "targets": [ - { - "Library": { - "crate_name": "icu_locale_core", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "icu_locale_core", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "zerovec" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "litemap 0.8.1", - "target": "litemap" - }, - { - "id": "tinystr 0.8.2", - "target": "tinystr" - }, - { - "id": "writeable 0.6.2", - "target": "writeable" - }, - { - "id": "zerovec 0.11.5", - "target": "zerovec" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "displaydoc 0.2.5", - "target": "displaydoc" - } - ], - "selects": {} - }, - "version": "2.1.1" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "icu_normalizer 2.1.1": { - "name": "icu_normalizer", - "version": "2.1.1", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/icu_normalizer/2.1.1/download", - "sha256": "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" - } - }, - "targets": [ - { - "Library": { - "crate_name": "icu_normalizer", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "icu_normalizer", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "compiled_data" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "icu_collections 2.1.1", - "target": "icu_collections" - }, - { - "id": "icu_normalizer_data 2.1.1", - "target": "icu_normalizer_data" - }, - { - "id": "icu_provider 2.1.1", - "target": "icu_provider" - }, - { - "id": "smallvec 1.15.1", - "target": "smallvec" - }, - { - "id": "zerovec 0.11.5", - "target": "zerovec" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "2.1.1" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "icu_normalizer_data 2.1.1": { - "name": "icu_normalizer_data", - "version": "2.1.1", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/icu_normalizer_data/2.1.1/download", - "sha256": "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" - } - }, - "targets": [ - { - "Library": { - "crate_name": "icu_normalizer_data", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "icu_normalizer_data", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "icu_normalizer_data 2.1.1", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "2.1.1" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "icu_properties 2.1.2": { - "name": "icu_properties", - "version": "2.1.2", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/icu_properties/2.1.2/download", - "sha256": "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" - } - }, - "targets": [ - { - "Library": { - "crate_name": "icu_properties", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "icu_properties", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "compiled_data" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "icu_collections 2.1.1", - "target": "icu_collections" - }, - { - "id": "icu_locale_core 2.1.1", - "target": "icu_locale_core" - }, - { - "id": "icu_properties_data 2.1.2", - "target": "icu_properties_data" - }, - { - "id": "icu_provider 2.1.1", - "target": "icu_provider" - }, - { - "id": "zerotrie 0.2.3", - "target": "zerotrie" - }, - { - "id": "zerovec 0.11.5", - "target": "zerovec" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "2.1.2" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "icu_properties_data 2.1.2": { - "name": "icu_properties_data", - "version": "2.1.2", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/icu_properties_data/2.1.2/download", - "sha256": "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" - } - }, - "targets": [ - { - "Library": { - "crate_name": "icu_properties_data", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "icu_properties_data", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "icu_properties_data 2.1.2", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "2.1.2" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "icu_provider 2.1.1": { - "name": "icu_provider", - "version": "2.1.1", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/icu_provider/2.1.1/download", - "sha256": "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" - } - }, - "targets": [ - { - "Library": { - "crate_name": "icu_provider", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "icu_provider", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "baked" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "icu_locale_core 2.1.1", - "target": "icu_locale_core" - }, - { - "id": "writeable 0.6.2", - "target": "writeable" - }, - { - "id": "yoke 0.8.1", - "target": "yoke" - }, - { - "id": "zerofrom 0.1.6", - "target": "zerofrom" - }, - { - "id": "zerotrie 0.2.3", - "target": "zerotrie" - }, - { - "id": "zerovec 0.11.5", - "target": "zerovec" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "displaydoc 0.2.5", - "target": "displaydoc" - } - ], - "selects": {} - }, - "version": "2.1.1" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "id-arena 2.3.0": { - "name": "id-arena", - "version": "2.3.0", - "package_url": "https://github.com/fitzgen/id-arena", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/id-arena/2.3.0/download", - "sha256": "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - } - }, - "targets": [ - { - "Library": { - "crate_name": "id_arena", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "id_arena", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "edition": "2021", - "version": "2.3.0" - }, - "license": "MIT/Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "idna 1.1.0": { - "name": "idna", - "version": "1.1.0", - "package_url": "https://github.com/servo/rust-url/", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/idna/1.1.0/download", - "sha256": "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" - } - }, - "targets": [ - { - "Library": { - "crate_name": "idna", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "idna", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "compiled_data", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "idna_adapter 1.2.1", - "target": "idna_adapter" - }, - { - "id": "smallvec 1.15.1", - "target": "smallvec" - }, - { - "id": "utf8_iter 1.0.4", - "target": "utf8_iter" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "1.1.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "idna_adapter 1.2.1": { - "name": "idna_adapter", - "version": "1.2.1", - "package_url": "https://github.com/hsivonen/idna_adapter", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/idna_adapter/1.2.1/download", - "sha256": "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" - } - }, - "targets": [ - { - "Library": { - "crate_name": "idna_adapter", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "idna_adapter", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "compiled_data" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "icu_normalizer 2.1.1", - "target": "icu_normalizer" - }, - { - "id": "icu_properties 2.1.2", - "target": "icu_properties" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.2.1" - }, - "license": "Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "indexmap 2.13.0": { - "name": "indexmap", - "version": "2.13.0", - "package_url": "https://github.com/indexmap-rs/indexmap", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/indexmap/2.13.0/download", - "sha256": "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" - } - }, - "targets": [ - { - "Library": { - "crate_name": "indexmap", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "indexmap", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": { - "aarch64-apple-darwin": [ - "serde" - ], - "aarch64-unknown-linux-gnu": [ - "serde" - ], - "x86_64-pc-windows-msvc": [ - "serde" - ], - "x86_64-unknown-linux-gnu": [ - "serde" - ], - "x86_64-unknown-nixos-gnu": [ - "serde" - ] - } - }, - "deps": { - "common": [ - { - "id": "equivalent 1.0.2", - "target": "equivalent" - }, - { - "id": "hashbrown 0.16.1", - "target": "hashbrown" - } - ], - "selects": { - "aarch64-apple-darwin": [ - { - "id": "serde_core 1.0.228", - "target": "serde_core" - } - ], - "aarch64-unknown-linux-gnu": [ - { - "id": "serde_core 1.0.228", - "target": "serde_core" - } - ], - "x86_64-pc-windows-msvc": [ - { - "id": "serde_core 1.0.228", - "target": "serde_core" - } - ], - "x86_64-unknown-linux-gnu": [ - { - "id": "serde_core 1.0.228", - "target": "serde_core" - } - ], - "x86_64-unknown-nixos-gnu": [ - { - "id": "serde_core 1.0.228", - "target": "serde_core" - } - ] - } - }, - "edition": "2021", - "version": "2.13.0" - }, - "license": "Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "ipconfig 0.3.4": { - "name": "ipconfig", - "version": "0.3.4", - "package_url": "https://github.com/liranringel/ipconfig", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/ipconfig/0.3.4/download", - "sha256": "4d40460c0ce33d6ce4b0630ad68ff63d6661961c48b6dba35e5a4d81cfb48222" - } - }, - "targets": [ - { - "Library": { - "crate_name": "ipconfig", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "ipconfig", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "computer", - "default" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "ipconfig 0.3.4", - "target": "build_script_build" - }, - { - "id": "windows-registry 0.6.1", - "target": "windows_registry" - }, - { - "id": "windows-result 0.4.1", - "target": "windows_result" - } - ], - "selects": { - "cfg(windows)": [ - { - "id": "socket2 0.6.3", - "target": "socket2" - }, - { - "id": "widestring 1.2.1", - "target": "widestring" - }, - { - "id": "windows-sys 0.61.2", - "target": "windows_sys" - } - ] - } - }, - "edition": "2018", - "version": "0.3.4" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT/Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "ipnet 2.12.0": { - "name": "ipnet", - "version": "2.12.0", - "package_url": "https://github.com/krisprice/ipnet", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/ipnet/2.12.0/download", - "sha256": "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" - } - }, - "targets": [ - { - "Library": { - "crate_name": "ipnet", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "ipnet", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "serde", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "serde 1.0.228", - "target": "serde" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "2.12.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "itertools 0.13.0": { - "name": "itertools", - "version": "0.13.0", - "package_url": "https://github.com/rust-itertools/itertools", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/itertools/0.13.0/download", - "sha256": "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" - } - }, - "targets": [ - { - "Library": { - "crate_name": "itertools", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "itertools", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "either 1.15.0", - "target": "either" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.13.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "itoa 1.0.18": { - "name": "itoa", - "version": "1.0.18", - "package_url": "https://github.com/dtolnay/itoa", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/itoa/1.0.18/download", - "sha256": "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" - } - }, - "targets": [ - { - "Library": { - "crate_name": "itoa", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "itoa", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "1.0.18" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "jni 0.22.4": { - "name": "jni", - "version": "0.22.4", - "package_url": "https://github.com/jni-rs/jni-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/jni/0.22.4/download", - "sha256": "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" - } - }, - "targets": [ - { - "Library": { - "crate_name": "jni", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "jni", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "cfg-if 1.0.4", - "target": "cfg_if" - }, - { - "id": "combine 4.6.7", - "target": "combine" - }, - { - "id": "jni 0.22.4", - "target": "build_script_build" - }, - { - "id": "jni-sys 0.4.1", - "target": "jni_sys" - }, - { - "id": "log 0.4.29", - "target": "log" - }, - { - "id": "simd_cesu8 1.1.1", - "target": "simd_cesu8" - }, - { - "id": "thiserror 2.0.18", - "target": "thiserror" - } - ], - "selects": { - "cfg(windows)": [ - { - "id": "windows-link 0.2.1", - "target": "windows_link" - } - ] - } - }, - "edition": "2024", - "proc_macro_deps": { - "common": [ - { - "id": "jni-macros 0.22.4", - "target": "jni_macros" - } - ], - "selects": {} - }, - "version": "0.22.4" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "walkdir 2.5.0", - "target": "walkdir" - } - ], - "selects": {} - } - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": null - }, - "jni-macros 0.22.4": { - "name": "jni-macros", - "version": "0.22.4", - "package_url": "https://github.com/jni-rs/jni-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/jni-macros/0.22.4/download", - "sha256": "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "jni_macros", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "jni_macros", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "jni-macros 0.22.4", - "target": "build_script_build" - }, - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "simd_cesu8 1.1.1", - "target": "simd_cesu8" - }, - { - "id": "syn 2.0.117", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2024", - "version": "0.22.4" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "rustc_version 0.4.1", - "target": "rustc_version" - } - ], - "selects": {} - } - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": null - }, - "jni-sys 0.4.1": { - "name": "jni-sys", - "version": "0.4.1", - "package_url": "https://github.com/jni-rs/jni-sys", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/jni-sys/0.4.1/download", - "sha256": "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" - } - }, - "targets": [ - { - "Library": { - "crate_name": "jni_sys", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "jni_sys", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "jni-sys-macros 0.4.1", - "target": "jni_sys_macros" - } - ], - "selects": {} - }, - "version": "0.4.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "jni-sys-macros 0.4.1": { - "name": "jni-sys-macros", - "version": "0.4.1", - "package_url": "https://github.com/jni-rs/jni-sys", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/jni-sys-macros/0.4.1/download", - "sha256": "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "jni_sys_macros", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "jni_sys_macros", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.4.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": null - }, - "js-sys 0.3.91": { - "name": "js-sys", - "version": "0.3.91", - "package_url": "https://github.com/wasm-bindgen/wasm-bindgen/tree/master/crates/js-sys", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/js-sys/0.3.91/download", - "sha256": "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" - } - }, - "targets": [ - { - "Library": { - "crate_name": "js_sys", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "js_sys", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "once_cell 1.21.4", - "target": "once_cell" - }, - { - "id": "wasm-bindgen 0.2.114", - "target": "wasm_bindgen" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.3.91" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "leb128fmt 0.1.0": { - "name": "leb128fmt", - "version": "0.1.0", - "package_url": "https://github.com/bluk/leb128fmt", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/leb128fmt/0.1.0/download", - "sha256": "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - } - }, - "targets": [ - { - "Library": { - "crate_name": "leb128fmt", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "leb128fmt", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "0.1.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "libc 0.2.183": { - "name": "libc", - "version": "0.2.183", - "package_url": "https://github.com/rust-lang/libc", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/libc/0.2.183/download", - "sha256": "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" - } - }, - "targets": [ - { - "Library": { - "crate_name": "libc", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "libc", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [], - "selects": { - "aarch64-apple-darwin": [ - "default", - "std" - ], - "aarch64-unknown-linux-gnu": [ - "default", - "std" - ], - "wasm32-wasip1": [ - "default", - "std" - ], - "x86_64-unknown-linux-gnu": [ - "default", - "std" - ], - "x86_64-unknown-nixos-gnu": [ - "default", - "std" - ] - } - }, - "deps": { - "common": [ - { - "id": "libc 0.2.183", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.2.183" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "libloading 0.8.9": { - "name": "libloading", - "version": "0.8.9", - "package_url": "https://github.com/nagisa/rust_libloading/", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/libloading/0.8.9/download", - "sha256": "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" - } - }, - "targets": [ - { - "Library": { - "crate_name": "libloading", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "libloading", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [], - "selects": { - "cfg(unix)": [ - { - "id": "cfg-if 1.0.4", - "target": "cfg_if" - } - ], - "cfg(windows)": [ - { - "id": "windows-link 0.2.1", - "target": "windows_link" - } - ] - } - }, - "edition": "2015", - "version": "0.8.9" - }, - "license": "ISC", - "license_ids": [ - "ISC" - ], - "license_file": "LICENSE" - }, - "linked-hash-map 0.5.6": { - "name": "linked-hash-map", - "version": "0.5.6", - "package_url": "https://github.com/contain-rs/linked-hash-map", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/linked-hash-map/0.5.6/download", - "sha256": "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - } - }, - "targets": [ - { - "Library": { - "crate_name": "linked_hash_map", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "linked_hash_map", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2015", - "version": "0.5.6" - }, - "license": "MIT/Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "litemap 0.8.1": { - "name": "litemap", - "version": "0.8.1", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/litemap/0.8.1/download", - "sha256": "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" - } - }, - "targets": [ - { - "Library": { - "crate_name": "litemap", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "litemap", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "0.8.1" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "lock_api 0.4.14": { - "name": "lock_api", - "version": "0.4.14", - "package_url": "https://github.com/Amanieu/parking_lot", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/lock_api/0.4.14/download", - "sha256": "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" - } - }, - "targets": [ - { - "Library": { - "crate_name": "lock_api", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "lock_api", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "atomic_usize", - "default" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "scopeguard 1.2.0", - "target": "scopeguard" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.4.14" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "log 0.4.29": { - "name": "log", - "version": "0.4.29", - "package_url": "https://github.com/rust-lang/log", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/log/0.4.29/download", - "sha256": "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" - } - }, - "targets": [ - { - "Library": { - "crate_name": "log", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "log", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "0.4.29" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "lru-cache 0.1.2": { - "name": "lru-cache", - "version": "0.1.2", - "package_url": "https://github.com/contain-rs/lru-cache", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/lru-cache/0.1.2/download", - "sha256": "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" - } - }, - "targets": [ - { - "Library": { - "crate_name": "lru_cache", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "lru_cache", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "linked-hash-map 0.5.6", - "target": "linked_hash_map" - } - ], - "selects": {} - }, - "edition": "2015", - "version": "0.1.2" - }, - "license": "MIT/Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "memchr 2.8.0": { - "name": "memchr", - "version": "2.8.0", - "package_url": "https://github.com/BurntSushi/memchr", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/memchr/2.8.0/download", - "sha256": "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" - } - }, - "targets": [ - { - "Library": { - "crate_name": "memchr", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "memchr", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "std" - ], - "selects": {} - }, - "edition": "2021", - "version": "2.8.0" - }, - "license": "Unlicense OR MIT", - "license_ids": [ - "MIT", - "Unlicense" - ], - "license_file": "LICENSE-MIT" - }, - "minimal-lexical 0.2.1": { - "name": "minimal-lexical", - "version": "0.2.1", - "package_url": "https://github.com/Alexhuszagh/minimal-lexical", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/minimal-lexical/0.2.1/download", - "sha256": "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - } - }, - "targets": [ - { - "Library": { - "crate_name": "minimal_lexical", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "minimal_lexical", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "std" - ], - "selects": {} - }, - "edition": "2018", - "version": "0.2.1" - }, - "license": "MIT/Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "mio 1.1.1": { - "name": "mio", - "version": "1.1.1", - "package_url": "https://github.com/tokio-rs/mio", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/mio/1.1.1/download", - "sha256": "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" - } - }, - "targets": [ - { - "Library": { - "crate_name": "mio", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "mio", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "net", - "os-ext", - "os-poll" - ], - "selects": {} - }, - "deps": { - "common": [], - "selects": { - "cfg(target_os = \"hermit\")": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(target_os = \"wasi\")": [ - { - "id": "libc 0.2.183", - "target": "libc" - }, - { - "id": "wasi 0.11.1+wasi-snapshot-preview1", - "target": "wasi" - } - ], - "cfg(unix)": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(windows)": [ - { - "id": "windows-sys 0.61.2", - "target": "windows_sys" - } - ] - } - }, - "edition": "2021", - "version": "1.1.1" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "mockall 0.13.1": { - "name": "mockall", - "version": "0.13.1", - "package_url": "https://github.com/asomers/mockall", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/mockall/0.13.1/download", - "sha256": "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" - } - }, - "targets": [ - { - "Library": { - "crate_name": "mockall", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "mockall", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "cfg-if 1.0.4", - "target": "cfg_if" - }, - { - "id": "downcast 0.11.0", - "target": "downcast" - }, - { - "id": "fragile 2.0.1", - "target": "fragile" - }, - { - "id": "predicates 3.1.4", - "target": "predicates" - }, - { - "id": "predicates-tree 1.0.13", - "target": "predicates_tree" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "mockall_derive 0.13.1", - "target": "mockall_derive" - } - ], - "selects": {} - }, - "version": "0.13.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "mockall_derive 0.13.1": { - "name": "mockall_derive", - "version": "0.13.1", - "package_url": "https://github.com/asomers/mockall", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/mockall_derive/0.13.1/download", - "sha256": "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "mockall_derive", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "mockall_derive", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "cfg-if 1.0.4", - "target": "cfg_if" - }, - { - "id": "mockall_derive 0.13.1", - "target": "build_script_build" - }, - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.13.1" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "moka 0.12.15": { - "name": "moka", - "version": "0.12.15", - "package_url": "https://github.com/moka-rs/moka", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/moka/0.12.15/download", - "sha256": "957228ad12042ee839f93c8f257b62b4c0ab5eaae1d4fa60de53b27c9d7c5046" - } - }, - "targets": [ - { - "Library": { - "crate_name": "moka", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "moka", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "sync" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "crossbeam-channel 0.5.15", - "target": "crossbeam_channel" - }, - { - "id": "crossbeam-epoch 0.9.18", - "target": "crossbeam_epoch" - }, - { - "id": "crossbeam-utils 0.8.21", - "target": "crossbeam_utils" - }, - { - "id": "equivalent 1.0.2", - "target": "equivalent" - }, - { - "id": "parking_lot 0.12.5", - "target": "parking_lot" - }, - { - "id": "portable-atomic 1.13.1", - "target": "portable_atomic" - }, - { - "id": "smallvec 1.15.1", - "target": "smallvec" - }, - { - "id": "tagptr 0.2.0", - "target": "tagptr" - }, - { - "id": "uuid 1.22.0", - "target": "uuid" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.12.15" - }, - "license": "(MIT OR Apache-2.0) AND Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "ndk-context 0.1.1": { - "name": "ndk-context", - "version": "0.1.1", - "package_url": "https://github.com/rust-windowing/android-ndk-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/ndk-context/0.1.1/download", - "sha256": "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" - } - }, - "targets": [ - { - "Library": { - "crate_name": "ndk_context", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "ndk_context", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "0.1.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": null - }, - "nom 7.1.3": { - "name": "nom", - "version": "7.1.3", - "package_url": "https://github.com/Geal/nom", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/nom/7.1.3/download", - "sha256": "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" - } - }, - "targets": [ - { - "Library": { - "crate_name": "nom", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "nom", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "memchr 2.8.0", - "target": "memchr" - }, - { - "id": "minimal-lexical 0.2.1", - "target": "minimal_lexical" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "7.1.3" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "num-conv 0.2.1": { - "name": "num-conv", - "version": "0.2.1", - "package_url": "https://github.com/jhpratt/num-conv", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/num-conv/0.2.1/download", - "sha256": "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" - } - }, - "targets": [ - { - "Library": { - "crate_name": "num_conv", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "num_conv", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "0.2.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-Apache" - }, - "num-traits 0.2.19": { - "name": "num-traits", - "version": "0.2.19", - "package_url": "https://github.com/rust-num/num-traits", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/num-traits/0.2.19/download", - "sha256": "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" - } - }, - "targets": [ - { - "Library": { - "crate_name": "num_traits", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "num_traits", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "num-traits 0.2.19", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.2.19" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "autocfg 1.5.0", - "target": "autocfg" - } - ], - "selects": {} - } - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "once_cell 1.21.4": { - "name": "once_cell", - "version": "1.21.4", - "package_url": "https://github.com/matklad/once_cell", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/once_cell/1.21.4/download", - "sha256": "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" - } - }, - "targets": [ - { - "Library": { - "crate_name": "once_cell", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "once_cell", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "critical-section", - "default", - "portable-atomic", - "race", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "critical-section 1.2.0", - "target": "critical_section" - }, - { - "id": "portable-atomic 1.13.1", - "target": "portable_atomic" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.21.4" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "parking_lot 0.12.5": { - "name": "parking_lot", - "version": "0.12.5", - "package_url": "https://github.com/Amanieu/parking_lot", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/parking_lot/0.12.5/download", - "sha256": "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" - } - }, - "targets": [ - { - "Library": { - "crate_name": "parking_lot", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "parking_lot", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "lock_api 0.4.14", - "target": "lock_api" - }, - { - "id": "parking_lot_core 0.9.12", - "target": "parking_lot_core" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.12.5" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "parking_lot_core 0.9.12": { - "name": "parking_lot_core", - "version": "0.9.12", - "package_url": "https://github.com/Amanieu/parking_lot", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/parking_lot_core/0.9.12/download", - "sha256": "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" - } - }, - "targets": [ - { - "Library": { - "crate_name": "parking_lot_core", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "parking_lot_core", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "cfg-if 1.0.4", - "target": "cfg_if" - }, - { - "id": "parking_lot_core 0.9.12", - "target": "build_script_build" - }, - { - "id": "smallvec 1.15.1", - "target": "smallvec" - } - ], - "selects": { - "cfg(target_os = \"redox\")": [ - { - "id": "redox_syscall 0.5.18", - "target": "syscall" - } - ], - "cfg(unix)": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(windows)": [ - { - "id": "windows-link 0.2.1", - "target": "windows_link" - } - ] - } - }, - "edition": "2021", - "version": "0.9.12" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "percent-encoding 2.3.2": { - "name": "percent-encoding", - "version": "2.3.2", - "package_url": "https://github.com/servo/rust-url/", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/percent-encoding/2.3.2/download", - "sha256": "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - } - }, - "targets": [ - { - "Library": { - "crate_name": "percent_encoding", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "percent_encoding", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "std" - ], - "selects": {} - }, - "edition": "2018", - "version": "2.3.2" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "pin-project-lite 0.2.17": { - "name": "pin-project-lite", - "version": "0.2.17", - "package_url": "https://github.com/taiki-e/pin-project-lite", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/pin-project-lite/0.2.17/download", - "sha256": "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" - } - }, - "targets": [ - { - "Library": { - "crate_name": "pin_project_lite", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "pin_project_lite", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2018", - "version": "0.2.17" - }, - "license": "Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "portable-atomic 1.13.1": { - "name": "portable-atomic", - "version": "1.13.1", - "package_url": "https://github.com/taiki-e/portable-atomic", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/portable-atomic/1.13.1/download", - "sha256": "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" - } - }, - "targets": [ - { - "Library": { - "crate_name": "portable_atomic", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "portable_atomic", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "fallback" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "portable-atomic 1.13.1", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "1.13.1" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "potential_utf 0.1.4": { - "name": "potential_utf", - "version": "0.1.4", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/potential_utf/0.1.4/download", - "sha256": "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" - } - }, - "targets": [ - { - "Library": { - "crate_name": "potential_utf", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "potential_utf", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "zerovec" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "zerovec 0.11.5", - "target": "zerovec" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.1.4" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "powerfmt 0.2.0": { - "name": "powerfmt", - "version": "0.2.0", - "package_url": "https://github.com/jhpratt/powerfmt", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/powerfmt/0.2.0/download", - "sha256": "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - } - }, - "targets": [ - { - "Library": { - "crate_name": "powerfmt", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "powerfmt", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "0.2.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-Apache" - }, - "predicates 3.1.4": { - "name": "predicates", - "version": "3.1.4", - "package_url": "https://github.com/assert-rs/predicates-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/predicates/3.1.4/download", - "sha256": "ada8f2932f28a27ee7b70dd6c1c39ea0675c55a36879ab92f3a715eaa1e63cfe" - } - }, - "targets": [ - { - "Library": { - "crate_name": "predicates", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "predicates", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "anstyle 1.0.14", - "target": "anstyle" - }, - { - "id": "predicates-core 1.0.10", - "target": "predicates_core" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "3.1.4" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "predicates-core 1.0.10": { - "name": "predicates-core", - "version": "1.0.10", - "package_url": "https://github.com/assert-rs/predicates-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/predicates-core/1.0.10/download", - "sha256": "cad38746f3166b4031b1a0d39ad9f954dd291e7854fcc0eed52ee41a0b50d144" - } - }, - "targets": [ - { - "Library": { - "crate_name": "predicates_core", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "predicates_core", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "1.0.10" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "predicates-tree 1.0.13": { - "name": "predicates-tree", - "version": "1.0.13", - "package_url": "https://github.com/assert-rs/predicates-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/predicates-tree/1.0.13/download", - "sha256": "d0de1b847b39c8131db0467e9df1ff60e6d0562ab8e9a16e568ad0fdb372e2f2" - } - }, - "targets": [ - { - "Library": { - "crate_name": "predicates_tree", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "predicates_tree", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "predicates-core 1.0.10", - "target": "predicates_core" - }, - { - "id": "termtree 0.5.1", - "target": "termtree" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.0.13" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "prefix-trie 0.8.3": { - "name": "prefix-trie", - "version": "0.8.3", - "package_url": "https://github.com/tiborschneider/prefix-trie", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/prefix-trie/0.8.3/download", - "sha256": "90f561214012d3fc240a1f9c817cc4d57f5310910d066069c1b093f766bb5966" - } - }, - "targets": [ - { - "Library": { - "crate_name": "prefix_trie", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "prefix_trie", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "ipnet" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "either 1.15.0", - "target": "either" - }, - { - "id": "ipnet 2.12.0", - "target": "ipnet" - }, - { - "id": "num-traits 0.2.19", - "target": "num_traits" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.8.3" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "prettyplease 0.2.37": { - "name": "prettyplease", - "version": "0.2.37", - "package_url": "https://github.com/dtolnay/prettyplease", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/prettyplease/0.2.37/download", - "sha256": "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" - } - }, - "targets": [ - { - "Library": { - "crate_name": "prettyplease", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "prettyplease", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "verbatim" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "prettyplease 0.2.37", - "target": "build_script_build" - }, - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "syn 2.0.117", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.2.37" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ], - "links": "prettyplease02" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "proc-macro2 1.0.106": { - "name": "proc-macro2", - "version": "1.0.106", - "package_url": "https://github.com/dtolnay/proc-macro2", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/proc-macro2/1.0.106/download", - "sha256": "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" - } - }, - "targets": [ - { - "Library": { - "crate_name": "proc_macro2", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "proc_macro2", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "proc-macro" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "proc-macro2 1.0.106", - "target": "build_script_build" - }, - { - "id": "unicode-ident 1.0.24", - "target": "unicode_ident" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.0.106" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "quote 1.0.45": { - "name": "quote", - "version": "1.0.45", - "package_url": "https://github.com/dtolnay/quote", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/quote/1.0.45/download", - "sha256": "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" - } - }, - "targets": [ - { - "Library": { - "crate_name": "quote", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "quote", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "proc-macro" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.0.45" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "r-efi 6.0.0": { - "name": "r-efi", - "version": "6.0.0", - "package_url": "https://github.com/r-efi/r-efi", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/r-efi/6.0.0/download", - "sha256": "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" - } - }, - "targets": [ - { - "Library": { - "crate_name": "r_efi", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "r_efi", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2018", - "version": "6.0.0" - }, - "license": "MIT OR Apache-2.0 OR LGPL-2.1-or-later", - "license_ids": [ - "Apache-2.0", - "LGPL-2.1", - "MIT" - ], - "license_file": null - }, - "rand 0.10.1": { - "name": "rand", - "version": "0.10.1", - "package_url": "https://github.com/rust-random/rand", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/rand/0.10.1/download", - "sha256": "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" - } - }, - "targets": [ - { - "Library": { - "crate_name": "rand", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "rand", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "std", - "std_rng", - "sys_rng", - "thread_rng" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "chacha20 0.10.0", - "target": "chacha20" - }, - { - "id": "getrandom 0.4.2", - "target": "getrandom" - }, - { - "id": "rand_core 0.10.1", - "target": "rand_core" - } - ], - "selects": {} - }, - "edition": "2024", - "version": "0.10.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "rand_core 0.10.1": { - "name": "rand_core", - "version": "0.10.1", - "package_url": "https://github.com/rust-random/rand_core", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/rand_core/0.10.1/download", - "sha256": "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" - } - }, - "targets": [ - { - "Library": { - "crate_name": "rand_core", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "rand_core", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2024", - "version": "0.10.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "redox_syscall 0.5.18": { - "name": "redox_syscall", - "version": "0.5.18", - "package_url": "https://gitlab.redox-os.org/redox-os/syscall", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/redox_syscall/0.5.18/download", - "sha256": "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" - } - }, - "targets": [ - { - "Library": { - "crate_name": "syscall", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "syscall", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "bitflags 2.11.0", - "target": "bitflags" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.5.18" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "regex 1.12.3": { - "name": "regex", - "version": "1.12.3", - "package_url": "https://github.com/rust-lang/regex", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/regex/1.12.3/download", - "sha256": "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" - } - }, - "targets": [ - { - "Library": { - "crate_name": "regex", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "regex", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "std", - "unicode-perl" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "regex-automata 0.4.14", - "target": "regex_automata" - }, - { - "id": "regex-syntax 0.8.10", - "target": "regex_syntax" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.12.3" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "regex-automata 0.4.14": { - "name": "regex-automata", - "version": "0.4.14", - "package_url": "https://github.com/rust-lang/regex", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/regex-automata/0.4.14/download", - "sha256": "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" - } - }, - "targets": [ - { - "Library": { - "crate_name": "regex_automata", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "regex_automata", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "meta", - "nfa-pikevm", - "nfa-thompson", - "std", - "syntax", - "unicode-perl", - "unicode-word-boundary" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "regex-syntax 0.8.10", - "target": "regex_syntax" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.4.14" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "regex-syntax 0.8.10": { - "name": "regex-syntax", - "version": "0.8.10", - "package_url": "https://github.com/rust-lang/regex", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/regex-syntax/0.8.10/download", - "sha256": "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" - } - }, - "targets": [ - { - "Library": { - "crate_name": "regex_syntax", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "regex_syntax", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "std", - "unicode-perl" - ], - "selects": {} - }, - "edition": "2021", - "version": "0.8.10" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "resolv-conf 0.7.6": { - "name": "resolv-conf", - "version": "0.7.6", - "package_url": "https://github.com/hickory-dns/resolv-conf", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/resolv-conf/0.7.6/download", - "sha256": "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" - } - }, - "targets": [ - { - "Library": { - "crate_name": "resolv_conf", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "resolv_conf", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "system" - ], - "selects": {} - }, - "edition": "2021", - "version": "0.7.6" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "ring 0.17.14": { - "name": "ring", - "version": "0.17.14", - "package_url": "https://github.com/briansmith/ring", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/ring/0.17.14/download", - "sha256": "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" - } - }, - "targets": [ - { - "Library": { - "crate_name": "ring", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "ring", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "default", - "dev_urandom_fallback", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "cfg-if 1.0.4", - "target": "cfg_if" - }, - { - "id": "getrandom 0.2.17", - "target": "getrandom" - }, - { - "id": "ring 0.17.14", - "target": "build_script_build" - }, - { - "id": "untrusted 0.9.0", - "target": "untrusted" - } - ], - "selects": { - "cfg(all(all(target_arch = \"aarch64\", target_endian = \"little\"), target_os = \"windows\"))": [ - { - "id": "windows-sys 0.52.0", - "target": "windows_sys" - } - ], - "cfg(all(all(target_arch = \"aarch64\", target_endian = \"little\"), target_vendor = \"apple\", any(target_os = \"ios\", target_os = \"macos\", target_os = \"tvos\", target_os = \"visionos\", target_os = \"watchos\")))": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(all(any(all(target_arch = \"aarch64\", target_endian = \"little\"), all(target_arch = \"arm\", target_endian = \"little\")), any(target_os = \"android\", target_os = \"linux\")))": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ] - } - }, - "edition": "2021", - "version": "0.17.14" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "cc 1.2.57", - "target": "cc" - } - ], - "selects": {} - }, - "links": "ring_core_0_17_14_" - }, - "license": "Apache-2.0 AND ISC", - "license_ids": [ - "Apache-2.0", - "ISC" - ], - "license_file": "LICENSE" - }, - "rustc-hash 1.1.0": { - "name": "rustc-hash", - "version": "1.1.0", - "package_url": "https://github.com/rust-lang-nursery/rustc-hash", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/rustc-hash/1.1.0/download", - "sha256": "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - } - }, - "targets": [ - { - "Library": { - "crate_name": "rustc_hash", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "rustc_hash", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "edition": "2015", - "version": "1.1.0" - }, - "license": "Apache-2.0/MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "rustc_version 0.4.1": { - "name": "rustc_version", - "version": "0.4.1", - "package_url": "https://github.com/djc/rustc-version-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/rustc_version/0.4.1/download", - "sha256": "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" - } - }, - "targets": [ - { - "Library": { - "crate_name": "rustc_version", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "rustc_version", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "semver 1.0.27", - "target": "semver" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.4.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "rustls 0.23.37": { - "name": "rustls", - "version": "0.23.37", - "package_url": "https://github.com/rustls/rustls", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/rustls/0.23.37/download", - "sha256": "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" - } - }, - "targets": [ - { - "Library": { - "crate_name": "rustls", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "rustls", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "log", - "logging", - "ring", - "std", - "tls12" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "log 0.4.29", - "target": "log" - }, - { - "id": "once_cell 1.21.4", - "target": "once_cell" - }, - { - "id": "ring 0.17.14", - "target": "ring" - }, - { - "id": "rustls 0.23.37", - "target": "build_script_build" - }, - { - "id": "rustls-pki-types 1.14.0", - "target": "rustls_pki_types", - "alias": "pki_types" - }, - { - "id": "rustls-webpki 0.103.13", - "target": "webpki" - }, - { - "id": "subtle 2.6.1", - "target": "subtle" - }, - { - "id": "zeroize 1.8.2", - "target": "zeroize" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.23.37" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ], - "link_deps": { - "common": [ - { - "id": "ring 0.17.14", - "target": "ring" - } - ], - "selects": {} - } - }, - "license": "Apache-2.0 OR ISC OR MIT", - "license_ids": [ - "Apache-2.0", - "ISC", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "rustls-pki-types 1.14.0": { - "name": "rustls-pki-types", - "version": "1.14.0", - "package_url": "https://github.com/rustls/pki-types", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/rustls-pki-types/1.14.0/download", - "sha256": "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" - } - }, - "targets": [ - { - "Library": { - "crate_name": "rustls_pki_types", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "rustls_pki_types", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "default", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "zeroize 1.8.2", - "target": "zeroize" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.14.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "rustls-webpki 0.103.13": { - "name": "rustls-webpki", - "version": "0.103.13", - "package_url": "https://github.com/rustls/webpki", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/rustls-webpki/0.103.13/download", - "sha256": "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" - } - }, - "targets": [ - { - "Library": { - "crate_name": "webpki", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "webpki", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "ring", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "ring 0.17.14", - "target": "ring" - }, - { - "id": "rustls-pki-types 1.14.0", - "target": "rustls_pki_types", - "alias": "pki_types" - }, - { - "id": "untrusted 0.9.0", - "target": "untrusted" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.103.13" - }, - "license": "ISC", - "license_ids": [ - "ISC" - ], - "license_file": "LICENSE" - }, - "rustversion 1.0.22": { - "name": "rustversion", - "version": "1.0.22", - "package_url": "https://github.com/dtolnay/rustversion", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/rustversion/1.0.22/download", - "sha256": "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "rustversion", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build/build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "rustversion", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "rustversion 1.0.22", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "1.0.22" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "same-file 1.0.6": { - "name": "same-file", - "version": "1.0.6", - "package_url": "https://github.com/BurntSushi/same-file", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/same-file/1.0.6/download", - "sha256": "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" - } - }, - "targets": [ - { - "Library": { - "crate_name": "same_file", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "same_file", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [], - "selects": { - "cfg(windows)": [ - { - "id": "winapi-util 0.1.11", - "target": "winapi_util" - } - ] - } - }, - "edition": "2018", - "version": "1.0.6" - }, - "license": "Unlicense/MIT", - "license_ids": [ - "MIT", - "Unlicense" - ], - "license_file": "LICENSE-MIT" - }, - "scopeguard 1.2.0": { - "name": "scopeguard", - "version": "1.2.0", - "package_url": "https://github.com/bluss/scopeguard", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/scopeguard/1.2.0/download", - "sha256": "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - } - }, - "targets": [ - { - "Library": { - "crate_name": "scopeguard", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "scopeguard", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2015", - "version": "1.2.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "semver 1.0.27": { - "name": "semver", - "version": "1.0.27", - "package_url": "https://github.com/dtolnay/semver", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/semver/1.0.27/download", - "sha256": "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" - } - }, - "targets": [ - { - "Library": { - "crate_name": "semver", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "semver", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "edition": "2018", - "version": "1.0.27" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "serde 1.0.228": { - "name": "serde", - "version": "1.0.228", - "package_url": "https://github.com/serde-rs/serde", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/serde/1.0.228/download", - "sha256": "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" - } - }, - "targets": [ - { - "Library": { - "crate_name": "serde", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "serde", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "derive", - "serde_derive", - "std" - ], - "selects": { - "aarch64-apple-darwin": [ - "alloc" - ], - "aarch64-unknown-linux-gnu": [ - "alloc" - ], - "x86_64-pc-windows-msvc": [ - "alloc" - ], - "x86_64-unknown-linux-gnu": [ - "alloc" - ], - "x86_64-unknown-nixos-gnu": [ - "alloc" - ] - } - }, - "deps": { - "common": [ - { - "id": "serde 1.0.228", - "target": "build_script_build" - }, - { - "id": "serde_core 1.0.228", - "target": "serde_core" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "serde_derive 1.0.228", - "target": "serde_derive" - } - ], - "selects": {} - }, - "version": "1.0.228" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "serde_core 1.0.228": { - "name": "serde_core", - "version": "1.0.228", - "package_url": "https://github.com/serde-rs/serde", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/serde_core/1.0.228/download", - "sha256": "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" - } - }, - "targets": [ - { - "Library": { - "crate_name": "serde_core", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "serde_core", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "result", - "std" - ], - "selects": { - "aarch64-apple-darwin": [ - "alloc" - ], - "aarch64-unknown-linux-gnu": [ - "alloc" - ], - "x86_64-pc-windows-msvc": [ - "alloc" - ], - "x86_64-unknown-linux-gnu": [ - "alloc" - ], - "x86_64-unknown-nixos-gnu": [ - "alloc" - ] - } - }, - "deps": { - "common": [ - { - "id": "serde_core 1.0.228", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [], - "selects": { - "cfg(any())": [ - { - "id": "serde_derive 1.0.228", - "target": "serde_derive" - } - ] - } - }, - "version": "1.0.228" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "serde_derive 1.0.228": { - "name": "serde_derive", - "version": "1.0.228", - "package_url": "https://github.com/serde-rs/serde", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/serde_derive/1.0.228/download", - "sha256": "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "serde_derive", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "serde_derive", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.0.228" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "serde_json 1.0.149": { - "name": "serde_json", - "version": "1.0.149", - "package_url": "https://github.com/serde-rs/json", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/serde_json/1.0.149/download", - "sha256": "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" - } - }, - "targets": [ - { - "Library": { - "crate_name": "serde_json", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "serde_json", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "itoa 1.0.18", - "target": "itoa" - }, - { - "id": "memchr 2.8.0", - "target": "memchr" - }, - { - "id": "serde_core 1.0.228", - "target": "serde_core" - }, - { - "id": "serde_json 1.0.149", - "target": "build_script_build" - }, - { - "id": "zmij 1.0.21", - "target": "zmij" - } - ], - "selects": { - "cfg(any())": [ - { - "id": "serde 1.0.228", - "target": "serde" - } - ] - } - }, - "edition": "2021", - "version": "1.0.149" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "shlex 1.3.0": { - "name": "shlex", - "version": "1.3.0", - "package_url": "https://github.com/comex/rust-shlex", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/shlex/1.3.0/download", - "sha256": "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - } - }, - "targets": [ - { - "Library": { - "crate_name": "shlex", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "shlex", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "edition": "2015", - "version": "1.3.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "simd_cesu8 1.1.1": { - "name": "simd_cesu8", - "version": "1.1.1", - "package_url": "https://github.com/seancroach/simd_cesu8", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/simd_cesu8/1.1.1/download", - "sha256": "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" - } - }, - "targets": [ - { - "Library": { - "crate_name": "simd_cesu8", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "simd_cesu8", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "simdutf8 0.1.5", - "target": "simdutf8" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.1.1" - }, - "license": "Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "simdutf8 0.1.5": { - "name": "simdutf8", - "version": "0.1.5", - "package_url": "https://github.com/rusticstuff/simdutf8", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/simdutf8/0.1.5/download", - "sha256": "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" - } - }, - "targets": [ - { - "Library": { - "crate_name": "simdutf8", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "simdutf8", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "std" - ], - "selects": {} - }, - "edition": "2018", - "version": "0.1.5" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-Apache" - }, - "slab 0.4.12": { - "name": "slab", - "version": "0.4.12", - "package_url": "https://github.com/tokio-rs/slab", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/slab/0.4.12/download", - "sha256": "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - } - }, - "targets": [ - { - "Library": { - "crate_name": "slab", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "slab", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "edition": "2018", - "version": "0.4.12" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "smallvec 1.15.1": { - "name": "smallvec", - "version": "1.15.1", - "package_url": "https://github.com/servo/rust-smallvec", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/smallvec/1.15.1/download", - "sha256": "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - } - }, - "targets": [ - { - "Library": { - "crate_name": "smallvec", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "smallvec", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "const_generics" - ], - "selects": {} - }, - "edition": "2018", - "version": "1.15.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "socket2 0.6.3": { - "name": "socket2", - "version": "0.6.3", - "package_url": "https://github.com/rust-lang/socket2", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/socket2/0.6.3/download", - "sha256": "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" - } - }, - "targets": [ - { - "Library": { - "crate_name": "socket2", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "socket2", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "all" - ], - "selects": {} - }, - "deps": { - "common": [], - "selects": { - "cfg(any(unix, target_os = \"wasi\"))": [ - { - "id": "libc 0.2.183", - "target": "libc" - } - ], - "cfg(windows)": [ - { - "id": "windows-sys 0.61.2", - "target": "windows_sys" - } - ] - } - }, - "edition": "2021", - "version": "0.6.3" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "stable_deref_trait 1.2.1": { - "name": "stable_deref_trait", - "version": "1.2.1", - "package_url": "https://github.com/storyyeller/stable_deref_trait", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/stable_deref_trait/1.2.1/download", - "sha256": "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - } - }, - "targets": [ - { - "Library": { - "crate_name": "stable_deref_trait", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "stable_deref_trait", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2015", - "version": "1.2.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "subtle 2.6.1": { - "name": "subtle", - "version": "2.6.1", - "package_url": "https://github.com/dalek-cryptography/subtle", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/subtle/2.6.1/download", - "sha256": "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - } - }, - "targets": [ - { - "Library": { - "crate_name": "subtle", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "subtle", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2018", - "version": "2.6.1" - }, - "license": "BSD-3-Clause", - "license_ids": [ - "BSD-3-Clause" - ], - "license_file": "LICENSE" - }, - "syn 2.0.117": { - "name": "syn", - "version": "2.0.117", - "package_url": "https://github.com/dtolnay/syn", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/syn/2.0.117/download", - "sha256": "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" - } - }, - "targets": [ - { - "Library": { - "crate_name": "syn", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "syn", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "clone-impls", - "default", - "derive", - "extra-traits", - "fold", - "full", - "parsing", - "printing", - "proc-macro", - "visit", - "visit-mut" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "unicode-ident 1.0.24", - "target": "unicode_ident" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "2.0.117" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "synstructure 0.13.2": { - "name": "synstructure", - "version": "0.13.2", - "package_url": "https://github.com/mystor/synstructure", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/synstructure/0.13.2/download", - "sha256": "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" - } - }, - "targets": [ - { - "Library": { - "crate_name": "synstructure", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "synstructure", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "proc-macro" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.13.2" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "system-configuration 0.7.0": { - "name": "system-configuration", - "version": "0.7.0", - "package_url": "https://github.com/mullvad/system-configuration-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/system-configuration/0.7.0/download", - "sha256": "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" - } - }, - "targets": [ - { - "Library": { - "crate_name": "system_configuration", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "system_configuration", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "bitflags 2.11.0", - "target": "bitflags" - }, - { - "id": "core-foundation 0.9.4", - "target": "core_foundation" - }, - { - "id": "system-configuration-sys 0.6.0", - "target": "system_configuration_sys" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.7.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "system-configuration-sys 0.6.0": { - "name": "system-configuration-sys", - "version": "0.6.0", - "package_url": "https://github.com/mullvad/system-configuration-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/system-configuration-sys/0.6.0/download", - "sha256": "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" - } - }, - "targets": [ - { - "Library": { - "crate_name": "system_configuration_sys", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "system_configuration_sys", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "core-foundation-sys 0.8.7", - "target": "core_foundation_sys" - }, - { - "id": "libc 0.2.183", - "target": "libc" - }, - { - "id": "system-configuration-sys 0.6.0", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.6.0" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "tagptr 0.2.0": { - "name": "tagptr", - "version": "0.2.0", - "package_url": "https://github.com/oliver-giersch/tagptr.git", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/tagptr/0.2.0/download", - "sha256": "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" - } - }, - "targets": [ - { - "Library": { - "crate_name": "tagptr", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "tagptr", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2018", - "version": "0.2.0" - }, - "license": "MIT/Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "termtree 0.5.1": { - "name": "termtree", - "version": "0.5.1", - "package_url": "https://github.com/rust-cli/termtree", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/termtree/0.5.1/download", - "sha256": "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" - } - }, - "targets": [ - { - "Library": { - "crate_name": "termtree", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "termtree", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "0.5.1" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE-MIT" - }, - "test-programs 0.1.0": { - "name": "test-programs", - "version": "0.1.0", - "package_url": "https://github.com/envoyproxy/envoy", - "repository": null, - "targets": [], - "library_target_name": null, - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "0.1.0" - }, - "license": "Apache-2.0", - "license_ids": [ - "Apache-2.0" - ], - "license_file": null - }, - "thiserror 2.0.18": { - "name": "thiserror", - "version": "2.0.18", - "package_url": "https://github.com/dtolnay/thiserror", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/thiserror/2.0.18/download", - "sha256": "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" - } - }, - "targets": [ - { - "Library": { - "crate_name": "thiserror", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "thiserror", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "thiserror 2.0.18", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "thiserror-impl 2.0.18", - "target": "thiserror_impl" - } - ], - "selects": {} - }, - "version": "2.0.18" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "thiserror-impl 2.0.18": { - "name": "thiserror-impl", - "version": "2.0.18", - "package_url": "https://github.com/dtolnay/thiserror", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/thiserror-impl/2.0.18/download", - "sha256": "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "thiserror_impl", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "thiserror_impl", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "2.0.18" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "time 0.3.47": { - "name": "time", - "version": "0.3.47", - "package_url": "https://github.com/time-rs/time", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/time/0.3.47/download", - "sha256": "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" - } - }, - "targets": [ - { - "Library": { - "crate_name": "time", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "time", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "default", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "deranged 0.5.8", - "target": "deranged" - }, - { - "id": "num-conv 0.2.1", - "target": "num_conv" - }, - { - "id": "powerfmt 0.2.0", - "target": "powerfmt" - }, - { - "id": "time-core 0.1.8", - "target": "time_core" - } - ], - "selects": {} - }, - "edition": "2024", - "version": "0.3.47" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-Apache" - }, - "time-core 0.1.8": { - "name": "time-core", - "version": "0.1.8", - "package_url": "https://github.com/time-rs/time", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/time-core/0.1.8/download", - "sha256": "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" - } - }, - "targets": [ - { - "Library": { - "crate_name": "time_core", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "time_core", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2024", - "version": "0.1.8" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-Apache" - }, - "tinystr 0.8.2": { - "name": "tinystr", - "version": "0.8.2", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/tinystr/0.8.2/download", - "sha256": "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" - } - }, - "targets": [ - { - "Library": { - "crate_name": "tinystr", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "tinystr", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "zerovec" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "zerovec 0.11.5", - "target": "zerovec" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "displaydoc 0.2.5", - "target": "displaydoc" - } - ], - "selects": {} - }, - "version": "0.8.2" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "tinyvec 1.11.0": { - "name": "tinyvec", - "version": "1.11.0", - "package_url": "https://github.com/Lokathor/tinyvec", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/tinyvec/1.11.0/download", - "sha256": "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" - } - }, - "targets": [ - { - "Library": { - "crate_name": "tinyvec", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "tinyvec", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "default", - "tinyvec_macros" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "tinyvec_macros 0.1.1", - "target": "tinyvec_macros" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "1.11.0" - }, - "license": "Zlib OR Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT", - "Zlib" - ], - "license_file": "LICENSE-APACHE.md" - }, - "tinyvec_macros 0.1.1": { - "name": "tinyvec_macros", - "version": "0.1.1", - "package_url": "https://github.com/Soveu/tinyvec_macros", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/tinyvec_macros/0.1.1/download", - "sha256": "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - } - }, - "targets": [ - { - "Library": { - "crate_name": "tinyvec_macros", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "tinyvec_macros", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2018", - "version": "0.1.1" - }, - "license": "MIT OR Apache-2.0 OR Zlib", - "license_ids": [ - "Apache-2.0", - "MIT", - "Zlib" - ], - "license_file": "LICENSE-APACHE.md" - }, - "tokio 1.50.0": { - "name": "tokio", - "version": "1.50.0", - "package_url": "https://github.com/tokio-rs/tokio", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/tokio/1.50.0/download", - "sha256": "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" - } - }, - "targets": [ - { - "Library": { - "crate_name": "tokio", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "tokio", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "bytes", - "default", - "io-util", - "libc", - "macros", - "mio", - "net", - "rt", - "rt-multi-thread", - "socket2", - "sync", - "time", - "tokio-macros" - ], - "selects": { - "x86_64-pc-windows-msvc": [ - "windows-sys" - ] - } - }, - "deps": { - "common": [ - { - "id": "bytes 1.11.1", - "target": "bytes" - }, - { - "id": "mio 1.1.1", - "target": "mio" - }, - { - "id": "pin-project-lite 0.2.17", - "target": "pin_project_lite" - } - ], - "selects": { - "aarch64-apple-darwin": [ - { - "id": "libc 0.2.183", - "target": "libc" - }, - { - "id": "socket2 0.6.3", - "target": "socket2" - } - ], - "aarch64-unknown-linux-gnu": [ - { - "id": "libc 0.2.183", - "target": "libc" - }, - { - "id": "socket2 0.6.3", - "target": "socket2" - } - ], - "x86_64-pc-windows-msvc": [ - { - "id": "socket2 0.6.3", - "target": "socket2" - }, - { - "id": "windows-sys 0.61.2", - "target": "windows_sys" - } - ], - "x86_64-unknown-linux-gnu": [ - { - "id": "libc 0.2.183", - "target": "libc" - }, - { - "id": "socket2 0.6.3", - "target": "socket2" - } - ], - "x86_64-unknown-nixos-gnu": [ - { - "id": "libc 0.2.183", - "target": "libc" - }, - { - "id": "socket2 0.6.3", - "target": "socket2" - } - ] - } - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "tokio-macros 2.6.1", - "target": "tokio_macros" - } - ], - "selects": {} - }, - "version": "1.50.0" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "tokio-macros 2.6.1": { - "name": "tokio-macros", - "version": "2.6.1", - "package_url": "https://github.com/tokio-rs/tokio", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/tokio-macros/2.6.1/download", - "sha256": "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "tokio_macros", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "tokio_macros", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "2.6.1" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "tokio-rustls 0.26.4": { - "name": "tokio-rustls", - "version": "0.26.4", - "package_url": "https://github.com/rustls/tokio-rustls", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/tokio-rustls/0.26.4/download", - "sha256": "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" - } - }, - "targets": [ - { - "Library": { - "crate_name": "tokio_rustls", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "tokio_rustls", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "early-data", - "ring" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "rustls 0.23.37", - "target": "rustls" - }, - { - "id": "tokio 1.50.0", - "target": "tokio" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.26.4" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "tokio-util 0.7.18": { - "name": "tokio-util", - "version": "0.7.18", - "package_url": "https://github.com/tokio-rs/tokio", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/tokio-util/0.7.18/download", - "sha256": "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" - } - }, - "targets": [ - { - "Library": { - "crate_name": "tokio_util", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "tokio_util", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "codec", - "default", - "io" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "bytes 1.11.1", - "target": "bytes" - }, - { - "id": "futures-core 0.3.32", - "target": "futures_core" - }, - { - "id": "futures-sink 0.3.32", - "target": "futures_sink" - }, - { - "id": "pin-project-lite 0.2.17", - "target": "pin_project_lite" - }, - { - "id": "tokio 1.50.0", - "target": "tokio" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.7.18" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "tracing 0.1.44": { - "name": "tracing", - "version": "0.1.44", - "package_url": "https://github.com/tokio-rs/tracing", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/tracing/0.1.44/download", - "sha256": "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" - } - }, - "targets": [ - { - "Library": { - "crate_name": "tracing", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "tracing", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "pin-project-lite 0.2.17", - "target": "pin_project_lite" - }, - { - "id": "tracing-core 0.1.36", - "target": "tracing_core" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.1.44" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "tracing-core 0.1.36": { - "name": "tracing-core", - "version": "0.1.36", - "package_url": "https://github.com/tokio-rs/tracing", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/tracing-core/0.1.36/download", - "sha256": "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" - } - }, - "targets": [ - { - "Library": { - "crate_name": "tracing_core", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "tracing_core", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "once_cell", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "once_cell 1.21.4", - "target": "once_cell" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "0.1.36" - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE" - }, - "unicode-ident 1.0.24": { - "name": "unicode-ident", - "version": "1.0.24", - "package_url": "https://github.com/dtolnay/unicode-ident", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/unicode-ident/1.0.24/download", - "sha256": "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - } - }, - "targets": [ - { - "Library": { - "crate_name": "unicode_ident", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "unicode_ident", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "1.0.24" - }, - "license": "(MIT OR Apache-2.0) AND Unicode-3.0", - "license_ids": [ - "Apache-2.0", - "MIT", - "Unicode-3.0" - ], - "license_file": "LICENSE-APACHE" - }, - "unicode-xid 0.2.6": { - "name": "unicode-xid", - "version": "0.2.6", - "package_url": "https://github.com/unicode-rs/unicode-xid", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/unicode-xid/0.2.6/download", - "sha256": "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - } - }, - "targets": [ - { - "Library": { - "crate_name": "unicode_xid", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "unicode_xid", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default" - ], - "selects": {} - }, - "edition": "2015", - "version": "0.2.6" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "untrusted 0.9.0": { - "name": "untrusted", - "version": "0.9.0", - "package_url": "https://github.com/briansmith/untrusted", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/untrusted/0.9.0/download", - "sha256": "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - } - }, - "targets": [ - { - "Library": { - "crate_name": "untrusted", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "untrusted", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2018", - "version": "0.9.0" - }, - "license": "ISC", - "license_ids": [ - "ISC" - ], - "license_file": "LICENSE.txt" - }, - "url 2.5.8": { - "name": "url", - "version": "2.5.8", - "package_url": "https://github.com/servo/rust-url", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/url/2.5.8/download", - "sha256": "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" - } - }, - "targets": [ - { - "Library": { - "crate_name": "url", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "url", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "form_urlencoded 1.2.2", - "target": "form_urlencoded" - }, - { - "id": "idna 1.1.0", - "target": "idna" - }, - { - "id": "percent-encoding 2.3.2", - "target": "percent_encoding" - } - ], - "selects": {} - }, - "edition": "2018", - "version": "2.5.8" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "utf8_iter 1.0.4": { - "name": "utf8_iter", - "version": "1.0.4", - "package_url": "https://github.com/hsivonen/utf8_iter", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/utf8_iter/1.0.4/download", - "sha256": "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - } - }, - "targets": [ - { - "Library": { - "crate_name": "utf8_iter", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "utf8_iter", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "1.0.4" - }, - "license": "Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "uuid 1.22.0": { - "name": "uuid", - "version": "1.22.0", - "package_url": "https://github.com/uuid-rs/uuid", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/uuid/1.22.0/download", - "sha256": "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" - } - }, - "targets": [ - { - "Library": { - "crate_name": "uuid", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "uuid", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "rng", - "std", - "v4" - ], - "selects": {} - }, - "deps": { - "common": [], - "selects": { - "aarch64-apple-darwin": [ - { - "id": "getrandom 0.4.2", - "target": "getrandom" - } - ], - "aarch64-unknown-linux-gnu": [ - { - "id": "getrandom 0.4.2", - "target": "getrandom" - } - ], - "wasm32-wasip1": [ - { - "id": "getrandom 0.4.2", - "target": "getrandom" - } - ], - "x86_64-pc-windows-msvc": [ - { - "id": "getrandom 0.4.2", - "target": "getrandom" - } - ], - "x86_64-unknown-linux-gnu": [ - { - "id": "getrandom 0.4.2", - "target": "getrandom" - } - ], - "x86_64-unknown-nixos-gnu": [ - { - "id": "getrandom 0.4.2", - "target": "getrandom" - } - ] - } - }, - "edition": "2021", - "version": "1.22.0" - }, - "license": "Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "walkdir 2.5.0": { - "name": "walkdir", - "version": "2.5.0", - "package_url": "https://github.com/BurntSushi/walkdir", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/walkdir/2.5.0/download", - "sha256": "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" - } - }, - "targets": [ - { - "Library": { - "crate_name": "walkdir", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "walkdir", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "same-file 1.0.6", - "target": "same_file" - } - ], - "selects": { - "cfg(windows)": [ - { - "id": "winapi-util 0.1.11", - "target": "winapi_util" - } - ] - } - }, - "edition": "2018", - "version": "2.5.0" - }, - "license": "Unlicense/MIT", - "license_ids": [ - "MIT", - "Unlicense" - ], - "license_file": "LICENSE-MIT" - }, - "wasi 0.11.1+wasi-snapshot-preview1": { - "name": "wasi", - "version": "0.11.1+wasi-snapshot-preview1", - "package_url": "https://github.com/bytecodealliance/wasi", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wasi/0.11.1+wasi-snapshot-preview1/download", - "sha256": "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wasi", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wasi", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "edition": "2018", - "version": "0.11.1+wasi-snapshot-preview1" - }, - "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "wasip2 1.0.2+wasi-0.2.9": { - "name": "wasip2", - "version": "1.0.2+wasi-0.2.9", - "package_url": "https://github.com/bytecodealliance/wasi-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wasip2/1.0.2+wasi-0.2.9/download", - "sha256": "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wasip2", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wasip2", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "wit-bindgen 0.51.0", - "target": "wit_bindgen" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.0.2+wasi-0.2.9" - }, - "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": null - }, - "wasip3 0.4.0+wasi-0.3.0-rc-2026-01-06": { - "name": "wasip3", - "version": "0.4.0+wasi-0.3.0-rc-2026-01-06", - "package_url": "https://github.com/bytecodealliance/wasi-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wasip3/0.4.0+wasi-0.3.0-rc-2026-01-06/download", - "sha256": "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wasip3", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wasip3", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "wit-bindgen 0.51.0", - "target": "wit_bindgen" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.4.0+wasi-0.3.0-rc-2026-01-06" - }, - "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": null - }, - "wasm-bindgen 0.2.114": { - "name": "wasm-bindgen", - "version": "0.2.114", - "package_url": "https://github.com/wasm-bindgen/wasm-bindgen", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wasm-bindgen/0.2.114/download", - "sha256": "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wasm_bindgen", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wasm_bindgen", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "cfg-if 1.0.4", - "target": "cfg_if" - }, - { - "id": "once_cell 1.21.4", - "target": "once_cell" - }, - { - "id": "wasm-bindgen 0.2.114", - "target": "build_script_build" - }, - { - "id": "wasm-bindgen-shared 0.2.114", - "target": "wasm_bindgen_shared" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "wasm-bindgen-macro 0.2.114", - "target": "wasm_bindgen_macro" - } - ], - "selects": {} - }, - "version": "0.2.114" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ], - "link_deps": { - "common": [ - { - "id": "wasm-bindgen-shared 0.2.114", - "target": "wasm_bindgen_shared" - } - ], - "selects": {} - }, - "proc_macro_deps": { - "common": [ - { - "id": "rustversion 1.0.22", - "target": "rustversion", - "alias": "rustversion_compat" - } - ], - "selects": {} - } - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "wasm-bindgen-macro 0.2.114": { - "name": "wasm-bindgen-macro", - "version": "0.2.114", - "package_url": "https://github.com/wasm-bindgen/wasm-bindgen/tree/master/crates/macro", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wasm-bindgen-macro/0.2.114/download", - "sha256": "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "wasm_bindgen_macro", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wasm_bindgen_macro", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "wasm-bindgen-macro-support 0.2.114", - "target": "wasm_bindgen_macro_support" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.2.114" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "wasm-bindgen-macro-support 0.2.114": { - "name": "wasm-bindgen-macro-support", - "version": "0.2.114", - "package_url": "https://github.com/wasm-bindgen/wasm-bindgen/tree/master/crates/macro-support", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wasm-bindgen-macro-support/0.2.114/download", - "sha256": "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wasm_bindgen_macro_support", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wasm_bindgen_macro_support", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "bumpalo 3.20.2", - "target": "bumpalo" - }, - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - }, - { - "id": "wasm-bindgen-shared 0.2.114", - "target": "wasm_bindgen_shared" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.2.114" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "wasm-bindgen-shared 0.2.114": { - "name": "wasm-bindgen-shared", - "version": "0.2.114", - "package_url": "https://github.com/wasm-bindgen/wasm-bindgen/tree/master/crates/shared", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wasm-bindgen-shared/0.2.114/download", - "sha256": "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wasm_bindgen_shared", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wasm_bindgen_shared", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "unicode-ident 1.0.24", - "target": "unicode_ident" - }, - { - "id": "wasm-bindgen-shared 0.2.114", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.2.114" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ], - "links": "wasm_bindgen" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "wasm-encoder 0.244.0": { - "name": "wasm-encoder", - "version": "0.244.0", - "package_url": "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-encoder", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wasm-encoder/0.244.0/download", - "sha256": "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wasm_encoder", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wasm_encoder", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "component-model", - "std", - "wasmparser" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "leb128fmt 0.1.0", - "target": "leb128fmt" - }, - { - "id": "wasmparser 0.244.0", - "target": "wasmparser" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.244.0" - }, - "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": null - }, - "wasm-metadata 0.244.0": { - "name": "wasm-metadata", - "version": "0.244.0", - "package_url": "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-metadata", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wasm-metadata/0.244.0/download", - "sha256": "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wasm_metadata", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wasm_metadata", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "anyhow 1.0.102", - "target": "anyhow" - }, - { - "id": "indexmap 2.13.0", - "target": "indexmap" - }, - { - "id": "wasm-encoder 0.244.0", - "target": "wasm_encoder" - }, - { - "id": "wasmparser 0.244.0", - "target": "wasmparser" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.244.0" - }, - "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": null - }, - "wasmparser 0.244.0": { - "name": "wasmparser", - "version": "0.244.0", - "package_url": "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasmparser", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wasmparser/0.244.0/download", - "sha256": "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wasmparser", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wasmparser", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "component-model", - "features", - "hash-collections", - "simd", - "std", - "validate" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "bitflags 2.11.0", - "target": "bitflags" - }, - { - "id": "hashbrown 0.15.5", - "target": "hashbrown" - }, - { - "id": "indexmap 2.13.0", - "target": "indexmap" - }, - { - "id": "semver 1.0.27", - "target": "semver" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.244.0" - }, - "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": null - }, - "webpki-roots 1.0.6": { - "name": "webpki-roots", - "version": "1.0.6", - "package_url": "https://github.com/rustls/webpki-roots", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/webpki-roots/1.0.6/download", - "sha256": "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" - } - }, - "targets": [ - { - "Library": { - "crate_name": "webpki_roots", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "webpki_roots", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "rustls-pki-types 1.14.0", - "target": "rustls_pki_types", - "alias": "pki_types" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.0.6" - }, - "license": "CDLA-Permissive-2.0", - "license_ids": [ - "CDLA-Permissive-2.0" - ], - "license_file": "LICENSE" - }, - "widestring 1.2.1": { - "name": "widestring", - "version": "1.2.1", - "package_url": "https://github.com/VoidStarKat/widestring-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/widestring/1.2.1/download", - "sha256": "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" - } - }, - "targets": [ - { - "Library": { - "crate_name": "widestring", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "widestring", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "default", - "std" - ], - "selects": {} - }, - "edition": "2021", - "version": "1.2.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "winapi-util 0.1.11": { - "name": "winapi-util", - "version": "0.1.11", - "package_url": "https://github.com/BurntSushi/winapi-util", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/winapi-util/0.1.11/download", - "sha256": "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" - } - }, - "targets": [ - { - "Library": { - "crate_name": "winapi_util", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "winapi_util", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [], - "selects": { - "cfg(windows)": [ - { - "id": "windows-sys 0.61.2", - "target": "windows_sys" - } - ] - } - }, - "edition": "2021", - "version": "0.1.11" - }, - "license": "Unlicense OR MIT", - "license_ids": [ - "MIT", - "Unlicense" - ], - "license_file": "LICENSE-MIT" - }, - "windows-link 0.2.1": { - "name": "windows-link", - "version": "0.2.1", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows-link/0.2.1/download", - "sha256": "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_link", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_link", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "0.2.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows-registry 0.6.1": { - "name": "windows-registry", - "version": "0.6.1", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows-registry/0.6.1/download", - "sha256": "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_registry", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_registry", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "windows-link 0.2.1", - "target": "windows_link" - }, - { - "id": "windows-result 0.4.1", - "target": "windows_result" - }, - { - "id": "windows-strings 0.5.1", - "target": "windows_strings" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.6.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows-result 0.4.1": { - "name": "windows-result", - "version": "0.4.1", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows-result/0.4.1/download", - "sha256": "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_result", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_result", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "default", - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "windows-link 0.2.1", - "target": "windows_link" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.4.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows-strings 0.5.1": { - "name": "windows-strings", - "version": "0.5.1", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows-strings/0.5.1/download", - "sha256": "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_strings", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_strings", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "std" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "windows-link 0.2.1", - "target": "windows_link" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.5.1" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows-sys 0.52.0": { - "name": "windows-sys", - "version": "0.52.0", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows-sys/0.52.0/download", - "sha256": "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_sys", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_sys", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "windows-targets 0.52.6", - "target": "windows_targets" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.52.0" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows-sys 0.61.2": { - "name": "windows-sys", - "version": "0.61.2", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows-sys/0.61.2/download", - "sha256": "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_sys", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_sys", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "Wdk", - "Wdk_Foundation", - "Wdk_Storage", - "Wdk_Storage_FileSystem", - "Wdk_System", - "Wdk_System_IO", - "Win32", - "Win32_Foundation", - "Win32_Networking", - "Win32_Networking_WinSock", - "Win32_Security", - "Win32_Storage", - "Win32_Storage_FileSystem", - "Win32_System", - "Win32_System_IO", - "Win32_System_Pipes", - "Win32_System_Registry", - "Win32_System_SystemServices", - "Win32_System_Threading", - "Win32_System_WindowsProgramming", - "default" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "windows-link 0.2.1", - "target": "windows_link" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.61.2" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows-targets 0.52.6": { - "name": "windows-targets", - "version": "0.52.6", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows-targets/0.52.6/download", - "sha256": "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_targets", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_targets", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [], - "selects": { - "aarch64-pc-windows-gnullvm": [ - { - "id": "windows_aarch64_gnullvm 0.52.6", - "target": "windows_aarch64_gnullvm" - } - ], - "cfg(all(any(target_arch = \"x86_64\", target_arch = \"arm64ec\"), target_env = \"msvc\", not(windows_raw_dylib)))": [ - { - "id": "windows_x86_64_msvc 0.52.6", - "target": "windows_x86_64_msvc" - } - ], - "cfg(all(target_arch = \"aarch64\", target_env = \"msvc\", not(windows_raw_dylib)))": [ - { - "id": "windows_aarch64_msvc 0.52.6", - "target": "windows_aarch64_msvc" - } - ], - "cfg(all(target_arch = \"x86\", target_env = \"gnu\", not(target_abi = \"llvm\"), not(windows_raw_dylib)))": [ - { - "id": "windows_i686_gnu 0.52.6", - "target": "windows_i686_gnu" - } - ], - "cfg(all(target_arch = \"x86\", target_env = \"msvc\", not(windows_raw_dylib)))": [ - { - "id": "windows_i686_msvc 0.52.6", - "target": "windows_i686_msvc" - } - ], - "cfg(all(target_arch = \"x86_64\", target_env = \"gnu\", not(target_abi = \"llvm\"), not(windows_raw_dylib)))": [ - { - "id": "windows_x86_64_gnu 0.52.6", - "target": "windows_x86_64_gnu" - } - ], - "i686-pc-windows-gnullvm": [ - { - "id": "windows_i686_gnullvm 0.52.6", - "target": "windows_i686_gnullvm" - } - ], - "x86_64-pc-windows-gnullvm": [ - { - "id": "windows_x86_64_gnullvm 0.52.6", - "target": "windows_x86_64_gnullvm" - } - ] - } - }, - "edition": "2021", - "version": "0.52.6" - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows_aarch64_gnullvm 0.52.6": { - "name": "windows_aarch64_gnullvm", - "version": "0.52.6", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows_aarch64_gnullvm/0.52.6/download", - "sha256": "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_aarch64_gnullvm", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_aarch64_gnullvm", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "windows_aarch64_gnullvm 0.52.6", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.52.6" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows_aarch64_msvc 0.52.6": { - "name": "windows_aarch64_msvc", - "version": "0.52.6", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows_aarch64_msvc/0.52.6/download", - "sha256": "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_aarch64_msvc", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_aarch64_msvc", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "windows_aarch64_msvc 0.52.6", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.52.6" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows_i686_gnu 0.52.6": { - "name": "windows_i686_gnu", - "version": "0.52.6", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows_i686_gnu/0.52.6/download", - "sha256": "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_i686_gnu", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_i686_gnu", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "windows_i686_gnu 0.52.6", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.52.6" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows_i686_gnullvm 0.52.6": { - "name": "windows_i686_gnullvm", - "version": "0.52.6", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows_i686_gnullvm/0.52.6/download", - "sha256": "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_i686_gnullvm", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_i686_gnullvm", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "windows_i686_gnullvm 0.52.6", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.52.6" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows_i686_msvc 0.52.6": { - "name": "windows_i686_msvc", - "version": "0.52.6", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows_i686_msvc/0.52.6/download", - "sha256": "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_i686_msvc", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_i686_msvc", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "windows_i686_msvc 0.52.6", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.52.6" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows_x86_64_gnu 0.52.6": { - "name": "windows_x86_64_gnu", - "version": "0.52.6", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows_x86_64_gnu/0.52.6/download", - "sha256": "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_x86_64_gnu", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_x86_64_gnu", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "windows_x86_64_gnu 0.52.6", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.52.6" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows_x86_64_gnullvm 0.52.6": { - "name": "windows_x86_64_gnullvm", - "version": "0.52.6", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows_x86_64_gnullvm/0.52.6/download", - "sha256": "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_x86_64_gnullvm", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_x86_64_gnullvm", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "windows_x86_64_gnullvm 0.52.6", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.52.6" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "windows_x86_64_msvc 0.52.6": { - "name": "windows_x86_64_msvc", - "version": "0.52.6", - "package_url": "https://github.com/microsoft/windows-rs", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/windows_x86_64_msvc/0.52.6/download", - "sha256": "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - } - }, - "targets": [ - { - "Library": { - "crate_name": "windows_x86_64_msvc", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "windows_x86_64_msvc", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "windows_x86_64_msvc 0.52.6", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.52.6" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT OR Apache-2.0", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "license-apache-2.0" - }, - "wit-bindgen 0.51.0": { - "name": "wit-bindgen", - "version": "0.51.0", - "package_url": "https://github.com/bytecodealliance/wit-bindgen", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wit-bindgen/0.51.0/download", - "sha256": "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wit_bindgen", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wit_bindgen", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "wit-bindgen 0.51.0", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2024", - "version": "0.51.0" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "wit-bindgen-core 0.51.0": { - "name": "wit-bindgen-core", - "version": "0.51.0", - "package_url": "https://github.com/bytecodealliance/wit-bindgen", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wit-bindgen-core/0.51.0/download", - "sha256": "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wit_bindgen_core", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wit_bindgen_core", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "anyhow 1.0.102", - "target": "anyhow" - }, - { - "id": "heck 0.5.0", - "target": "heck" - }, - { - "id": "wit-parser 0.244.0", - "target": "wit_parser" - } - ], - "selects": {} - }, - "edition": "2024", - "version": "0.51.0" - }, - "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "wit-bindgen-rust 0.51.0": { - "name": "wit-bindgen-rust", - "version": "0.51.0", - "package_url": "https://github.com/bytecodealliance/wit-bindgen", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wit-bindgen-rust/0.51.0/download", - "sha256": "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wit_bindgen_rust", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wit_bindgen_rust", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "anyhow 1.0.102", - "target": "anyhow" - }, - { - "id": "heck 0.5.0", - "target": "heck" - }, - { - "id": "indexmap 2.13.0", - "target": "indexmap" - }, - { - "id": "prettyplease 0.2.37", - "target": "prettyplease" - }, - { - "id": "syn 2.0.117", - "target": "syn" - }, - { - "id": "wasm-metadata 0.244.0", - "target": "wasm_metadata" - }, - { - "id": "wit-bindgen-core 0.51.0", - "target": "wit_bindgen_core" - }, - { - "id": "wit-bindgen-rust 0.51.0", - "target": "build_script_build" - }, - { - "id": "wit-component 0.244.0", - "target": "wit_component" - } - ], - "selects": {} - }, - "edition": "2024", - "version": "0.51.0" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ], - "link_deps": { - "common": [ - { - "id": "prettyplease 0.2.37", - "target": "prettyplease" - } - ], - "selects": {} - } - }, - "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "wit-bindgen-rust-macro 0.51.0": { - "name": "wit-bindgen-rust-macro", - "version": "0.51.0", - "package_url": "https://github.com/bytecodealliance/wit-bindgen", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wit-bindgen-rust-macro/0.51.0/download", - "sha256": "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "wit_bindgen_rust_macro", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wit_bindgen_rust_macro", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "anyhow 1.0.102", - "target": "anyhow" - }, - { - "id": "prettyplease 0.2.37", - "target": "prettyplease" - }, - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - }, - { - "id": "wit-bindgen-core 0.51.0", - "target": "wit_bindgen_core" - }, - { - "id": "wit-bindgen-rust 0.51.0", - "target": "wit_bindgen_rust" - }, - { - "id": "wit-bindgen-rust-macro 0.51.0", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2024", - "version": "0.51.0" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ], - "link_deps": { - "common": [ - { - "id": "prettyplease 0.2.37", - "target": "prettyplease" - } - ], - "selects": {} - } - }, - "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "wit-component 0.244.0": { - "name": "wit-component", - "version": "0.244.0", - "package_url": "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wit-component", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wit-component/0.244.0/download", - "sha256": "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wit_component", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wit_component", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "anyhow 1.0.102", - "target": "anyhow" - }, - { - "id": "bitflags 2.11.0", - "target": "bitflags" - }, - { - "id": "indexmap 2.13.0", - "target": "indexmap" - }, - { - "id": "log 0.4.29", - "target": "log" - }, - { - "id": "serde 1.0.228", - "target": "serde" - }, - { - "id": "serde_json 1.0.149", - "target": "serde_json" - }, - { - "id": "wasm-encoder 0.244.0", - "target": "wasm_encoder" - }, - { - "id": "wasm-metadata 0.244.0", - "target": "wasm_metadata" - }, - { - "id": "wasmparser 0.244.0", - "target": "wasmparser" - }, - { - "id": "wit-parser 0.244.0", - "target": "wit_parser" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "serde_derive 1.0.228", - "target": "serde_derive" - } - ], - "selects": {} - }, - "version": "0.244.0" - }, - "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": null - }, - "wit-parser 0.244.0": { - "name": "wit-parser", - "version": "0.244.0", - "package_url": "https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wit-parser", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/wit-parser/0.244.0/download", - "sha256": "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" - } - }, - "targets": [ - { - "Library": { - "crate_name": "wit_parser", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "wit_parser", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "decoding", - "default", - "serde", - "serde_json" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "anyhow 1.0.102", - "target": "anyhow" - }, - { - "id": "id-arena 2.3.0", - "target": "id_arena" - }, - { - "id": "indexmap 2.13.0", - "target": "indexmap" - }, - { - "id": "log 0.4.29", - "target": "log" - }, - { - "id": "semver 1.0.27", - "target": "semver" - }, - { - "id": "serde 1.0.228", - "target": "serde" - }, - { - "id": "serde_json 1.0.149", - "target": "serde_json" - }, - { - "id": "unicode-xid 0.2.6", - "target": "unicode_xid" - }, - { - "id": "wasmparser 0.244.0", - "target": "wasmparser" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "serde_derive 1.0.228", - "target": "serde_derive" - } - ], - "selects": {} - }, - "version": "0.244.0" - }, - "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": null - }, - "writeable 0.6.2": { - "name": "writeable", - "version": "0.6.2", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/writeable/0.6.2/download", - "sha256": "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" - } - }, - "targets": [ - { - "Library": { - "crate_name": "writeable", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "writeable", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "edition": "2021", - "version": "0.6.2" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "yoke 0.8.1": { - "name": "yoke", - "version": "0.8.1", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/yoke/0.8.1/download", - "sha256": "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" - } - }, - "targets": [ - { - "Library": { - "crate_name": "yoke", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "yoke", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "derive", - "zerofrom" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "stable_deref_trait 1.2.1", - "target": "stable_deref_trait" - }, - { - "id": "zerofrom 0.1.6", - "target": "zerofrom" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "yoke-derive 0.8.1", - "target": "yoke_derive" - } - ], - "selects": {} - }, - "version": "0.8.1" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "yoke-derive 0.8.1": { - "name": "yoke-derive", - "version": "0.8.1", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/yoke-derive/0.8.1/download", - "sha256": "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "yoke_derive", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "yoke_derive", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - }, - { - "id": "synstructure 0.13.2", - "target": "synstructure" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.8.1" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "zerofrom 0.1.6": { - "name": "zerofrom", - "version": "0.1.6", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/zerofrom/0.1.6/download", - "sha256": "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" - } - }, - "targets": [ - { - "Library": { - "crate_name": "zerofrom", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "zerofrom", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "derive" - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "zerofrom-derive 0.1.6", - "target": "zerofrom_derive" - } - ], - "selects": {} - }, - "version": "0.1.6" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "zerofrom-derive 0.1.6": { - "name": "zerofrom-derive", - "version": "0.1.6", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/zerofrom-derive/0.1.6/download", - "sha256": "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "zerofrom_derive", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "zerofrom_derive", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - }, - { - "id": "synstructure 0.13.2", - "target": "synstructure" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.1.6" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "zeroize 1.8.2": { - "name": "zeroize", - "version": "1.8.2", - "package_url": "https://github.com/RustCrypto/utils", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/zeroize/1.8.2/download", - "sha256": "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" - } - }, - "targets": [ - { - "Library": { - "crate_name": "zeroize", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "zeroize", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "alloc", - "default" - ], - "selects": {} - }, - "edition": "2021", - "version": "1.8.2" - }, - "license": "Apache-2.0 OR MIT", - "license_ids": [ - "Apache-2.0", - "MIT" - ], - "license_file": "LICENSE-APACHE" - }, - "zerotrie 0.2.3": { - "name": "zerotrie", - "version": "0.2.3", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/zerotrie/0.2.3/download", - "sha256": "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" - } - }, - "targets": [ - { - "Library": { - "crate_name": "zerotrie", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "zerotrie", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "yoke", - "zerofrom" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "yoke 0.8.1", - "target": "yoke" - }, - { - "id": "zerofrom 0.1.6", - "target": "zerofrom" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "displaydoc 0.2.5", - "target": "displaydoc" - } - ], - "selects": {} - }, - "version": "0.2.3" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "zerovec 0.11.5": { - "name": "zerovec", - "version": "0.11.5", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/zerovec/0.11.5/download", - "sha256": "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" - } - }, - "targets": [ - { - "Library": { - "crate_name": "zerovec", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "zerovec", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "crate_features": { - "common": [ - "derive", - "yoke" - ], - "selects": {} - }, - "deps": { - "common": [ - { - "id": "yoke 0.8.1", - "target": "yoke" - }, - { - "id": "zerofrom 0.1.6", - "target": "zerofrom" - } - ], - "selects": {} - }, - "edition": "2021", - "proc_macro_deps": { - "common": [ - { - "id": "zerovec-derive 0.11.2", - "target": "zerovec_derive" - } - ], - "selects": {} - }, - "version": "0.11.5" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "zerovec-derive 0.11.2": { - "name": "zerovec-derive", - "version": "0.11.2", - "package_url": "https://github.com/unicode-org/icu4x", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/zerovec-derive/0.11.2/download", - "sha256": "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" - } - }, - "targets": [ - { - "ProcMacro": { - "crate_name": "zerovec_derive", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "zerovec_derive", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "proc-macro2 1.0.106", - "target": "proc_macro2" - }, - { - "id": "quote 1.0.45", - "target": "quote" - }, - { - "id": "syn 2.0.117", - "target": "syn" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "0.11.2" - }, - "license": "Unicode-3.0", - "license_ids": [ - "Unicode-3.0" - ], - "license_file": "LICENSE" - }, - "zmij 1.0.21": { - "name": "zmij", - "version": "1.0.21", - "package_url": "https://github.com/dtolnay/zmij", - "repository": { - "Http": { - "url": "https://static.crates.io/crates/zmij/1.0.21/download", - "sha256": "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" - } - }, - "targets": [ - { - "Library": { - "crate_name": "zmij", - "crate_root": "src/lib.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - }, - { - "BuildScript": { - "crate_name": "build_script_build", - "crate_root": "build.rs", - "srcs": { - "allow_empty": true, - "include": [ - "**/*.rs" - ] - } - } - } - ], - "library_target_name": "zmij", - "common_attrs": { - "compile_data_glob": [ - "**" - ], - "deps": { - "common": [ - { - "id": "zmij 1.0.21", - "target": "build_script_build" - } - ], - "selects": {} - }, - "edition": "2021", - "version": "1.0.21" - }, - "build_script_attrs": { - "compile_data_glob": [ - "**" - ], - "compile_data_glob_excludes": [ - "**/*.rs" - ], - "data_glob": [ - "**" - ] - }, - "license": "MIT", - "license_ids": [ - "MIT" - ], - "license_file": "LICENSE-MIT" - } - }, - "binary_crates": [], - "workspace_members": { - "envoy-dynamic-modules-builtin-extensions 0.1.0": "source/extensions/dynamic_modules/builtin_extensions", - "envoy-proxy-dynamic-modules-rust-sdk 0.1.0": "source/extensions/dynamic_modules/sdk/rust", - "test-programs 0.1.0": "test/extensions/dynamic_modules/test_data/rust" - }, - "conditions": { - "aarch64-apple-darwin": [ - "aarch64-apple-darwin" - ], - "aarch64-pc-windows-gnullvm": [], - "aarch64-unknown-linux-gnu": [ - "aarch64-unknown-linux-gnu" - ], - "cfg(all(all(target_arch = \"aarch64\", target_endian = \"little\"), target_os = \"windows\"))": [], - "cfg(all(all(target_arch = \"aarch64\", target_endian = \"little\"), target_vendor = \"apple\", any(target_os = \"ios\", target_os = \"macos\", target_os = \"tvos\", target_os = \"visionos\", target_os = \"watchos\")))": [ - "aarch64-apple-darwin" - ], - "cfg(all(any(all(target_arch = \"aarch64\", target_endian = \"little\"), all(target_arch = \"arm\", target_endian = \"little\")), any(target_os = \"android\", target_os = \"linux\")))": [ - "aarch64-unknown-linux-gnu" - ], - "cfg(all(any(target_arch = \"x86_64\", target_arch = \"arm64ec\"), target_env = \"msvc\", not(windows_raw_dylib)))": [ - "x86_64-pc-windows-msvc" - ], - "cfg(all(any(target_os = \"linux\", target_os = \"android\"), not(any(all(target_os = \"linux\", target_env = \"\"), getrandom_backend = \"custom\", getrandom_backend = \"linux_raw\", getrandom_backend = \"rdrand\", getrandom_backend = \"rndr\"))))": [ - "aarch64-unknown-linux-gnu", - "x86_64-unknown-linux-gnu", - "x86_64-unknown-nixos-gnu" - ], - "cfg(all(target_arch = \"aarch64\", target_env = \"msvc\", not(windows_raw_dylib)))": [], - "cfg(all(target_arch = \"aarch64\", target_os = \"android\"))": [], - "cfg(all(target_arch = \"aarch64\", target_os = \"linux\"))": [ - "aarch64-unknown-linux-gnu" - ], - "cfg(all(target_arch = \"aarch64\", target_vendor = \"apple\"))": [ - "aarch64-apple-darwin" - ], - "cfg(all(target_arch = \"loongarch64\", target_os = \"linux\"))": [], - "cfg(all(target_arch = \"wasm32\", target_os = \"wasi\", target_env = \"p2\"))": [], - "cfg(all(target_arch = \"wasm32\", target_os = \"wasi\", target_env = \"p3\"))": [], - "cfg(all(target_arch = \"x86\", target_env = \"gnu\", not(target_abi = \"llvm\"), not(windows_raw_dylib)))": [], - "cfg(all(target_arch = \"x86\", target_env = \"msvc\", not(windows_raw_dylib)))": [], - "cfg(all(target_arch = \"x86_64\", target_env = \"gnu\", not(target_abi = \"llvm\"), not(windows_raw_dylib)))": [ - "x86_64-unknown-linux-gnu", - "x86_64-unknown-nixos-gnu" - ], - "cfg(all(target_os = \"uefi\", getrandom_backend = \"efi_rng\"))": [], - "cfg(any())": [], - "cfg(any(target_arch = \"x86_64\", target_arch = \"x86\"))": [ - "x86_64-pc-windows-msvc", - "x86_64-unknown-linux-gnu", - "x86_64-unknown-nixos-gnu" - ], - "cfg(any(target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"hurd\", target_os = \"illumos\", target_os = \"cygwin\", all(target_os = \"horizon\", target_arch = \"arm\")))": [], - "cfg(any(target_os = \"haiku\", target_os = \"redox\", target_os = \"nto\", target_os = \"aix\"))": [], - "cfg(any(target_os = \"ios\", target_os = \"visionos\", target_os = \"watchos\", target_os = \"tvos\"))": [], - "cfg(any(target_os = \"macos\", target_os = \"openbsd\", target_os = \"vita\", target_os = \"emscripten\"))": [ - "aarch64-apple-darwin" - ], - "cfg(any(unix, target_os = \"wasi\"))": [ - "aarch64-apple-darwin", - "aarch64-unknown-linux-gnu", - "wasm32-wasip1", - "x86_64-unknown-linux-gnu", - "x86_64-unknown-nixos-gnu" - ], - "cfg(target_os = \"android\")": [], - "cfg(target_os = \"hermit\")": [], - "cfg(target_os = \"netbsd\")": [], - "cfg(target_os = \"redox\")": [], - "cfg(target_os = \"solaris\")": [], - "cfg(target_os = \"vxworks\")": [], - "cfg(target_os = \"wasi\")": [ - "wasm32-wasip1" - ], - "cfg(unix)": [ - "aarch64-apple-darwin", - "aarch64-unknown-linux-gnu", - "x86_64-unknown-linux-gnu", - "x86_64-unknown-nixos-gnu" - ], - "cfg(windows)": [ - "x86_64-pc-windows-msvc" - ], - "i686-pc-windows-gnullvm": [], - "wasm32-unknown-unknown": [ - "wasm32-unknown-unknown" - ], - "wasm32-wasip1": [ - "wasm32-wasip1" - ], - "x86_64-pc-windows-gnullvm": [], - "x86_64-pc-windows-msvc": [ - "x86_64-pc-windows-msvc" - ], - "x86_64-unknown-linux-gnu": [ - "x86_64-unknown-linux-gnu", - "x86_64-unknown-nixos-gnu" - ], - "x86_64-unknown-nixos-gnu": [ - "x86_64-unknown-nixos-gnu" - ] - }, - "direct_deps": [ - "bindgen 0.70.1", - "hickory-resolver 0.26.1", - "mockall 0.13.1", - "serde 1.0.228", - "serde_json 1.0.149", - "time 0.3.47", - "tokio 1.50.0", - "url 2.5.8" - ], - "direct_dev_deps": [], - "unused_patches": [] -} diff --git a/bazel/get_workspace_status b/bazel/get_workspace_status index 4cfce22fd..c780ec09a 100755 --- a/bazel/get_workspace_status +++ b/bazel/get_workspace_status @@ -17,6 +17,10 @@ # done by prefixing keys with "STABLE_". To avoid breaking compatibility with # other status scripts, this one still echos the non-stable ("volatile") names. +# The year @envoy_toolshed//certs uses to stamp generated test certificates. +# Certificates are valid from Jan 1 of this year, which keeps them from ageing out of validity. +echo "STABLE_CERT_EPOCH_YEAR $(date -u +%Y)" + # If this SOURCE_VERSION file exists then it must have been placed here by a # distribution doing a non-git, source build. # Distributions would be expected to echo the commit/tag as BUILD_SCM_REVISION diff --git a/bazel/local_llvm.bzl b/bazel/local_llvm.bzl deleted file mode 100644 index ca8f47d27..000000000 --- a/bazel/local_llvm.bzl +++ /dev/null @@ -1,62 +0,0 @@ -"""Provide @llvm_toolchain_llvm when building with a local LLVM (BAZEL_LLVM_PATH). - -In local LLVM mode envoy_toolchains() creates @llvm_toolchain_llvm without the -//:clang-format target that @envoy//tools/clang-format depends on. Pre-creating -the repo here (before envoy_toolchains(), which skips existing repos) adds that -target. No-op when BAZEL_LLVM_PATH is unset: the hermetic toolchain already -provides //:clang-format. -""" - -load("@envoy_repo//:compiler.bzl", "LLVM_PATH") - -# This repo replaces the one envoy_toolchains() would create, so it must define every -# target Envoy's _LLVM_LOCAL_BUILD (bazel/toolchains.bzl) does, plus clang-format. The -# globs below are deliberately a superset of Envoy's exact file lists so that upstream -# adding a file to _LLVM_LOCAL_BUILD does not silently break the local LLVM build. -_LLVM_LOCAL_BUILD = """\ -package(default_visibility = ["//visibility:public"]) - -exports_files(glob( - [ - "bin/*", - "lib/**", - "lib64/**", - "include/**", - ], - allow_empty = True, -)) - -filegroup( - name = "include", - srcs = glob([ - "include/**/c++/**", - "lib/clang/*/include/**", - ]), -) - -filegroup( - name = "all_includes", - srcs = glob( - ["include/**"], - allow_empty = True, - ), -) - -filegroup( - name = "symbolizer", - srcs = glob(["bin/llvm-symbolizer*"]), -) - -filegroup( - name = "clang-format", - srcs = ["bin/clang-format"], -) -""" - -def local_llvm_repo(name): - if LLVM_PATH: - native.new_local_repository( - name = name, - path = LLVM_PATH, - build_file_content = _LLVM_LOCAL_BUILD, - ) diff --git a/bazel/platform_mappings b/bazel/platform_mappings deleted file mode 100644 index 46c5307b3..000000000 --- a/bazel/platform_mappings +++ /dev/null @@ -1,16 +0,0 @@ -platforms: - //bazel:linux_aarch64 - --cpu=aarch64 - --crosstool_top=//bazel/toolchains:toolchain - - //bazel:linux_x86_64 - --cpu=k8 - --crosstool_top=//bazel/toolchains:toolchain - -flags: - --cpu=k8 - //bazel:linux_x86_64 - - --cpu=aarch64 - //bazel:linux_aarch64 - diff --git a/bazel/setup_clang.sh b/bazel/setup_clang.sh deleted file mode 100755 index c9a80195d..000000000 --- a/bazel/setup_clang.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -BAZELRC_FILE="${BAZELRC_FILE:-$(bazel info workspace)/clang.bazelrc}" - -LLVM_PREFIX=$1 - -if [[ ! -e "${LLVM_PREFIX}/bin/llvm-config" ]]; then - echo "Error: cannot find llvm-config in ${LLVM_PREFIX}." - exit 1 -fi - -BINDIR="$("${LLVM_PREFIX}"/bin/llvm-config --bindir)" -PATH="${BINDIR}:${PATH}" -export PATH - -LLVM_VERSION="$(llvm-config --version)" -LLVM_LIBDIR="$(llvm-config --libdir)" -LLVM_TARGET="$(llvm-config --host-target)" - -RT_LIBRARY_PATH="${LLVM_LIBDIR}/clang/${LLVM_VERSION}/lib/${LLVM_TARGET}" - -echo "# Generated file, do not edit. If you want to disable clang, just delete this file. -build:clang-local --action_env='PATH=${PATH}' --host_action_env='PATH=${PATH}' -build:clang-local --action_env='LLVM_CONFIG=${LLVM_PREFIX}/bin/llvm-config' --host_action_env='LLVM_CONFIG=${LLVM_PREFIX}/bin/llvm-config' -build:clang-local --repo_env='LLVM_CONFIG=${LLVM_PREFIX}/bin/llvm-config' -build:clang-local --linkopt='-L$(llvm-config --libdir)' -build:clang-local --linkopt='-Wl,-rpath,$(llvm-config --libdir)' - -build:clang-asan --linkopt='-L${RT_LIBRARY_PATH}' -" >"${BAZELRC_FILE}" diff --git a/bazel/toolchains/BUILD b/bazel/toolchains/BUILD deleted file mode 100644 index 2aa0b67ac..000000000 --- a/bazel/toolchains/BUILD +++ /dev/null @@ -1,275 +0,0 @@ -load("@rules_cc//cc:defs.bzl", "cc_toolchain", "cc_toolchain_suite") -load(":cc_toolchain_config.bzl", "cc_toolchain_config") - -# Using platform-provided files -filegroup(name = "empty") - -config_setting( - name = "msan_target_build", - constraint_values = [ - "//bazel:cilium_target_platform_enabled", - ], - values = {"define": "ENVOY_CONFIG_MSAN=1"}, -) - -config_setting( - name = "tsan_target_build", - constraint_values = [ - "//bazel:cilium_target_platform_enabled", - ], - values = {"define": "ENVOY_CONFIG_TSAN=1"}, -) - -toolchain( - name = "aarch64_linux_cc_toolchain", - exec_compatible_with = ["@platforms//os:linux"], - target_compatible_with = [ - "@platforms//cpu:aarch64", - "@platforms//os:linux", - ], - toolchain = ":clang_aarch64_linux_cc_toolchain", - toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", -) - -cc_toolchain( - name = "clang_aarch64_linux_cc_toolchain", - all_files = ":empty", - compiler_files = ":empty", - dwp_files = ":empty", - linker_files = ":empty", - objcopy_files = ":empty", - strip_files = ":empty", - toolchain_config = ":clang_aarch64_linux_toolchain_config", -) - -cc_toolchain_config( - name = "clang_aarch64_linux_toolchain_config", - abi_libc_version = "aarch64", - abi_version = "aarch64", - compile_flags = [ - "--target=aarch64-unknown-linux-gnu", - "-fuse-ld=lld", # cmake compiler test needs this - "-U_FORTIFY_SOURCE", - "-fstack-protector", - "-Wall", - "-Wunused-but-set-parameter", - "-Wthread-safety-analysis", - "-Wno-free-nonheap-object", - "-fno-omit-frame-pointer", - # Needed by Envoy dependencies to build: - "-Wno-unused-command-line-argument", # tcmalloc needs this since -fuse-ld was added above - "-Wno-deprecated-builtins", - ], - compiler = "clang", - coverage_compile_flags = ["--coverage"], - coverage_link_flags = ["--coverage"], - cpu = "aarch64", - cxx_builtin_include_directories = [ - "/usr/lib/llvm-18", - "/usr/lib/clang", - "/usr/aarch64-linux-gnu/include", - "/usr/include", - ], - cxx_flags = ["-std=c++0x"], - dbg_compile_flags = ["-g"], - # Cross-compilation flags exported as environment variables for foreign_cc - # rules (e.g. liburing's configure_make). This ensures foreign build systems - # see the correct --target when they use CFLAGS/CPPFLAGS from the environment. - foreign_cc_env = { - "CFLAGS": "--target=aarch64-unknown-linux-gnu -fuse-ld=lld", - "CPPFLAGS": "--target=aarch64-unknown-linux-gnu -fuse-ld=lld", - # -lc is needed because liburing builds a shared library with -Wl,-z,defs - # which requires all symbols (including memset from libc) to be resolved. - # The cross-compiler driver doesn't implicitly add -lc for shared libraries. - "LDFLAGS": "--target=aarch64-unknown-linux-gnu -fuse-ld=lld -lc", - }, - host_system_name = "local", - link_flags = [ - "--target=aarch64-unknown-linux-gnu", - "-fuse-ld=lld", - "-Wl,-no-as-needed", - "-Wl,-z,relro,-z,now", - "-lm", - ], - link_libs = [ - "-l:libstdc++.a", - "-latomic", - ], - opt_compile_flags = [ - "-g0", - "-O2", - "-D_FORTIFY_SOURCE=1", - "-DNDEBUG", - "-ffunction-sections", - "-fdata-sections", - ], - opt_link_flags = ["-Wl,--gc-sections"], - supports_start_end_lib = True, - target_libc = "glibc", - target_system_name = "aarch64-linux-gnu", - tool_paths = { - "ar": "/usr/bin/llvm-ar", - "compat-ld": "/usr/bin/lld", - "ld": "/usr/bin/lld", - "gold": "/usr/bin/lld", - "cpp": "/usr/bin/clang-cpp", - "gcc": "/usr/bin/clang", - "dwp": "/usr/bin/llvm-dwp", - "gcov": "/usr/bin/llvm-cov", - "nm": "/usr/bin/llvm-nm", - "objcopy": "/usr/bin/llvm-objcopy", - "objdump": "/usr/bin/llvm-objdump", - "strip": "/usr/bin/llvm-strip", - }, - toolchain_identifier = "linux_aarch64", - unfiltered_compile_flags = [ - "-Wno-builtin-macro-redefined", - "-D__DATE__=\"redacted\"", - "-D__TIMESTAMP__=\"redacted\"", - "-D__TIME__=\"redacted\"", - ], - # - # cxx_builtin_include_directories entries need "" prefix if sysroot is set - # - # builtin_sysroot = "/sysroot", -) - -toolchain( - name = "x86_64_linux_cc_toolchain", - exec_compatible_with = ["@platforms//os:linux"], - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], - toolchain = ":clang_x86_64_linux_cc_toolchain", - toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", -) - -cc_toolchain( - name = "clang_x86_64_linux_cc_toolchain", - all_files = ":empty", - compiler_files = ":empty", - dwp_files = ":empty", - linker_files = ":empty", - objcopy_files = ":empty", - strip_files = ":empty", - toolchain_config = ":clang_x86_64_linux_toolchain_config", -) - -cc_toolchain_config( - name = "clang_x86_64_linux_toolchain_config", - abi_libc_version = "unknown", - abi_version = "unknown", - compile_flags = [ - "--target=x86_64-unknown-linux-gnu", - "-fuse-ld=lld", # cmake compiler test needs this - "-U_FORTIFY_SOURCE", - "-fstack-protector", - "-Wall", - "-Wunused-but-set-parameter", - "-Wthread-safety-analysis", - "-Wno-free-nonheap-object", - "-fno-omit-frame-pointer", - # Needed by Envoy dependencies to build: - "-Wno-unused-command-line-argument", # tcmalloc needs this since -fuse-ld was added above - "-Wno-deprecated-builtins", - ], - compiler = "clang", - coverage_compile_flags = ["--coverage"], - coverage_link_flags = ["--coverage"], - cpu = "k8", - cxx_builtin_include_directories = [ - "/usr/lib/llvm-18", - "/usr/lib/clang", - "/usr/x86_64-linux-gnu/include", - "/usr/include", - ], - cxx_flags = ["-std=c++0x"] + select({ - "@envoy//bazel:msan_build": ["-stdlib=libc++"], - "@envoy//bazel:tsan_build": ["-stdlib=libc++"], - "//conditions:default": [], - }), - dbg_compile_flags = ["-g"], - host_system_name = "local", - link_flags = [ - "--target=x86_64-unknown-linux-gnu", - "-fuse-ld=lld", - "-Wl,-no-as-needed", - "-Wl,-z,relro,-z,now", - "-lm", - ] + select({ - "@envoy//bazel:msan_build": ["-L/usr/lib/llvm-18/lib"], - "@envoy//bazel:tsan_build": ["-L/usr/lib/llvm-18/lib"], - "//conditions:default": [], - }), - # Envoy supplies instrumented libc++ for MSAN and TSAN targets. - # Non-instrumented Bazel exec tools use the system libc++ runtime below. - link_libs = select({ - ":msan_target_build": [ - "-latomic", - ], - ":tsan_target_build": [ - "-latomic", - ], - "@envoy//bazel:msan_build": [ - "-l:libc++.a", - "-l:libc++abi.a", - "-latomic", - ], - "@envoy//bazel:tsan_build": [ - "-l:libc++.a", - "-l:libc++abi.a", - "-latomic", - ], - "//conditions:default": [ - "-l:libstdc++.a", - "-latomic", - ], - }), - opt_compile_flags = [ - "-g0", - "-O2", - "-D_FORTIFY_SOURCE=1", - "-DNDEBUG", - "-ffunction-sections", - "-fdata-sections", - ], - opt_link_flags = ["-Wl,--gc-sections"], - supports_start_end_lib = True, - target_libc = "unknown", - target_system_name = "unknown", - tool_paths = { - "ar": "/usr/bin/llvm-ar", - "compat-ld": "/usr/bin/lld", - "ld": "/usr/bin/lld", - "gold": "/usr/bin/lld", - "cpp": "/usr/bin/clang-cpp", - "gcc": "/usr/bin/clang", - "dwp": "/usr/bin/llvm-dwp", - "gcov": "/usr/bin/llvm-cov", - "nm": "/usr/bin/llvm-nm", - "objcopy": "/usr/bin/llvm-objcopy", - "objdump": "/usr/bin/llvm-objdump", - "strip": "/usr/bin/llvm-strip", - }, - toolchain_identifier = "linux_x86_64", - unfiltered_compile_flags = [ - "-Wno-builtin-macro-redefined", - "-D__DATE__=\"redacted\"", - "-D__TIMESTAMP__=\"redacted\"", - "-D__TIME__=\"redacted\"", - ], - # - # cxx_builtin_include_directories entries need "%sysroot%" prefix if sysroot is set - # - # builtin_sysroot = "/sysroot", -) - -# still needed to avoid use of local_config_cc toolchain -cc_toolchain_suite( - name = "toolchain", - toolchains = { - "k8": ":clang_x86_64_linux_cc_toolchain", - "aarch64": ":clang_aarch64_linux_cc_toolchain", - }, -) diff --git a/bazel/toolchains/cc_toolchain_config.bzl b/bazel/toolchains/cc_toolchain_config.bzl deleted file mode 100644 index 500f69d96..000000000 --- a/bazel/toolchains/cc_toolchain_config.bzl +++ /dev/null @@ -1,1287 +0,0 @@ -# Copied from https://github.com/envoyproxy/envoy-build-tools -# Originally generatd by https://github.com/bazelbuild/bazel-toolchains -# -# Copyright 2019 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""A Starlark cc_toolchain configuration rule""" - -load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES") -load( - "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", - "env_entry", - "env_set", - "feature", - "feature_set", - "flag_group", - "flag_set", - "tool_path", - "variable_with_value", - "with_feature_set", -) - -def layering_check_features(compiler): - if compiler != "clang": - return [] - return [ - feature( - name = "use_module_maps", - requires = [feature_set(features = ["module_maps"])], - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.cpp_header_parsing, - ACTION_NAMES.cpp_module_compile, - ], - flag_groups = [ - flag_group( - flags = [ - "-fmodule-name=%{module_name}", - "-fmodule-map-file=%{module_map_file}", - ], - ), - ], - ), - ], - ), - - # Tell blaze we support module maps in general, so they will be generated - # for all c/c++ rules. - # Note: not all C++ rules support module maps; thus, do not imply this - # feature from other features - instead, require it. - feature(name = "module_maps", enabled = True), - feature( - name = "layering_check", - implies = ["use_module_maps"], - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.cpp_header_parsing, - ACTION_NAMES.cpp_module_compile, - ], - flag_groups = [ - flag_group(flags = [ - "-fmodules-strict-decluse", - "-Wprivate-header", - ]), - flag_group( - iterate_over = "dependent_module_map_files", - flags = [ - "-fmodule-map-file=%{dependent_module_map_files}", - ], - ), - ], - ), - ], - ), - ] - -all_compile_actions = [ - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.linkstamp_compile, - ACTION_NAMES.assemble, - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.cpp_header_parsing, - ACTION_NAMES.cpp_module_compile, - ACTION_NAMES.cpp_module_codegen, - ACTION_NAMES.clif_match, - ACTION_NAMES.lto_backend, -] - -all_cpp_compile_actions = [ - ACTION_NAMES.cpp_compile, - ACTION_NAMES.linkstamp_compile, - ACTION_NAMES.cpp_header_parsing, - ACTION_NAMES.cpp_module_compile, - ACTION_NAMES.cpp_module_codegen, - ACTION_NAMES.clif_match, -] - -preprocessor_compile_actions = [ - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.linkstamp_compile, - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.cpp_header_parsing, - ACTION_NAMES.cpp_module_compile, - ACTION_NAMES.clif_match, -] - -codegen_compile_actions = [ - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.linkstamp_compile, - ACTION_NAMES.assemble, - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.cpp_module_codegen, - ACTION_NAMES.lto_backend, -] - -all_link_actions = [ - ACTION_NAMES.cpp_link_executable, - ACTION_NAMES.cpp_link_dynamic_library, - ACTION_NAMES.cpp_link_nodeps_dynamic_library, -] - -lto_index_actions = [ - ACTION_NAMES.lto_index_for_executable, - ACTION_NAMES.lto_index_for_dynamic_library, - ACTION_NAMES.lto_index_for_nodeps_dynamic_library, -] - -def _impl(ctx): - tool_paths = [ - tool_path(name = name, path = path) - for name, path in ctx.attr.tool_paths.items() - ] - action_configs = [] - - supports_pic_feature = feature( - name = "supports_pic", - enabled = True, - ) - supports_start_end_lib_feature = feature( - name = "supports_start_end_lib", - enabled = True, - ) - - default_compile_flags_feature = feature( - name = "default_compile_flags", - enabled = True, - flag_sets = [ - flag_set( - actions = all_compile_actions, - flag_groups = ([ - flag_group( - flags = ctx.attr.compile_flags, - ), - ] if ctx.attr.compile_flags else []), - ), - flag_set( - actions = all_compile_actions, - flag_groups = ([ - flag_group( - flags = ctx.attr.dbg_compile_flags, - ), - ] if ctx.attr.dbg_compile_flags else []), - with_features = [with_feature_set(features = ["dbg"])], - ), - flag_set( - actions = all_compile_actions, - flag_groups = ([ - flag_group( - flags = ctx.attr.opt_compile_flags, - ), - ] if ctx.attr.opt_compile_flags else []), - with_features = [with_feature_set(features = ["opt"])], - ), - flag_set( - actions = all_cpp_compile_actions + [ACTION_NAMES.lto_backend], - flag_groups = ([ - flag_group( - flags = ctx.attr.cxx_flags, - ), - ] if ctx.attr.cxx_flags else []), - ), - ], - ) - - default_link_flags_feature = feature( - name = "default_link_flags", - enabled = True, - flag_sets = [ - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = ([ - flag_group( - flags = ctx.attr.link_flags, - ), - ] if ctx.attr.link_flags else []), - ), - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = ([ - flag_group( - flags = ctx.attr.opt_link_flags, - ), - ] if ctx.attr.opt_link_flags else []), - with_features = [with_feature_set(features = ["opt"])], - ), - ], - ) - - dbg_feature = feature(name = "dbg") - - opt_feature = feature(name = "opt") - - sysroot_feature = feature( - name = "sysroot", - enabled = True, - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.linkstamp_compile, - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.cpp_header_parsing, - ACTION_NAMES.cpp_module_compile, - ACTION_NAMES.cpp_module_codegen, - ACTION_NAMES.lto_backend, - ACTION_NAMES.clif_match, - ] + all_link_actions + lto_index_actions, - flag_groups = [ - flag_group( - flags = ["--sysroot=%{sysroot}"], - expand_if_available = "sysroot", - ), - ], - ), - ], - ) - - fdo_optimize_feature = feature( - name = "fdo_optimize", - flag_sets = [ - flag_set( - actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], - flag_groups = [ - flag_group( - flags = [ - "-fprofile-use=%{fdo_profile_path}", - "-fprofile-correction", - ], - expand_if_available = "fdo_profile_path", - ), - ], - ), - ], - provides = ["profile"], - ) - - supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) - - user_compile_flags_feature = feature( - name = "user_compile_flags", - enabled = True, - flag_sets = [ - flag_set( - actions = all_compile_actions, - flag_groups = [ - flag_group( - flags = ["%{user_compile_flags}"], - iterate_over = "user_compile_flags", - expand_if_available = "user_compile_flags", - ), - ], - ), - ], - ) - - unfiltered_compile_flags_feature = feature( - name = "unfiltered_compile_flags", - enabled = True, - flag_sets = [ - flag_set( - actions = all_compile_actions, - flag_groups = ([ - flag_group( - flags = ctx.attr.unfiltered_compile_flags, - ), - ] if ctx.attr.unfiltered_compile_flags else []), - ), - ], - ) - - library_search_directories_feature = feature( - name = "library_search_directories", - flag_sets = [ - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = [ - flag_group( - flags = ["-L%{library_search_directories}"], - iterate_over = "library_search_directories", - expand_if_available = "library_search_directories", - ), - ], - ), - ], - ) - - static_libgcc_feature = feature( - name = "static_libgcc", - enabled = True, - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.cpp_link_executable, - ACTION_NAMES.cpp_link_dynamic_library, - ACTION_NAMES.lto_index_for_executable, - ACTION_NAMES.lto_index_for_dynamic_library, - ], - flag_groups = [flag_group(flags = ["-static-libgcc"])], - with_features = [ - with_feature_set(features = ["static_link_cpp_runtimes"]), - ], - ), - ], - ) - - pic_feature = feature( - name = "pic", - enabled = True, - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.assemble, - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.linkstamp_compile, - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.cpp_module_codegen, - ACTION_NAMES.cpp_module_compile, - ], - flag_groups = [ - flag_group(flags = ["-fPIC"], expand_if_available = "pic"), - ], - ), - ], - ) - - per_object_debug_info_feature = feature( - name = "per_object_debug_info", - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.assemble, - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.cpp_module_codegen, - ], - flag_groups = [ - flag_group( - flags = ["-gsplit-dwarf"], - expand_if_available = "per_object_debug_info_file", - ), - ], - ), - ], - ) - - preprocessor_defines_feature = feature( - name = "preprocessor_defines", - enabled = True, - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.linkstamp_compile, - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.cpp_header_parsing, - ACTION_NAMES.cpp_module_compile, - ACTION_NAMES.clif_match, - ], - flag_groups = [ - flag_group( - flags = ["-D%{preprocessor_defines}"], - iterate_over = "preprocessor_defines", - ), - ], - ), - ], - ) - - cs_fdo_optimize_feature = feature( - name = "cs_fdo_optimize", - flag_sets = [ - flag_set( - actions = [ACTION_NAMES.lto_backend], - flag_groups = [ - flag_group( - flags = [ - "-fprofile-use=%{fdo_profile_path}", - "-Wno-profile-instr-unprofiled", - "-Wno-profile-instr-out-of-date", - "-fprofile-correction", - ], - expand_if_available = "fdo_profile_path", - ), - ], - ), - ], - provides = ["csprofile"], - ) - - autofdo_feature = feature( - name = "autofdo", - flag_sets = [ - flag_set( - actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], - flag_groups = [ - flag_group( - flags = [ - "-fauto-profile=%{fdo_profile_path}", - "-fprofile-correction", - ], - expand_if_available = "fdo_profile_path", - ), - ], - ), - ], - provides = ["profile"], - ) - - runtime_library_search_directories_feature = feature( - name = "runtime_library_search_directories", - flag_sets = [ - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = [ - flag_group( - iterate_over = "runtime_library_search_directories", - flag_groups = [ - flag_group( - flags = [ - "-Wl,-rpath,$EXEC_ORIGIN/%{runtime_library_search_directories}", - ], - expand_if_true = "is_cc_test", - ), - flag_group( - flags = [ - "-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}", - ], - expand_if_false = "is_cc_test", - ), - ], - expand_if_available = - "runtime_library_search_directories", - ), - ], - with_features = [ - with_feature_set(features = ["static_link_cpp_runtimes"]), - ], - ), - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = [ - flag_group( - iterate_over = "runtime_library_search_directories", - flag_groups = [ - flag_group( - flags = [ - "-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}", - ], - ), - ], - expand_if_available = - "runtime_library_search_directories", - ), - ], - with_features = [ - with_feature_set( - not_features = ["static_link_cpp_runtimes"], - ), - ], - ), - ], - ) - - fission_support_feature = feature( - name = "fission_support", - flag_sets = [ - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = [ - flag_group( - flags = ["-Wl,--gdb-index"], - expand_if_available = "is_using_fission", - ), - ], - ), - ], - ) - - shared_flag_feature = feature( - name = "shared_flag", - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.cpp_link_dynamic_library, - ACTION_NAMES.cpp_link_nodeps_dynamic_library, - ACTION_NAMES.lto_index_for_dynamic_library, - ACTION_NAMES.lto_index_for_nodeps_dynamic_library, - ], - flag_groups = [flag_group(flags = ["-shared"])], - ), - ], - ) - - random_seed_feature = feature( - name = "random_seed", - enabled = True, - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.cpp_module_codegen, - ACTION_NAMES.cpp_module_compile, - ], - flag_groups = [ - flag_group( - flags = ["-frandom-seed=%{output_file}"], - expand_if_available = "output_file", - ), - ], - ), - ], - ) - - includes_feature = feature( - name = "includes", - enabled = True, - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.linkstamp_compile, - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.cpp_header_parsing, - ACTION_NAMES.cpp_module_compile, - ACTION_NAMES.clif_match, - ACTION_NAMES.objc_compile, - ACTION_NAMES.objcpp_compile, - ], - flag_groups = [ - flag_group( - flags = ["-include", "%{includes}"], - iterate_over = "includes", - expand_if_available = "includes", - ), - ], - ), - ], - ) - - fdo_instrument_feature = feature( - name = "fdo_instrument", - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ] + all_link_actions + lto_index_actions, - flag_groups = [ - flag_group( - flags = [ - "-fprofile-generate=%{fdo_instrument_path}", - "-fno-data-sections", - ], - expand_if_available = "fdo_instrument_path", - ), - ], - ), - ], - provides = ["profile"], - ) - - cs_fdo_instrument_feature = feature( - name = "cs_fdo_instrument", - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.lto_backend, - ] + all_link_actions + lto_index_actions, - flag_groups = [ - flag_group( - flags = [ - "-fcs-profile-generate=%{cs_fdo_instrument_path}", - ], - expand_if_available = "cs_fdo_instrument_path", - ), - ], - ), - ], - provides = ["csprofile"], - ) - - include_paths_feature = feature( - name = "include_paths", - enabled = True, - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.linkstamp_compile, - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.cpp_header_parsing, - ACTION_NAMES.cpp_module_compile, - ACTION_NAMES.clif_match, - ACTION_NAMES.objc_compile, - ACTION_NAMES.objcpp_compile, - ], - flag_groups = [ - flag_group( - flags = ["-iquote", "%{quote_include_paths}"], - iterate_over = "quote_include_paths", - ), - flag_group( - flags = ["-I%{include_paths}"], - iterate_over = "include_paths", - ), - flag_group( - flags = ["-isystem", "%{system_include_paths}"], - iterate_over = "system_include_paths", - ), - ], - ), - ], - ) - - symbol_counts_feature = feature( - name = "symbol_counts", - flag_sets = [ - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = [ - flag_group( - flags = [ - "-Wl,--print-symbol-counts=%{symbol_counts_output}", - ], - expand_if_available = "symbol_counts_output", - ), - ], - ), - ], - ) - - llvm_coverage_map_format_feature = feature( - name = "llvm_coverage_map_format", - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.cpp_module_compile, - ACTION_NAMES.objc_compile, - ACTION_NAMES.objcpp_compile, - ], - flag_groups = [ - flag_group( - flags = [ - "-fprofile-instr-generate", - "-fcoverage-mapping", - ], - ), - ], - ), - flag_set( - actions = all_link_actions + lto_index_actions + [ - "objc-executable", - "objc++-executable", - ], - flag_groups = [ - flag_group(flags = ["-fprofile-instr-generate"]), - ], - ), - ], - requires = [feature_set(features = ["coverage"])], - provides = ["profile"], - ) - - strip_debug_symbols_feature = feature( - name = "strip_debug_symbols", - flag_sets = [ - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = [ - flag_group( - flags = ["-Wl,-S"], - expand_if_available = "strip_debug_symbols", - ), - ], - ), - ], - ) - - build_interface_libraries_feature = feature( - name = "build_interface_libraries", - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.cpp_link_dynamic_library, - ACTION_NAMES.cpp_link_nodeps_dynamic_library, - ACTION_NAMES.lto_index_for_dynamic_library, - ACTION_NAMES.lto_index_for_nodeps_dynamic_library, - ], - flag_groups = [ - flag_group( - flags = [ - "%{generate_interface_library}", - "%{interface_library_builder_path}", - "%{interface_library_input_path}", - "%{interface_library_output_path}", - ], - expand_if_available = "generate_interface_library", - ), - ], - with_features = [ - with_feature_set( - features = ["supports_interface_shared_libraries"], - ), - ], - ), - ], - ) - - libraries_to_link_feature = feature( - name = "libraries_to_link", - flag_sets = [ - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = [ - flag_group( - iterate_over = "libraries_to_link", - flag_groups = [ - flag_group( - flags = ["-Wl,--start-lib"], - expand_if_equal = variable_with_value( - name = "libraries_to_link.type", - value = "object_file_group", - ), - ), - flag_group( - flags = ["-Wl,-whole-archive"], - expand_if_true = - "libraries_to_link.is_whole_archive", - ), - flag_group( - flags = ["%{libraries_to_link.object_files}"], - iterate_over = "libraries_to_link.object_files", - expand_if_equal = variable_with_value( - name = "libraries_to_link.type", - value = "object_file_group", - ), - ), - flag_group( - flags = ["%{libraries_to_link.name}"], - expand_if_equal = variable_with_value( - name = "libraries_to_link.type", - value = "object_file", - ), - ), - flag_group( - flags = ["%{libraries_to_link.name}"], - expand_if_equal = variable_with_value( - name = "libraries_to_link.type", - value = "interface_library", - ), - ), - flag_group( - flags = ["%{libraries_to_link.name}"], - expand_if_equal = variable_with_value( - name = "libraries_to_link.type", - value = "static_library", - ), - ), - flag_group( - flags = ["-l%{libraries_to_link.name}"], - expand_if_equal = variable_with_value( - name = "libraries_to_link.type", - value = "dynamic_library", - ), - ), - flag_group( - flags = ["-l:%{libraries_to_link.name}"], - expand_if_equal = variable_with_value( - name = "libraries_to_link.type", - value = "versioned_dynamic_library", - ), - ), - flag_group( - flags = ["-Wl,-no-whole-archive"], - expand_if_true = "libraries_to_link.is_whole_archive", - ), - flag_group( - flags = ["-Wl,--end-lib"], - expand_if_equal = variable_with_value( - name = "libraries_to_link.type", - value = "object_file_group", - ), - ), - ], - expand_if_available = "libraries_to_link", - ), - flag_group( - flags = ["-Wl,@%{thinlto_param_file}"], - expand_if_true = "thinlto_param_file", - ), - ], - ), - ], - ) - - user_link_flags_feature = feature( - name = "user_link_flags", - flag_sets = [ - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = [ - flag_group( - flags = ["%{user_link_flags}"], - iterate_over = "user_link_flags", - expand_if_available = "user_link_flags", - ), - ] + ([flag_group(flags = ctx.attr.link_libs)] if ctx.attr.link_libs else []), - ), - ], - ) - - fdo_prefetch_hints_feature = feature( - name = "fdo_prefetch_hints", - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.lto_backend, - ], - flag_groups = [ - flag_group( - flags = [ - "-mllvm", - "-prefetch-hints-file=%{fdo_prefetch_hints_path}", - ], - expand_if_available = "fdo_prefetch_hints_path", - ), - ], - ), - ], - ) - - linkstamps_feature = feature( - name = "linkstamps", - flag_sets = [ - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = [ - flag_group( - flags = ["%{linkstamp_paths}"], - iterate_over = "linkstamp_paths", - expand_if_available = "linkstamp_paths", - ), - ], - ), - ], - ) - - gcc_coverage_map_format_feature = feature( - name = "gcc_coverage_map_format", - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.cpp_module_compile, - ACTION_NAMES.objc_compile, - ACTION_NAMES.objcpp_compile, - "objc-executable", - "objc++-executable", - ], - flag_groups = [ - flag_group( - flags = ["-fprofile-arcs", "-ftest-coverage"], - expand_if_available = "gcov_gcno_file", - ), - ], - ), - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = [flag_group(flags = ["--coverage"])], - ), - ], - requires = [feature_set(features = ["coverage"])], - provides = ["profile"], - ) - - archiver_flags_feature = feature( - name = "archiver_flags", - flag_sets = [ - flag_set( - actions = [ACTION_NAMES.cpp_link_static_library], - flag_groups = [ - flag_group(flags = ["rcsD"]), - flag_group( - flags = ["%{output_execpath}"], - expand_if_available = "output_execpath", - ), - ], - ), - flag_set( - actions = [ACTION_NAMES.cpp_link_static_library], - flag_groups = [ - flag_group( - iterate_over = "libraries_to_link", - flag_groups = [ - flag_group( - flags = ["%{libraries_to_link.name}"], - expand_if_equal = variable_with_value( - name = "libraries_to_link.type", - value = "object_file", - ), - ), - flag_group( - flags = ["%{libraries_to_link.object_files}"], - iterate_over = "libraries_to_link.object_files", - expand_if_equal = variable_with_value( - name = "libraries_to_link.type", - value = "object_file_group", - ), - ), - ], - expand_if_available = "libraries_to_link", - ), - ], - ), - ], - ) - - force_pic_flags_feature = feature( - name = "force_pic_flags", - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.cpp_link_executable, - ACTION_NAMES.lto_index_for_executable, - ], - flag_groups = [ - flag_group( - flags = ["-pie"], - expand_if_available = "force_pic", - ), - ], - ), - ], - ) - - dependency_file_feature = feature( - name = "dependency_file", - enabled = True, - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.assemble, - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.cpp_module_compile, - ACTION_NAMES.objc_compile, - ACTION_NAMES.objcpp_compile, - ACTION_NAMES.cpp_header_parsing, - ACTION_NAMES.clif_match, - ], - flag_groups = [ - flag_group( - flags = ["-MD", "-MF", "%{dependency_file}"], - expand_if_available = "dependency_file", - ), - ], - ), - ], - ) - - dynamic_library_linker_tool_path = tool_paths - dynamic_library_linker_tool_feature = feature( - name = "dynamic_library_linker_tool", - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.cpp_link_dynamic_library, - ACTION_NAMES.cpp_link_nodeps_dynamic_library, - ACTION_NAMES.lto_index_for_dynamic_library, - ACTION_NAMES.lto_index_for_nodeps_dynamic_library, - ], - flag_groups = [ - flag_group( - flags = [" + cppLinkDynamicLibraryToolPath + "], - expand_if_available = "generate_interface_library", - ), - ], - with_features = [ - with_feature_set( - features = ["supports_interface_shared_libraries"], - ), - ], - ), - ], - ) - - output_execpath_flags_feature = feature( - name = "output_execpath_flags", - flag_sets = [ - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = [ - flag_group( - flags = ["-o", "%{output_execpath}"], - expand_if_available = "output_execpath", - ), - ], - ), - ], - ) - - # Note that we also set --coverage for c++-link-nodeps-dynamic-library. The - # generated code contains references to gcov symbols, and the dynamic linker - # can't resolve them unless the library is linked against gcov. - coverage_feature = feature( - name = "coverage", - provides = ["profile"], - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.preprocess_assemble, - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ACTION_NAMES.cpp_header_parsing, - ACTION_NAMES.cpp_module_compile, - ], - flag_groups = ([ - flag_group(flags = ctx.attr.coverage_compile_flags), - ] if ctx.attr.coverage_compile_flags else []), - ), - flag_set( - actions = all_link_actions + lto_index_actions, - flag_groups = ([ - flag_group(flags = ctx.attr.coverage_link_flags), - ] if ctx.attr.coverage_link_flags else []), - ), - ], - ) - - thinlto_feature = feature( - name = "thin_lto", - flag_sets = [ - flag_set( - actions = [ - ACTION_NAMES.c_compile, - ACTION_NAMES.cpp_compile, - ] + all_link_actions + lto_index_actions, - flag_groups = [ - flag_group(flags = ["-flto=thin"]), - flag_group( - expand_if_available = "lto_indexing_bitcode_file", - flags = [ - "-Xclang", - "-fthin-link-bitcode=%{lto_indexing_bitcode_file}", - ], - ), - ], - ), - flag_set( - actions = [ACTION_NAMES.linkstamp_compile], - flag_groups = [flag_group(flags = ["-DBUILD_LTO_TYPE=thin"])], - ), - flag_set( - actions = lto_index_actions, - flag_groups = [ - flag_group(flags = [ - "-flto=thin", - "-Wl,-plugin-opt,thinlto-index-only%{thinlto_optional_params_file}", - "-Wl,-plugin-opt,thinlto-emit-imports-files", - "-Wl,-plugin-opt,thinlto-prefix-replace=%{thinlto_prefix_replace}", - ]), - flag_group( - expand_if_available = "thinlto_object_suffix_replace", - flags = [ - "-Wl,-plugin-opt,thinlto-object-suffix-replace=%{thinlto_object_suffix_replace}", - ], - ), - flag_group( - expand_if_available = "thinlto_merged_object_file", - flags = [ - "-Wl,-plugin-opt,obj-path=%{thinlto_merged_object_file}", - ], - ), - ], - ), - flag_set( - actions = [ACTION_NAMES.lto_backend], - flag_groups = [ - flag_group(flags = [ - "-c", - "-fthinlto-index=%{thinlto_index}", - "-o", - "%{thinlto_output_object_file}", - "-x", - "ir", - "%{thinlto_input_bitcode_file}", - ]), - ], - ), - ], - ) - - # Export cross-compilation flags as environment variables for foreign_cc rules - # (e.g. rules_foreign_cc's configure_make). These env vars are picked up by - # cc_common.get_environment_variables() and exported globally in the build - # script prelude, making them available to both configure and make steps. - # This is needed because some foreign build systems (like liburing) override - # CFLAGS internally, losing the --target flag from the toolchain's compile_flags. - foreign_cc_env_feature = feature( - name = "foreign_cc_env", - enabled = bool(ctx.attr.foreign_cc_env), - env_sets = [ - env_set( - actions = all_compile_actions + all_link_actions, - env_entries = [ - env_entry(key = key, value = value) - for key, value in ctx.attr.foreign_cc_env.items() - ], - ), - ] if ctx.attr.foreign_cc_env else [], - ) - - is_linux = ctx.attr.target_libc != "macosx" - - # TODO(#8303): Mac crosstool should also declare every feature. - if is_linux: - features = [ - dependency_file_feature, - random_seed_feature, - pic_feature, - per_object_debug_info_feature, - preprocessor_defines_feature, - includes_feature, - include_paths_feature, - fdo_instrument_feature, - cs_fdo_instrument_feature, - cs_fdo_optimize_feature, - thinlto_feature, - fdo_prefetch_hints_feature, - autofdo_feature, - build_interface_libraries_feature, - dynamic_library_linker_tool_feature, - symbol_counts_feature, - shared_flag_feature, - linkstamps_feature, - output_execpath_flags_feature, - runtime_library_search_directories_feature, - library_search_directories_feature, - archiver_flags_feature, - force_pic_flags_feature, - fission_support_feature, - strip_debug_symbols_feature, - coverage_feature, - supports_pic_feature, - ] + ( - [ - supports_start_end_lib_feature, - ] if ctx.attr.supports_start_end_lib else [] - ) + [ - default_compile_flags_feature, - default_link_flags_feature, - libraries_to_link_feature, - user_link_flags_feature, - static_libgcc_feature, - fdo_optimize_feature, - supports_dynamic_linker_feature, - dbg_feature, - opt_feature, - user_compile_flags_feature, - sysroot_feature, - unfiltered_compile_flags_feature, - foreign_cc_env_feature, - ] + layering_check_features(ctx.attr.compiler) - else: - features = [ - supports_pic_feature, - ] + ( - [ - supports_start_end_lib_feature, - ] if ctx.attr.supports_start_end_lib else [] - ) + [ - coverage_feature, - default_compile_flags_feature, - default_link_flags_feature, - fdo_optimize_feature, - supports_dynamic_linker_feature, - dbg_feature, - opt_feature, - user_compile_flags_feature, - sysroot_feature, - unfiltered_compile_flags_feature, - foreign_cc_env_feature, - ] + layering_check_features(ctx.attr.compiler) - - return cc_common.create_cc_toolchain_config_info( - ctx = ctx, - features = features, - action_configs = action_configs, - cxx_builtin_include_directories = ctx.attr.cxx_builtin_include_directories, - toolchain_identifier = ctx.attr.toolchain_identifier, - host_system_name = ctx.attr.host_system_name, - target_system_name = ctx.attr.target_system_name, - target_cpu = ctx.attr.cpu, - target_libc = ctx.attr.target_libc, - compiler = ctx.attr.compiler, - abi_version = ctx.attr.abi_version, - abi_libc_version = ctx.attr.abi_libc_version, - tool_paths = tool_paths, - builtin_sysroot = ctx.attr.builtin_sysroot, - ) - -cc_toolchain_config = rule( - implementation = _impl, - attrs = { - "cpu": attr.string(mandatory = True), - "compiler": attr.string(mandatory = True), - "toolchain_identifier": attr.string(mandatory = True), - "host_system_name": attr.string(mandatory = True), - "target_system_name": attr.string(mandatory = True), - "target_libc": attr.string(mandatory = True), - "abi_version": attr.string(mandatory = True), - "abi_libc_version": attr.string(mandatory = True), - "cxx_builtin_include_directories": attr.string_list(), - "tool_paths": attr.string_dict(), - "compile_flags": attr.string_list(), - "dbg_compile_flags": attr.string_list(), - "opt_compile_flags": attr.string_list(), - "cxx_flags": attr.string_list(), - "link_flags": attr.string_list(), - "link_libs": attr.string_list(), - "opt_link_flags": attr.string_list(), - "unfiltered_compile_flags": attr.string_list(), - "coverage_compile_flags": attr.string_list(), - "coverage_link_flags": attr.string_list(), - "supports_start_end_lib": attr.bool(), - "builtin_sysroot": attr.string(), - "foreign_cc_env": attr.string_dict(), - }, - provides = [CcToolchainConfigInfo], -) diff --git a/cilium/BUILD b/cilium/BUILD index 1a5fca29a..844ec05c7 100644 --- a/cilium/BUILD +++ b/cilium/BUILD @@ -12,7 +12,6 @@ envoy_cc_library( name = "tls_wrapper_lib", srcs = ["tls_wrapper.cc"], hdrs = ["tls_wrapper.h"], - repository = "@envoy", deps = [ "//cilium:filter_state_lib", "//cilium:network_policy_lib", @@ -39,7 +38,6 @@ envoy_cc_library( "network_policy.h", "policy_id.h", ], - repository = "@envoy", deps = [ "//cilium:accesslog_lib", "//cilium:conntrack_lib", @@ -54,6 +52,7 @@ envoy_cc_library( "@envoy//source/common/init:watcher_lib", "@envoy//source/common/local_info:local_info_lib", "@envoy//source/common/network:address_lib", + "@envoy//source/common/protobuf:arena_wrapped_proto_lib", "@envoy//source/common/router:config_utility_lib", "@envoy//source/common/stats:timespan_lib", "@envoy//source/common/tls:context_config_lib", @@ -75,7 +74,6 @@ envoy_cc_library( "socket_option_ip_transparent.h", "socket_option_source_address.h", ], - repository = "@envoy", deps = [ "privileged_service_client_lib", "//cilium:filter_state_lib", @@ -94,7 +92,6 @@ envoy_cc_library( "filter_state_cilium_destination.h", "filter_state_cilium_policy.h", ], - repository = "@envoy", deps = [ "//cilium:network_policy_lib", "@envoy//source/common/common:logger_lib", @@ -109,7 +106,6 @@ envoy_cc_library( hdrs = [ "grpc_subscription.h", ], - repository = "@envoy", deps = [ "@abseil-cpp//absl/strings", "@envoy//envoy/network:connection_interface", @@ -128,7 +124,6 @@ envoy_cc_library( hdrs = [ "l7policy.h", ], - repository = "@envoy", deps = [ "//cilium:accesslog_lib", "//cilium:filter_state_lib", @@ -156,12 +151,11 @@ envoy_cc_library( "websocket_config.h", "websocket_protocol.h", ], - repository = "@envoy", deps = [ "//cilium:accesslog_lib", "//cilium:filter_state_lib", "//cilium/api:websocket_cc_proto", - "@com_google_protobuf//third_party/utf8_range:utf8_validity", + "@abseil-cpp//absl/types:span", "@envoy//bazel/external/http_parser", "@envoy//envoy/common/crypto:crypto_interface", "@envoy//source/common/common:base64_lib", @@ -176,6 +170,7 @@ envoy_cc_library( "@envoy//source/common/stream_info:uint64_accessor_lib", "@envoy//source/common/tcp_proxy", "@envoy_api//envoy/extensions/request_id/uuid/v3:pkg_cc_proto", + "@protobuf//third_party/utf8_range:utf8_validity", ], ) @@ -187,7 +182,6 @@ envoy_cc_library( hdrs = [ "accesslog.h", ], - repository = "@envoy", deps = [ "//cilium:uds_client_lib", "//cilium/api:accesslog_proto_cc_proto", @@ -205,7 +199,6 @@ envoy_cc_library( hdrs = [ "uds_client.h", ], - repository = "@envoy", deps = [ "@envoy//source/common/common:minimal_logger_lib", "@envoy//source/common/common:thread_lib", @@ -226,7 +219,6 @@ envoy_cc_library( "//:linux/bpf_common.h", "//:linux/type_mapper.h", ], - repository = "@envoy", deps = [ "privileged_service_client_lib", "@envoy//source/common/common:logger_lib", @@ -242,7 +234,6 @@ envoy_cc_library( hdrs = [ "ipcache.h", ], - repository = "@envoy", deps = [ "//cilium:bpf_lib", "@envoy//envoy/singleton:manager_interface", @@ -260,7 +251,6 @@ envoy_cc_library( hdrs = [ "conntrack.h", ], - repository = "@envoy", deps = [ "//cilium:bpf_lib", "@envoy//envoy/network:connection_interface", @@ -272,26 +262,6 @@ envoy_cc_library( ], ) -envoy_cc_library( - name = "proxylib_lib", - srcs = [ - "proxylib.cc", - ], - hdrs = [ - "proxylib.h", - "//proxylib:libcilium.h", - "//proxylib:types.h", - ], - repository = "@envoy", - deps = [ - "@envoy//envoy/network:connection_interface", - "@envoy//envoy/singleton:manager_interface", - "@envoy//source/common/buffer:buffer_lib", - "@envoy//source/common/common:assert_lib", - "@envoy//source/common/common:logger_lib", - ], -) - envoy_cc_library( name = "network_filter_lib", srcs = [ @@ -300,12 +270,10 @@ envoy_cc_library( hdrs = [ "network_filter.h", ], - repository = "@envoy", deps = [ "//cilium:conntrack_lib", "//cilium:filter_state_lib", "//cilium:network_policy_lib", - "//cilium:proxylib_lib", "//cilium/api:network_filter_cc_proto", "@envoy//envoy/buffer:buffer_interface", "@envoy//envoy/network:connection_interface", @@ -330,7 +298,6 @@ envoy_cc_library( "bpf_metadata.h", "host_map.h", ], - repository = "@envoy", deps = [ "//cilium:conntrack_lib", "//cilium:filter_state_lib", @@ -353,6 +320,7 @@ envoy_cc_library( "@envoy//source/common/common:assert_lib", "@envoy//source/common/common:logger_lib", "@envoy//source/common/network:address_lib", + "@envoy//source/common/protobuf:arena_wrapped_proto_lib", "@envoy//source/common/router:config_utility_lib", "@envoy_api//envoy/config/core/v3:pkg_cc_proto", ], @@ -362,7 +330,6 @@ envoy_cc_library( name = "privileged_service_client_lib", srcs = ["privileged_service_client.cc"], hdrs = ["privileged_service_client.h"], - repository = "@envoy", deps = [ "//starter:privileged_service_protocol", "@envoy//envoy/api:os_sys_calls_interface", @@ -375,7 +342,6 @@ envoy_cc_library( name = "health_check_sink_lib", srcs = ["health_check_sink.cc"], hdrs = ["health_check_sink.h"], - repository = "@envoy", deps = [ "//cilium:uds_client_lib", "//cilium/api:health_check_sink_cc_proto", diff --git a/cilium/api/network_filter.proto b/cilium/api/network_filter.proto index 157ba77a7..d31f475ee 100644 --- a/cilium/api/network_filter.proto +++ b/cilium/api/network_filter.proto @@ -5,11 +5,10 @@ option go_package = "github.com/cilium/proxy/go/cilium/api;cilium"; package cilium; message NetworkFilter { - // Path to the proxylib to be opened - string proxylib = 1; - - // Transparent set of parameters provided for proxylib initialization - map proxylib_params = 2; + // Fields 1 and 2 were used for proxylib (Envoy Go extensions) configuration, + // which has been removed. + reserved 1, 2; + reserved "proxylib", "proxylib_params"; // Path to the unix domain socket for the cilium access log. string access_log_path = 5; diff --git a/cilium/api/npds.proto b/cilium/api/npds.proto index 2d28992ad..3577da71b 100644 --- a/cilium/api/npds.proto +++ b/cilium/api/npds.proto @@ -188,9 +188,10 @@ message PortNetworkPolicyRule { } }]; - // Optional L7 protocol parser name. This is only used if the parser is not - // one of the well knows ones. If specified, the l7 parser having this name - // needs to be built in to libcilium.so. + // Optional L7 protocol name. This is only used if the protocol is not + // one of the well known ones. If specified, it is added to the requested + // application protocols of the connection for filter chain matching, and + // names the Envoy filter whose dynamic metadata is matched by 'l7_rules'. string l7_proto = 2; // Optional. If not specified, any L7 request is matched by this predicate. @@ -218,7 +219,7 @@ message HttpNetworkPolicyRules { // The set of HTTP network policy rules. // An HTTP request is matched if any of its rules matches the request. // Required and may not be empty. - repeated HttpNetworkPolicyRule http_rules = 1 [(validate.rules).repeated .min_items = 1]; + repeated HttpNetworkPolicyRule http_rules = 1 [(validate.rules).repeated.min_items = 1]; } message HeaderMatch { @@ -278,7 +279,7 @@ message KafkaNetworkPolicyRules { // The set of Kafka network policy rules. // A Kafka request is matched if any of its rules matches the request. // Required and may not be empty. - repeated KafkaNetworkPolicyRule kafka_rules = 1 [(validate.rules).repeated .min_items = 1]; + repeated KafkaNetworkPolicyRule kafka_rules = 1 [(validate.rules).repeated.min_items = 1]; } // A Kafka network policy rule, as a conjunction of predicates on Kafka diff --git a/cilium/api/nphds.proto b/cilium/api/nphds.proto index bb5628510..4e7b69141 100644 --- a/cilium/api/nphds.proto +++ b/cilium/api/nphds.proto @@ -41,8 +41,6 @@ message NetworkPolicyHosts { // The set of IP addresses of the hosts on which the network policy is // enforced. Optional. May be empty. - repeated string host_addresses = 2 [ - (validate.rules).repeated .unique = true, - (validate.rules).repeated .items.string.min_len = 1 - ]; + repeated string host_addresses = 2 + [(validate.rules).repeated.unique = true, (validate.rules).repeated.items.string.min_len = 1]; } diff --git a/cilium/conntrack.cc b/cilium/conntrack.cc index 040ee6104..6a831d1cf 100644 --- a/cilium/conntrack.cc +++ b/cilium/conntrack.cc @@ -113,9 +113,9 @@ uint32_t CtMap::lookupSrcIdentity(const Network::Address::Ip* sip, const Network bool ingress) { ENVOY_LOG(debug, "cilium.bpf_metadata: Using conntrack map global"); - struct IPv4CtTuple key4 {}; - struct IPv6CtTuple key6 {}; - struct CtEntry value {}; + struct IPv4CtTuple key4{}; + struct IPv6CtTuple key6{}; + struct CtEntry value{}; if (sip->version() == Network::Address::IpVersion::v4 && dip->version() == Network::Address::IpVersion::v4) { diff --git a/cilium/filter_state_cilium_policy.cc b/cilium/filter_state_cilium_policy.cc index 1bf350a92..0053e2c98 100644 --- a/cilium/filter_state_cilium_policy.cc +++ b/cilium/filter_state_cilium_policy.cc @@ -23,10 +23,8 @@ bool CiliumPolicyFilterState::enforceNetworkPolicy(const Network::Connection& co uint32_t destination_identity, uint16_t destination_port, const absl::string_view sni, - /* OUT */ bool& use_proxy_lib, /* OUT */ std::string& l7_proto, /* INOUT */ AccessLog::Entry& log_entry) const { - use_proxy_lib = false; l7_proto = ""; // enforce pod policy first, if any @@ -44,7 +42,7 @@ bool CiliumPolicyFilterState::enforceNetworkPolicy(const Network::Connection& co } // populate l7proto_ if available - use_proxy_lib = port_policy.useProxylib(proxy_id_, remote_id, l7_proto); + port_policy.useProxylib(proxy_id_, remote_id, l7_proto); } // enforce Ingress policy 2nd, if any diff --git a/cilium/filter_state_cilium_policy.h b/cilium/filter_state_cilium_policy.h index 09c65784f..9a78ec0af 100644 --- a/cilium/filter_state_cilium_policy.h +++ b/cilium/filter_state_cilium_policy.h @@ -63,7 +63,6 @@ class CiliumPolicyFilterState : public StreamInfo::FilterState::Object, bool enforceNetworkPolicy(const Network::Connection& conn, uint32_t destination_identity, uint16_t destination_port, const absl::string_view sni, - /* OUT */ bool& use_proxy_lib, /* OUT */ std::string& l7_proto, /* INOUT */ AccessLog::Entry& log_entry) const; diff --git a/cilium/host_map.cc b/cilium/host_map.cc index 79af22144..c6eea1fc0 100644 --- a/cilium/host_map.cc +++ b/cilium/host_map.cc @@ -25,7 +25,6 @@ #include "envoy/thread_local/thread_local_object.h" #include "source/common/common/logger.h" -#include "source/common/common/macros.h" #include "absl/numeric/int128.h" #include "absl/status/status.h" @@ -266,16 +265,10 @@ PolicyHostMap::onConfigUpdate(const std::vectorinsert(config); } - // Force 'this' to be not deleted for as long as the lambda stays - // alive. Note that generally capturing a shared pointer is - // dangerous as it may happen that there is a circular reference - // from 'this' to itself via the lambda capture, leading to 'this' - // never being released. It should happen in this case, though. - std::shared_ptr shared_this = shared_from_this(); - - // Assign the new map to all threads. - tls_->set([shared_this, newmap](Event::Dispatcher&) -> ThreadLocal::ThreadLocalObjectSharedPtr { - UNREFERENCED_PARAMETER(shared_this); + // Assign the new map to all threads. The slot keeps the callback for the lifetime of the slot + // (it is replayed on worker threads registered later), so it must not capture a shared pointer + // to 'this': that would form a reference cycle through tls_ and leak the map. + tls_->set([newmap](Event::Dispatcher&) -> ThreadLocal::ThreadLocalObjectSharedPtr { ENVOY_LOG(trace, "PolicyHostMap: Assigning new map"); return newmap; }); @@ -302,16 +295,10 @@ PolicyHostMap::onConfigUpdate(const std::vectorinsert(config); } - // Force 'this' to be not deleted for as long as the lambda stays - // alive. Note that generally capturing a shared pointer is - // dangerous as it may happen that there is a circular reference - // from 'this' to itself via the lambda capture, leading to 'this' - // never being released. It should happen in this case, though. - ManagedGrpcSubscriptionSharedPtr shared_this = shared_from_this(); - - // Assign the new map to all threads. - tls_->set([shared_this, newmap](Event::Dispatcher&) -> ThreadLocal::ThreadLocalObjectSharedPtr { - UNREFERENCED_PARAMETER(shared_this); + // Assign the new map to all threads. The slot keeps the callback for the lifetime of the slot + // (it is replayed on worker threads registered later), so it must not capture a shared pointer + // to 'this': that would form a reference cycle through tls_ and leak the map. + tls_->set([newmap](Event::Dispatcher&) -> ThreadLocal::ThreadLocalObjectSharedPtr { ENVOY_LOG(trace, "PolicyHostMap: Assigning new map"); return newmap; }); diff --git a/cilium/host_map.h b/cilium/host_map.h index f9fdf8648..a5096e387 100644 --- a/cilium/host_map.h +++ b/cilium/host_map.h @@ -26,8 +26,8 @@ #include "source/common/common/logger.h" #include "source/common/network/utility.h" +#include "source/common/protobuf/arena_wrapped_proto.h" #include "source/common/protobuf/message_validator_impl.h" -#include "source/common/protobuf/protobuf.h" #include "source/common/protobuf/utility.h" #include "absl/container/flat_hash_map.h" @@ -72,8 +72,8 @@ class PolicyHostDecoder : public Envoy::Config::OpaqueResourceDecoder { PolicyHostDecoder() : validation_visitor_(ProtobufMessage::getNullValidationVisitor()) {} // Config::OpaqueResourceDecoder - ProtobufTypes::MessagePtr decodeResource(const Protobuf::Any& resource) override { - auto typed_message = std::make_unique(); + ArenaWrappedProto decodeResource(const Protobuf::Any& resource) override { + ArenaWrappedProto typed_message; // If the Any is a synthetic empty message (e.g. because the resource field // was not set in Resource, this might be empty, so we shouldn't decode. if (!resource.type_url().empty()) { @@ -219,7 +219,7 @@ class PolicyHostMap : public Singleton::Instance, public ManagedGrpcSubscription const std::string& system_version_info) override; private: - ThreadLocal::SlotPtr tls_; + ThreadLocal::SlotSharedPtr tls_; std::string name_; uint64_t accepted_stream_generation_{0}; static uint64_t instance_id_; diff --git a/cilium/ipcache.cc b/cilium/ipcache.cc index 0f49e2526..ca20aea4b 100644 --- a/cilium/ipcache.cc +++ b/cilium/ipcache.cc @@ -115,8 +115,8 @@ bool IpCache::openLocked() { } uint32_t IpCache::resolve(const Network::Address::Ip* ip, std::chrono::microseconds cache_ttl) { - struct IpCacheKey key {}; - struct RemoteEndpointInfo value {}; + struct IpCacheKey key{}; + struct RemoteEndpointInfo value{}; if (ip->version() == Network::Address::IpVersion::v4) { key.lpm_key = {32 + 32, {}}; diff --git a/cilium/network_filter.cc b/cilium/network_filter.cc index 6d3be35ef..1ee72cbaa 100644 --- a/cilium/network_filter.cc +++ b/cilium/network_filter.cc @@ -15,7 +15,6 @@ #include "envoy/stream_info/stream_info.h" #include "envoy/upstream/host_description.h" -#include "source/common/buffer/buffer_impl.h" #include "source/common/common/logger.h" #include "source/common/network/upstream_server_name.h" #include "source/common/network/upstream_subject_alt_names.h" @@ -30,8 +29,6 @@ #include "cilium/api/network_filter.pb.validate.h" // IWYU pragma: keep #include "cilium/filter_state_cilium_destination.h" #include "cilium/filter_state_cilium_policy.h" -#include "cilium/proxylib.h" -#include "proxylib/types.h" namespace Envoy { namespace Server { @@ -81,9 +78,6 @@ Config::Config(const ::cilium::NetworkFilter& config, if (!access_log_path.empty()) { access_log_ = Cilium::AccessLog::open(access_log_path, time_source_); } - if (!config.proxylib().empty()) { - proxylib_ = std::make_shared(config.proxylib(), config.proxylib_params()); - } } void Config::log(Cilium::AccessLog::Entry& entry, ::cilium::EntryType type) { @@ -110,9 +104,8 @@ bool Instance::enforceNetworkPolicy(const Cilium::CiliumPolicyFilterState* polic stream_info.downstreamAddressProvider().remoteAddress(), destination_identity, dst_address, &config_->time_source_); - bool use_proxy_lib; - if (!policy_fs->enforceNetworkPolicy(conn, remote_id_, destination_port_, sni, use_proxy_lib, - l7proto_, log_entry_)) { + if (!policy_fs->enforceNetworkPolicy(conn, remote_id_, destination_port_, sni, l7proto_, + log_entry_)) { ENVOY_CONN_LOG(debug, "cilium.network: policy DENY on id: {} port: {} sni: \"{}\"", conn, remote_id_, destination_port_, sni); config_->log(log_entry_, ::cilium::EntryType::Denied); @@ -126,22 +119,6 @@ bool Instance::enforceNetworkPolicy(const Cilium::CiliumPolicyFilterState* polic ENVOY_LOG(debug, "cilium.network: policy ALLOW on id: {} port: {} sni: \"{}\"", remote_id_, destination_port_, sni); - if (use_proxy_lib) { - const std::string& policy_name = policy_fs->pod_ip_; - - // Initialize Go parser if requested - if (config_->proxylib_.get() != nullptr) { - go_parser_ = config_->proxylib_->newInstance( - conn, l7proto_, policy_fs->ingress_, policy_fs->source_identity_, destination_identity, - stream_info.downstreamAddressProvider().remoteAddress()->asString(), - dst_address->asString(), policy_name); - if (go_parser_.get() == nullptr) { - ENVOY_CONN_LOG(warn, "cilium.network: Go parser \"{}\" not found", conn, l7proto_); - return false; - } - } - } - should_buffer_ = false; return true; } @@ -149,11 +126,6 @@ Network::FilterStatus Instance::onNewConnection() { auto& conn = callbacks_->connection(); ENVOY_CONN_LOG(debug, "cilium.network: onNewConnection", conn); - // Buffer data until proxylib policy is available, if configured with proxylib - if (config_->proxylib_.get() != nullptr) { - should_buffer_ = true; - } - const auto policy_fs = conn.streamInfo().filterState()->getDataReadOnly( Cilium::CiliumPolicyFilterState::key()); @@ -273,41 +245,7 @@ Network::FilterStatus Instance::onData(Buffer::Instance& data, bool end_stream) end_stream); const char* reason; - if (should_buffer_) { - // Buffer data until upstream is selected and policy resolved - buffer_.move(data); - return Network::FilterStatus::Continue; - } - // Prepend buffered data if any - if (buffer_.length() > 0) { - data.prepend(buffer_); - } - if (go_parser_) { - FilterResult res = - go_parser_->onIo(false, data, end_stream); // 'false' marks original direction data - ENVOY_CONN_LOG(trace, "cilium.network::onData: \'GoFilter::OnIO\' returned {}", conn, - Envoy::Cilium::toString(res)); - - if (res != FILTER_OK) { - // Drop the connection due to an error - go_parser_->close(); - reason = "proxylib error"; - goto drop_close; - } - - if (go_parser_->wantReplyInject()) { - ENVOY_CONN_LOG(trace, "cilium.network::onData: calling write() on an empty buffer", conn); - - // We have no idea when, if ever new data will be received on the - // reverse direction. Connection write on an empty buffer will cause - // write filter chain to be called, and gives our write path the - // opportunity to inject data. - Buffer::OwnedImpl empty; - conn.write(empty, false); - } - - go_parser_->setOrigEndStream(end_stream); - } else if (!l7proto_.empty()) { + if (!l7proto_.empty()) { const auto& metadata = conn.streamInfo().dynamicMetadata(); const auto& filter_metadata = metadata.filter_metadata(); const auto metadata_it = filter_metadata.find(l7proto_); @@ -349,25 +287,7 @@ Network::FilterStatus Instance::onData(Buffer::Instance& data, bool end_stream) return Network::FilterStatus::StopIteration; } -Network::FilterStatus Instance::onWrite(Buffer::Instance& data, bool end_stream) { - if (go_parser_) { - FilterResult res = - go_parser_->onIo(true, data, end_stream); // 'true' marks reverse direction data - ENVOY_CONN_LOG(trace, "cilium.network::OnWrite: \'GoFilter::OnIO\' returned {}", - callbacks_->connection(), Envoy::Cilium::toString(res)); - - if (res != FILTER_OK) { - // Drop the connection due to an error - go_parser_->close(); - return Network::FilterStatus::StopIteration; - } - - // XXX: Unfortunately continueReading() continues from the next filter, and - // there seems to be no way to trigger the whole filter chain to be called. - - go_parser_->setReplyEndStream(end_stream); - } - +Network::FilterStatus Instance::onWrite(Buffer::Instance&, bool) { return Network::FilterStatus::Continue; } diff --git a/cilium/network_filter.h b/cilium/network_filter.h index 6a8009148..2e70f5f9d 100644 --- a/cilium/network_filter.h +++ b/cilium/network_filter.h @@ -12,7 +12,6 @@ #include "envoy/server/factory_context.h" #include "envoy/stream_info/stream_info.h" -#include "source/common/buffer/buffer_impl.h" #include "source/common/common/logger.h" #include "absl/strings/string_view.h" @@ -21,7 +20,6 @@ #include "cilium/api/network_filter.pb.h" #include "cilium/filter_state_cilium_destination.h" #include "cilium/filter_state_cilium_policy.h" -#include "cilium/proxylib.h" namespace Envoy { namespace Filter { @@ -42,7 +40,6 @@ class Config : Logger::Loggable { void log(Cilium::AccessLog::Entry&, ::cilium::EntryType); - Cilium::GoFilterSharedPtr proxylib_; TimeSource& time_source_; private: @@ -84,9 +81,6 @@ class Instance : public Network::Filter, Logger::Loggable { uint32_t remote_id_ = 0; uint16_t destination_port_ = 0; std::string l7proto_; - bool should_buffer_ = false; - Buffer::OwnedImpl buffer_; // Buffer for initial connection data - Cilium::GoFilter::InstancePtr go_parser_; Cilium::AccessLog::Entry log_entry_{}; }; diff --git a/cilium/network_policy.cc b/cilium/network_policy.cc index 90f924ed7..5b8617325 100644 --- a/cilium/network_policy.cc +++ b/cilium/network_policy.cc @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -88,18 +87,14 @@ using RuleVerdict = enum { } // namespace Cilium } // namespace Envoy -// Envoy routes ENVOY_LOG() through spdlog, which is built with SPDLOG_USE_STD_FORMAT, so this -// has to be a std::formatter rather than a fmt::formatter. -namespace std { +// Envoy routes ENVOY_LOG() through spdlog, which formats its arguments with fmtlib. +namespace fmt { -// NOLINTNEXTLINE(readability-identifier-naming) -template <> struct formatter { - template constexpr ParseContext::iterator parse(ParseContext& ctx) { - return ctx.begin(); - } +template <> struct formatter { + constexpr auto parse(fmt::format_parse_context& ctx) { return ctx.begin(); } - template - FmtContext::iterator format(Envoy::Cilium::RuleVerdict verdict, FmtContext& ctx) const { + template + auto format(Envoy::Cilium::RuleVerdict verdict, FormatContext& ctx) const { absl::string_view name; switch (verdict) { case Envoy::Cilium::RuleVerdict::None: @@ -122,7 +117,7 @@ template <> struct formatter { } }; -} // namespace std +} // namespace fmt namespace Envoy { namespace Cilium { diff --git a/cilium/network_policy.h b/cilium/network_policy.h index e6d096b80..e7c39c110 100644 --- a/cilium/network_policy.h +++ b/cilium/network_policy.h @@ -24,8 +24,8 @@ #include "source/common/common/logger.h" #include "source/common/common/macros.h" #include "source/common/common/thread.h" +#include "source/common/protobuf/arena_wrapped_proto.h" #include "source/common/protobuf/message_validator_impl.h" -#include "source/common/protobuf/protobuf.h" #include "source/common/protobuf/utility.h" #include "absl/strings/ascii.h" @@ -150,8 +150,8 @@ class NetworkPolicyDecoder : public Envoy::Config::OpaqueResourceDecoder { NetworkPolicyDecoder() : validation_visitor_(ProtobufMessage::getNullValidationVisitor()) {} // Config::OpaqueResourceDecoder - ProtobufTypes::MessagePtr decodeResource(const Protobuf::Any& resource) override { - auto typed_message = std::make_unique(); + ArenaWrappedProto decodeResource(const Protobuf::Any& resource) override { + ArenaWrappedProto typed_message; // If the Any is a synthetic empty message (e.g. because the resource field // was not set in Resource, this might be empty, so we shouldn't decode. if (!resource.type_url().empty()) { diff --git a/cilium/proxylib.cc b/cilium/proxylib.cc deleted file mode 100644 index 126bffd8f..000000000 --- a/cilium/proxylib.cc +++ /dev/null @@ -1,337 +0,0 @@ -#include "cilium/proxylib.h" - -#include -#include - -#include -#include -#include - -#include "envoy/buffer/buffer.h" -#include "envoy/common/exception.h" -#include "envoy/network/connection.h" - -#include "source/common/common/assert.h" -#include "source/common/common/logger.h" -#include "source/common/protobuf/protobuf.h" // IWYU pragma: keep - -#include "absl/container/fixed_array.h" -#include "proxylib/types.h" - -namespace Envoy { -namespace Cilium { - -GoFilter::GoFilter(const std::string& go_module, - const Protobuf::Map<::std::string, ::std::string>& params) { - ENVOY_LOG(info, "GoFilter: Opening go module {}", go_module); - ::dlerror(); // clear any possible error state - go_module_handle_ = ::dlopen(go_module.c_str(), RTLD_NOW); - if (!go_module_handle_) { - throw EnvoyException( - fmt::format("cilium.network: Cannot load go module \'{}\': {}", go_module, dlerror())); - } - - go_close_module_ = GoCloseModuleCB(::dlsym(go_module_handle_, "CloseModule")); - if (!go_close_module_) { - throw EnvoyException(fmt::format("cilium.network: Cannot find symbol \'CloseModule\' from " - "module \'{}\': {}", - go_module, dlerror())); - } - GoOpenModuleCB go_open_module = GoOpenModuleCB(::dlsym(go_module_handle_, "OpenModule")); - if (!go_open_module) { - throw EnvoyException(fmt::format("cilium.network: Cannot find symbol \'OpenModule\' from " - "module \'{}\': {}", - go_module, dlerror())); - } else { - // Convert params to KeyValue pairs - auto num = params.size(); - absl::FixedArray values(num); - - int i = 0; - for (const auto& pair : params) { - values[i].key = GoString(pair.first); - values[i++].value = GoString(pair.second); - } - - go_module_id_ = - go_open_module(GoKeyValueSlice(values.data(), num), ENVOY_LOG_CHECK_LEVEL(debug)); - if (go_module_id_ == 0) { - throw EnvoyException( - fmt::format("cilium.network: \'{}::OpenModule()\' rejected parameters", go_module)); - } - } - - go_on_new_connection_ = GoOnNewConnectionCB(::dlsym(go_module_handle_, "OnNewConnection")); - if (!go_on_new_connection_) { - throw EnvoyException(fmt::format("cilium.network: Cannot find symbol \'OnNewConnection\' " - "from module \'{}\': {}", - go_module, dlerror())); - } - go_on_data_ = GoOnDataCB(::dlsym(go_module_handle_, "OnData")); - if (!go_on_data_) { - throw EnvoyException( - fmt::format("cilium.network: Cannot find symbol \'OnData\' from module \'{}\': {}", - go_module, dlerror())); - } - go_close_ = GoCloseCB(::dlsym(go_module_handle_, "Close")); - if (!go_close_) { - throw EnvoyException( - fmt::format("cilium.network: Cannot find symbol \'Close\' from module \'{}\': {}", - go_module, dlerror())); - } -} - -GoFilter::~GoFilter() { - if (go_module_id_ != 0) { - go_close_module_(go_module_id_); - } - if (go_module_handle_) { - ::dlclose(go_module_handle_); - } -} - -GoFilter::InstancePtr GoFilter::newInstance(Network::Connection& conn, const std::string& go_proto, - bool ingress, uint32_t src_id, uint32_t dst_id, - const std::string& src_addr, - const std::string& dst_addr, - const std::string& policy_name) const { - InstancePtr parser{nullptr}; - if (go_module_handle_) { - parser = std::make_unique(*this, conn); - ENVOY_CONN_LOG(trace, "GoFilter: Calling go module", conn); - auto res = (*go_on_new_connection_)( - go_module_id_, go_proto, conn.id(), ingress, src_id, dst_id, src_addr, dst_addr, - policy_name, &parser->orig_.inject_slice_, &parser->reply_.inject_slice_); - if (res == FILTER_OK) { - parser->connection_id_ = conn.id(); - } else { - ENVOY_CONN_LOG(warn, "Cilium Network: Connection with parser \"{}\" rejected: {}", conn, - go_proto, toString(res)); - parser.reset(nullptr); - } - } - return parser; -} - -FilterResult GoFilter::Instance::onIo(bool reply, Buffer::Instance& data, bool end_stream) { - auto& dir = reply ? reply_ : orig_; - int64_t data_len = data.length(); - - // Pass bytes based on an earlier verdict? - if (dir.pass_bytes_ > 0) { - ASSERT(dir.drop_bytes_ == 0); // Can't drop and pass the same bytes - ASSERT(dir.buffer_.length() == 0); // Passed data is not buffered - ASSERT(dir.need_bytes_ == 0); // Passed bytes can't be needed - // Can return immediately if passing more that we have input. - // May need to process injected data even when there is no input left. - if (dir.pass_bytes_ > data_len) { - if (data_len > 0) { - ENVOY_CONN_LOG(debug, "Cilium Network::OnIO: Passing all input: {} bytes: {} ", conn_, - data_len, data.toString()); - dir.pass_bytes_ -= data_len; - } - return FILTER_OK; // all of 'data' is passed to the next filter - } - // Pass of dir.pass_bytes_ is done after buffer rearrangement below. - // Using the available APIs it is easier to move data from the beginning of - // a buffer to another rather than from the end of a buffer to another. - } else { - // Drop bytes based on an earlier verdict? - if (dir.drop_bytes_ > 0) { - ASSERT(dir.buffer_.length() == 0); // Dropped data is not buffered - ASSERT(dir.need_bytes_ == 0); // Dropped bytes can't be needed - // Can return immediately if passing more that we have input. - // May need to process injected data even when there is no input left. - if (dir.drop_bytes_ > data_len) { - if (data_len > 0) { - ENVOY_CONN_LOG(debug, "Cilium Network::OnIO: Dropping all input: {} bytes: {} ", conn_, - data_len, data.toString()); - dir.drop_bytes_ -= data_len; - data.drain(data_len); - } - return FILTER_OK; // everything was dropped, nothing more to be done - } - ENVOY_CONN_LOG(debug, "Cilium Network::OnIO: Dropping first {} bytes of input: {}", conn_, - dir.drop_bytes_, data.toString()); - data.drain(dir.drop_bytes_); - dir.drop_bytes_ = 0; - // At frame boundary, more data may remain - } - } - - // Move data to the end of the input buffer, use 'data' as the output buffer - dir.buffer_.move(data); - ASSERT(data.length() == 0); - auto& input = dir.buffer_; - int64_t input_len = input.length(); - auto& output = data; - - // Move pre-passed input to output. - // Note that the case of all new input being passed is already taken care of - // above. - if (dir.pass_bytes_ > 0) { - ENVOY_CONN_LOG(debug, "Cilium Network::OnIO: Passing first {} bytes of input: {}", conn_, - input_len, input.toString()); - output.move(input, dir.pass_bytes_); - input_len -= dir.pass_bytes_; - dir.pass_bytes_ = 0; - // At frame boundary, more data may remain - } - - // Output now at frame boundary, output frame(s) injected by the reverse - // direction first - if (dir.inject_slice_.len() > 0) { - ENVOY_CONN_LOG( - debug, "Cilium Network::OnIO: Reverse Injecting: {} bytes: {} ", conn_, - dir.inject_slice_.len(), - std::string(reinterpret_cast(dir.inject_slice_.data_), dir.inject_slice_.len())); - output.add(dir.inject_slice_.data_, dir.inject_slice_.len()); - dir.inject_slice_.reset(); - } - - // Do nothing if we don't have enough input (partial input remains buffered) - if (input_len < dir.need_bytes_) { - return FILTER_OK; - } - dir.need_bytes_ = 0; - - const int max_ops = 16; // Make shorter for testing purposes - FilterOp ops[max_ops]; - GoFilterOpSlice op_slice(ops, max_ops); - - FilterResult res; - bool terminal_op_seen = false; - bool inject_buf_exhausted = false; - - do { - op_slice.reset(); - Buffer::RawSliceVector raw_slices = input.getRawSlices(); - - int64_t total_length = 0; - absl::FixedArray> buffer_slices(raw_slices.size()); - uint64_t non_empty_slices = 0; - for (const Buffer::RawSlice& raw_slice : raw_slices) { - if (raw_slice.len_ > 0) { - buffer_slices[non_empty_slices++] = - GoSlice(reinterpret_cast(raw_slice.mem_), raw_slice.len_); - total_length += raw_slice.len_; - } - } - GoDataSlices input_slices(buffer_slices.begin(), non_empty_slices); - - ENVOY_CONN_LOG(trace, "Cilium Network::OnIO: Calling go module with {} bytes of data", conn_, - total_length); - res = (*parent_.go_on_data_)(connection_id_, reply, end_stream, &input_slices, &op_slice); - ENVOY_CONN_LOG(trace, "Cilium Network::OnIO: \'go_on_data\' returned {}, ops({})", conn_, - toString(res), op_slice.len()); - if (res == FILTER_OK) { - // Process all returned filter operations. - for (int i = 0; i < op_slice.len(); i++) { - auto op = ops[i].op; - auto n_bytes = ops[i].n_bytes; - - if (n_bytes == 0) { - ENVOY_CONN_LOG(warn, "Cilium Network::OnIO: INVALID op ({}) length: {} bytes", conn_, op, - n_bytes); - return FILTER_PARSER_ERROR; - } - - if (terminal_op_seen) { - ENVOY_CONN_LOG(warn, - "Cilium Network::OnIO: Filter operation {} after " - "terminal operation.", - conn_, op); - return FILTER_PARSER_ERROR; - } - - switch (op) { - case FILTEROP_MORE: - ENVOY_CONN_LOG(debug, "Cilium Network::OnIO: FILTEROP_MORE: {} bytes", conn_, n_bytes); - dir.need_bytes_ = input_len + n_bytes; - terminal_op_seen = true; // MORE can not be followed with other ops. - continue; // errors out if more operations follow - - case FILTEROP_PASS: - ENVOY_CONN_LOG(debug, "Cilium Network::OnIO: FILTEROP_PASS: {} bytes", conn_, n_bytes); - if (n_bytes > input_len) { - output.move(input, input_len); - dir.pass_bytes_ = n_bytes - input_len; // pass the remainder later - input_len = 0; - terminal_op_seen = true; // PASS more than input is terminal operation. - continue; // errors out if more operations follow - } - output.move(input, n_bytes); - input_len -= n_bytes; - break; - - case FILTEROP_DROP: - ENVOY_CONN_LOG(debug, "Cilium Network::OnIO: FILTEROP_DROP: {} bytes", conn_, n_bytes); - if (n_bytes > input_len) { - input.drain(input_len); - dir.drop_bytes_ = n_bytes - input_len; // drop the remainder later - input_len = 0; - terminal_op_seen = true; // DROP more than input is terminal operation. - continue; // errors out if more operations follow - } - input.drain(n_bytes); - input_len -= n_bytes; - break; - - case FILTEROP_INJECT: - if (n_bytes > dir.inject_slice_.len()) { - ENVOY_CONN_LOG(warn, - "Cilium Network::OnIO: FILTEROP_INJECT: INVALID " - "length: {} bytes", - conn_, n_bytes); - return FILTER_PARSER_ERROR; - } - ENVOY_CONN_LOG(debug, "Cilium Network::OnIO: FILTEROP_INJECT: {} bytes: {}", conn_, - n_bytes, - std::string(reinterpret_cast(dir.inject_slice_.data_), - dir.inject_slice_.len())); - output.add(dir.inject_slice_.data_, n_bytes); - dir.inject_slice_.drain(n_bytes); - break; - - case FILTEROP_ERROR: - default: - ENVOY_CONN_LOG(warn, "Cilium Network::OnIO: FILTEROP_ERROR: {} bytes", conn_, n_bytes); - return FILTER_PARSER_ERROR; - } - } - } else { - // Close the connection an any error - ENVOY_CONN_LOG(warn, "Cilium Network::OnIO: FILTER_POLICY_DROP {}", conn_, toString(res)); - return FILTER_PARSER_ERROR; - } - - if (dir.inject_slice_.len() > 0) { - ENVOY_CONN_LOG(warn, "Cilium Network::OnIO: {} bytes abandoned in inject buffer", conn_, - dir.inject_slice_.len()); - return FILTER_PARSER_ERROR; - } - - inject_buf_exhausted = dir.inject_slice_.atCapacity(); - - // Make space for more injected data - dir.inject_slice_.reset(); - - // Loop back if ops or inject buffer was exhausted - } while (!terminal_op_seen && (op_slice.len() == max_ops || inject_buf_exhausted)); - - if (output.length() < 100) { - ENVOY_CONN_LOG(debug, "Cilium Network::OnIO: Output on return: {}", conn_, output.toString()); - } else { - ENVOY_CONN_LOG(debug, "Cilium Network::OnIO: Output length return: {}", conn_, output.length()); - } - return res; -} - -void GoFilter::Instance::close() { - (*parent_.go_close_)(connection_id_); - connection_id_ = 0; - conn_.close(Network::ConnectionCloseType::FlushWrite); -} - -} // namespace Cilium -} // namespace Envoy diff --git a/cilium/proxylib.h b/cilium/proxylib.h deleted file mode 100644 index f826d159e..000000000 --- a/cilium/proxylib.h +++ /dev/null @@ -1,187 +0,0 @@ -#pragma once - -#include - -#include -#include -#include - -#include "envoy/buffer/buffer.h" -#include "envoy/network/connection.h" - -#include "source/common/buffer/buffer_impl.h" -#include "source/common/common/logger.h" - -#include "proxylib/libcilium.h" -#include "proxylib/types.h" - -namespace Envoy { -namespace Cilium { - -struct GoString { - GoString(const std::string& str) : mem_(str.c_str()), len_(str.length()) {} - GoString() : mem_(nullptr), len_(0) {} - - const char* mem_; - GoInt len_; -}; - -template struct GoSlice { - GoSlice() : data_(nullptr), len_(0) {} - GoSlice(T* data, GoInt len) : data_(data), len_(len), cap_(len) {} // Initialized as full - GoInt len() const { return len_; } - GoInt cap() const { return cap_; } - T& operator[](GoInt x) { return data_[x]; } - const T& operator[](GoInt x) const { return data_[x]; } - operator T*() { return data_; } - operator const T*() const { return data_; } - operator void*() { return data_; } - operator const void*() const { return data_; } - - T* data_; - GoInt len_; - GoInt cap_; -}; - -inline std::string toString(const FilterResult res) { - switch (res) { - case FILTER_OK: - return "No error"; - case FILTER_PARSER_ERROR: - return "Parser error"; - case FILTER_UNKNOWN_CONNECTION: - return "Unknown connection"; - case FILTER_UNKNOWN_PARSER: - return "Unknown parser"; - case FILTER_INVALID_ADDRESS: - return "Invalid address"; - case FILTER_POLICY_DROP: - return "Connection rejected"; - case FILTER_INVALID_INSTANCE: - return "Invalid proxylib instance"; - case FILTER_UNKNOWN_ERROR: - break; - } - return "Unknown error"; -} - -// Slice that remembers the base pointer and that can be reset. -// Note that these have more header data than GoSlices and therefore may not -// used as array elements passed to Go! -template struct ResetableSlice : GoSlice { - // Templated base class member access is a bit ugly - using GoSlice::data_; - using GoSlice::len_; - using GoSlice::cap_; - - ResetableSlice(T* data, GoInt cap) : GoSlice(data, cap), base_(data) { - len_ = 0; // Init as empty - } - - // Non-Go helpers to consume data filled in by Go. Must reset() before slice - // used by Go again. - GoInt drain(GoInt len) { - if (len > len_) { - len = len_; - } - data_ += len; - len_ -= len; - - return len; - } - bool atCapacity() { - // Return true if all of the available space was used, not affected by - // draining - return (data_ + len_) >= (base_ + cap_); - } - void reset() { - data_ = base_; - len_ = 0; - } - - // private part not visible to Go - T* base_; -}; - -struct GoStringPair { - GoString key; - GoString value; -}; - -using GoKeyValueSlice = GoSlice; -using GoOpenModuleCB = uint64_t (*)(GoKeyValueSlice, bool); -using GoCloseModuleCB = void (*)(uint64_t); - -using GoBufferSlice = ResetableSlice; -using GoOnNewConnectionCB = FilterResult (*)(uint64_t, GoString, uint64_t, bool, uint32_t, uint32_t, - GoString, GoString, GoString, GoBufferSlice*, - GoBufferSlice*); - -using GoDataSlices = GoSlice>; // Scatter-gather buffer list as '[][]byte' -using GoFilterOpSlice = ResetableSlice; -using GoOnDataCB = FilterResult (*)(uint64_t, bool, bool, GoDataSlices*, GoFilterOpSlice*); -using GoCloseCB = void (*)(uint64_t); - -class GoFilter : public Logger::Loggable { -public: - GoFilter(const std::string& go_module, const Protobuf::Map<::std::string, ::std::string>&); - ~GoFilter(); - - class Instance : public Logger::Loggable { - public: - Instance(const GoFilter& parent, Network::Connection& conn) : parent_(parent), conn_(conn) {} - ~Instance() { - if (connection_id_) { - // Tell Go parser to scrap the state kept for the connection - (*parent_.go_close_)(connection_id_); - } - } - - void close(); - - FilterResult onIo(bool reply, Buffer::Instance& data, bool end_stream); - - bool wantReplyInject() const { return reply_.wantToInject(); } - void setOrigEndStream(bool end_stream) { orig_.closed_ = end_stream; } - void setReplyEndStream(bool end_stream) { reply_.closed_ = end_stream; } - - struct Direction { - Direction() : inject_slice_(inject_buf_, sizeof(inject_buf_)) {} - - bool wantToInject() const { return !closed_ && inject_slice_.len() > 0; } - void close() { closed_ = true; } - - Buffer::OwnedImpl buffer_; // Buffered data in this direction - int64_t need_bytes_{0}; // Number of additional data bytes needed before can parse again - int64_t pass_bytes_{0}; // Number of bytes to pass without calling the parser again - int64_t drop_bytes_{0}; - bool closed_{false}; - GoBufferSlice inject_slice_; - uint8_t inject_buf_[1024]; - }; - - const GoFilter& parent_; - Network::Connection& conn_; - Direction orig_; - Direction reply_; - uint64_t connection_id_ = 0; - }; - using InstancePtr = std::unique_ptr; - - InstancePtr newInstance(Network::Connection& conn, const std::string& go_proto, bool ingress, - uint32_t src_id, uint32_t dst_id, const std::string& src_addr, - const std::string& dst_addr, const std::string& policy_name) const; - -private: - void* go_module_handle_{nullptr}; - GoCloseModuleCB go_close_module_; - GoOnNewConnectionCB go_on_new_connection_; - GoOnDataCB go_on_data_; - GoCloseCB go_close_; - uint64_t go_module_id_{0}; -}; - -using GoFilterSharedPtr = std::shared_ptr; - -} // namespace Cilium -} // namespace Envoy diff --git a/cilium/secret_watcher.cc b/cilium/secret_watcher.cc index 8446ef185..3b4277794 100644 --- a/cilium/secret_watcher.cc +++ b/cilium/secret_watcher.cc @@ -51,7 +51,7 @@ secretProvider(Server::Configuration::TransportSocketFactoryContext& context, const envoy::config::core::v3::ConfigSource& sds_config_source = getSDSConfig(sds_name, config_source); return context.serverFactoryContext().secretManager().findOrCreateGenericSecretProvider( - sds_config_source, sds_name, context.serverFactoryContext(), context.initManager()); + sds_config_source, sds_name, context.serverFactoryContext(), context.initManager(), true); } } // namespace diff --git a/cilium/websocket_codec.cc b/cilium/websocket_codec.cc index 2ff0bc800..e7c321894 100644 --- a/cilium/websocket_codec.cc +++ b/cilium/websocket_codec.cc @@ -35,6 +35,7 @@ #include "absl/strings/ascii.h" #include "absl/strings/string_view.h" +#include "absl/types/span.h" #include "cilium/websocket_config.h" #include "cilium/websocket_protocol.h" #include "third_party/utf8_range/utf8_validity.h" @@ -754,7 +755,7 @@ void Codec::Encoder::encode(Buffer::Instance& data, uint8_t opcode) { auto hex_len = std::min(data.length(), 20UL); const uint8_t* hex_data = reinterpret_cast(data.linearize(hex_len)); ENVOY_LOG(debug, "websocket encoder: {} bytes: 0x{}, opcode: {}", data.length(), - Hex::encode(hex_data, hex_len), opcode); + Hex::encode(absl::Span(hex_data, hex_len)), opcode); auto& config = parent_.config(); const size_t payload_len = data.length(); @@ -844,12 +845,14 @@ void Codec::Decoder::decode(Buffer::Instance& data, bool end_stream) { ENVOY_LOG(trace, "websocket decoder: unmasking payload remaining: {}, offset: {}, processing: " "{}: 0x{}", - payload_remaining_, mask_offset_, n_bytes, Hex::encode(buf, hex_len)); + payload_remaining_, mask_offset_, n_bytes, + Hex::encode(absl::Span(buf, hex_len))); mask_offset_ = maskData(buf, n_bytes, mask_, mask_offset_); } ENVOY_LOG(trace, "websocket decoder: payload remaining: {}, offset: {}, processing: {}: 0x{}", - payload_remaining_, mask_offset_, n_bytes, Hex::encode(buf, hex_len)); + payload_remaining_, mask_offset_, n_bytes, + Hex::encode(absl::Span(buf, hex_len))); if (close_received_) { // No data is accepted after CLOSE has been received. diff --git a/envoy.bazelrc b/envoy.bazelrc index 935475d33..cb391ab96 100644 --- a/envoy.bazelrc +++ b/envoy.bazelrc @@ -19,31 +19,24 @@ startup --host_jvm_args="-DBAZEL_TRACK_SOURCE_DIRECTORIES=1" # global ############################################################################# -common --noenable_bzlmod -common --enable_workspace +try-import %workspace%/ci.bazelrc + common --noincompatible_disallow_empty_glob common --noincompatible_disallow_ctx_resolve_tools common --legacy_external_runfiles -fetch --color=yes -run --color=yes +common --registry=https://bcr.bazel.build/ +common --registry=https://raw.githubusercontent.com/envoyproxy/bazel-registry/20dc7c2578669f36e7c18510e65c7178cf5bb304 +# common --registry=file:///bazel-registry +# this can be useful for dev +# common --lockfile_mode=off -build --color=yes build --jobs=HOST_CPUS-1 build --workspace_status_command="bash bazel/get_workspace_status" build --incompatible_strict_action_env -build --java_runtime_version=remotejdk_11 -build --tool_java_runtime_version=remotejdk_11 -build --java_language_version=11 -build --tool_java_language_version=11 -# TODO(jwendell): Remove after https://github.com/protocolbuffers/protobuf/issues/20760 is fixed. -build --extra_toolchains=@envoy//bazel:envoy_java_toolchain_definition # silence absl logspam. build --copt=-DABSL_MIN_LOG_LEVEL=4 # Global C++ standard and common warning suppressions -build --cxxopt=-std=c++20 --host_cxxopt=-std=c++20 -build --copt=-Wno-deprecated-declarations -build --define envoy_mobile_listener=enabled build --experimental_repository_downloader_retries=2 build --experimental_cc_static_library build --enable_platform_specific_config @@ -57,6 +50,10 @@ build --action_env=BAZEL_VOLATILE_DIRTY --host_action_env=BAZEL_VOLATILE_DIRTY build --test_summary=terse +# rules_external_jvm triggers unwanted android toolchain setup if this is set +# if you actually require this you should override it (see mobile/.bazelrc) +common --repo_env=ANDROID_HOME= + # TODO(keith): Remove once these 2 are the default build --incompatible_config_setting_private_default_visibility build --incompatible_enforce_config_setting_visibility @@ -67,16 +64,9 @@ test --experimental_ui_max_stdouterr_bytes=11712829 #default 1048576 # Allow tags to influence execution requirements common --incompatible_allow_tags_propagation -# Python -common --@rules_python//python/config_settings:bootstrap_impl=script -build --incompatible_default_to_explicit_init_py - # We already have absl in the build, define absl=1 to tell googletest to use absl for backtrace. build --define absl=1 -# Disable ICU linking for googleurl. -build --@googleurl//build_config:system_icu=0 - # Test options build --test_env=HEAPCHECK=normal --test_env=PPROF_PATH @@ -84,8 +74,43 @@ build --test_env=HEAPCHECK=normal --test_env=PPROF_PATH coverage --config=coverage coverage --build_tests_only +# Envoy deprecation +common --@envoy//bazel:deprecated_repo_arg_allowed=false + +# BCR modules with no registry override — deprecated absl Mutex shims / TSA false positives / fuzz semantics. +build --per_file_copt=external/antlr4-cpp-runtime.*@-Wno-deprecated-declarations +build --per_file_copt=external/c-ares.*@-Wno-unused-function +build --per_file_copt=external/google_benchmark.*@-Wno-thread-safety-analysis +build --per_file_copt=external/libprotobuf-mutator.*@-Wno-unused-result +build --per_file_copt=external/librdkafka.*@-Wno-unused-variable,-Wno-unused-but-set-variable,-Wno-sometimes-uninitialized,-Wno-uninitialized,-Wno-implicit-enum-enum-cast +build --per_file_copt=external/re2.*@-Wno-deprecated-declarations + + +############################################################################# +# global: deps +############################################################################# + +# Python +common --@rules_python//python/config_settings:bootstrap_impl=script +build --incompatible_default_to_explicit_init_py + +# Rust # Specifies the rustfmt.toml for all rustfmt_test targets. build --@rules_rust//rust/settings:rustfmt.toml=@envoy//:rustfmt.toml +common --@rules_rust//rust/settings:skip_fission_for_rust=true + +# kafka +build --@librdkafka//:with_ssl=false +build --@librdkafka//:with_zlib=false +build --per_file_copt=contrib/kafka/.*\.cc@-Wno-old-style-cast + +common --incompatible_enable_proto_toolchain_resolution + +# these are here to detect if the toolchain attempts to compile protoc +common --per_file_copt=bazel-out/.*/bin/external/protobuf.*/protoc@--THIS_CC_TOOLCHAIN_IS_BROKEN + +# TODO(phlax): Remove this once a proper fix for the deprecated enum lands +build --per_file_copt=external/envoy_api.*/route_components\.pb\.cc@-Wno-deprecated-declarations ############################################################################# @@ -96,7 +121,6 @@ build:linux --copt=-fdebug-types-section # Enable position independent code (this is the default on macOS and Windows) # (Workaround for https://github.com/bazelbuild/rules_foreign_cc/issues/421) build:linux --copt=-fPIC -build:linux --cxxopt=-fsized-deallocation --host_cxxopt=-fsized-deallocation build:linux --conlyopt=-fexceptions build:linux --fission=dbg,opt build:linux --features=per_object_debug_info @@ -105,30 +129,13 @@ build:linux --features=per_object_debug_info build:macos --action_env=PATH=/opt/homebrew/bin:/opt/local/bin:/usr/local/bin:/usr/bin:/bin build:macos --host_action_env=PATH=/opt/homebrew/bin:/opt/local/bin:/usr/local/bin:/usr/bin:/bin build:macos --define tcmalloc=disabled -build:macos --cxxopt=-Wno-nullability-completeness -build:macos --@toolchains_llvm//toolchain/config:compiler-rt=false -build:macos --@toolchains_llvm//toolchain/config:libunwind=false +build:macos --cxxopt=-std=c++20 --host_cxxopt=-std=c++20 ############################################################################# # compiler ############################################################################# -# Common flags for Clang (shared between all clang variants) -common:clang-common --linkopt=-fuse-ld=lld -common:clang-common --@toolchains_llvm//toolchain/config:compiler-rt=false -common:clang-common --@toolchains_llvm//toolchain/config:libunwind=false - -# Clang with libc++ (default) -common:clang --config=clang-common -common:clang --config=libc++ -common:clang --host_platform=@clang_platform -common:clang --repo_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 - -# Clang installed to non-standard location (ie not /opt/llvm/) -common:clang-local --config=clang-common -common:clang-local --config=libc++ - # Use gold linker for gcc compiler. build:gcc --config=libstdc++ build:gcc --test_env=HEAPCHECK= @@ -149,7 +156,6 @@ build:gcc --cxxopt=-Wno-nonnull-compare build:gcc --cxxopt=-Wno-trigraphs build:gcc --linkopt=-fuse-ld=gold --host_linkopt=-fuse-ld=gold build:gcc --host_platform=@envoy//bazel/rbe/toolchains:rbe_linux_gcc_platform -build:gcc --linkopt=-fuse-ld=gold --host_linkopt=-fuse-ld=gold build:gcc --action_env=BAZEL_LINKOPTS=-lm:-fuse-ld=gold # libc++ - default for clang @@ -158,13 +164,10 @@ common:libc++ --action_env=LDFLAGS="-stdlib=libc++ -fuse-ld=lld" common:libc++ --action_env=BAZEL_CXXOPTS=-stdlib=libc++ common:libc++ --action_env=BAZEL_LINKLIBS=-l%:libc++.a:-l%:libc++abi.a common:libc++ --action_env=BAZEL_LINKOPTS=-lm:-pthread -common:libc++ --define force_libcpp=enabled -common:libc++ --@envoy//bazel:libc++=true # libstdc++ - currently only used for gcc build:libstdc++ --action_env=BAZEL_LINKLIBS=-l%:libstdc++.a -build:libstdc++ --@envoy//bazel:libc++=false -build:libstdc++ --@envoy//bazel:libstdc++=true +build:libstdc++ --repo_env=BAZEL_USE_LIBSTDCPP=True ############################################################################# @@ -201,7 +204,7 @@ build:coverage --coverage_report_generator=@envoy//tools/coverage:report_generat build:test-coverage --test_arg="-l trace" build:test-coverage --test_arg="--log-path /dev/null" -build:test-coverage --test_tag_filters=-nocoverage,-fuzz_target +build:test-coverage --test_tag_filters=-nocoverage,-fuzz_target,-quiche ## Compile-time-options testing # Right now, none of the available compile-time options conflict with each other. If this @@ -220,6 +223,9 @@ build:compile-time-options --copt=-Wno-error=deprecated-enum-enum-conversion build:compile-time-options --test_env=ENVOY_HAS_EXTRA_EXTENSIONS=true build:compile-time-options --@envoy//bazel:http3=False build:compile-time-options --@envoy//source/extensions/filters/http/kill_request:enabled +# This is a Protobuf feature which breaks dynamic casting of messages. Turn it +# on here to prevent raw dynamic_casts from being added to Envoy. +build:compile-time-options --copt=-DPROTOBUF_ENABLE_CUSTOM_VTABLES=1 ############################################################################# @@ -232,23 +238,25 @@ common:fips-common --@envoy//bazel:fips=True # BoringSSL FIPS common:boringssl-fips --config=fips-common -common:boringssl-fips --@envoy//bazel:ssl=@boringssl_fips//:ssl -common:boringssl-fips --@envoy//bazel:crypto=@boringssl_fips//:crypto - -# AWS-LC FIPS -common:aws-lc-fips --config=fips-common -common:aws-lc-fips --@envoy//bazel:ssl=@aws_lc//:ssl -common:aws-lc-fips --@envoy//bazel:crypto=@aws_lc//:crypto -common:aws-lc-fips --@envoy//bazel:http3=False +common:boringssl-fips --@envoy//bazel:ssl=@boringssl-fips//:ssl +common:boringssl-fips --@envoy//bazel:crypto=@boringssl-fips//:crypto # OpenSSL common:openssl --@envoy//bazel:openssl=True common:openssl --@envoy//bazel:ssl=@envoy//compat/openssl:ssl common:openssl --@envoy//bazel:crypto=@envoy//compat/openssl:crypto +# Route QUICHE's SSL to the OpenSSL compat layer too. QUICHE is still linked in +# OpenSSL builds via non-QUIC features (e.g. HTTP datagram / CONNECT-UDP capsule +# support), and must use the same SSL implementation as the rest of the binary +# to avoid linking BoringSSL and OpenSSL together (symbol/ABI collisions). common:openssl --copt=-DENVOY_SSL_OPENSSL common:openssl --host_copt=-DENVOY_SSL_OPENSSL common:openssl --@envoy//bazel:http3=False -common:openssl --test_tag_filters=-nofips +# Exclude QUIC/HTTP3 sources from the quiche module overlay when HTTP/3 is +# disabled. This keeps QUIC code that depends on BoringSSL-only primitives +# (e.g. SIPHASH_24) out of the OpenSSL build. +common:openssl --define=quiche_disable_http3=true +common:openssl --test_tag_filters=-nofips,-quiche common:openssl --build_tag_filters=-nofips @@ -270,7 +278,7 @@ build:asan --linkopt=-l:libclang_rt.ubsan_standalone_cxx.a build:asan --action_env=ENVOY_UBSAN_VPTR=1 build:asan --copt=-fsanitize=vptr,function build:asan --linkopt=-fsanitize=vptr,function -build:asan --linkopt='-L/opt/llvm/lib/clang/18/lib/x86_64-unknown-linux-gnu' +build:asan --linkopt='-L/opt/llvm/lib/clang/22/lib/x86_64-unknown-linux-gnu' # Basic ASAN/UBSAN that works for gcc or llvm build:asan-common --config=sanitizer @@ -281,7 +289,7 @@ build:asan-common --build_tag_filters=-no_san build:asan-common --test_tag_filters=-no_san build:asan-common --copt -fsanitize=address,undefined build:asan-common --linkopt -fsanitize=address,undefined -# vptr and function sanitizer are enabled in asan when using --config=clang. +# vptr and function sanitizer are enabled in asan build:asan-common --copt -fno-sanitize=vptr,function build:asan-common --linkopt -fno-sanitize=vptr,function build:asan-common --copt -DADDRESS_SANITIZER=1 @@ -312,6 +320,7 @@ build:msan --test_tag_filters=-no_san build:msan --define ENVOY_CONFIG_MSAN=1 build:msan --copt -fsanitize=memory build:msan --linkopt -fsanitize=memory +build:msan --linkopt=-Wl,--allow-multiple-definition build:msan --copt -fsanitize-memory-track-origins=2 build:msan --copt -DMEMORY_SANITIZER=1 build:msan --test_env=MSAN_SYMBOLIZER_PATH @@ -325,6 +334,7 @@ build:tsan --config=sanitizer build:tsan --define ENVOY_CONFIG_TSAN=1 build:tsan --copt -fsanitize=thread build:tsan --linkopt -fsanitize=thread +build:tsan --linkopt=-Wl,--allow-multiple-definition build:tsan --copt -DTHREAD_SANITIZER=1 build:tsan --build_tag_filters=-no_san,-no_tsan build:tsan --test_tag_filters=-no_san,-no_tsan @@ -351,17 +361,16 @@ build:asan-fuzzer --config=asan build:asan-fuzzer --copt=-fno-omit-frame-pointer # Remove UBSAN halt_on_error to avoid crashing on protobuf errors. build:asan-fuzzer --test_env=UBSAN_OPTIONS=print_stacktrace=1 -build:asan-fuzzer --linkopt=-lc++ build:fuzz-coverage --config=plain-fuzzer build:fuzz-coverage --run_under=@envoy//bazel/coverage:fuzz_coverage_wrapper.sh -build:fuzz-coverage --test_tag_filters=-nocoverage +build:fuzz-coverage --test_tag_filters=-nocoverage,-quiche # Existing fuzz tests don't need a full WASM runtime and in generally we don't really want to # fuzz dependencies anyways. On the other hand, disabling WASM reduces the build time and # resources required to build and run the tests. -build:fuzz-coverage --define=wasm=disabled +build:fuzz-coverage --@proxy-wasm-cpp-host//bazel:engine=disabled build:fuzz-coverage --config=fuzz-coverage-config -build:fuzz-coverage-config --//tools/coverage:config=@envoy//test:fuzz_coverage_config +build:fuzz-coverage-config --@envoy//tools/coverage:config=@envoy//test:fuzz_coverage_config build:oss-fuzz --config=fuzzing build:oss-fuzz --config=libc++ @@ -375,7 +384,6 @@ build:oss-fuzz --linkopt=-fno-sanitize=vptr build:oss-fuzz --define=tcmalloc=disabled build:oss-fuzz --define=signal_trace=disabled build:oss-fuzz --copt=-D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -build:oss-fuzz --define=force_libcpp=enabled build:oss-fuzz --linkopt=-lc++ build:oss-fuzz --linkopt=-pthread @@ -409,7 +417,7 @@ build:clang-tidy --build_tag_filters=-notidy # Compile database generation config build:compdb --build_tag_filters=-nocompdb -common:cves --//tools/dependency:cve-data=//tools/dependency:cve-data-dir +common:cves --@envoy//tools/dependency:cve-data=@envoy//tools/dependency:cve-data-dir build:docs-ci --action_env=DOCS_RST_CHECK=1 --host_action_env=DOCS_RST_CHECK=1 @@ -418,46 +426,9 @@ build:sizeopt -c opt --copt -Os ############################################################################# -# remote: Setup for cache, BES, RBE, and Docker workers +# remote: Docker workers ############################################################################# -build:remote --spawn_strategy=remote,sandboxed,local -build:remote --strategy=Javac=remote,sandboxed,local -build:remote --strategy=Closure=remote,sandboxed,local -build:remote --strategy=Genrule=remote,sandboxed,local -build:remote --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 -# This flag may be more generally useful - it sets foreign_cc builds -jauto. -# It is only set here because if it were the default it risks OOMing on local builds. -build:remote --@envoy//bazel/foreign_cc:parallel_builds - -## RBE (Engflow Envoy) - -# this is not included in the `--config=rbe` target - set it to publish to engflow ui -common:bes --bes_backend=grpcs://mordenite.cluster.engflow.com/ -common:bes --bes_results_url=https://mordenite.cluster.engflow.com/invocation/ -common:bes --bes_timeout=3600s -common:bes --bes_upload_mode=fully_async -common:bes --nolegacy_important_outputs - -common:engflow-common --google_default_credentials=false -common:engflow-common --credential_helper=*.engflow.com=%workspace%/bazel/engflow-bazel-credential-helper.sh -common:engflow-common --grpc_keepalive_time=60s -common:engflow-common --grpc_keepalive_timeout=30s -common:engflow-common --remote_cache_compression - -# this provides access to RBE+cache -common:rbe --config=remote-cache -common:rbe --config=remote-exec - -# this provides access to just cache -common:remote-cache --config=engflow-common -common:remote-cache --remote_cache=grpcs://mordenite.cluster.engflow.com -common:remote-cache --remote_timeout=3600s - -common:remote-exec --remote_executor=grpcs://mordenite.cluster.engflow.com -common:remote-exec --jobs=200 -common:remote-exec --define=engflow_rbe=true - # Docker sandboxes build:docker-sandbox --spawn_strategy=docker build:docker-sandbox --strategy=Javac=docker @@ -468,61 +439,19 @@ build:docker-sandbox --experimental_docker_verbose build:docker-sandbox --experimental_enable_docker_sandbox build:docker-clang --config=docker-sandbox -build:docker-clang --config=clang build:docker-gcc --config=docker-sandbox build:docker-gcc --config=gcc build:docker-asan --config=docker-sandbox -build:docker-asan --config=clang build:docker-asan --config=asan build:docker-msan --config=docker-sandbox -build:docker-msan --config=clang build:docker-msan --config=msan build:docker-tsan --config=docker-sandbox -build:docker-tsan --config=clang build:docker-tsan --config=tsan - -############################################################################# -# ci -############################################################################# - -# CI configurations -build:remote-ci --config=ci -build:remote-ci --remote_download_minimal - -# Note this config is used by mobile CI also. -common:ci --noshow_progress -common:ci --noshow_loading_progress -common:ci --test_output=errors - - -############################################################################# -# debug: Various Bazel debugging flags -############################################################################# -# debug/bazel -common:debug-bazel --announce_rc -common:debug-bazel -s -# debug/sandbox -common:debug-sandbox --verbose_failures -common:debug-sandbox --sandbox_debug -# debug/coverage -common:debug-coverage --action_env=VERBOSE_COVERAGE=true -common:debug-coverage --test_env=VERBOSE_COVERAGE=true -common:debug-coverage --test_env=DISPLAY_LCOV_CMD=true -common:debug-coverage --config=debug-tests -# debug/tests -common:debug-tests --test_output=all -# debug/everything -common:debug --config=debug-bazel -common:debug --config=debug-sandbox -common:debug --config=debug-coverage -common:debug --config=debug-tests - -try-import %workspace%/repo.bazelrc try-import %workspace%/clang.bazelrc try-import %workspace%/user.bazelrc try-import %workspace%/local_tsan.bazelrc diff --git a/envoy_build_config/extensions_build_config.bzl b/envoy_build_config/extensions_build_config.bzl index c81c258cb..17d759983 100644 --- a/envoy_build_config/extensions_build_config.bzl +++ b/envoy_build_config/extensions_build_config.bzl @@ -50,6 +50,7 @@ EXTENSIONS = { # Config validators # + # "envoy.config.validators.dynamic_modules": "//source/extensions/config/validators/dynamic_modules:config", # "envoy.config.validators.minimum_clusters_validator": "//source/extensions/config/validators/minimum_clusters:config", # @@ -80,6 +81,7 @@ EXTENSIONS = { # "envoy.health_checkers.dynamic_modules": "//source/extensions/health_checkers/dynamic_modules:config", "envoy.health_checkers.redis": "//source/extensions/health_checkers/redis:config", "envoy.health_checkers.thrift": "//source/extensions/health_checkers/thrift:config", + # "envoy.health_checkers.udp": "//source/extensions/health_checkers/udp:health_checker_lib", "envoy.health_checkers.tcp": "//source/extensions/health_checkers/tcp:health_checker_lib", "envoy.health_checkers.http": "//source/extensions/health_checkers/http:health_checker_lib", "envoy.health_checkers.grpc": "//source/extensions/health_checkers/grpc:health_checker_lib", @@ -129,6 +131,7 @@ EXTENSIONS = { # # "envoy.matching.inputs.cel_data_input": "//source/extensions/matching/http/cel_input:cel_input_lib", # "envoy.matching.inputs.dynamic_module_data_input": "//source/extensions/matching/http/dynamic_modules:data_input_lib", + # "envoy.matching.inputs.dynamic_module_string_data_input": "//source/extensions/matching/http/dynamic_modules:string_data_input_lib", # # Dynamic Metadata Matching Input @@ -224,11 +227,13 @@ EXTENSIONS = { "envoy.filters.http.router": "//source/extensions/filters/http/router:config", "envoy.filters.http.set_filter_state": "//source/extensions/filters/http/set_filter_state:config", "envoy.filters.http.set_metadata": "//source/extensions/filters/http/set_metadata:config", + # "envoy.filters.http.body_size_limit": "//source/extensions/filters/http/body_size_limit:config", # "envoy.filters.http.tap": "//source/extensions/filters/http/tap:config", # "envoy.filters.http.thrift_to_metadata": "//source/extensions/filters/http/thrift_to_metadata:config", "envoy.filters.http.wasm": "//source/extensions/filters/http/wasm:config", "envoy.filters.http.stateful_session": "//source/extensions/filters/http/stateful_session:config", # "envoy.filters.http.sse_to_metadata": "//source/extensions/filters/http/sse_to_metadata:config", + # "envoy.filters.http.aws_eventstream_parser": "//source/extensions/filters/http/aws_eventstream_parser:config", # "envoy.filters.http.header_mutation": "//source/extensions/filters/http/header_mutation:config", # "envoy.filters.http.transform": "//source/extensions/filters/http/transform:config", @@ -401,6 +406,7 @@ EXTENSIONS = { # # "envoy.internal_redirect_predicates.allow_listed_routes": "//source/extensions/internal_redirect/allow_listed_routes:config", + # "envoy.internal_redirect_predicates.filter_state": "//source/extensions/internal_redirect/filter_state:config", # "envoy.internal_redirect_predicates.previous_routes": "//source/extensions/internal_redirect/previous_routes:config", # "envoy.internal_redirect_predicates.safe_cross_scheme": "//source/extensions/internal_redirect/safe_cross_scheme:config", @@ -418,6 +424,7 @@ EXTENSIONS = { # Watchdog actions # + # "envoy.watchdog.backtrace_action": "//source/extensions/watchdog/backtrace_action:config", # "envoy.watchdog.profile_action": "//source/extensions/watchdog/profile_action:config", # @@ -434,6 +441,7 @@ EXTENSIONS = { # "envoy.rate_limit_descriptors.expr": "//source/extensions/rate_limit_descriptors/expr:config", + # "envoy.rate_limit_descriptors.jwt_claim": "//source/extensions/rate_limit_descriptors/jwt_claim:config", # # IO socket @@ -449,10 +457,17 @@ EXTENSIONS = { # "envoy.tls.cert_validator.dynamic_modules": "//source/extensions/transport_sockets/tls/cert_validator/dynamic_modules:config", # "envoy.tls.cert_validator.spiffe": "//source/extensions/transport_sockets/tls/cert_validator/spiffe:config", + # + # TLS handshakers + # + + # "envoy.tls.handshakers.dynamic_modules": "//source/extensions/transport_sockets/tls/handshakers/dynamic_modules:config", + # # HTTP header formatters # + # "envoy.http.stateful_header_formatters.dynamic_modules": "//source/extensions/http/header_formatters/dynamic_modules:config", "envoy.http.stateful_header_formatters.preserve_case": "//source/extensions/http/header_formatters/preserve_case:config", # @@ -487,6 +502,13 @@ EXTENSIONS = { # # "envoy.http.ext_proc.response_processors.save_processing_response": "//source/extensions/http/ext_proc/response_processors/save_processing_response:save_processing_response_lib", + # + # AI filters + # + # "envoy.http.ai_filters.request_info": "//source/extensions/http/ai_filters/request_info:config", + # "envoy.http.ai_filters.schema_validation": "//source/extensions/http/ai_filters/schema_validation:config", + # "envoy.http.ai_filters.transcoder": "//source/extensions/http/ai_filters/transcoder:config", + # # Injected credentials # @@ -612,6 +634,7 @@ EXTENSIONS = { # # HTTP Early Header Mutation # + # "envoy.http.early_header_mutation.dynamic_modules": "//source/extensions/http/early_header_mutation/dynamic_modules:config", "envoy.http.early_header_mutation.header_mutation": "//source/extensions/http/early_header_mutation/header_mutation:config", # @@ -642,8 +665,15 @@ EXTENSIONS = { # # Cluster specifier plugin # - # "envoy.router.cluster_specifier_plugin.lua": "//source/extensions/router/cluster_specifiers/lua:config", - # "envoy.router.cluster_specifier_plugin.matcher": "//source/extensions/router/cluster_specifiers/matcher:config", + # "envoy.router.cluster_specifier_plugin.dynamic_modules": "//source/extensions/router/cluster_specifiers/dynamic_modules:config", + # "envoy.router.cluster_specifier_plugin.lua": "//source/extensions/router/cluster_specifiers/lua:config", + # "envoy.router.cluster_specifier_plugin.matcher": "//source/extensions/router/cluster_specifiers/matcher:config", + # "envoy.router.cluster_specifier_plugin.priority_group": "//source/extensions/router/cluster_specifiers/priority_group:config", + + # + # Route specifier + # + # "envoy.router.route_specifiers.dynamic_modules": "//source/extensions/router/route_specifiers/dynamic_modules:config", # # Extensions for generic proxy @@ -665,12 +695,15 @@ EXTENSIONS = { # Local address selectors # "envoy.upstream.local_address_selector.filter_state_override": "//source/extensions/local_address_selectors/filter_state_override:config", + + # + # Queue policy + # + # "envoy.queue_policy.fifo": "//source/extensions/queue_policy/fifo:fifo_queue_policy_impl", } # These can be changed to ["//visibility:public"], for downstream builds which # need to directly reference Envoy extensions. -# These can be changed to ["//visibility:public"], for downstream builds which -# need to directly reference Envoy extensions. EXTENSION_CONFIG_VISIBILITY = ["//visibility:public"] EXTENSION_PACKAGE_VISIBILITY = ["//visibility:public"] CONTRIB_EXTENSION_PACKAGE_VISIBILITY = ["//visibility:public"] diff --git a/go.mod b/go.mod index c78f74649..d14a37730 100644 --- a/go.mod +++ b/go.mod @@ -5,14 +5,9 @@ go 1.26.4 toolchain go1.27.2 require ( - github.com/cilium/kafka v0.0.0-20180809090225-01ce283b732b github.com/envoyproxy/go-control-plane/envoy v1.37.0 github.com/envoyproxy/protoc-gen-validate v1.3.3 - github.com/sirupsen/logrus v1.10.2 - github.com/stretchr/testify v1.12.1 - golang.org/x/sys v0.48.0 google.golang.org/genproto/googleapis/api v0.0.0-20261005182115-fad411399dd8 - google.golang.org/genproto/googleapis/rpc v0.0.0-20261005182115-fad411399dd8 google.golang.org/grpc v1.84.0 google.golang.org/protobuf v1.36.12 ) @@ -20,17 +15,18 @@ require ( require ( cel.dev/expr v0.25.2 // indirect github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 // indirect - github.com/golang/snappy v0.0.4 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/lyft/protoc-gen-star/v2 v2.0.4 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20260702190614-8ae5a48058df // indirect github.com/spf13/afero v1.15.0 // indirect - go.yaml.in/yaml/v3 v3.0.5 // indirect + github.com/stretchr/testify v1.12.1 // indirect golang.org/x/mod v0.38.0 // indirect golang.org/x/net v0.58.0 // indirect golang.org/x/sync v0.22.0 // indirect + golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.41.0 // indirect golang.org/x/tools v0.48.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20261005182115-fad411399dd8 // indirect google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2 // indirect ) diff --git a/go.sum b/go.sum index f214e4c75..99d8cae55 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ cel.dev/expr v0.25.2 h1:K6j46C81hXtZQfuX60cVWQFBJahKSE2gfRbNuvr5bFs= cel.dev/expr v0.25.2/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= -github.com/cilium/kafka v0.0.0-20180809090225-01ce283b732b h1:+bsFX/WOMIoaayXVyRem1awcpz3icz/HoL8Dxg/m6a4= -github.com/cilium/kafka v0.0.0-20180809090225-01ce283b732b/go.mod h1:ktgizta3CPZBKz5uW272SJyjiro0vn4nOVP7Pk4RopA= github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik= github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= github.com/envoyproxy/go-control-plane/envoy v1.37.0 h1:u3riX6BoYRfF4Dr7dwSOroNfdSbEPe9Yyl09/B6wBrQ= @@ -10,8 +8,6 @@ github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMD github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= @@ -20,8 +16,6 @@ github.com/lyft/protoc-gen-star/v2 v2.0.4 h1:JDlNKttNIRd68AAIychs0AqEpO8/I/WYi01 github.com/lyft/protoc-gen-star/v2 v2.0.4/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/planetscale/vtprotobuf v0.6.1-0.20260702190614-8ae5a48058df h1:x2ymdov8jnZLDPfI+VVcf/ZvzuZ2u36ieXTuQASMkWI= github.com/planetscale/vtprotobuf v0.6.1-0.20260702190614-8ae5a48058df/go.mod h1:araspv2uYKozbi5lrKaqpv1/Uei7eQSml8JCw2A3IRg= -github.com/sirupsen/logrus v1.10.2 h1:G2SED73/qrAu6YwbdxOD6peLkCBI3z7L+ykJFTXJBBo= -github.com/sirupsen/logrus v1.10.2/go.mod h1:SLEg8TqYulVKKfIGHldVp2K2aYz2DKSVBq4g/H5bR7Q= github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= diff --git a/go/cilium/api/network_filter.pb.go b/go/cilium/api/network_filter.pb.go index 74f594c08..fd4ac5cad 100644 --- a/go/cilium/api/network_filter.pb.go +++ b/go/cilium/api/network_filter.pb.go @@ -23,10 +23,6 @@ const ( type NetworkFilter struct { state protoimpl.MessageState `protogen:"open.v1"` - // Path to the proxylib to be opened - Proxylib string `protobuf:"bytes,1,opt,name=proxylib,proto3" json:"proxylib,omitempty"` - // Transparent set of parameters provided for proxylib initialization - ProxylibParams map[string]string `protobuf:"bytes,2,rep,name=proxylib_params,json=proxylibParams,proto3" json:"proxylib_params,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // Path to the unix domain socket for the cilium access log. AccessLogPath string `protobuf:"bytes,5,opt,name=access_log_path,json=accessLogPath,proto3" json:"access_log_path,omitempty"` unknownFields protoimpl.UnknownFields @@ -63,20 +59,6 @@ func (*NetworkFilter) Descriptor() ([]byte, []int) { return file_cilium_api_network_filter_proto_rawDescGZIP(), []int{0} } -func (x *NetworkFilter) GetProxylib() string { - if x != nil { - return x.Proxylib - } - return "" -} - -func (x *NetworkFilter) GetProxylibParams() map[string]string { - if x != nil { - return x.ProxylibParams - } - return nil -} - func (x *NetworkFilter) GetAccessLogPath() string { if x != nil { return x.AccessLogPath @@ -88,14 +70,9 @@ var File_cilium_api_network_filter_proto protoreflect.FileDescriptor const file_cilium_api_network_filter_proto_rawDesc = "" + "\n" + - "\x1fcilium/api/network_filter.proto\x12\x06cilium\"\xea\x01\n" + - "\rNetworkFilter\x12\x1a\n" + - "\bproxylib\x18\x01 \x01(\tR\bproxylib\x12R\n" + - "\x0fproxylib_params\x18\x02 \x03(\v2).cilium.NetworkFilter.ProxylibParamsEntryR\x0eproxylibParams\x12&\n" + - "\x0faccess_log_path\x18\x05 \x01(\tR\raccessLogPath\x1aA\n" + - "\x13ProxylibParamsEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B.Z,github.com/cilium/proxy/go/cilium/api;ciliumb\x06proto3" + "\x1fcilium/api/network_filter.proto\x12\x06cilium\"^\n" + + "\rNetworkFilter\x12&\n" + + "\x0faccess_log_path\x18\x05 \x01(\tR\raccessLogPathJ\x04\b\x01\x10\x02J\x04\b\x02\x10\x03R\bproxylibR\x0fproxylib_paramsB.Z,github.com/cilium/proxy/go/cilium/api;ciliumb\x06proto3" var ( file_cilium_api_network_filter_proto_rawDescOnce sync.Once @@ -109,18 +86,16 @@ func file_cilium_api_network_filter_proto_rawDescGZIP() []byte { return file_cilium_api_network_filter_proto_rawDescData } -var file_cilium_api_network_filter_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_cilium_api_network_filter_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_cilium_api_network_filter_proto_goTypes = []any{ (*NetworkFilter)(nil), // 0: cilium.NetworkFilter - nil, // 1: cilium.NetworkFilter.ProxylibParamsEntry } var file_cilium_api_network_filter_proto_depIdxs = []int32{ - 1, // 0: cilium.NetworkFilter.proxylib_params:type_name -> cilium.NetworkFilter.ProxylibParamsEntry - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_cilium_api_network_filter_proto_init() } @@ -134,7 +109,7 @@ func file_cilium_api_network_filter_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_cilium_api_network_filter_proto_rawDesc), len(file_cilium_api_network_filter_proto_rawDesc)), NumEnums: 0, - NumMessages: 2, + NumMessages: 1, NumExtensions: 0, NumServices: 0, }, diff --git a/go/cilium/api/network_filter.pb.validate.go b/go/cilium/api/network_filter.pb.validate.go index 5e2c8af18..fefef53df 100644 --- a/go/cilium/api/network_filter.pb.validate.go +++ b/go/cilium/api/network_filter.pb.validate.go @@ -57,10 +57,6 @@ func (m *NetworkFilter) validate(all bool) error { var errors []error - // no validation rules for Proxylib - - // no validation rules for ProxylibParams - // no validation rules for AccessLogPath if len(errors) > 0 { diff --git a/go/cilium/api/npds.pb.go b/go/cilium/api/npds.pb.go index d17569698..41033d0b3 100644 --- a/go/cilium/api/npds.pb.go +++ b/go/cilium/api/npds.pb.go @@ -454,9 +454,10 @@ type PortNetworkPolicyRule struct { // = "([*]{1,2}|)" // PATTERN = "^([.])*$" ServerNames []string `protobuf:"bytes,6,rep,name=server_names,json=serverNames,proto3" json:"server_names,omitempty"` - // Optional L7 protocol parser name. This is only used if the parser is not - // one of the well knows ones. If specified, the l7 parser having this name - // needs to be built in to libcilium.so. + // Optional L7 protocol name. This is only used if the protocol is not + // one of the well known ones. If specified, it is added to the requested + // application protocols of the connection for filter chain matching, and + // names the Envoy filter whose dynamic metadata is matched by 'l7_rules'. L7Proto string `protobuf:"bytes,2,opt,name=l7_proto,json=l7Proto,proto3" json:"l7_proto,omitempty"` // Optional. If not specified, any L7 request is matched by this predicate. // All rules on any given port must have the same type of L7 rules! diff --git a/healthcheck/BUILD b/healthcheck/BUILD index 8621f5456..889f4c720 100644 --- a/healthcheck/BUILD +++ b/healthcheck/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_binary") +load("@rules_go//go:def.bzl", "go_binary") licenses(["notice"]) # Apache 2 diff --git a/patches/0001-network-Add-callback-for-upstream-authorization.patch b/patches/0001-network-Add-callback-for-upstream-authorization.patch index 22307a170..f60f55180 100644 --- a/patches/0001-network-Add-callback-for-upstream-authorization.patch +++ b/patches/0001-network-Add-callback-for-upstream-authorization.patch @@ -1,7 +1,7 @@ -From 4044a8fd8a2552319be18e04f88d78d69d1ca791 Mon Sep 17 00:00:00 2001 +From d723c6604233e2c398103104a95cef33a8477b2e Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Mon, 5 May 2025 11:15:52 +1000 -Subject: [PATCH 1/6] network: Add callback for upstream authorization +Subject: [PATCH 1/8] network: Add callback for upstream authorization Add new ReadFilterCallbacks addUpstreamCallback() and iterateUpstreamCallbacks(). Network filters can add callbacks using @@ -42,10 +42,10 @@ Signed-off-by: Jarno Rajahalme 15 files changed, 124 insertions(+) diff --git a/envoy/http/filter.h b/envoy/http/filter.h -index e14eaef745..af5859fc02 100644 +index dfc1c9c45b..cd58840ccc 100644 --- a/envoy/http/filter.h +++ b/envoy/http/filter.h -@@ -915,6 +915,14 @@ public: +@@ -929,6 +929,14 @@ public: virtual OptRef upstreamOverrideHost() const PURE; @@ -61,10 +61,10 @@ index e14eaef745..af5859fc02 100644 * @return true if the filter should shed load based on the system pressure, typically memory. */ diff --git a/envoy/network/filter.h b/envoy/network/filter.h -index 494a60ca82..d61c948092 100644 +index acd892d926..01c5156c7b 100644 --- a/envoy/network/filter.h +++ b/envoy/network/filter.h -@@ -161,6 +161,22 @@ public: +@@ -162,6 +162,22 @@ public: using WriteFilterSharedPtr = std::shared_ptr; @@ -87,7 +87,7 @@ index 494a60ca82..d61c948092 100644 /** * Callbacks used by individual read filter instances to communicate with the filter manager. */ -@@ -220,6 +236,18 @@ public: +@@ -228,6 +244,18 @@ public: */ virtual bool startUpstreamSecureTransport() PURE; @@ -123,10 +123,10 @@ index 78ba8b8c6a..1daa0e1fa9 100644 // An API for the UpstreamRequest to get callbacks from either an HTTP or TCP diff --git a/source/common/http/async_client_impl.h b/source/common/http/async_client_impl.h -index 6ce7b2d9c5..fd76fa1c3e 100644 +index 44178c078f..524c85b9b6 100644 --- a/source/common/http/async_client_impl.h +++ b/source/common/http/async_client_impl.h -@@ -295,6 +295,11 @@ private: +@@ -277,6 +277,11 @@ private: ResponseHeaderMapOptRef responseHeaders() override { return {}; } ResponseTrailerMapOptRef responseTrailers() override { return {}; } @@ -139,10 +139,10 @@ index 6ce7b2d9c5..fd76fa1c3e 100644 void dumpState(std::ostream& os, int indent_level) const override { const char* spaces = spacesForLevel(indent_level); diff --git a/source/common/http/conn_manager_impl.h b/source/common/http/conn_manager_impl.h -index 564f2f544b..6e26574091 100644 +index e71be649e6..7924870492 100644 --- a/source/common/http/conn_manager_impl.h +++ b/source/common/http/conn_manager_impl.h -@@ -343,6 +343,12 @@ private: +@@ -354,6 +354,12 @@ private: } std::optional routeConfig(); @@ -156,10 +156,10 @@ index 564f2f544b..6e26574091 100644 // Updates the snapped_route_config_ (by reselecting scoped route configuration), if a scope is diff --git a/source/common/http/filter_manager.cc b/source/common/http/filter_manager.cc -index 170629b1be..5861b15c28 100644 +index 881e2096ca..23ab2ff48d 100644 --- a/source/common/http/filter_manager.cc +++ b/source/common/http/filter_manager.cc -@@ -2048,5 +2048,10 @@ ActiveStreamDecoderFilter::upstreamOverrideHost() const { +@@ -2154,5 +2154,10 @@ ActiveStreamDecoderFilter::upstreamOverrideHost() const { return parent_.upstream_override_host_; } @@ -171,10 +171,10 @@ index 170629b1be..5861b15c28 100644 } // namespace Http } // namespace Envoy diff --git a/source/common/http/filter_manager.h b/source/common/http/filter_manager.h -index f52948b8b5..7ade3fddd7 100644 +index 2d8588fb9f..d4447cc5ad 100644 --- a/source/common/http/filter_manager.h +++ b/source/common/http/filter_manager.h -@@ -310,6 +310,8 @@ struct ActiveStreamDecoderFilter : public ActiveStreamFilterBase, +@@ -311,6 +311,8 @@ struct ActiveStreamDecoderFilter : public ActiveStreamFilterBase, void setUpstreamOverrideHost(Upstream::LoadBalancerContext::OverrideHost) override; OptRef upstreamOverrideHost() const override; bool shouldLoadShed() const override; @@ -183,7 +183,7 @@ index f52948b8b5..7ade3fddd7 100644 void sendGoAwayAndClose(bool graceful = false) override; // Each decoder filter instance checks if the request passed to the filter is gRPC -@@ -606,6 +608,12 @@ public: +@@ -607,6 +609,12 @@ public: * This is used for HTTP/1.1 codec. */ virtual bool isHalfCloseEnabled() PURE; @@ -197,10 +197,10 @@ index f52948b8b5..7ade3fddd7 100644 /** diff --git a/source/common/network/filter_manager_impl.h b/source/common/network/filter_manager_impl.h -index e2923755fd..d879a6e8f8 100644 +index 2ba07db2fa..962dbb3d63 100644 --- a/source/common/network/filter_manager_impl.h +++ b/source/common/network/filter_manager_impl.h -@@ -172,6 +172,13 @@ private: +@@ -175,6 +175,13 @@ private: parent_.host_description_ = host; } bool startUpstreamSecureTransport() override { return parent_.startUpstreamSecureTransport(); } @@ -214,7 +214,7 @@ index e2923755fd..d879a6e8f8 100644 FilterManagerImpl& parent_; ReadFilterSharedPtr filter_; -@@ -213,6 +220,20 @@ private: +@@ -216,6 +223,20 @@ private: FilterStatus onWrite(ActiveWriteFilter* filter, WriteBufferSource& buffer_source); void onResumeWriting(ActiveWriteFilter* filter, WriteBufferSource& buffer_source); @@ -236,10 +236,10 @@ index e2923755fd..d879a6e8f8 100644 const ConnectionSocket& socket_; Upstream::HostDescriptionConstSharedPtr host_description_; diff --git a/source/common/router/router.cc b/source/common/router/router.cc -index 452f578665..bd6ccea120 100644 +index 375298f6f0..5fe5c7cbeb 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc -@@ -810,6 +810,14 @@ bool Filter::continueDecodeHeaders(Http::RequestHeaderMap& headers, bool end_str +@@ -821,6 +821,14 @@ bool Filter::continueDecodeHeaders(Http::RequestHeaderMap& headers, bool end_str return false; } @@ -255,10 +255,10 @@ index 452f578665..bd6ccea120 100644 const Http::HeaderEntry* header_max_stream_duration_entry = headers.EnvoyUpstreamStreamDurationMs(); diff --git a/source/common/router/upstream_request.h b/source/common/router/upstream_request.h -index 3c3093ebc4..fb6698ddec 100644 +index b6245d21a4..4c1f0375eb 100644 --- a/source/common/router/upstream_request.h +++ b/source/common/router/upstream_request.h -@@ -360,6 +360,11 @@ public: +@@ -363,6 +363,11 @@ public: } OptRef upstreamCallbacks() override { return {*this}; } @@ -271,10 +271,10 @@ index 3c3093ebc4..fb6698ddec 100644 StreamInfo::StreamInfo& upstreamStreamInfo() override { return upstream_request_.streamInfo(); } OptRef downstreamWebTransportSession() override; diff --git a/source/common/tcp_proxy/tcp_proxy.cc b/source/common/tcp_proxy/tcp_proxy.cc -index 36101861b5..baa76e24bd 100644 +index 58a6865683..0b55421559 100644 --- a/source/common/tcp_proxy/tcp_proxy.cc +++ b/source/common/tcp_proxy/tcp_proxy.cc -@@ -850,6 +850,13 @@ bool Filter::maybeTunnel(Upstream::ThreadLocalCluster& cluster) { +@@ -885,6 +885,13 @@ bool Filter::maybeTunnel(Upstream::ThreadLocalCluster& cluster) { upstream_decoder_filter_callbacks_, getStreamInfo()); } if (generic_conn_pool_) { @@ -289,10 +289,10 @@ index 36101861b5..baa76e24bd 100644 connect_attempts_++; getStreamInfo().setAttemptCount(connect_attempts_); diff --git a/source/common/tcp_proxy/tcp_proxy.h b/source/common/tcp_proxy/tcp_proxy.h -index 7e2be743e0..ac99d09c75 100644 +index a6e3b16aaf..a875a6968d 100644 --- a/source/common/tcp_proxy/tcp_proxy.h +++ b/source/common/tcp_proxy/tcp_proxy.h -@@ -634,6 +634,10 @@ public: +@@ -655,6 +655,10 @@ public: return {}; } bool shouldLoadShed() const override { return false; } @@ -303,7 +303,7 @@ index 7e2be743e0..ac99d09c75 100644 void restoreContextOnContinue(ScopeTrackedObjectStack& tracked_object_stack) override { tracked_object_stack.add(*this); } -@@ -677,6 +681,7 @@ protected: +@@ -703,6 +707,7 @@ protected: NoHealthyUpstream, ResourceLimitExceeded, NoRoute, @@ -312,10 +312,10 @@ index 7e2be743e0..ac99d09c75 100644 // Callbacks for different error and success states during connection establishment diff --git a/source/common/tcp_proxy/upstream.cc b/source/common/tcp_proxy/upstream.cc -index b4010cf850..298e9f6e11 100644 +index 46dfd944f8..e912ac6a7a 100644 --- a/source/common/tcp_proxy/upstream.cc +++ b/source/common/tcp_proxy/upstream.cc -@@ -345,6 +345,10 @@ void TcpConnPool::newStream(GenericConnectionPoolCallbacks& callbacks) { +@@ -356,6 +356,10 @@ void TcpConnPool::newStream(GenericConnectionPoolCallbacks& callbacks) { } } @@ -326,7 +326,7 @@ index b4010cf850..298e9f6e11 100644 void TcpConnPool::onPoolFailure(ConnectionPool::PoolFailureReason reason, absl::string_view failure_reason, Upstream::HostDescriptionConstSharedPtr host) { -@@ -451,6 +455,10 @@ void HttpConnPool::newStream(GenericConnectionPoolCallbacks& callbacks) { +@@ -463,6 +467,10 @@ void HttpConnPool::newStream(GenericConnectionPoolCallbacks& callbacks) { } } @@ -338,7 +338,7 @@ index b4010cf850..298e9f6e11 100644 absl::string_view failure_reason, Upstream::HostDescriptionConstSharedPtr host) { diff --git a/source/common/tcp_proxy/upstream.h b/source/common/tcp_proxy/upstream.h -index efce490a68..40aecea00a 100644 +index 4d9e240c4c..d33e646d8c 100644 --- a/source/common/tcp_proxy/upstream.h +++ b/source/common/tcp_proxy/upstream.h @@ -42,6 +42,7 @@ public: @@ -358,10 +358,10 @@ index efce490a68..40aecea00a 100644 // Http::ConnectionPool::Callbacks, void onPoolFailure(ConnectionPool::PoolFailureReason reason, diff --git a/source/extensions/api_listeners/default_api_listener/api_listener_impl.h b/source/extensions/api_listeners/default_api_listener/api_listener_impl.h -index 415670d67c..8c807f9d5b 100644 +index ae2f60b787..427e8ceb54 100644 --- a/source/extensions/api_listeners/default_api_listener/api_listener_impl.h +++ b/source/extensions/api_listeners/default_api_listener/api_listener_impl.h -@@ -81,6 +81,9 @@ protected: +@@ -82,6 +82,9 @@ protected: } Network::Connection& connection() override { return connection_; } const Network::ConnectionSocket& socket() override { PANIC("not implemented"); } @@ -372,5 +372,5 @@ index 415670d67c..8c807f9d5b 100644 // Synthetic class that acts as a stub for the connection backing the // Network::ReadFilterCallbacks. -- -2.55.0 +2.56.0 diff --git a/patches/0002-listener-add-socket-options.patch b/patches/0002-listener-add-socket-options.patch index aac653815..82e8c15bf 100644 --- a/patches/0002-listener-add-socket-options.patch +++ b/patches/0002-listener-add-socket-options.patch @@ -1,7 +1,7 @@ -From 7eca64c432be0a808baaf9e6261eb41372a17926 Mon Sep 17 00:00:00 2001 +From 3b6df43474f58458989be37dd69168d68a37ebac Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Mon, 14 Aug 2023 10:01:21 +0300 -Subject: [PATCH 2/6] listener: add socket options +Subject: [PATCH 2/8] listener: add socket options This reverts commit 170c89eb0b2afb7a39d44d0f8dfb77444ffc038f. @@ -32,10 +32,10 @@ index e9fcd320fe..a11f7d8730 100644 /** diff --git a/source/common/listener_manager/listener_impl.cc b/source/common/listener_manager/listener_impl.cc -index 82ebb4590e..74db624f77 100644 +index 48e6618289..a6cba58fa5 100644 --- a/source/common/listener_manager/listener_impl.cc +++ b/source/common/listener_manager/listener_impl.cc -@@ -1056,6 +1056,9 @@ Stats::Scope& PerListenerFactoryContextImpl::prefixedScope() { +@@ -1121,6 +1121,9 @@ Stats::Scope& PerListenerFactoryContextImpl::prefixedScope() { Stats::Scope& PerListenerFactoryContextImpl::listenerScope() { return listener_factory_context_base_->listenerScope(); } @@ -46,10 +46,10 @@ index 82ebb4590e..74db624f77 100644 bool ListenerImpl::createNetworkFilterChain( diff --git a/source/common/listener_manager/listener_impl.h b/source/common/listener_manager/listener_impl.h -index 4e89f24cde..f5d5ad06dd 100644 +index aa3f531993..978f6f04f8 100644 --- a/source/common/listener_manager/listener_impl.h +++ b/source/common/listener_manager/listener_impl.h -@@ -191,6 +191,8 @@ public: +@@ -195,6 +195,8 @@ public: Stats::Scope& prefixedScope() override; Stats::Scope& listenerScope() override; @@ -58,9 +58,9 @@ index 4e89f24cde..f5d5ad06dd 100644 ListenerFactoryContextBaseImpl& parentFactoryContext() { return *listener_factory_context_base_; } friend class ListenerImpl; -@@ -341,6 +343,13 @@ public: - return listener_factory_context_->listener_factory_context_base_->listener_info_; - } +@@ -346,6 +348,13 @@ public: + // FilterChainUpdateCallbacks + void drainFilterChain(Network::DrainableFilterChainSharedPtr draining) override; + void addListenSocketOptions(const Network::Socket::OptionsSharedPtr& append_options) { + for (std::vector::size_type i = 0; @@ -123,5 +123,5 @@ index cf2d40afac..ca3051a159 100644 MOCK_METHOD(const Network::DrainDecision&, drainDecision, ()); MOCK_METHOD(Init::Manager&, initManager, ()); -- -2.55.0 +2.56.0 diff --git a/patches/0003-original_dst_cluster-Avoid-multiple-hosts-for-the-sa.patch b/patches/0003-original_dst_cluster-Avoid-multiple-hosts-for-the-sa.patch index 7d9703e78..f1273d07c 100644 --- a/patches/0003-original_dst_cluster-Avoid-multiple-hosts-for-the-sa.patch +++ b/patches/0003-original_dst_cluster-Avoid-multiple-hosts-for-the-sa.patch @@ -1,7 +1,7 @@ -From c560662bfd12e46100972f8c94741d810c04aadf Mon Sep 17 00:00:00 2001 +From 2815f051dee010e4472f1aa2577e1b540c5a30e4 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 24 May 2024 18:27:28 +0200 -Subject: [PATCH 3/6] original_dst_cluster: Avoid multiple hosts for the same +Subject: [PATCH 3/8] original_dst_cluster: Avoid multiple hosts for the same address Connection pool containers use HostSharedPtr as map keys, rather than the @@ -30,7 +30,7 @@ Signed-off-by: Jarno Rajahalme 2 files changed, 208 insertions(+), 132 deletions(-) diff --git a/source/extensions/clusters/original_dst/original_dst_cluster.cc b/source/extensions/clusters/original_dst/original_dst_cluster.cc -index d8ef2862b1..5a8c3e2820 100644 +index 1eddc0b05e..12acbf8c89 100644 --- a/source/extensions/clusters/original_dst/original_dst_cluster.cc +++ b/source/extensions/clusters/original_dst/original_dst_cluster.cc @@ -29,6 +29,19 @@ OriginalDstClusterHandle::~OriginalDstClusterHandle() { @@ -293,7 +293,7 @@ index d8ef2862b1..5a8c3e2820 100644 // // Using the used_ bit is preserved for backwards compatibility and to // add a delay between load balancers choosing a host and grabbing a -@@ -286,65 +365,57 @@ void OriginalDstCluster::cleanup() { +@@ -286,64 +365,56 @@ void OriginalDstCluster::cleanup() { // 3) will not delete h since it takes at least one cleanup_interval for // the host to set used_ bit for h to false. bool keep = false; @@ -302,8 +302,7 @@ index d8ef2862b1..5a8c3e2820 100644 keep = true; - hosts->used_ = false; // Mark to be removed during the next round. + host_use->used_ = false; // Mark to be removed during the next round. - } else if (Runtime::runtimeFeatureEnabled( - "envoy.reloadable_features.original_dst_rely_on_idle_timeout")) { + } else { - // Check that all hosts (first, as well as others that may have been added concurrently) - // are not in use by any connection pool. - if (hosts->host_->used()) { @@ -496,5 +495,5 @@ index ff665dc300..818b8c31ff 100644 std::optional metadata_key_; std::optional port_override_; -- -2.55.0 +2.56.0 diff --git a/patches/0004-thread_local-reset-slot-in-worker-threads-first.patch b/patches/0004-thread_local-reset-slot-in-worker-threads-first.patch index 7a98cd2a9..1f03b47c3 100644 --- a/patches/0004-thread_local-reset-slot-in-worker-threads-first.patch +++ b/patches/0004-thread_local-reset-slot-in-worker-threads-first.patch @@ -1,7 +1,7 @@ -From f8c8cff10b0e498cf0e4f5edce427bf93774da38 Mon Sep 17 00:00:00 2001 +From 8ec88021cb53e84392460e1a0fe97e92653a8052 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Mon, 23 Dec 2024 22:43:15 +0100 -Subject: [PATCH 4/6] thread_local: reset slot in worker threads first +Subject: [PATCH 4/8] thread_local: reset slot in worker threads first Thread local slots refer to their data via shared pointers. Reset the shared pointer first in the worker threads, and last in the main thread @@ -18,10 +18,10 @@ Signed-off-by: Jarno Rajahalme 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/envoy/thread_local/thread_local.h b/envoy/thread_local/thread_local.h -index 13ff7496ff..da982ccea5 100644 +index ff9754e8b7..8aa4e8162a 100644 --- a/envoy/thread_local/thread_local.h +++ b/envoy/thread_local/thread_local.h -@@ -248,6 +248,13 @@ public: +@@ -253,6 +253,13 @@ public: * @return true if global threading has been shutdown or false if not. */ virtual bool isShutdown() const PURE; @@ -36,10 +36,10 @@ index 13ff7496ff..da982ccea5 100644 } // namespace ThreadLocal diff --git a/source/common/thread_local/thread_local_impl.cc b/source/common/thread_local/thread_local_impl.cc -index 1231c044f7..f0c3696bd1 100644 +index a98b484197..ca98ca54f6 100644 --- a/source/common/thread_local/thread_local_impl.cc +++ b/source/common/thread_local/thread_local_impl.cc -@@ -165,7 +165,8 @@ void InstanceImpl::removeSlot(uint32_t slot) { +@@ -169,7 +169,8 @@ void InstanceImpl::removeSlot(uint32_t slot) { free_slot_indexes_.end(), fmt::format("slot index {} already in free slot set!", slot)); free_slot_indexes_.push_back(slot); @@ -49,7 +49,7 @@ index 1231c044f7..f0c3696bd1 100644 // This runs on each thread and clears the slot, making it available for a new allocations. // This is safe even if a new allocation comes in, because everything happens with post() and // will be sequenced after this removal. It is also safe if there are callbacks pending on -@@ -173,7 +174,12 @@ void InstanceImpl::removeSlot(uint32_t slot) { +@@ -177,7 +178,12 @@ void InstanceImpl::removeSlot(uint32_t slot) { if (slot < thread_local_data_.data_.size()) { thread_local_data_.data_[slot] = nullptr; } @@ -63,7 +63,7 @@ index 1231c044f7..f0c3696bd1 100644 } void InstanceImpl::runOnAllThreads(std::function cb) { -@@ -208,6 +214,22 @@ void InstanceImpl::runOnAllThreads(std::function cb, +@@ -212,6 +218,22 @@ void InstanceImpl::runOnAllThreads(std::function cb, } } @@ -87,7 +87,7 @@ index 1231c044f7..f0c3696bd1 100644 if (thread_local_data_.data_.size() <= index) { thread_local_data_.data_.resize(index + 1); diff --git a/source/common/thread_local/thread_local_impl.h b/source/common/thread_local/thread_local_impl.h -index a2aa9351f0..01af0cc83a 100644 +index 884f29cf4e..025dd04274 100644 --- a/source/common/thread_local/thread_local_impl.h +++ b/source/common/thread_local/thread_local_impl.h @@ -29,6 +29,7 @@ public: @@ -99,7 +99,7 @@ index a2aa9351f0..01af0cc83a 100644 private: // On destruction returns the slot index to the deferred delete queue (detaches it). This allows diff --git a/test/mocks/thread_local/mocks.h b/test/mocks/thread_local/mocks.h -index 7ca4fa8147..171bc4a1bb 100644 +index d3aa517c53..cd9cc93685 100644 --- a/test/mocks/thread_local/mocks.h +++ b/test/mocks/thread_local/mocks.h @@ -27,6 +27,10 @@ public: @@ -111,8 +111,8 @@ index 7ca4fa8147..171bc4a1bb 100644 + main_cb(); + } - SlotPtr allocateSlotMock() { return SlotPtr{new SlotImpl(*this, current_slot_++)}; } + SlotSharedPtr allocateSlotMock() { return SlotSharedPtr{new SlotImpl(*this, current_slot_++)}; } void runOnAllThreads1(std::function cb) { cb(); } -- -2.55.0 +2.56.0 diff --git a/patches/0005-http-header-expose-attribute.patch b/patches/0005-http-header-expose-attribute.patch index 2b156eaff..bc472d854 100644 --- a/patches/0005-http-header-expose-attribute.patch +++ b/patches/0005-http-header-expose-attribute.patch @@ -1,7 +1,7 @@ -From c14ff1ecf9ca8108848e4b9e663dbac7e6537963 Mon Sep 17 00:00:00 2001 +From 706be304d134e04851b660c68f8a2f6e1abbb67d Mon Sep 17 00:00:00 2001 From: Tam Mach Date: Wed, 19 Mar 2025 21:07:05 +1100 -Subject: [PATCH 5/6] Expose HTTP Header matcher attribute +Subject: [PATCH 5/8] Expose HTTP Header matcher attribute Signed-off-by: Tam Mach --- @@ -9,10 +9,10 @@ Signed-off-by: Tam Mach 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/source/common/http/header_utility.h b/source/common/http/header_utility.h -index 31d7cfb356..7a114bfac1 100644 +index 6255187202..d00a859c35 100644 --- a/source/common/http/header_utility.h +++ b/source/common/http/header_utility.h -@@ -96,7 +96,6 @@ public: +@@ -98,7 +98,6 @@ public: return matchesHeaders(request_headers); }; @@ -20,8 +20,8 @@ index 31d7cfb356..7a114bfac1 100644 const LowerCaseString name_; const bool invert_match_; const bool treat_missing_as_empty_; -@@ -158,12 +157,13 @@ public: - return invert_match_; +@@ -167,12 +166,13 @@ public: + : matchesHeaders(request_headers); } - protected: @@ -34,10 +34,10 @@ index 31d7cfb356..7a114bfac1 100644 + protected: + // A matcher specific implementation to match the given header_value. + virtual bool specificMatchesHeaders(absl::string_view header_value) const PURE; - }; - - // Corresponds to the exact_match from the HeaderMatchSpecifier proto in the RDS API. -@@ -172,11 +172,12 @@ public: + // Latched value of the `match_headers_individually` runtime feature, read once at + // construction instead of on every match. + const bool match_individually_ = false; +@@ -184,11 +184,12 @@ public: HeaderDataExactMatch(const envoy::config::route::v3::HeaderMatcher& config) : HeaderDataBaseImpl(config), expected_value_(config.exact_match()) {} @@ -51,7 +51,7 @@ index 31d7cfb356..7a114bfac1 100644 }; // Corresponds to the safe_regex_match from the HeaderMatchSpecifier proto in the RDS API. -@@ -191,6 +192,7 @@ public: +@@ -203,6 +204,7 @@ public: return std::unique_ptr( new HeaderDataRegexMatch(config, std::move(*regex_or_error))); } @@ -59,7 +59,7 @@ index 31d7cfb356..7a114bfac1 100644 protected: HeaderDataRegexMatch(const envoy::config::route::v3::HeaderMatcher& config, -@@ -201,7 +203,6 @@ public: +@@ -213,7 +215,6 @@ public: bool specificMatchesHeaders(absl::string_view header_value) const override { return regex_->match(header_value); }; @@ -67,7 +67,7 @@ index 31d7cfb356..7a114bfac1 100644 }; // Corresponds to the range_match from the HeaderMatchSpecifier proto in the RDS API. -@@ -211,15 +212,14 @@ public: +@@ -223,15 +224,14 @@ public: : HeaderDataBaseImpl(config), range_start_(config.range_match().start()), range_end_(config.range_match().end()) {} @@ -85,7 +85,7 @@ index 31d7cfb356..7a114bfac1 100644 }; // Corresponds to the prefix_match from the HeaderMatchSpecifier proto in the RDS API. -@@ -228,11 +228,11 @@ public: +@@ -240,11 +240,11 @@ public: HeaderDataPrefixMatch(const envoy::config::route::v3::HeaderMatcher& config) : HeaderDataBaseImpl(config), prefix_(config.prefix_match()) {} @@ -98,7 +98,7 @@ index 31d7cfb356..7a114bfac1 100644 }; // Corresponds to the suffix_match from the HeaderMatchSpecifier proto in the RDS API. -@@ -241,11 +241,13 @@ public: +@@ -253,11 +253,13 @@ public: HeaderDataSuffixMatch(const envoy::config::route::v3::HeaderMatcher& config) : HeaderDataBaseImpl(config), suffix_(config.suffix_match()) {} @@ -113,7 +113,7 @@ index 31d7cfb356..7a114bfac1 100644 }; // Corresponds to the contains_match from the HeaderMatchSpecifier proto in the RDS API. -@@ -254,11 +256,11 @@ public: +@@ -266,11 +268,11 @@ public: HeaderDataContainsMatch(const envoy::config::route::v3::HeaderMatcher& config) : HeaderDataBaseImpl(config), expected_substr_(config.contains_match()) {} @@ -126,7 +126,7 @@ index 31d7cfb356..7a114bfac1 100644 }; // Corresponds to the string_match from the HeaderMatchSpecifier proto in the RDS API. -@@ -269,11 +271,11 @@ public: +@@ -281,11 +283,11 @@ public: : HeaderDataBaseImpl(config), string_match_(std::make_unique( config.string_match(), factory_context)) {} @@ -140,5 +140,5 @@ index 31d7cfb356..7a114bfac1 100644 using HeaderDataPtr = std::unique_ptr; -- -2.55.0 +2.56.0 diff --git a/patches/0006-config-add-grpc-mux-stream-event-callback.patch b/patches/0006-config-add-grpc-mux-stream-event-callback.patch index e8ca40d18..fa269e9a7 100644 --- a/patches/0006-config-add-grpc-mux-stream-event-callback.patch +++ b/patches/0006-config-add-grpc-mux-stream-event-callback.patch @@ -1,11 +1,11 @@ -From 9d7d0dbed5d3219608e06fb2e05556dfd3acc2bb Mon Sep 17 00:00:00 2001 +From b44c30f294f119aeb0a07f18efc137b1832c225a Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Mon, 17 Aug 2026 18:52:54 +1000 -Subject: [PATCH 6/6] config: add grpc mux stream event callback +Subject: [PATCH 6/8] config: add grpc mux stream event callback --- envoy/config/BUILD | 1 + - envoy/config/grpc_mux.h | 19 ++++++++++ + envoy/config/grpc_mux.h | 18 ++++++++++ source/common/config/BUILD | 9 +++++ .../config/grpc_mux_stream_event_tracker.h | 36 +++++++++++++++++++ source/common/config/null_grpc_mux_impl.h | 10 ++++++ @@ -19,37 +19,34 @@ Subject: [PATCH 6/6] config: add grpc mux stream event callback .../grpc/xds_mux/grpc_mux_impl.h | 20 +++++++++++ .../config/grpc_subscription_impl_test.cc | 36 +++++++++++++++++++ test/mocks/config/mocks.h | 4 +++ - 15 files changed, 164 insertions(+) + 15 files changed, 163 insertions(+) create mode 100644 source/common/config/grpc_mux_stream_event_tracker.h diff --git a/envoy/config/BUILD b/envoy/config/BUILD -index ad9f959847..616c47916c 100644 +index 7304150354..4ff4bf2098 100644 --- a/envoy/config/BUILD +++ b/envoy/config/BUILD -@@ -65,6 +65,7 @@ envoy_cc_library( +@@ -83,6 +83,7 @@ envoy_cc_library( name = "grpc_mux_interface", hdrs = ["grpc_mux.h"], deps = [ + "//envoy/common:callback", ":eds_resources_cache_interface", ":subscription_interface", - "//envoy/stats:stats_macros", + "//envoy/common:backoff_strategy_interface", diff --git a/envoy/config/grpc_mux.h b/envoy/config/grpc_mux.h -index f8aa1b3e4b..ca8c6f1c62 100644 +index 4e7bd91a11..8f756f8cce 100644 --- a/envoy/config/grpc_mux.h +++ b/envoy/config/grpc_mux.h -@@ -1,8 +1,10 @@ - #pragma once - -+#include - #include +@@ -6,6 +6,7 @@ + #include #include "envoy/common/backoff_strategy.h" +#include "envoy/common/callback.h" - #include "envoy/common/exception.h" #include "envoy/common/pure.h" - #include "envoy/config/custom_config_validators.h" -@@ -19,6 +21,11 @@ namespace Envoy { + #include "envoy/config/core/v3/config_source.pb.h" + #include "envoy/config/eds_resources_cache.h" +@@ -26,6 +27,11 @@ namespace Envoy { namespace Config { using ScopedResume = std::unique_ptr; @@ -61,7 +58,7 @@ index f8aa1b3e4b..ca8c6f1c62 100644 /** * All control plane related stats. @see stats_macros.h */ -@@ -65,6 +72,18 @@ public: +@@ -105,6 +111,18 @@ public: */ virtual void start() PURE; @@ -81,10 +78,10 @@ index f8aa1b3e4b..ca8c6f1c62 100644 * Pause discovery requests for a given API type. This is useful when we're processing an update * for LDS or CDS and don't want a flood of updates for RDS or EDS respectively. Discovery diff --git a/source/common/config/BUILD b/source/common/config/BUILD -index ba2ee65f1f..d772e8a95e 100644 +index 53fbc5b55e..7e0f6f8535 100644 --- a/source/common/config/BUILD +++ b/source/common/config/BUILD -@@ -87,11 +87,20 @@ envoy_cc_library( +@@ -88,11 +88,20 @@ envoy_cc_library( "@abseil-cpp//absl/container:btree", ], ) @@ -148,7 +145,7 @@ index 0000000000..686348502d +} // namespace Config +} // namespace Envoy diff --git a/source/common/config/null_grpc_mux_impl.h b/source/common/config/null_grpc_mux_impl.h -index 590d32f30b..34ebb0e6da 100644 +index 266d5376d7..7eb0cfb913 100644 --- a/source/common/config/null_grpc_mux_impl.h +++ b/source/common/config/null_grpc_mux_impl.h @@ -1,6 +1,7 @@ @@ -172,9 +169,9 @@ index 590d32f30b..34ebb0e6da 100644 ScopedResume pause(const std::string&) override { return std::make_unique([] {}); } -@@ -44,6 +51,9 @@ public: +@@ -40,6 +47,9 @@ public: void onEstablishmentFailure(bool) override {} - void onDiscoveryResponse(std::unique_ptr&&, + void onDiscoveryResponse(ResponseProtoPtr&&, ControlPlaneStats&) override {} + +private: @@ -183,7 +180,7 @@ index 590d32f30b..34ebb0e6da 100644 } // namespace Config diff --git a/source/extensions/config_subscription/grpc/BUILD b/source/extensions/config_subscription/grpc/BUILD -index 3d5ef9dee2..7bc6f98a62 100644 +index 6b59e9fa35..1ade1b1591 100644 --- a/source/extensions/config_subscription/grpc/BUILD +++ b/source/extensions/config_subscription/grpc/BUILD @@ -30,6 +30,7 @@ envoy_cc_extension( @@ -203,7 +200,7 @@ index 3d5ef9dee2..7bc6f98a62 100644 ":watch_map_lib", "//envoy/config:custom_config_validators_interface", diff --git a/source/extensions/config_subscription/grpc/grpc_mux_impl.cc b/source/extensions/config_subscription/grpc/grpc_mux_impl.cc -index e8be9a58ce..29b04801c7 100644 +index dd9f77427c..f63fa417cc 100644 --- a/source/extensions/config_subscription/grpc/grpc_mux_impl.cc +++ b/source/extensions/config_subscription/grpc/grpc_mux_impl.cc @@ -575,6 +575,7 @@ void GrpcMuxImpl::onStreamEstablished() { @@ -223,7 +220,7 @@ index e8be9a58ce..29b04801c7 100644 void GrpcMuxImpl::queueDiscoveryRequest(absl::string_view queue_item) { diff --git a/source/extensions/config_subscription/grpc/grpc_mux_impl.h b/source/extensions/config_subscription/grpc/grpc_mux_impl.h -index eb47c049ff..f02dfc2a01 100644 +index 3067c98db5..e7e79681c6 100644 --- a/source/extensions/config_subscription/grpc/grpc_mux_impl.h +++ b/source/extensions/config_subscription/grpc/grpc_mux_impl.h @@ -3,6 +3,7 @@ @@ -242,7 +239,7 @@ index eb47c049ff..f02dfc2a01 100644 #include "absl/container/node_hash_map.h" #include "xds/core/v3/resource_name.pb.h" -@@ -56,6 +58,13 @@ public: +@@ -59,6 +61,13 @@ public: void start() override; @@ -256,7 +253,7 @@ index eb47c049ff..f02dfc2a01 100644 // GrpcMux ScopedResume pause(const std::string& type_url) override; ScopedResume pause(const std::vector type_urls) override; -@@ -327,6 +336,7 @@ private: +@@ -329,6 +338,7 @@ private: const bool skip_subsequent_node_; CustomConfigValidatorsPtr config_validators_; XdsConfigTrackerOptRef xds_config_tracker_; @@ -265,7 +262,7 @@ index eb47c049ff..f02dfc2a01 100644 EdsResourcesCachePtr eds_resources_cache_; const std::string target_xds_authority_; diff --git a/source/extensions/config_subscription/grpc/new_grpc_mux_impl.cc b/source/extensions/config_subscription/grpc/new_grpc_mux_impl.cc -index 0a59a4abcf..46659f5d43 100644 +index 57e1f86c8a..6fd416fc03 100644 --- a/source/extensions/config_subscription/grpc/new_grpc_mux_impl.cc +++ b/source/extensions/config_subscription/grpc/new_grpc_mux_impl.cc @@ -198,6 +198,7 @@ void NewGrpcMuxImpl::onStreamEstablished() { @@ -285,7 +282,7 @@ index 0a59a4abcf..46659f5d43 100644 void NewGrpcMuxImpl::onWriteable() { trySendDiscoveryRequests(); } diff --git a/source/extensions/config_subscription/grpc/new_grpc_mux_impl.h b/source/extensions/config_subscription/grpc/new_grpc_mux_impl.h -index 45b8a3fc59..1320833b90 100644 +index 4419193961..9889891141 100644 --- a/source/extensions/config_subscription/grpc/new_grpc_mux_impl.h +++ b/source/extensions/config_subscription/grpc/new_grpc_mux_impl.h @@ -1,6 +1,7 @@ @@ -304,10 +301,10 @@ index 45b8a3fc59..1320833b90 100644 #include "source/extensions/config_subscription/grpc/watch_map.h" namespace Envoy { -@@ -46,6 +48,13 @@ public: - static void shutdownAll(); - - void shutdown() { shutdown_ = true; } +@@ -49,6 +51,13 @@ public: + shutdown_ = true; + xds_config_tracker_.reset(); + } + Common::CallbackHandlePtr + addStreamEventCallback(GrpcMuxStreamEventCallback callback) override { + return stream_event_tracker_.addStreamEventCallback(std::move(callback)); @@ -318,7 +315,7 @@ index 45b8a3fc59..1320833b90 100644 GrpcMuxWatchPtr addWatch(const std::string& type_url, const absl::flat_hash_set& resources, -@@ -221,6 +230,7 @@ private: +@@ -243,6 +252,7 @@ private: const LocalInfo::LocalInfo& local_info_; CustomConfigValidatorsPtr config_validators_; @@ -339,10 +336,10 @@ index a0fa33be75..912f49b39c 100644 "//source/extensions/config_subscription/grpc:pausable_ack_queue_lib", "//source/extensions/config_subscription/grpc:watch_map_lib", diff --git a/source/extensions/config_subscription/grpc/xds_mux/grpc_mux_impl.cc b/source/extensions/config_subscription/grpc/xds_mux/grpc_mux_impl.cc -index cb221ac889..010d6bc2bc 100644 +index 243e04a296..f90a4877f5 100644 --- a/source/extensions/config_subscription/grpc/xds_mux/grpc_mux_impl.cc +++ b/source/extensions/config_subscription/grpc/xds_mux/grpc_mux_impl.cc -@@ -339,6 +339,7 @@ void GrpcMuxImpl::handleEstablishedStream() { +@@ -366,6 +366,7 @@ void GrpcMuxImpl::handleEstablishedStream() { maybeUpdateQueueSizeStat(0); pausable_ack_queue_.clear(); trySendDiscoveryRequests(); @@ -350,7 +347,7 @@ index cb221ac889..010d6bc2bc 100644 } template -@@ -363,6 +364,7 @@ void GrpcMuxImpl::handleStreamEstablishmentFailure( +@@ -390,6 +391,7 @@ void GrpcMuxImpl::handleStreamEstablishmentFailure( } } while (all_subscribed.size() != subscriptions_.size()); should_send_initial_resource_versions_ = next_attempt_may_send_initial_resource_version; @@ -359,7 +356,7 @@ index cb221ac889..010d6bc2bc 100644 template diff --git a/source/extensions/config_subscription/grpc/xds_mux/grpc_mux_impl.h b/source/extensions/config_subscription/grpc/xds_mux/grpc_mux_impl.h -index a268014701..3cea9bc79f 100644 +index 53b310fe7e..1ea9467db0 100644 --- a/source/extensions/config_subscription/grpc/xds_mux/grpc_mux_impl.h +++ b/source/extensions/config_subscription/grpc/xds_mux/grpc_mux_impl.h @@ -3,6 +3,7 @@ @@ -378,7 +375,7 @@ index a268014701..3cea9bc79f 100644 #include "source/extensions/config_subscription/grpc/pausable_ack_queue.h" #include "source/extensions/config_subscription/grpc/watch_map.h" #include "source/extensions/config_subscription/grpc/xds_mux/delta_subscription_state.h" -@@ -81,6 +83,13 @@ public: +@@ -84,6 +86,13 @@ public: SubscriptionCallbacks& callbacks, OpaqueResourceDecoderSharedPtr resource_decoder, const SubscriptionOptions& options) override; @@ -392,7 +389,7 @@ index a268014701..3cea9bc79f 100644 void updateWatch(const std::string& type_url, Watch* watch, const absl::flat_hash_set& resources, const SubscriptionOptions& options); -@@ -242,6 +251,7 @@ private: +@@ -267,6 +276,7 @@ private: // this one is up to GrpcMux. const LocalInfo::LocalInfo& local_info_; Common::CallbackHandlePtr dynamic_update_callback_handle_; @@ -400,7 +397,7 @@ index a268014701..3cea9bc79f 100644 CustomConfigValidatorsPtr config_validators_; XdsConfigTrackerOptRef xds_config_tracker_; XdsResourcesDelegateOptRef xds_resources_delegate_; -@@ -294,6 +304,13 @@ private: +@@ -310,6 +320,13 @@ private: class NullGrpcMuxImpl : public GrpcMux { public: void start() override {} @@ -414,7 +411,7 @@ index a268014701..3cea9bc79f 100644 ScopedResume pause(const std::string&) override { return std::make_unique([]() {}); -@@ -321,6 +338,9 @@ public: +@@ -333,6 +350,9 @@ public: Upstream::LoadStatsReporter* loadStatsReporter() const override { return nullptr; } Upstream::LoadStatsReporter* maybeCreateLoadStatsReporter() override { return nullptr; } @@ -472,10 +469,10 @@ index e70750ed4f..b0f84d66f1 100644 // ignore later ones. This allows the nonce to be used. TEST_P(GrpcSubscriptionImplTest, RepeatedNonce) { diff --git a/test/mocks/config/mocks.h b/test/mocks/config/mocks.h -index 72b2fd2133..787e52c321 100644 +index c3274c9d1f..3ab8387df1 100644 --- a/test/mocks/config/mocks.h +++ b/test/mocks/config/mocks.h -@@ -161,6 +161,10 @@ public: +@@ -178,6 +178,10 @@ public: MOCK_METHOD(ScopedResume, pause, (const std::string& type_url), (override)); MOCK_METHOD(ScopedResume, pause, (const std::vector type_urls), (override)); @@ -487,5 +484,5 @@ index 72b2fd2133..787e52c321 100644 (const absl::flat_hash_set& resources, const std::string& type_url, SubscriptionCallbacks& callbacks, SubscriptionStats& stats, -- -2.55.0 +2.56.0 diff --git a/patches/0007-network-Allow-write-filters-to-consume-data-after-e.patch b/patches/0007-network-Allow-write-filters-to-consume-data-after-e.patch index 748c0902b..fa0c254fc 100644 --- a/patches/0007-network-Allow-write-filters-to-consume-data-after-e.patch +++ b/patches/0007-network-Allow-write-filters-to-consume-data-after-e.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From a05eee3d4f193bf98eb679698add64dfcc2108ca Mon Sep 17 00:00:00 2001 From: Cilium Authors Date: Mon, 24 Aug 2026 08:00:00 +0200 -Subject: [PATCH] network: Allow write filters to consume data after end stream +Subject: [PATCH 7/8] network: Allow write filters to consume data after end + stream A protocol filter may synthesize an end stream for the data it exposes while the underlying transport remains open for protocol control frames. Give write @@ -15,10 +16,10 @@ does not permit application data to be written to the transport after FIN. 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/source/common/network/connection_impl.cc b/source/common/network/connection_impl.cc -index 8ce180e730..bc34812540 100644 +index 4b1190356d..85f56c8cef 100644 --- a/source/common/network/connection_impl.cc +++ b/source/common/network/connection_impl.cc -@@ -595,16 +595,10 @@ void ConnectionImpl::write(Buffer::Instance& data, bool end_stream, bool through +@@ -588,16 +588,10 @@ void ConnectionImpl::write(Buffer::Instance& data, bool end_stream, bool through ASSERT(!end_stream || enable_half_close_); ASSERT(dispatcher_.isThreadSafe()); @@ -39,7 +40,7 @@ index 8ce180e730..bc34812540 100644 // NOTE: This is kind of a hack, but currently we don't support restart/continue on the write // path, so we just pass around the buffer passed to us in this function. If we ever // support buffer/restart/continue on the write path this needs to get more complicated. -@@ -618,6 +612,14 @@ void ConnectionImpl::write(Buffer::Instance& data, bool end_stream, bool through +@@ -611,6 +605,14 @@ void ConnectionImpl::write(Buffer::Instance& data, bool end_stream, bool through } } @@ -55,4 +56,5 @@ index 8ce180e730..bc34812540 100644 if (data.length() > 0 || end_stream) { ENVOY_CONN_LOG(trace, "writing {} bytes, end_stream {}", *this, data.length(), end_stream); -- -2.43.0 +2.56.0 + diff --git a/patches/0008-tcp_proxy-Allow-filters-to-wait-for-upstream-close.patch b/patches/0008-tcp_proxy-Allow-filters-to-wait-for-upstream-close.patch index ceb0cbab7..3a9e9491a 100644 --- a/patches/0008-tcp_proxy-Allow-filters-to-wait-for-upstream-close.patch +++ b/patches/0008-tcp_proxy-Allow-filters-to-wait-for-upstream-close.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 2befee5802d38ca10423aad8e80e5d1641216c77 Mon Sep 17 00:00:00 2001 From: Cilium Authors Date: Tue, 25 Aug 2026 16:00:00 +0200 -Subject: [PATCH] tcp_proxy: Allow filters to wait for peer close +Subject: [PATCH 8/8] tcp_proxy: Allow filters to wait for peer close A protocol filter may need either side of a raw TCP proxy connection to remain open after its local stream has ended so the peer can finish a protocol-level @@ -21,13 +21,13 @@ propagate resets without delay. source/common/tcp_proxy/BUILD | 1 + source/common/tcp_proxy/tcp_proxy.cc | 40 +++++++++++++++++++++---- source/common/tcp_proxy/tcp_proxy.h | 9 ++++-- - source/common/tcp_proxy/upstream.cc | 25 +++++++++++++--- + source/common/tcp_proxy/upstream.cc | 22 +++++++++++--- source/common/tcp_proxy/upstream.h | 21 ++++++++++++- test/common/tcp_proxy/tcp_proxy_test.cc | 17 +++++++++++ - 6 files changed, 100 insertions(+), 13 deletions(-) + 6 files changed, 97 insertions(+), 13 deletions(-) diff --git a/source/common/tcp_proxy/BUILD b/source/common/tcp_proxy/BUILD -index 914382ab15..41a3f206f4 100644 +index abdacb291a..cb88cd34b8 100644 --- a/source/common/tcp_proxy/BUILD +++ b/source/common/tcp_proxy/BUILD @@ -20,6 +20,7 @@ envoy_cc_library( @@ -39,10 +39,10 @@ index 914382ab15..41a3f206f4 100644 "//envoy/tcp:upstream_interface", "//envoy/upstream:cluster_manager_interface", diff --git a/source/common/tcp_proxy/tcp_proxy.cc b/source/common/tcp_proxy/tcp_proxy.cc -index baa76e24bd..86f9465401 100644 +index 0b55421559..cf8ae56cd2 100644 --- a/source/common/tcp_proxy/tcp_proxy.cc +++ b/source/common/tcp_proxy/tcp_proxy.cc -@@ -468,6 +468,17 @@ void Filter::initialize(Network::ReadFilterCallbacks& callbacks, bool set_connec +@@ -492,6 +492,17 @@ void Filter::initialize(Network::ReadFilterCallbacks& callbacks, bool set_connec } } @@ -60,7 +60,7 @@ index baa76e24bd..86f9465401 100644 // Handle TLS handshake wait mode. if (connect_mode_ == UpstreamConnectMode::ON_DOWNSTREAM_TLS_HANDSHAKE) { const auto ssl_connection = read_callbacks_->connection().ssl(); -@@ -1261,7 +1272,8 @@ void Filter::onDownstreamEvent(Network::ConnectionEvent event) { +@@ -1311,7 +1322,8 @@ void Filter::onDownstreamEvent(Network::ConnectionEvent event) { conn_data->connection().state() != Network::Connection::State::Closed) { config_->drainManager().add(config_->sharedConfig(), std::move(conn_data), std::move(upstream_callbacks_), std::move(idle_timer_), @@ -70,7 +70,7 @@ index baa76e24bd..86f9465401 100644 } if (event == Network::ConnectionEvent::LocalClose || event == Network::ConnectionEvent::RemoteClose) { -@@ -1360,7 +1372,16 @@ void Filter::onUpstreamEvent(Network::ConnectionEvent event) { +@@ -1424,7 +1436,16 @@ void Filter::onUpstreamEvent(Network::ConnectionEvent event) { getStreamInfo().setResponseFlag(StreamInfo::CoreResponseFlag::UpstreamRemoteReset); read_callbacks_->connection().close(Network::ConnectionCloseType::AbortReset); } else { @@ -88,7 +88,7 @@ index baa76e24bd..86f9465401 100644 } } } -@@ -1576,9 +1597,11 @@ void UpstreamDrainManager::add(const Config::SharedConfigSharedPtr& config, +@@ -1640,9 +1661,11 @@ void UpstreamDrainManager::add(const Config::SharedConfigSharedPtr& config, const std::shared_ptr& callbacks, Event::TimerPtr&& idle_timer, std::optional idle_timeout, @@ -102,7 +102,7 @@ index baa76e24bd..86f9465401 100644 callbacks->drain(*drainer); // Use temporary to ensure we get the pointer before we move it out of drainer -@@ -1597,10 +1620,11 @@ Drainer::Drainer(UpstreamDrainManager& parent, const Config::SharedConfigSharedP +@@ -1661,10 +1684,11 @@ Drainer::Drainer(UpstreamDrainManager& parent, const Config::SharedConfigSharedP const std::shared_ptr& callbacks, Tcp::ConnectionPool::ConnectionDataPtr&& conn_data, Event::TimerPtr&& idle_timer, std::optional idle_timeout, @@ -116,7 +116,7 @@ index baa76e24bd..86f9465401 100644 ENVOY_CONN_LOG(trace, "draining the upstream connection", upstream_conn_data_->connection()); config_->stats().upstream_flush_total_.inc(); config_->stats().upstream_flush_active_.inc(); -@@ -1618,6 +1642,10 @@ void Drainer::onEvent(Network::ConnectionEvent event) { +@@ -1682,6 +1706,10 @@ void Drainer::onEvent(Network::ConnectionEvent event) { } void Drainer::onData(Buffer::Instance& data, bool) { @@ -128,10 +128,10 @@ index baa76e24bd..86f9465401 100644 // There is no downstream connection to send any data to, but the upstream // sent some data. Try to behave similar to what the kernel would do diff --git a/source/common/tcp_proxy/tcp_proxy.h b/source/common/tcp_proxy/tcp_proxy.h -index ac99d09c75..36343fed4e 100644 +index a875a6968d..9d0a38df9a 100644 --- a/source/common/tcp_proxy/tcp_proxy.h +++ b/source/common/tcp_proxy/tcp_proxy.h -@@ -755,6 +755,8 @@ protected: +@@ -795,6 +795,8 @@ protected: Network::TransportSocketOptionsConstSharedPtr transport_socket_options_; Network::Socket::OptionsSharedPtr upstream_options_; std::optional idle_timeout_; @@ -140,7 +140,7 @@ index ac99d09c75..36343fed4e 100644 uint32_t connect_attempts_{}; bool connecting_{}; bool downstream_closed_{}; -@@ -788,7 +790,8 @@ public: +@@ -828,7 +830,8 @@ public: const std::shared_ptr& callbacks, Tcp::ConnectionPool::ConnectionDataPtr&& conn_data, Event::TimerPtr&& idle_timer, std::optional idle_timeout, @@ -150,7 +150,7 @@ index ac99d09c75..36343fed4e 100644 void onEvent(Network::ConnectionEvent event); void onData(Buffer::Instance& data, bool end_stream); -@@ -805,6 +808,7 @@ private: +@@ -845,6 +848,7 @@ private: std::optional idle_timeout_; Upstream::HostDescriptionConstSharedPtr upstream_host_; Config::SharedConfigSharedPtr config_; @@ -158,7 +158,7 @@ index ac99d09c75..36343fed4e 100644 }; using DrainerPtr = std::unique_ptr; -@@ -816,7 +820,8 @@ public: +@@ -856,7 +860,8 @@ public: Tcp::ConnectionPool::ConnectionDataPtr&& upstream_conn_data, const std::shared_ptr& callbacks, Event::TimerPtr&& idle_timer, std::optional idle_timeout, @@ -169,50 +169,46 @@ index ac99d09c75..36343fed4e 100644 private: diff --git a/source/common/tcp_proxy/upstream.cc b/source/common/tcp_proxy/upstream.cc -index 298e9f6e11..0bfae101bb 100644 +index e912ac6a7a..4862827608 100644 --- a/source/common/tcp_proxy/upstream.cc +++ b/source/common/tcp_proxy/upstream.cc -@@ -1,6 +1,7 @@ - #include "source/common/tcp_proxy/upstream.h" +@@ -2,6 +2,7 @@ + #include "envoy/common/platform.h" #include "envoy/http/header_map.h" +#include "envoy/stream_info/uint64_accessor.h" #include "envoy/upstream/cluster_manager.h" #include "source/common/http/codec_client.h" -@@ -65,8 +66,10 @@ void generateAndStoreRequestId(const TunnelingConfigHelper& config, Http::Reques - } +@@ -67,8 +68,10 @@ void generateAndStoreRequestId(const TunnelingConfigHelper& config, Http::Reques TcpUpstream::TcpUpstream(Tcp::ConnectionPool::ConnectionDataPtr&& data, -- Tcp::ConnectionPool::UpstreamCallbacks& upstream_callbacks) -- : upstream_conn_data_(std::move(data)) { -+ Tcp::ConnectionPool::UpstreamCallbacks& upstream_callbacks, + Tcp::ConnectionPool::UpstreamCallbacks& upstream_callbacks, +- StreamInfo::StreamInfo& downstream_info) +- : upstream_conn_data_(std::move(data)), downstream_info_(downstream_info) { ++ StreamInfo::StreamInfo& downstream_info, + std::chrono::milliseconds upstream_flush_wait_timeout) -+ : upstream_conn_data_(std::move(data)), ++ : upstream_conn_data_(std::move(data)), downstream_info_(downstream_info), + upstream_flush_wait_timeout_(upstream_flush_wait_timeout) { Network::ClientConnection& connection = upstream_conn_data_->connection(); connection.enableHalfClose(true); upstream_conn_data_->addUpstreamCallbacks(upstream_callbacks); -@@ -131,8 +134,13 @@ Tcp::ConnectionPool::ConnectionData* TcpUpstream::onDownstreamEvent(Network::Con - // The close call may result in this object being deleted. Latch the - // connection locally so it can be returned for potential draining. - auto* conn_data = upstream_conn_data_.release(); -+ const bool wait_for_peer_close = upstream_flush_wait_timeout_.count() > 0; -+ if (wait_for_peer_close) { +@@ -143,6 +146,9 @@ Tcp::ConnectionPool::ConnectionData* TcpUpstream::onDownstreamEvent(Network::Con + close_type = Network::ConnectionCloseType::AbortReset; + close_reason = + StreamInfo::LocalCloseReasons::get().ClosingUpstreamTcpDueToDownstreamResetClose; ++ } else if (upstream_flush_wait_timeout_.count() > 0) { + conn_data->connection().setDelayedCloseTimeout(upstream_flush_wait_timeout_); -+ } - conn_data->connection().close( -- Network::ConnectionCloseType::FlushWrite, -+ wait_for_peer_close ? Network::ConnectionCloseType::FlushWriteAndDelay -+ : Network::ConnectionCloseType::FlushWrite, - StreamInfo::LocalCloseReasons::get().ClosingUpstreamTcpDueToDownstreamRemoteClose); ++ close_type = Network::ConnectionCloseType::FlushWriteAndDelay; + } + conn_data->connection().close(close_type, close_reason); return conn_data; - } else if (event == Network::ConnectionEvent::LocalClose) { -@@ -369,7 +377,16 @@ void TcpConnPool::onPoolReady(Tcp::ConnectionPool::ConnectionDataPtr&& conn_data +@@ -380,8 +386,16 @@ void TcpConnPool::onPoolReady(Tcp::ConnectionPool::ConnectionDataPtr&& conn_data Tcp::ConnectionPool::ConnectionData* latched_data = conn_data.get(); Network::Connection& connection = conn_data->connection(); -- auto upstream = std::make_unique(std::move(conn_data), upstream_callbacks_); +- auto upstream = +- std::make_unique(std::move(conn_data), upstream_callbacks_, downstream_info_); + std::chrono::milliseconds upstream_flush_wait_timeout{0}; + const StreamInfo::UInt64Accessor* flush_wait_timeout = + downstream_info_.filterState()->getDataReadOnly( @@ -222,12 +218,12 @@ index 298e9f6e11..0bfae101bb 100644 + } + + auto upstream = std::make_unique(std::move(conn_data), upstream_callbacks_, -+ upstream_flush_wait_timeout); ++ downstream_info_, upstream_flush_wait_timeout); callbacks_->onGenericPoolReady( &connection.streamInfo(), std::move(upstream), host, latched_data->connection().connectionInfoProvider(), diff --git a/source/common/tcp_proxy/upstream.h b/source/common/tcp_proxy/upstream.h -index 40aecea00a..ad16e68a49 100644 +index d33e646d8c..e05c19b1e4 100644 --- a/source/common/tcp_proxy/upstream.h +++ b/source/common/tcp_proxy/upstream.h @@ -1,5 +1,7 @@ @@ -260,29 +256,29 @@ index 40aecea00a..ad16e68a49 100644 class TcpConnPool : public GenericConnPool, public Tcp::ConnectionPool::Callbacks { public: -@@ -183,7 +200,8 @@ private: - class TcpUpstream : public GenericUpstream { +@@ -184,7 +201,8 @@ class TcpUpstream : public GenericUpstream { public: TcpUpstream(Tcp::ConnectionPool::ConnectionDataPtr&& data, -- Tcp::ConnectionPool::UpstreamCallbacks& callbacks); -+ Tcp::ConnectionPool::UpstreamCallbacks& callbacks, + Tcp::ConnectionPool::UpstreamCallbacks& callbacks, +- StreamInfo::StreamInfo& downstream_info); ++ StreamInfo::StreamInfo& downstream_info, + std::chrono::milliseconds upstream_flush_wait_timeout = {}); // GenericUpstream bool readDisable(bool disable) override; -@@ -198,6 +216,7 @@ public: - +@@ -200,6 +218,7 @@ public: private: Tcp::ConnectionPool::ConnectionDataPtr upstream_conn_data_; + StreamInfo::StreamInfo& downstream_info_; + const std::chrono::milliseconds upstream_flush_wait_timeout_; }; class HttpUpstream : public GenericUpstream, protected Http::StreamCallbacks { diff --git a/test/common/tcp_proxy/tcp_proxy_test.cc b/test/common/tcp_proxy/tcp_proxy_test.cc -index fc038cc875..f06047fe74 100644 +index a17416c9a8..3865185e12 100644 --- a/test/common/tcp_proxy/tcp_proxy_test.cc +++ b/test/common/tcp_proxy/tcp_proxy_test.cc -@@ -433,6 +433,23 @@ TEST_P(TcpProxyTest, UpstreamRemoteDisconnect) { +@@ -534,6 +534,23 @@ TEST_P(TcpProxyTest, UpstreamRemoteDisconnect) { upstream_callbacks_->onEvent(Network::ConnectionEvent::RemoteClose); } @@ -306,3 +302,6 @@ index fc038cc875..f06047fe74 100644 // Test that upstream RemoteClose propagates AbortReset (default behavior) // when upstream detected close type is RemoteReset. TEST_P(TcpProxyTest, UpstreamRemoteCloseWithRstPropagation) { +-- +2.56.0 + diff --git a/proxylib/BUILD b/proxylib/BUILD deleted file mode 100644 index 81bcddcf5..000000000 --- a/proxylib/BUILD +++ /dev/null @@ -1,7 +0,0 @@ -licenses(["notice"]) # Apache 2 - -exports_files([ - "libcilium.h", - "types.h", - "libcilium.so", -]) diff --git a/proxylib/Makefile b/proxylib/Makefile deleted file mode 100644 index 977e25740..000000000 --- a/proxylib/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright Authors of Cilium -# SPDX-License-Identifier: Apache-2.0 - -include ../Makefile.defs - -# Support CGO cross-compiling for amd64 and arm64 targets -NATIVE_ARCH = $(shell GOARCH= $(GO) env GOARCH) -CGO_CC = -CROSS_ARCH = -ifneq ($(GOARCH),$(NATIVE_ARCH)) - CROSS_ARCH = $(GOARCH) -endif -ifeq ($(CROSS_ARCH),arm64) - CGO_CC = CC=aarch64-linux-gnu-gcc -else ifeq ($(CROSS_ARCH),amd64) - CGO_CC = CC=x86_64-linux-gnu-gcc -endif -GO_BUILD_FLAGS ?= -GO_BUILD_WITH_CGO = CGO_ENABLED=1 $(CGO_CC) $(GO) build $(GO_BUILD_FLAGS) - -EXTRA_GO_BUILD_LDFLAGS = -extldflags -Wl,-soname,libcilium.so - -TARGET := libcilium.so - -.PHONY: all $(TARGET) clean header libcilium.h test - -all: $(TARGET) - -$(TARGET): - $(QUIET)$(GO_BUILD_WITH_CGO) -ldflags '$(EXTRA_GO_BUILD_LDFLAGS)' -o $@ -buildmode=c-shared - -clean: - -$(QUIET)rm -f $(TARGET) - $(QUIET)$(GO_CLEAN) - -header: libcilium.h -libcilium.h: proxylib.go - $(GO) tool cgo -exportheader libcilium.h proxylib.go - -test: - $(GO) test -mod=vendor -cover ./... diff --git a/proxylib/accesslog/client.go b/proxylib/accesslog/client.go deleted file mode 100644 index 17ad438b4..000000000 --- a/proxylib/accesslog/client.go +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package accesslog - -import ( - "net" - "sync" - "sync/atomic" - - "google.golang.org/protobuf/proto" - "github.com/sirupsen/logrus" - - cilium "github.com/cilium/proxy/go/cilium/api" - "github.com/cilium/proxy/proxylib/proxylib" -) - -type Client struct { - connected uint32 // Accessed atomically without locking - path string - mutex sync.Mutex // Used to protect opening the connection - conn atomic.Pointer[net.UnixConn] // Read atomically without locking -} - -func (cl *Client) connect() *net.UnixConn { - if cl.path == "" { - return nil - } - - if atomic.LoadUint32(&cl.connected) > 0 { - // Guaranteed to be non-nil - return cl.conn.Load() - } - - cl.mutex.Lock() - defer cl.mutex.Unlock() - - conn := cl.conn.Load() - - // Did someone else connect while we were contending on the lock? - // cl.connected may be written to by others concurrently - if atomic.LoadUint32(&cl.connected) > 0 { - return conn - } - - if conn != nil { - conn.Close() // not setting conn to nil! - } - logrus.Debugf("Accesslog: Connecting to Cilium access log socket: %s", cl.path) - conn, err := net.DialUnix("unixpacket", nil, &net.UnixAddr{Name: cl.path, Net: "unixpacket"}) - if err != nil { - logrus.WithError(err).Error("Accesslog: DialUnix() failed") - return nil - } - - cl.conn.Store(conn) - - // Always have a non-nil 'cl.conn' after 'cl.connected' is set for the first time! - atomic.StoreUint32(&cl.connected, 1) - return conn -} - -func (cl *Client) Log(pblog *cilium.LogEntry) { - if conn := cl.connect(); conn != nil { - // Encode - logmsg, err := proto.Marshal(pblog) - if err != nil { - logrus.WithError(err).Error("Accesslog: Protobuf marshaling error") - return - } - - // Write - _, err = conn.Write(logmsg) - if err != nil { - logrus.WithError(err).Error("Accesslog: Write() failed") - atomic.StoreUint32(&cl.connected, 0) // Mark connection as broken - } - } else { - logrus.Debugf("Accesslog: No connection, cannot send: %s", pblog.String()) - } -} - -func (c *Client) Path() string { - return c.path -} - -func NewClient(accessLogPath string) proxylib.AccessLogger { - client := &Client{ - path: accessLogPath, - } - client.connect() - return client -} - -func (cl *Client) Close() { - conn := cl.conn.Load() - if conn != nil { - conn.Close() - } -} diff --git a/proxylib/cassandra/cassandraparser.go b/proxylib/cassandra/cassandraparser.go deleted file mode 100644 index 11653b57e..000000000 --- a/proxylib/cassandra/cassandraparser.go +++ /dev/null @@ -1,703 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package cassandra - -import ( - "bytes" - "encoding/binary" - "fmt" - "regexp" - "strings" - - "github.com/sirupsen/logrus" - - cilium "github.com/cilium/proxy/go/cilium/api" - . "github.com/cilium/proxy/proxylib/proxylib" -) - -// -// Cassandra v3/v4 Parser -// -// Spec: https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v4.spec -// - -// Current Cassandra parser supports filtering on messages where the opcode is 'query-like' -// (i.e., opcode 'query', 'prepare', 'batch'. In those scenarios, we match on query_action and query_table. -// Examples: -// query_action = 'select', query_table = 'system.*' -// query_action = 'insert', query_table = 'attendance.daily_records' -// query_action = 'select', query_table = 'deathstar.scrum_notes' -// query_action = 'insert', query_table = 'covalent.foo' -// -// Batch requests are logged as invidual queries, but an entire batch request will be allowed -// only if all requests are allowed. - -// Non-query client requests, including 'Options', 'Auth_Response', 'Startup', and 'Register' -// are automatically allowed to simplify the policy language. - -// There are known changes in protocol v2 that are not compatible with this parser, see the -// the "Changes from v2" in https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v3.spec - -type CassandraRule struct { - queryActionExact string - tableRegexCompiled *regexp.Regexp -} - -const cassHdrLen = 9 -const cassMaxLen = 268435456 // 256 MB, per spec - -const unknownPreparedQueryPath = "/unknown-prepared-query" - -func (rule *CassandraRule) Matches(data interface{}) bool { - // Cast 'data' to the type we give to 'Matches()' - - path, ok := data.(string) - if !ok { - logrus.Warning("Matches() called with type other than string") - return false - } - logrus.Debugf("Policy Match test for '%s'", path) - regexStr := "" - if rule.tableRegexCompiled != nil { - regexStr = rule.tableRegexCompiled.String() - } - - logrus.Debugf("Rule: action '%s', table '%s'", rule.queryActionExact, regexStr) - if path == unknownPreparedQueryPath { - logrus.Warning("Dropping execute for unknown prepared-id") - return false - } - parts := strings.Split(path, "/") - if len(parts) <= 2 { - // this is not a query-like request, just allow - return true - } else if len(parts) < 4 { - // should never happen unless we've messed up internally - // as path is either / or /// - logrus.Errorf("Invalid parsed path: '%s'", path) - return false - } - if rule.queryActionExact != "" && rule.queryActionExact != parts[2] { - logrus.Debugf("CassandraRule: query_action mismatch %v, %s", rule.queryActionExact, parts[1]) - return false - } - if len(parts[3]) > 0 && - rule.tableRegexCompiled != nil && - !rule.tableRegexCompiled.MatchString(parts[3]) { - logrus.Debugf("CassandraRule: table_regex mismatch '%v', '%s'", rule.tableRegexCompiled, parts[3]) - return false - } - - return true -} - -// CassandraRuleParser parses protobuf L7 rules to enforcement objects -// May panic -func CassandraRuleParser(rule *cilium.PortNetworkPolicyRule) []L7NetworkPolicyRule { - l7Rules := rule.GetL7Rules() - if l7Rules == nil { - return nil - } - - allowRules := l7Rules.GetL7AllowRules() - rules := make([]L7NetworkPolicyRule, 0, len(allowRules)) - for _, l7Rule := range allowRules { - var cr CassandraRule - for k, v := range l7Rule.Rule { - switch k { - case "query_action": - cr.queryActionExact = v - case "query_table": - if v != "" { - cr.tableRegexCompiled = regexp.MustCompile(v) - } - default: - ParseError(fmt.Sprintf("Unsupported key: %s", k), rule) - } - } - if len(cr.queryActionExact) > 0 { - // ensure this is a valid query action - res := queryActionMap[cr.queryActionExact] - if res == invalidAction { - ParseError(fmt.Sprintf("Unable to parse L7 cassandra rule with invalid query_action: '%s'", cr.queryActionExact), rule) - } else if res == actionNoTable && cr.tableRegexCompiled != nil { - ParseError(fmt.Sprintf("query_action '%s' is not compatible with a query_table match", cr.queryActionExact), rule) - } - - } - - logrus.Debugf("Parsed CassandraRule pair: %v", cr) - rules = append(rules, &cr) - } - return rules -} - -type CassandraParserFactory struct{} - -var cassandraParserFactory *CassandraParserFactory - -func init() { - logrus.Debug("init(): Registering cassandraParserFactory") - RegisterParserFactory("cassandra", cassandraParserFactory) - RegisterL7RuleParser("cassandra", CassandraRuleParser) -} - -type CassandraParser struct { - connection *Connection - keyspace string // stores current keyspace name from 'use' command - - // stores prepared query string while - // waiting for 'prepared' reply from server - // with a prepared id. - // replies associated via stream-id - preparedQueryPathByStreamID map[uint16]string - - // allowing us to enforce policy on query - // at the time of the execute command. - preparedQueryPathByPreparedID map[string]string // stores query string based on prepared-id, -} - -func (pf *CassandraParserFactory) Create(connection *Connection) interface{} { - logrus.Debugf("CassandraParserFactory: Create: %v", connection) - - p := CassandraParser{connection: connection} - p.preparedQueryPathByStreamID = make(map[uint16]string) - p.preparedQueryPathByPreparedID = make(map[string]string) - return &p -} - -func (p *CassandraParser) OnData(reply, endStream bool, dataArray [][]byte) (OpType, int) { - - // inefficient, but simple for now - data := bytes.Join(dataArray, []byte{}) - - if len(data) < cassHdrLen { - // Partial header received, ask for more - needs := cassHdrLen - len(data) - logrus.Debugf("Did not receive full header, need %d more bytes", needs) - return MORE, needs - } - - // full header available, read full request length - requestLen := binary.BigEndian.Uint32(data[5:9]) - logrus.Debugf("Request length = %d", requestLen) - if requestLen > cassMaxLen { - logrus.Errorf("Request length of %d is greater than 256 MB", requestLen) - return ERROR, int(ERROR_INVALID_FRAME_LENGTH) - } - - dataMissing := (cassHdrLen + int(requestLen)) - len(data) - if dataMissing > 0 { - // full header received, but only partial request - - logrus.Debugf("Hdr received, but need %d more bytes of request", dataMissing) - return MORE, dataMissing - } - - // we parse replies, but only to look for prepared-query-id responses - if reply { - if len(data) == 0 { - logrus.Debugf("ignoring zero length reply call to onData") - return NOP, 0 - - } - cassandraParseReply(p, data[0:(cassHdrLen+requestLen)]) - - logrus.Debugf("reply, passing %d bytes", (cassHdrLen + requestLen)) - return PASS, (cassHdrLen + int(requestLen)) - } - - err, paths := cassandraParseRequest(p, data[0:(cassHdrLen+requestLen)]) - if err != 0 { - logrus.Errorf("Parsing error %d", err) - return ERROR, int(err) - } - - logrus.Debugf("Request paths = %s", paths) - - matches := true - access_log_entry_type := cilium.EntryType_Request - unpreparedQuery := false - - for i := 0; i < len(paths); i++ { - if strings.HasPrefix(paths[i], "/query/use/") || - strings.HasPrefix(paths[i], "/batch/use/") || - strings.HasPrefix(paths[i], "/prepare/use/") { - // do not count a "use" query as a deny - continue - } - - if paths[i] == unknownPreparedQueryPath { - matches = false - unpreparedQuery = true - access_log_entry_type = cilium.EntryType_Denied - break - } - - if !p.connection.Matches(paths[i]) { - matches = false - access_log_entry_type = cilium.EntryType_Denied - break - } - } - - for i := 0; i < len(paths); i++ { - parts := strings.Split(paths[i], "/") - fields := map[string]string{} - - if len(parts) >= 3 && parts[2] == "use" { - // do not log 'use' queries - continue - } else if len(parts) == 4 { - fields["query_action"] = parts[2] - fields["query_table"] = parts[3] - } else if unpreparedQuery { - fields["error"] = "unknown prepared query id" - } else { - // do not log non-query accesses - continue - } - - p.connection.Log(access_log_entry_type, - &cilium.LogEntry_GenericL7{ - GenericL7: &cilium.L7LogEntry{ - Proto: "cassandra", - Fields: fields, - }, - }) - - } - - if !matches { - - // If we have already sent another error to the client, - // do not send unauthorized message - if !unpreparedQuery { - unauthMsg := make([]byte, len(unauthMsgBase)) - copy(unauthMsg, unauthMsgBase) - // We want to use the same protocol and stream ID - // as the incoming request. - // update the protocol to match the request - unauthMsg[0] = 0x80 | (data[0] & 0x07) - // update the stream ID to match the request - unauthMsg[2] = data[2] - unauthMsg[3] = data[3] - p.connection.Inject(true, unauthMsg) - } - return DROP, int(cassHdrLen + requestLen) - } - - return PASS, int(cassHdrLen + requestLen) -} - -// A full response (header + body) to be used as an -// "unauthorized" error to be sent to cassandra client as part of policy -// deny. Array must be updated to ensure that reply has -// protocol version and stream-id that matches the request. - -var unauthMsgBase = []byte{ - 0x0, // version (uint8) - must be set before injection - 0x0, // flags, (uint8) - 0x0, 0x0, // stream-id (uint16) - must be set before injection - 0x0, // opcode error (uint8) - 0x0, 0x0, 0x0, 0x1a, // request length (uint32) - update if text changes - 0x0, 0x0, 0x21, 0x00, // 'unauthorized error code' 0x2100 (uint32) - 0x0, 0x14, // length of error msg (uint16) - update if text changes - 'R', 'e', 'q', 'u', 'e', 's', 't', ' ', 'U', 'n', 'a', 'u', 't', 'h', 'o', 'r', 'i', 'z', 'e', 'd', -} - -// A full response (header + body) to be used as a -// "unprepared" error to be sent to cassandra client if proxy -// does not have the path for this prepare-query-id cached - -var unpreparedMsgBase = []byte{ - 0x0, // version (uint8) - must be set before injection - 0x0, // flags, (uint8) - 0x0, 0x0, // stream-id (uint16) - must be set before injection - 0x0, // opcode error (uint8) - 0x0, 0x0, 0x0, 0x0, // request length (uint32) - must be set based on - // of length of prepared query id - 0x0, 0x0, 0x25, 0x00, // 'unprepared error code' 0x2500 (uint32) - // must append [short bytes] array of prepared query id. -} - -// create reply byte buffer with error code 'unprepared' with code 0x2500 -// followed by a [short bytes] indicating the unknown ID -// must set stream-id of the response to match the request -func createUnpreparedMsg(version byte, streamID []byte, preparedID string) []byte { - - unpreparedMsg := make([]byte, len(unpreparedMsgBase)) - copy(unpreparedMsg, unpreparedMsgBase) - unpreparedMsg[0] = 0x80 | version - unpreparedMsg[2] = streamID[0] - unpreparedMsg[3] = streamID[1] - - idLen := len(preparedID) - idLenBytes := make([]byte, 2) - binary.BigEndian.PutUint16(idLenBytes, uint16(idLen)) - - reqLen := 4 + 2 + idLen - reqLenBytes := make([]byte, 4) - binary.BigEndian.PutUint32(reqLenBytes, uint32(reqLen)) - unpreparedMsg[5] = reqLenBytes[0] - unpreparedMsg[6] = reqLenBytes[1] - unpreparedMsg[7] = reqLenBytes[2] - unpreparedMsg[8] = reqLenBytes[3] - - res := append(unpreparedMsg, idLenBytes...) - return append(res, []byte(preparedID)...) -} - -var opcodeMap = map[byte]string{ - 0x00: "error", - 0x01: "startup", - 0x02: "ready", - 0x03: "authenticate", - 0x05: "options", - 0x06: "supported", - 0x07: "query", - 0x08: "result", - 0x09: "prepare", - 0x0A: "execute", - 0x0B: "register", - 0x0C: "event", - 0x0D: "batch", - 0x0E: "auth_challenge", - 0x0F: "auth_response", - 0x10: "auth_success", -} - -// map to test whether a 'query_action' is valid or not - -const invalidAction = 0 -const actionWithTable = 1 -const actionNoTable = 2 - -var queryActionMap = map[string]int{ - "select": actionWithTable, - "delete": actionWithTable, - "insert": actionWithTable, - "update": actionWithTable, - "create-table": actionWithTable, - "drop-table": actionWithTable, - "alter-table": actionWithTable, - "truncate-table": actionWithTable, - - // these queries take a keyspace - // and match against query_table - "use": actionWithTable, - "create-keyspace": actionWithTable, - "alter-keyspace": actionWithTable, - "drop-keyspace": actionWithTable, - - "drop-index": actionNoTable, - "create-index": actionNoTable, // TODO: we could tie this to table if we want - "create-materialized-view": actionNoTable, - "drop-materialized-view": actionNoTable, - - // TODO: these admin ops could be bundled into meta roles - // (e.g., role-mgmt, permission-mgmt) - "create-role": actionNoTable, - "alter-role": actionNoTable, - "drop-role": actionNoTable, - "grant-role": actionNoTable, - "revoke-role": actionNoTable, - "list-roles": actionNoTable, - "grant-permission": actionNoTable, - "revoke-permission": actionNoTable, - "list-permissions": actionNoTable, - "create-user": actionNoTable, - "alter-user": actionNoTable, - "drop-user": actionNoTable, - "list-users": actionNoTable, - - "create-function": actionNoTable, - "drop-function": actionNoTable, - "create-aggregate": actionNoTable, - "drop-aggregate": actionNoTable, - "create-type": actionNoTable, - "alter-type": actionNoTable, - "drop-type": actionNoTable, - "create-trigger": actionNoTable, - "drop-trigger": actionNoTable, -} - -func parseQuery(p *CassandraParser, query string) (string, string) { - var action string - var table string - - query = strings.TrimRight(query, ";") // remove potential trailing ; - fields := strings.Fields(strings.ToLower(query)) // handles all whitespace - - // we currently do not strip comments. It seems like cqlsh does - // strip comments, but its not clear if that can be assumed of all clients - // It should not be possible to "spoof" the 'action' as this is assumed to be - // the first token (leaving no room for a comment to start), but it could potentially - // trick this parser into thinking we're accessing table X, when in fact the - // query accesses table Y, which would obviously be a security vulnerability - // As a result, we look at each token here, and if any of them match the comment - // characters for cassandra, we fail parsing. - for i := 0; i < len(fields); i++ { - if len(fields[i]) >= 2 && - (fields[i][:2] == "--" || - fields[i][:2] == "/*" || - fields[i][:2] == "//") { - - logrus.Warnf("Unable to safely parse query with comments '%s'", query) - return "", "" - } - } - if len(fields) < 2 { - goto invalidQuery - } - - action = fields[0] - switch action { - case "select", "delete": - for i := 1; i < len(fields); i++ { - if fields[i] == "from" { - table = strings.ToLower(fields[i+1]) - } - } - if len(table) == 0 { - logrus.Warnf("Unable to parse table name from query '%s'", query) - return "", "" - } - case "insert": - // INSERT into - if len(fields) < 3 { - goto invalidQuery - } - table = strings.ToLower(fields[2]) - case "update": - // UPDATE - table = strings.ToLower(fields[1]) - case "use": - p.keyspace = strings.Trim(fields[1], "\"\\'") - logrus.Debugf("Saving keyspace '%s'", p.keyspace) - table = p.keyspace - case "alter", "create", "drop", "truncate", "list": - - action = strings.Join([]string{action, fields[1]}, "-") - if fields[1] == "table" || fields[1] == "keyspace" { - - if len(fields) < 3 { - goto invalidQuery - } - table = fields[2] - if table == "if" { - if action == "create-table" { - if len(fields) < 6 { - goto invalidQuery - } - // handle optional "IF NOT EXISTS" - table = fields[5] - } else if action == "drop-table" || action == "drop-keyspace" { - if len(fields) < 5 { - goto invalidQuery - } - // handle optional "IF EXISTS" - table = fields[4] - } - } - } - if action == "truncate" && len(fields) == 2 { - // special case, truncate can just be passed table name - table = fields[1] - } - if fields[1] == "materialized" { - action = action + "-view" - } else if fields[1] == "custom" { - action = "create-index" - } - default: - goto invalidQuery - } - - if len(table) > 0 && !strings.Contains(table, ".") && action != "use" { - table = p.keyspace + "." + table - } - return action, table - -invalidQuery: - - logrus.Errorf("Unable to parse query: '%s'", query) - return "", "" -} - -func cassandraParseRequest(p *CassandraParser, data []byte) (OpError, []string) { - - direction := data[0] & 0x80 // top bit - if direction != 0 { - logrus.Errorf("Direction bit is 'reply', but we are trying to parse a request") - return ERROR_INVALID_FRAME_TYPE, nil - } - - compressionFlag := data[1] & 0x01 - if compressionFlag == 1 { - logrus.Errorf("Compression flag set, unable to parse request beyond the header") - return ERROR_INVALID_FRAME_TYPE, nil - } - - opcode := data[4] - path := opcodeMap[opcode] - - // parse query string from query/prepare/batch requests - - // NOTE: parsing only prepare statements and passing all execute - // statements requires that we 'invalidate' all execute statements - // anytime policy changes, to ensure that no execute statements are - // allowed that correspond to prepared queries that would no longer - // be valid. A better option might be to cache all prepared queries, - // mapping the execution ID to allow/deny each time policy is changed. - if opcode == 0x07 || opcode == 0x09 { - // query || prepare - queryLen := binary.BigEndian.Uint32(data[9:13]) - endIndex := 13 + queryLen - query := string(data[13:endIndex]) - action, table := parseQuery(p, query) - - if action == "" { - return ERROR_INVALID_FRAME_TYPE, nil - } - - path = "/" + path + "/" + action + "/" + table - if opcode == 0x09 { - // stash 'path' for this prepared query based on stream id - // rewrite 'opcode' portion of the path to be 'execute' rather than 'prepare' - streamID := binary.BigEndian.Uint16(data[2:4]) - logrus.Debugf("Prepare query path '%s' with stream-id %d", path, streamID) - p.preparedQueryPathByStreamID[streamID] = strings.Replace(path, "prepare", "execute", 1) - } - return 0, []string{path} - } else if opcode == 0x0d { - // batch - - numQueries := binary.BigEndian.Uint16(data[10:12]) - paths := make([]string, numQueries) - logrus.Debugf("batch query count = %d", numQueries) - offset := 12 - for i := 0; i < int(numQueries); i++ { - kind := data[offset] - if kind == 0 { - // full query string - queryLen := int(binary.BigEndian.Uint32(data[offset+1 : offset+5])) - - query := string(data[offset+5 : offset+5+queryLen]) - action, table := parseQuery(p, query) - - if action == "" { - return ERROR_INVALID_FRAME_TYPE, nil - } - path = "/" + path + "/" + action + "/" + table - paths[i] = path - path = "batch" // reset for next item - offset = offset + 5 + queryLen - offset = readPastBatchValues(data, offset) - } else if kind == 1 { - // prepared query id - - idLen := int(binary.BigEndian.Uint16(data[offset+1 : offset+3])) - preparedID := string(data[offset+3 : (offset + 3 + idLen)]) - logrus.Debugf("Batch entry with prepared-id = '%s'", preparedID) - path := p.preparedQueryPathByPreparedID[preparedID] - if len(path) > 0 { - paths[i] = path - } else { - logrus.Warnf("No cached entry for prepared-id = '%s' in batch", preparedID) - unpreparedMsg := createUnpreparedMsg(data[0], data[2:4], preparedID) - p.connection.Inject(true, unpreparedMsg) - return 0, []string{unknownPreparedQueryPath} - } - offset = offset + 3 + idLen - - offset = readPastBatchValues(data, offset) - } else { - logrus.Errorf("unexpected value of 'kind' in batch query: %d", kind) - return ERROR_INVALID_FRAME_TYPE, nil - } - } - return 0, paths - } else if opcode == 0x0a { - // execute - - // parse out prepared query id, and then look up our - // cached query path for policy evaluation. - idLen := binary.BigEndian.Uint16(data[9:11]) - preparedID := string(data[11:(11 + idLen)]) - logrus.Debugf("Execute with prepared-id = '%s'", preparedID) - path := p.preparedQueryPathByPreparedID[preparedID] - - if len(path) == 0 { - logrus.Warnf("No cached entry for prepared-id = '%s'", preparedID) - unpreparedMsg := createUnpreparedMsg(data[0], data[2:4], preparedID) - p.connection.Inject(true, unpreparedMsg) - - // this path is special-cased in Matches() so that unknown - // prepared IDs are dropped if any rules are defined - return 0, []string{unknownPreparedQueryPath} - } - - return 0, []string{path} - } else { - // other opcode, just return type of opcode - - return 0, []string{"/" + path} - } - -} - -func readPastBatchValues(data []byte, initialOffset int) int { - numValues := int(binary.BigEndian.Uint16(data[initialOffset : initialOffset+2])) - offset := initialOffset + 2 - for i := 0; i < numValues; i++ { - valueLen := int(binary.BigEndian.Uint32(data[offset : offset+4])) - // handle 'null' (-1) and 'not set' (-2) case, where 0 bytes follow - if valueLen >= 0 { - offset = offset + 4 + valueLen - } - } - return offset -} - -// reply parsing is very basic, just focusing on parsing RESULT messages that -// contain prepared query IDs so that we can later enforce policy on "execute" requests. -func cassandraParseReply(p *CassandraParser, data []byte) { - - direction := data[0] & 0x80 // top bit - if direction != 0x80 { - logrus.Errorf("Direction bit is 'request', but we are trying to parse a reply") - return - } - - compressionFlag := data[1] & 0x01 - if compressionFlag == 1 { - logrus.Errorf("Compression flag set, unable to parse reply beyond the header") - return - } - - streamID := binary.BigEndian.Uint16(data[2:4]) - logrus.Debugf("Reply with opcode %d and stream-id %d", data[4], streamID) - // if this is an opcode == RESULT message of type 'prepared', associate the prepared - // statement id with the full query string that was included in the - // associated PREPARE request. The stream-id in this reply allows us to - // find the associated prepare query string. - if data[4] == 0x08 { - resultKind := binary.BigEndian.Uint32(data[9:13]) - logrus.Debugf("resultKind = %d", resultKind) - if resultKind == 0x0004 { - idLen := binary.BigEndian.Uint16(data[13:15]) - preparedID := string(data[15 : 15+idLen]) - logrus.Debugf("Result with prepared-id = '%s' for stream-id %d", preparedID, streamID) - path := p.preparedQueryPathByStreamID[streamID] - if len(path) > 0 { - // found cached query path to associate with this preparedID - p.preparedQueryPathByPreparedID[preparedID] = path - logrus.Debugf("Associating query path '%s' with prepared-id %s as part of stream-id %d", path, preparedID, streamID) - } else { - logrus.Warnf("Unable to find prepared query path associated with stream-id %d", streamID) - } - } - } -} diff --git a/proxylib/cassandra/cassandraparser_test.go b/proxylib/cassandra/cassandraparser_test.go deleted file mode 100644 index e02f36b90..000000000 --- a/proxylib/cassandra/cassandraparser_test.go +++ /dev/null @@ -1,789 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package cassandra - -import ( - "encoding/hex" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/cilium/proxy/proxylib/accesslog" - "github.com/cilium/proxy/proxylib/proxylib" - "github.com/cilium/proxy/proxylib/test" -) - -type CassandraSuite struct { - logServer *test.AccessLogServer - ins *proxylib.Instance -} - -// Set up access log server and Library instance for all the test cases -func setUpCassandraSuite(tb testing.TB) *CassandraSuite { - s := &CassandraSuite{} - s.logServer = test.StartAccessLogServer("access_log.sock", 10) - require.NotNil(tb, s.logServer) - s.ins = proxylib.NewInstance("node1", accesslog.NewClient(s.logServer.Path)) - require.NotNil(tb, s.ins) - - tb.Cleanup(func() { - s.logServer.Clear() - s.logServer.Close() - }) - return s -} - -func (s *CassandraSuite) checkAccessLogs(tb testing.TB, expPasses, expDrops int) { - passes, drops := s.logServer.Clear() - require.Equal(tb, expPasses, passes) - require.Equal(tb, expDrops, drops) -} - -// util function used for Cassandra tests, as we have cassandra requests -// as hex strings -func hexData(tb testing.TB, dataHex ...string) [][]byte { - data := make([][]byte, 0, len(dataHex)) - for i := range dataHex { - dataRaw, err := hex.DecodeString(dataHex[i]) - require.NoError(tb, err) - data = append(data, dataRaw) - } - return data -} - -func TestCassandraOnDataNoHeader(t *testing.T) { - s := setUpCassandraSuite(t) - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "no-policy") - data := hexData(t, "0400") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, - proxylib.MORE, 9-len(data[0])) -} - -func TestCassandraOnDataOptionsReq(t *testing.T) { - s := setUpCassandraSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "cassandra" - l7_rules: < - l7_allow_rules: < - rule: < - key: "query_action" - value: "select" - > - > - > - > - > - `}) - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - - data := hexData(t, "040000000500000000") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, - proxylib.PASS, len(data[0]), - proxylib.MORE, 9) -} - -// this passes a large query request that is missing just the last byte -func TestCassandraOnDataPartialReq(t *testing.T) { - s := setUpCassandraSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "cassandra" - l7_rules: < - l7_allow_rules: < - rule: < - key: "query_table" - value: ".*" - > - > - > - > - > - `}) - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - data := hexData(t, "0400000407000000760000006f53454c45435420636c75737465725f6e616d652c20646174615f63656e7465722c207261636b2c20746f6b656e732c20706172746974696f6e65722c20736368656d615f76657273696f6e2046524f4d2073797374656d2e6c6f63616c205748455245206b65793d276c6f63616c270001") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, - proxylib.MORE, 1) -} - -func TestCassandraOnDataQueryReq(t *testing.T) { - s := setUpCassandraSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "cassandra" - l7_rules: < - l7_allow_rules: < - rule: < - key: "query_table" - value: ".*" - > - > - > - > - > - `}) - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - data := hexData(t, "0400000407000000760000006f53454c45435420636c75737465725f6e616d652c20646174615f63656e7465722c207261636b2c20746f6b656e732c20706172746974696f6e65722c20736368656d615f76657273696f6e2046524f4d2073797374656d2e6c6f63616c205748455245206b65793d276c6f63616c27000100") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, - proxylib.PASS, len(data[0]), - proxylib.MORE, 9) -} - -func TestCassandraOnDataSplitQueryReq(t *testing.T) { - s := setUpCassandraSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "cassandra" - l7_rules: < - l7_allow_rules: < - rule: < - key: "query_table" - value: ".*" - > - > - > - > - > - `}) - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - data := hexData(t, "04000004070000007600", "00006f53454c45435420636c75737465725f6e616d652c20646174615f63656e7465722c207261636b2c20746f6b656e732c20706172746974696f6e65722c20736368656d615f76657273696f6e2046524f4d2073797374656d2e6c6f63616c205748455245206b65793d276c6f63616c27000100") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, - proxylib.PASS, len(data[0])+len(data[1]), - proxylib.MORE, 9) -} - -func TestCassandraOnDataMultiReq(t *testing.T) { - s := setUpCassandraSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "cassandra" - l7_rules: < - l7_allow_rules: < - rule: < - key: "query_table" - value: ".*" - > - > - > - > - > - `}) - - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - - data := hexData(t, "040000000500000000", - "0400000407000000760000006f53454c45435420636c75737465725f6e616d652c20646174615f63656e7465722c207261636b2c20746f6b656e732c20706172746974696f6e65722c20736368656d615f76657273696f6e2046524f4d2073797374656d2e6c6f63616c205748455245206b65793d276c6f63616c27000100") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, - proxylib.PASS, len(data[0]), - proxylib.PASS, len(data[1]), - proxylib.MORE, 9) -} - -func TestSimpleCassandraPolicy(t *testing.T) { - s := setUpCassandraSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "cassandra" - l7_rules: < - l7_allow_rules: < - rule: < - key: "query_table" - value: "no-match" - > - > - > - > - > - `}) - - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - - unauthMsg := createUnauthMsg(0x4) - data := hexData(t, "040000000500000000", - "0400000407000000760000006f53454c45435420636c75737465725f6e616d652c20646174615f63656e7465722c207261636b2c20746f6b656e732c20706172746974696f6e65722c20736368656d615f76657273696f6e2046524f4d2073797374656d2e6c6f63616c205748455245206b65793d276c6f63616c27000100") - conn.CheckOnDataOK(t, false, false, &data, unauthMsg, - proxylib.PASS, len(data[0]), - proxylib.DROP, len(data[1]), - proxylib.MORE, 9) - - // All passes are not access-logged - s.checkAccessLogs(t, 0, 1) -} - -func createUnauthMsg(streamID byte) []byte { - unauthMsg := make([]byte, len(unauthMsgBase)) - copy(unauthMsg, unauthMsgBase) - unauthMsg[0] = 0x84 - unauthMsg[2] = 0x0 - unauthMsg[3] = streamID - return unauthMsg -} - -// this test confirms that we correctly parse and allow a valid batch requests -func TestCassandraBatchRequestPolicy(t *testing.T) { - s := setUpCassandraSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "cassandra" - l7_rules: < - l7_allow_rules: < - rule: < - key: "query_table" - value: "db1.*" - > - > - > - > - > - `}) - - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - - batchMsg := []byte{ - 0x04, // version - 0x0, // flags, (uint8) - 0x0, 0x4, // stream-id (uint16) (test request uses 0x0004 as stream ID) - 0x0d, // opcode batch (uint8) - 0x0, 0x0, 0x0, 0x3c, // request length of 60 (uint32) - update if body changes - 0x0, // batch type == logged - 0x0, 0x2, // two batch messages - - // first batch message - 0x0, // type: non-prepared query - 0x0, 0x0, 0x0, 0x14, // [long string] length (20) - 'S', 'E', 'L', 'E', 'C', 'T', ' ', '*', ' ', 'F', 'R', 'O', 'M', ' ', 'd', 'b', '1', '.', 't', '1', - 0x0, 0x0, // # of bound values - - // second batch message - 0x0, // type: non-prepared query - 0x0, 0x0, 0x0, 0x14, // [long string] length (20) - 'S', 'E', 'L', 'E', 'C', 'T', ' ', '*', ' ', 'F', 'R', 'O', 'M', ' ', 'd', 'b', '1', '.', 't', '2', - 0x0, 0x0, // # of bound values - - 0x0, 0x0, // consistency level [short] - 0x0, // batch flags - } - data := [][]byte{batchMsg} - - conn.CheckOnDataOK(t, false, false, &data, []byte{}, - proxylib.PASS, len(data[0]), - proxylib.MORE, 9) - - // batch requests are access-logged individually - s.checkAccessLogs(t, 2, 0) -} - -// this test confirms that we correctly parse and deny a batch request -// if any of the requests are denied. -func (s *CassandraSuite) TestCassandraBatchRequestPolicyDenied(c *testing.T) { - s.ins.CheckInsertPolicyText(c, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "cassandra" - l7_rules: < - l7_allow_rules: < - rule: < - key: "query_table" - value: "db1.*" - > - > - > - > - > - `}) - - conn := s.ins.CheckNewConnectionOK(c, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - - batchMsg := []byte{ - 0x04, // version - 0x0, // flags, (uint8) - 0x0, 0x4, // stream-id (uint16) (test request uses 0x0004 as stream ID) - 0x0d, // opcode batch (uint8) - 0x0, 0x0, 0x0, 0x3c, // request length of 60 (uint32) - update if body changes - 0x0, // batch type == logged - 0x0, 0x2, // two batch messages - - // first batch message - 0x0, // type: non-prepared query - 0x0, 0x0, 0x0, 0x14, // [long string] length (20) - 'S', 'E', 'L', 'E', 'C', 'T', ' ', '*', ' ', 'F', 'R', 'O', 'M', ' ', 'd', 'b', '1', '.', 't', '1', - 0x0, 0x0, // # of bound values - - // second batch message (accesses db2.t2, which should be denied) - 0x0, // type: non-prepared query - 0x0, 0x0, 0x0, 0x14, // [long string] length (20) - 'S', 'E', 'L', 'E', 'C', 'T', ' ', '*', ' ', 'F', 'R', 'O', 'M', ' ', 'd', 'b', '2', '.', 't', '2', - 0x0, 0x0, // # of bound values - - 0x0, 0x0, // consistency level [short] - 0x0, // batch flags - } - data := [][]byte{batchMsg} - - unauthMsg := createUnauthMsg(0x4) - conn.CheckOnDataOK(c, false, false, &data, unauthMsg, - proxylib.DROP, len(data[0]), - proxylib.MORE, 9) - - // batch requests are access-logged individually - // Note: in this case, both accesses are denied, as a batch - // request is either entirely allowed or denied - s.checkAccessLogs(c, 0, 2) -} - -// test batch requests with prepared statements -func TestCassandraBatchRequestPreparedStatement(t *testing.T) { - s := setUpCassandraSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "cassandra" - l7_rules: < - l7_allow_rules: < - rule: < - key: "query_table" - value: "db3.*" - > - > - > - > - > - `}) - - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - - cassParser, ok := (conn.Parser).(*CassandraParser) - if !ok { - panic("failed to cast conn.Parser to *CassandraParser\n") - } - preparedQueryID1 := "aaaa" - cassParser.preparedQueryPathByPreparedID[preparedQueryID1] = "/batch/select/db3.t1" - preparedQueryID2 := "bbbb" - cassParser.preparedQueryPathByPreparedID[preparedQueryID2] = "/batch/select/db3.t2" - - batchMsg := []byte{ - 0x04, // version - 0x0, // flags, (uint8) - 0x0, 0x4, // stream-id (uint16) (test request uses 0x0004 as stream ID) - 0x0d, // opcode batch (uint8) - 0x0, 0x0, 0x0, 0x18, // request length of 60 (uint32) - update if body changes - 0x0, // batch type == logged - 0x0, 0x2, // two batch messages - - // first batch message - 0x1, // type: prepared query - 0x0, 0x4, // [short] length (4) - 'a', 'a', 'a', 'a', - 0x0, 0x0, // # of bound values - - // second batch message - 0x1, // type: non-prepared query - 0x0, 0x4, // [short] length (4) - 'b', 'b', 'b', 'b', - 0x0, 0x0, // # of bound values - - 0x0, 0x0, // consistency level [short] - 0x0, // batch flags - } - data := [][]byte{batchMsg} - - conn.CheckOnDataOK(t, false, false, &data, []byte{}, - proxylib.PASS, len(data[0]), - proxylib.MORE, 9) - - // batch requests are access-logged individually - s.checkAccessLogs(t, 2, 0) -} - -// test batch requests with prepared statements, including a deny -func TestCassandraBatchRequestPreparedStatementDenied(t *testing.T) { - s := setUpCassandraSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "cassandra" - l7_rules: < - l7_allow_rules: < - rule: < - key: "query_table" - value: "db3.*" - > - > - > - > - > - `}) - - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - - cassParser, ok := (conn.Parser).(*CassandraParser) - if !ok { - panic("failed to cast conn.Parser to *CassandraParser\n") - } - preparedQueryID1 := "aaaa" - cassParser.preparedQueryPathByPreparedID[preparedQueryID1] = "/batch/select/db3.t1" - preparedQueryID2 := "bbbb" - cassParser.preparedQueryPathByPreparedID[preparedQueryID2] = "/batch/select/db4.t2" - - batchMsg := []byte{ - 0x04, // version - 0x0, // flags, (uint8) - 0x0, 0x4, // stream-id (uint16) (test request uses 0x0004 as stream ID) - 0x0d, // opcode batch (uint8) - 0x0, 0x0, 0x0, 0x18, // request length of 60 (uint32) - update if body changes - 0x0, // batch type == logged - 0x0, 0x2, // two batch messages - - // first batch message - 0x1, // type: prepared query - 0x0, 0x4, // [short] length (4) - 'a', 'a', 'a', 'a', - 0x0, 0x0, // # of bound values - - // second batch message (accesses table db4, which should be denied) - 0x1, // type: non-prepared query - 0x0, 0x4, // [short] length (4) - 'b', 'b', 'b', 'b', - 0x0, 0x0, // # of bound values - - 0x0, 0x0, // consistency level [short] - 0x0, // batch flags - } - data := [][]byte{batchMsg} - - unauthMsg := createUnauthMsg(0x4) - conn.CheckOnDataOK(t, false, false, &data, unauthMsg, - proxylib.DROP, len(data[0]), - proxylib.MORE, 9) - - // batch requests are access-logged individually - s.checkAccessLogs(t, 0, 2) -} - -// test execute statement, allow request -func TestCassandraExecutePreparedStatement(t *testing.T) { - s := setUpCassandraSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "cassandra" - l7_rules: < - l7_allow_rules: < - rule: < - key: "query_table" - value: "db3.*" - > - > - > - > - > - `}) - - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - - cassParser, ok := (conn.Parser).(*CassandraParser) - if !ok { - panic("failed to cast conn.Parser to *CassandraParser\n") - } - preparedQueryID1 := "aaaa" - cassParser.preparedQueryPathByPreparedID[preparedQueryID1] = "/query/select/db3.t1" - - executeMsg := []byte{ - 0x04, // version - 0x0, // flags, (uint8) - 0x0, 0x4, // stream-id (uint16) (test request uses 0x0004 as stream ID) - 0x0a, // opcode execute (uint8) - 0x0, 0x0, 0x0, 0x09, // request length (uint32) - update if body changes - - // Execute request - 0x0, 0x4, // short bytes len (4) - 'a', 'a', 'a', 'a', - - // the rest of this is values that can be ignored by our parser, - // but we add some here to make sure that we're properly passing - // based on total request length. - 'x', 'y', 'z', - } - data := [][]byte{executeMsg} - - conn.CheckOnDataOK(t, false, false, &data, []byte{}, - proxylib.PASS, len(data[0]), - proxylib.MORE, 9) - - s.checkAccessLogs(t, 1, 0) -} - -// test execute statement with unknown prepared-id -func TestCassandraExecutePreparedStatementUnknownID(t *testing.T) { - s := setUpCassandraSuite(t) - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "cp1") - - executeMsg := []byte{ - 0x04, // version - 0x0, // flags, (uint8) - 0x0, 0x4, // stream-id (uint16) (test request uses 0x0004 as stream ID) - 0x0a, // opcode execute (uint8) - 0x0, 0x0, 0x0, 0x06, // request length (uint32) - update if body changes - - // Execute request - 0x0, 0x4, // short bytes len (4) - 'a', 'a', 'a', 'a', - } - data := [][]byte{executeMsg} - - unpreparedMsg := createUnpreparedMsg(0x04, []byte{0x0, 0x4}, "aaaa") - - conn.CheckOnDataOK(t, false, false, &data, unpreparedMsg, - proxylib.DROP, len(data[0]), - proxylib.MORE, 9) - - s.checkAccessLogs(t, 0, 1) -} - -// test parsing of a prepared query reply -func TestCassandraPreparedResultReply(t *testing.T) { - s := setUpCassandraSuite(t) - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "cp1") - - cassParser, ok := (conn.Parser).(*CassandraParser) - if !ok { - panic("failed to cast conn.Parser to *CassandraParser\n") - } - - // make sure there is a stream-id (4) that matches the request below - // this would have been populated by a "prepare" request - cassParser.preparedQueryPathByStreamID[uint16(4)] = "/query/select/db3.t1" - - preparedResultMsg := []byte{ - 0x84, // reply + version - 0x0, // flags, (uint8) - 0x0, 0x4, // stream-id (uint16) (test request uses 0x0004 as stream ID) - 0x08, // opcode result (uint8) - 0x0, 0x0, 0x0, 0x16, // request length 22 (uint32) - update if body changes - - // Prepared Result request - 0x0, 0x0, 0x0, 0x4, // [int] result type - 0x0, 0x4, // prepared-id len (short) - 'a', 'a', 'a', 'a', // prepared-id - 0x0, 0x0, 0x0, 0x0, // prepared results flags - 0x0, 0x0, 0x0, 0x0, // column-count - 0x0, 0x0, 0x0, 0x0, // pk-count - } - data := [][]byte{preparedResultMsg} - - conn.CheckOnDataOK(t, true, false, &data, []byte{}, - proxylib.PASS, len(data[0]), - proxylib.MORE, 9) - - // these replies are not access logged - s.checkAccessLogs(t, 0, 0) -} - -// test additional queries -func TestCassandraAdditionalQueries(t *testing.T) { - s := setUpCassandraSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "cassandra" - l7_rules: < - l7_allow_rules: < - rule: < - key: "query_table" - value: "db4.t1" - > - > - > - > - > - `}) - - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - - queries := []string{"CREATE TABLE db4.t1 (f1 varchar, f2 timeuuid, PRIMARY KEY ((f1), f2))", - "INSERT INTO db4.t1 (f1, f2, f3) values ('dan', now(), 'Cilium!')", - "UPDATE db4.t1 SET f1 = 'donald' where f2 in (1,2,3)", - "DROP TABLE db4.t1", - "TRUNCATE db4.t1", - "CREATE TABLE IF NOT EXISTS db4.t1 (f1 varchar, PRIMARY KEY(f1))", - } - - queryMsgBase := []byte{ - 0x04, // version - 0x0, // flags, (uint8) - 0x0, 0x5, // stream-id (uint16) (test request uses 0x0005 as stream ID) - 0x07, // opcode query (uint8) - 0x0, 0x0, 0x0, 0x0, // length of request - must be set - - // Query Req - 0x0, 0x0, 0x0, 0x0, // length of query (int) - must be set - // query string goes here - } - - data := make([][]byte, len(queries)) - for i := 0; i < len(queries); i++ { - queryLen := len(queries[i]) - - queryMsg := append(queryMsgBase, []byte(queries[i])...) - - // this works as long as query is less than 251 bytes - queryMsg[8] = byte(4 + queryLen) - queryMsg[12] = byte(queryLen) - - data[i] = queryMsg - } - conn.CheckOnDataOK(t, false, false, &data, []byte{}, - proxylib.PASS, len(data[0]), - proxylib.PASS, len(data[1]), - proxylib.PASS, len(data[2]), - proxylib.PASS, len(data[3]), - proxylib.PASS, len(data[4]), - proxylib.PASS, len(data[5]), - proxylib.MORE, 9) - - s.checkAccessLogs(t, 6, 0) -} - -// test use query, following by query that does not include the keyspace -func TestCassandraUseQuery(t *testing.T) { - s := setUpCassandraSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "cassandra" - l7_rules: < - l7_allow_rules: < - rule: < - key: "query_table" - value: "db5.t1" - > - > - > - > - > - `}) - - conn := s.ins.CheckNewConnectionOK(t, "cassandra", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - - // note: the second insert command intentionally does not include a keyspace, so that it will only - // be allowed if we properly propagate the keyspace from the previous use command - queries := []string{"USE db5", "INSERT INTO t1 (f1, f2, f3) values ('dan', now(), 'Cilium!')"} - - queryMsgBase := []byte{ - 0x04, // version - 0x0, // flags, (uint8) - 0x0, 0x5, // stream-id (uint16) (test request uses 0x0005 as stream ID) - 0x07, // opcode query (uint8) - 0x0, 0x0, 0x0, 0x0, // length of request - must be set - - // Query Req - 0x0, 0x0, 0x0, 0x0, // length of query (int) - must be set - // query string goes here - } - - data := make([][]byte, len(queries)) - for i := 0; i < len(queries); i++ { - queryLen := len(queries[i]) - - queryMsg := append(queryMsgBase, []byte(queries[i])...) - - // this works as long as query is less than 251 bytes - queryMsg[8] = byte(4 + queryLen) - queryMsg[12] = byte(queryLen) - - data[i] = queryMsg - } - conn.CheckOnDataOK(t, false, false, &data, []byte{}, - proxylib.PASS, len(data[0]), - proxylib.PASS, len(data[1]), - proxylib.MORE, 9) - - // use command will not show up in access log, so only expect one msg - s.checkAccessLogs(t, 1, 0) -} diff --git a/proxylib/kafka/kafkalib/doc.go b/proxylib/kafka/kafkalib/doc.go deleted file mode 100644 index 17b7623e7..000000000 --- a/proxylib/kafka/kafkalib/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -// Package kafkalib provides a library to parse Kafka requests and responses and -// apply policy rules -package kafkalib diff --git a/proxylib/kafka/kafkalib/error.go b/proxylib/kafka/kafkalib/error.go deleted file mode 100644 index d9491f3a2..000000000 --- a/proxylib/kafka/kafkalib/error.go +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package kafkalib - -// List of possible Kafka error codes -// Reference: https://kafka.apache.org/protocol#protocol_error_codes -const ( - ErrUnknown = -1 - ErrNone = 0 - ErrOffsetOutOfRange = 1 - ErrInvalidMessage = 2 - ErrUnknownTopicOrPartition = 3 - ErrInvalidMessageSize = 4 - ErrLeaderNotAvailable = 5 - ErrNotLeaderForPartition = 6 - ErrRequestTimeout = 7 - ErrBrokerNotAvailable = 8 - ErrReplicaNotAvailable = 9 - ErrMessageSizeTooLarge = 10 - ErrScaleControllerEpoch = 11 - ErrOffsetMetadataTooLarge = 12 - ErrNetwork = 13 - ErrOffsetLoadInProgress = 14 - ErrNoCoordinator = 15 - ErrNotCoordinator = 16 - ErrInvalidTopic = 17 - ErrRecordListTooLarge = 18 - ErrNotEnoughReplicas = 19 - ErrNotEnoughReplicasAfterAppend = 20 - ErrInvalidRequiredAcks = 21 - ErrIllegalGeneration = 22 - ErrInconsistentPartitionAssignmentStrategy = 23 - ErrUnknownParititonAssignmentStrategy = 24 - ErrUnknownConsumerID = 25 - ErrInvalidSessionTimeout = 26 - ErrRebalanceInProgress = 27 - ErrInvalidCommitOffsetSize = 28 - ErrTopicAuthorizationFailed = 29 - ErrGroupAuthorizationFailed = 30 - ErrClusterAuthorizationFailed = 31 - ErrInvalidTimeStamp = 32 -) diff --git a/proxylib/kafka/kafkalib/policy.go b/proxylib/kafka/kafkalib/policy.go deleted file mode 100644 index 3ed17b0db..000000000 --- a/proxylib/kafka/kafkalib/policy.go +++ /dev/null @@ -1,162 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package kafkalib - -import ( - "github.com/sirupsen/logrus" - - api "github.com/cilium/proxy/pkg/policy/api/kafka" -) - -type Rule struct { - // ApiVersion is the allowed version, or < 0 if all versions - // are to be allowed - APIVersion int16 - - // ApiKeys is the set of all numerical apiKeys that are allowed. - // If empty, all API keys are allowed. - APIKeys map[int16]struct{} - - // ClientID is the client identifier as provided in the request. - // - // From Kafka protocol documentation: - // This is a user supplied identifier for the client application. The - // user can use any identifier they like and it will be used when - // logging errors, monitoring aggregates, etc. For example, one might - // want to monitor not just the requests per second overall, but the - // number coming from each client application (each of which could - // reside on multiple servers). This id acts as a logical grouping - // across all requests from a particular client. - // - // If empty, all client identifiers are allowed. - ClientID string - - // Topic is the topic name contained in the message. If a Kafka request - // contains multiple topics, then all topics must be allowed or the - // message will be rejected. - // - // This constraint is ignored if the matched request message type - // doesn't contain any topic. Maximum size of Topic can be 249 - // characters as per recent Kafka spec and allowed characters are - // a-z, A-Z, 0-9, -, . and _ - // Older Kafka versions had longer topic lengths of 255, but in Kafka 0.10 - // version the length was changed from 255 to 249. For compatibility - // reasons we are allowing 255. - // - // If empty, all topics are allowed. - Topic string -} - -// NewRule creates a new rule from already sanitized inputs -func NewRule(apiVersion int32, apiKeys []int32, clientID, topic string) Rule { - r := Rule{ - APIVersion: int16(apiVersion), - ClientID: clientID, - Topic: topic, - APIKeys: make(map[int16]struct{}, len(apiKeys)), - } - for _, key := range apiKeys { - r.APIKeys[int16(key)] = struct{}{} - } - return r -} - -// CheckAPIKeyRole checks the apiKey value in the request, and returns true if -// it is allowed else false -func (r *Rule) CheckAPIKeyRole(kind int16) bool { - // wildcard expression - if len(r.APIKeys) == 0 { - return true - } - - // Check kind - _, ok := r.APIKeys[kind] - return ok -} - -// CheckAPIVersion returns true if 'apiVersion' is allowed -func (r *Rule) CheckAPIVersion(apiVersion int16) bool { - return r.APIVersion < 0 || apiVersion == r.APIVersion -} - -// CheckClientID returns true if 'clientID' is allowed -func (r *Rule) CheckClientID(clientID string) bool { - return r.ClientID == "" || clientID == r.ClientID -} - -// isTopicAPIKey returns true if kind is apiKey message type which contains a -// topic in its request. -func isTopicAPIKey(kind int16) bool { - switch kind { - case api.ProduceKey, - api.FetchKey, - api.OffsetsKey, - api.MetadataKey, - api.LeaderAndIsr, - api.StopReplica, - api.UpdateMetadata, - api.OffsetCommitKey, - api.OffsetFetchKey, - api.CreateTopicsKey, - api.DeleteTopicsKey, - api.DeleteRecordsKey, - api.OffsetForLeaderEpochKey, - api.AddPartitionsToTxnKey, - api.WriteTxnMarkersKey, - api.TxnOffsetCommitKey, - api.AlterReplicaLogDirsKey, - api.DescribeLogDirsKey, - api.CreatePartitionsKey: - - return true - } - return false -} - -// Matches returns true if Rule matches the request and and all required topics have matched. -func (r Rule) Matches(data interface{}) bool { - req, ok := data.(*RequestMessage) - if !ok { - logrus.Warningf("Matches() called with type other than Kafka RequestMessage: %v", data) - return false - } - - logrus.Debugf("Matching Kafka request %s against rule %v", req.String(), r) - - if !r.CheckAPIKeyRole(req.kind) { - return false - } - - if !r.CheckAPIVersion(req.version) { - return false - } - - if !r.CheckClientID(req.clientID) { - return false - } - - // Last step, check topic if applicable. - // Rule without a topic allows all topics and request types without topics - // are allowed regardless the rule's topic. - if r.Topic != "" && isTopicAPIKey(req.kind) { - // Rule has a topic constraint and the request type carries topics. - // - // Check it this rule's topic is in the request, but keep matching - // other rules (by returning false) even if this rule is satisfied - // if there are other topics in the request not matched yet. - // - // (req.topics is initialized with all the topics in the request - // before any rules are matched.) - if _, exists := req.topics[r.Topic]; exists { - delete(req.topics, r.Topic) - if len(req.topics) == 0 { - return true // all topics have matched - } - } - return false // more topic matches needed - } - - // All rule's constraints are satisfied - return true -} diff --git a/proxylib/kafka/kafkalib/policy_test.go b/proxylib/kafka/kafkalib/policy_test.go deleted file mode 100644 index 110583728..000000000 --- a/proxylib/kafka/kafkalib/policy_test.go +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package kafkalib - -import ( - "testing" - "time" - - "github.com/cilium/kafka/proto" - "github.com/stretchr/testify/require" - - "github.com/cilium/proxy/pkg/policy/api/kafka" -) - -type kafkaTestSuite struct{} - -var messages = make([]*proto.Message, 100) - -func setUpKafkaTestSuite(tb testing.TB) *kafkaTestSuite { - tb.Helper() - for i := range messages { - messages[i] = &proto.Message{ - Offset: int64(i), - Crc: uint32(i), - Key: nil, - Value: []byte(`Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur.`), - } - } - return &kafkaTestSuite{} -} - -// MatchesRule validates the Kafka request message against the provided list of -// rules. The function will return true if the policy allows the message, -// otherwise false is returned. -func (req *RequestMessage) MatchesRule(rules []Rule) bool { - for _, rule := range rules { - if rule.Matches(req) { - return true - } - } - return false -} - -func TestProduceRequest(c *testing.T) { - setUpKafkaTestSuite(c) - req := &proto.ProduceReq{ - CorrelationID: 241, - ClientID: "test", - Compression: proto.CompressionNone, - RequiredAcks: proto.RequiredAcksAll, - Timeout: time.Second, - Topics: []proto.ProduceReqTopic{ - { - Name: "foo", - Partitions: []proto.ProduceReqPartition{ - { - ID: 0, - Messages: messages, - }, - }, - }, - { - Name: "bar", - Partitions: []proto.ProduceReqPartition{ - { - ID: 0, - Messages: messages, - }, - }, - }, - }, - } - - reqMsg := RequestMessage{ - request: req, - } - - // empty rules should match nothing - reqMsg.setTopics() - require.False(c, reqMsg.MatchesRule([]Rule{})) - - // wildcard rule matches everything - reqMsg.setTopics() - require.True(c, reqMsg.MatchesRule([]Rule{{}})) - - reqMsg.setTopics() - require.False(c, reqMsg.MatchesRule([]Rule{ - NewRule(-1, nil, "", "foo"), - })) - - reqMsg.setTopics() - require.True(c, reqMsg.MatchesRule([]Rule{ - NewRule(-1, nil, "", "foo"), NewRule(-1, nil, "", "bar"), - })) - - reqMsg.setTopics() - require.False(c, reqMsg.MatchesRule([]Rule{ - NewRule(-1, nil, "", "foo"), NewRule(-1, nil, "", "baz"), - })) - - reqMsg.setTopics() - require.False(c, reqMsg.MatchesRule([]Rule{ - NewRule(-1, nil, "", "baz"), NewRule(-1, nil, "", "foo2"), - })) - - reqMsg.setTopics() - require.True(c, reqMsg.MatchesRule([]Rule{ - NewRule(-1, nil, "", "bar"), NewRule(-1, nil, "", "foo"), - })) - - reqMsg.setTopics() - require.True(c, reqMsg.MatchesRule([]Rule{ - NewRule(-1, nil, "", "bar"), NewRule(-1, nil, "", "foo"), NewRule(-1, nil, "", "baz"), - })) -} - -func TestUnknownRequest(t *testing.T) { - setUpKafkaTestSuite(t) - reqMsg := RequestMessage{kind: 18} // ApiVersions request - - // Empty rule should disallow - require.False(t, reqMsg.MatchesRule([]Rule{})) - - // Whitelisting of unknown message - rule1 := NewRule(-1, []int32{int32(kafka.MetadataKey)}, "", "") - rule2 := NewRule(-1, []int32{int32(kafka.APIVersionsKey)}, "", "") - require.True(t, reqMsg.MatchesRule([]Rule{rule1, rule2})) - - reqMsg = RequestMessage{kind: 19} - require.False(t, reqMsg.MatchesRule([]Rule{rule1, rule2})) -} diff --git a/proxylib/kafka/kafkalib/request.go b/proxylib/kafka/kafkalib/request.go deleted file mode 100644 index 873383abc..000000000 --- a/proxylib/kafka/kafkalib/request.go +++ /dev/null @@ -1,254 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package kafkalib - -import ( - "bytes" - "encoding/binary" - "encoding/json" - "fmt" - "io" - - "github.com/cilium/kafka/proto" - "github.com/sirupsen/logrus" -) - -// RequestMessage represents a Kafka request message -type RequestMessage struct { - kind int16 - version int16 - clientID string - rawMsg []byte - request interface{} - // Maintain a map of all topics in the request. We should - // allow the request only if all topics in the request are - // allowed by the rules. - topics map[string]struct{} -} - -// CorrelationID represents the correlation id as defined in the Kafka protocol -// specification -type CorrelationID uint32 - -// GetAPIKey returns the kind of Kafka request -func (req *RequestMessage) GetAPIKey() int16 { - return req.kind -} - -// GetRaw returns the raw Kafka request -func (req *RequestMessage) GetRaw() []byte { - return req.rawMsg -} - -// GetVersion returns the version Kafka request -func (req *RequestMessage) GetVersion() int16 { - return req.version -} - -// GetCorrelationID returns the Kafka request correlationID -func (req *RequestMessage) GetCorrelationID() CorrelationID { - if len(req.rawMsg) >= 12 { - return CorrelationID(binary.BigEndian.Uint32(req.rawMsg[8:12])) - } - - return CorrelationID(0) -} - -// SetCorrelationID modified the correlation ID of the Kafka request -func (req *RequestMessage) SetCorrelationID(id CorrelationID) { - if len(req.rawMsg) >= 12 { - binary.BigEndian.PutUint32(req.rawMsg[8:12], uint32(id)) - } -} - -func (req *RequestMessage) extractVersion() int16 { - return int16(binary.BigEndian.Uint16(req.rawMsg[6:8])) -} - -func (req *RequestMessage) extractClientID() string { - if req.version == 0 || len(req.rawMsg) < 14 { - return "" // 0 version has no client ID - } - // ref. https://kafka.apache.org/protocol#protocol_details - length := int16(binary.BigEndian.Uint16(req.rawMsg[12:14])) - if length <= 0 || len(req.rawMsg) < 14+int(length) { - return "" - } - return string(req.rawMsg[14 : 14+int(length)]) -} - -// String returns a human readable representation of the request message -func (req *RequestMessage) String() string { - b, err := json.Marshal(req.request) - if err != nil { - return err.Error() - } - - return fmt.Sprintf("apiKey=%d,apiVersion=%d,len=%d: %s", - req.kind, req.version, len(req.rawMsg), string(b)) -} - -// GetTopics returns the Kafka request list of topics -func (req *RequestMessage) GetTopics() []string { - if req.request == nil { - return nil - } - topics := make([]string, 0, len(req.topics)) - for topic := range req.topics { - topics = append(topics, topic) - } - return topics -} - -func (req *RequestMessage) setTopics() { - var topics []string - switch val := req.request.(type) { - case *proto.ProduceReq: - topics = produceTopics(val) - case *proto.FetchReq: - topics = fetchTopics(val) - case *proto.OffsetReq: - topics = offsetTopics(val) - case *proto.MetadataReq: - topics = metadataTopics(val) - case *proto.OffsetCommitReq: - topics = offsetCommitTopics(val) - case *proto.OffsetFetchReq: - topics = offsetFetchTopics(val) - } - req.topics = make(map[string]struct{}, len(topics)) - for _, topic := range topics { - req.topics[topic] = struct{}{} - } -} - -func produceTopics(req *proto.ProduceReq) []string { - topics := make([]string, len(req.Topics)) - for k, topic := range req.Topics { - topics[k] = topic.Name - } - return topics -} - -func fetchTopics(req *proto.FetchReq) []string { - topics := make([]string, len(req.Topics)) - for k, topic := range req.Topics { - topics[k] = topic.Name - } - return topics -} - -func offsetTopics(req *proto.OffsetReq) []string { - topics := make([]string, len(req.Topics)) - for k, topic := range req.Topics { - topics[k] = topic.Name - } - return topics -} - -func metadataTopics(req *proto.MetadataReq) []string { - topics := req.Topics - return topics -} - -func offsetCommitTopics(req *proto.OffsetCommitReq) []string { - topics := make([]string, len(req.Topics)) - for k, topic := range req.Topics { - topics[k] = topic.Name - } - return topics -} - -func offsetFetchTopics(req *proto.OffsetFetchReq) []string { - topics := make([]string, len(req.Topics)) - for k, topic := range req.Topics { - topics[k] = topic.Name - } - return topics -} - -// CreateResponse creates a response message based on the provided request -// message. The response will have the specified error code set in all topics -// and embedded partitions. -func (req *RequestMessage) CreateResponse(err error) (*ResponseMessage, error) { - switch val := req.request.(type) { - case *proto.ProduceReq: - return createProduceResponse(val, err) - case *proto.FetchReq: - return createFetchResponse(val, err) - case *proto.OffsetReq: - return createOffsetResponse(val, err) - case *proto.MetadataReq: - return createMetadataResponse(val, err) - case *proto.ConsumerMetadataReq: - return createConsumerMetadataResponse(val, err) - case *proto.OffsetCommitReq: - return createOffsetCommitResponse(val, err) - case *proto.OffsetFetchReq: - return createOffsetFetchResponse(val, err) - case nil: - return nil, fmt.Errorf("unsupported request API key %d", req.kind) - default: - // The switch cases above must correspond exactly to the switch cases - // in ReadRequest. - logrus.Panic(fmt.Sprintf("Kafka API key not handled: %d", req.kind)) - } - return nil, nil -} - -// CreateAuthErrorResponse creates Authorization error response message for 'req' -func (req *RequestMessage) CreateAuthErrorResponse() (*ResponseMessage, error) { - return req.CreateResponse(proto.ErrTopicAuthorizationFailed) -} - -// ReadRequest will read a Kafka request from an io.Reader and return the -// message or an error. -func ReadRequest(reader io.Reader) (*RequestMessage, error) { - req := &RequestMessage{} - var err error - - req.kind, req.rawMsg, err = proto.ReadReq(reader) - if err != nil { - return nil, err - } - - if len(req.rawMsg) < 12 { - return nil, fmt.Errorf("unexpected end of request (length < 12 bytes)") - } - req.version = req.extractVersion() - req.clientID = req.extractClientID() - - var nilSlice []byte - buf := bytes.NewBuffer(append(nilSlice, req.rawMsg...)) - - switch req.kind { - case proto.ProduceReqKind: - req.request, err = proto.ReadProduceReq(buf) - case proto.FetchReqKind: - req.request, err = proto.ReadFetchReq(buf) - case proto.OffsetReqKind: - req.request, err = proto.ReadOffsetReq(buf) - case proto.MetadataReqKind: - req.request, err = proto.ReadMetadataReq(buf) - case proto.ConsumerMetadataReqKind: - req.request, err = proto.ReadConsumerMetadataReq(buf) - case proto.OffsetCommitReqKind: - req.request, err = proto.ReadOffsetCommitReq(buf) - case proto.OffsetFetchReqKind: - req.request, err = proto.ReadOffsetFetchReq(buf) - default: - logrus.Debugf("Unknown Kafka request API key: %d in %s", req.kind, req.String()) - } - - if err != nil { - if logrus.IsLevelEnabled(logrus.DebugLevel) { - logrus.WithError(err).Debugf("Ignoring Kafka message %s due to parse error", req.String()) - } - return nil, err - } - - req.setTopics() - - return req, nil -} diff --git a/proxylib/kafka/kafkalib/response.go b/proxylib/kafka/kafkalib/response.go deleted file mode 100644 index fa2dd081a..000000000 --- a/proxylib/kafka/kafkalib/response.go +++ /dev/null @@ -1,304 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package kafkalib - -import ( - "encoding/binary" - "encoding/json" - "fmt" - "io" - - "github.com/cilium/kafka/proto" -) - -// ResponseMessage represents a Kafka response message. -type ResponseMessage struct { - rawMsg []byte - response interface{} -} - -// GetCorrelationID returns the Kafka request correlationID -func (res *ResponseMessage) GetCorrelationID() CorrelationID { - if len(res.rawMsg) >= 8 { - return CorrelationID(binary.BigEndian.Uint32(res.rawMsg[4:8])) - } - - return CorrelationID(0) -} - -// SetCorrelationID modified the correlation ID of the Kafka request -func (res *ResponseMessage) SetCorrelationID(id CorrelationID) { - if len(res.rawMsg) >= 8 { - binary.BigEndian.PutUint32(res.rawMsg[4:8], uint32(id)) - } -} - -// GetRaw returns the raw Kafka response -func (res *ResponseMessage) GetRaw() []byte { - return res.rawMsg -} - -// String returns a human readable representation of the response message -func (res *ResponseMessage) String() string { - b, err := json.Marshal(res.response) - if err != nil { - return err.Error() - } - return string(b) -} - -// ReadResponse will read a Kafka response from an io.Reader and return the -// message or an error. -func ReadResponse(reader io.Reader) (*ResponseMessage, error) { - rsp := &ResponseMessage{} - var err error - - _, rsp.rawMsg, err = proto.ReadResp(reader) - if err != nil { - return nil, err - } - - if len(rsp.rawMsg) < 6 { - return nil, - fmt.Errorf("unexpected end of response (length < 6 bytes)") - } - - return rsp, nil -} - -func createProduceResponse(req *proto.ProduceReq, err error) (*ResponseMessage, error) { - if req == nil { - return nil, fmt.Errorf("request is nil") - } - - resp := &proto.ProduceResp{ - CorrelationID: req.CorrelationID, - Topics: make([]proto.ProduceRespTopic, len(req.Topics)), - } - - for k, topic := range req.Topics { - resp.Topics[k] = proto.ProduceRespTopic{ - Name: topic.Name, - Partitions: make([]proto.ProduceRespPartition, len(topic.Partitions)), - } - - for k2, partition := range topic.Partitions { - resp.Topics[k].Partitions[k2] = proto.ProduceRespPartition{ - ID: partition.ID, - Err: err, - } - } - } - - b, err := resp.Bytes(req.Version) - if err != nil { - return nil, err - } - - return &ResponseMessage{ - response: resp, - rawMsg: b, - }, nil -} - -func createFetchResponse(req *proto.FetchReq, err error) (*ResponseMessage, error) { - if req == nil { - return nil, fmt.Errorf("request is nil") - } - - resp := &proto.FetchResp{ - CorrelationID: req.CorrelationID, - Topics: make([]proto.FetchRespTopic, len(req.Topics)), - } - - for k, topic := range req.Topics { - resp.Topics[k] = proto.FetchRespTopic{ - Name: topic.Name, - Partitions: make([]proto.FetchRespPartition, len(topic.Partitions)), - } - - for k2, partition := range topic.Partitions { - resp.Topics[k].Partitions[k2] = proto.FetchRespPartition{ - ID: partition.ID, - Err: err, - AbortedTransactions: nil, // nullable - } - } - } - - b, err := resp.Bytes(req.Version) - if err != nil { - return nil, err - } - - return &ResponseMessage{ - response: resp, - rawMsg: b, - }, nil -} - -func createOffsetResponse(req *proto.OffsetReq, err error) (*ResponseMessage, error) { - if req == nil { - return nil, fmt.Errorf("request is nil") - } - - resp := &proto.OffsetResp{ - CorrelationID: req.CorrelationID, - Topics: make([]proto.OffsetRespTopic, len(req.Topics)), - } - - for k, topic := range req.Topics { - resp.Topics[k] = proto.OffsetRespTopic{ - Name: topic.Name, - Partitions: make([]proto.OffsetRespPartition, len(topic.Partitions)), - } - - for k2, partition := range topic.Partitions { - resp.Topics[k].Partitions[k2] = proto.OffsetRespPartition{ - ID: partition.ID, - Err: err, - Offsets: make([]int64, 0), // Not nullable, so must never be nil. - } - } - } - - b, err := resp.Bytes(req.Version) - if err != nil { - return nil, err - } - - return &ResponseMessage{ - response: resp, - rawMsg: b, - }, nil -} - -func createMetadataResponse(req *proto.MetadataReq, err error) (*ResponseMessage, error) { - if req == nil { - return nil, fmt.Errorf("request is nil") - } - - var topics []proto.MetadataRespTopic - if req.Topics != nil { - topics = make([]proto.MetadataRespTopic, len(req.Topics)) - } - resp := &proto.MetadataResp{ - CorrelationID: req.CorrelationID, - Brokers: make([]proto.MetadataRespBroker, 0), // Not nullable, so must never be nil. - Topics: topics, - } - - for k, topic := range req.Topics { - resp.Topics[k] = proto.MetadataRespTopic{ - Name: topic, - Err: err, - Partitions: make([]proto.MetadataRespPartition, 0), // Not nullable, so must never be nil. - } - } - - b, err := resp.Bytes(req.Version) - if err != nil { - return nil, err - } - - return &ResponseMessage{ - response: resp, - rawMsg: b, - }, nil -} - -func createConsumerMetadataResponse(req *proto.ConsumerMetadataReq, err error) (*ResponseMessage, error) { - if req == nil { - return nil, fmt.Errorf("request is nil") - } - - resp := &proto.ConsumerMetadataResp{ - CorrelationID: req.CorrelationID, - Err: err, - } - - b, err := resp.Bytes(req.Version) - if err != nil { - return nil, err - } - - return &ResponseMessage{ - response: resp, - rawMsg: b, - }, nil -} - -func createOffsetCommitResponse(req *proto.OffsetCommitReq, err error) (*ResponseMessage, error) { - if req == nil { - return nil, fmt.Errorf("request is nil") - } - - resp := &proto.OffsetCommitResp{ - CorrelationID: req.CorrelationID, - Topics: make([]proto.OffsetCommitRespTopic, len(req.Topics)), - } - - for k, topic := range req.Topics { - resp.Topics[k] = proto.OffsetCommitRespTopic{ - Name: topic.Name, - Partitions: make([]proto.OffsetCommitRespPartition, len(topic.Partitions)), - } - - for k2, partition := range topic.Partitions { - resp.Topics[k].Partitions[k2] = proto.OffsetCommitRespPartition{ - ID: partition.ID, - Err: err, - } - } - } - - b, err := resp.Bytes(req.Version) - if err != nil { - return nil, err - } - - return &ResponseMessage{ - response: resp, - rawMsg: b, - }, nil -} - -func createOffsetFetchResponse(req *proto.OffsetFetchReq, err error) (*ResponseMessage, error) { - if req == nil { - return nil, fmt.Errorf("request is nil") - } - - var topics []proto.OffsetFetchRespTopic - if req.Topics != nil { - topics = make([]proto.OffsetFetchRespTopic, len(req.Topics)) - } - resp := &proto.OffsetFetchResp{ - CorrelationID: req.CorrelationID, - Topics: topics, - } - - for k, topic := range req.Topics { - resp.Topics[k] = proto.OffsetFetchRespTopic{ - Name: topic.Name, - Partitions: make([]proto.OffsetFetchRespPartition, len(topic.Partitions)), - } - - for k2, partition := range topic.Partitions { - resp.Topics[k].Partitions[k2] = proto.OffsetFetchRespPartition{ - ID: partition, - Err: err, - } - } - } - - b, err := resp.Bytes(req.Version) - if err != nil { - return nil, err - } - - return &ResponseMessage{ - response: resp, - rawMsg: b, - }, nil -} diff --git a/proxylib/kafka/parser.go b/proxylib/kafka/parser.go deleted file mode 100644 index 64b5271ba..000000000 --- a/proxylib/kafka/parser.go +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package kafka - -import ( - "encoding/binary" - - "github.com/sirupsen/logrus" - - cilium "github.com/cilium/proxy/go/cilium/api" - "github.com/cilium/proxy/proxylib/kafka/kafkalib" - . "github.com/cilium/proxy/proxylib/proxylib" -) - -const ( - parserName = "kafka" -) - -// KafkaRuleParser parses protobuf L7 rules to enforcement objects -// May panic -func KafkaRuleParser(rule *cilium.PortNetworkPolicyRule) []L7NetworkPolicyRule { - l7Rules := rule.GetKafkaRules() - if l7Rules == nil { - return nil - } - - allowRules := l7Rules.GetKafkaRules() - rules := make([]L7NetworkPolicyRule, 0, len(allowRules)) - for _, r := range allowRules { - rules = append(rules, kafkalib.NewRule(r.ApiVersion, r.ApiKeys, r.ClientId, r.Topic)) - } - return rules -} - -type KafkaParserFactory struct{} - -var kafkaParserFactory *KafkaParserFactory - -func init() { - logrus.Info("init(): Registering kafkaParserFactory") - RegisterParserFactory(parserName, kafkaParserFactory) - RegisterL7RuleParser(parserName, KafkaRuleParser) -} - -type KafkaParser struct { - connection *Connection -} - -func (pf *KafkaParserFactory) Create(connection *Connection) interface{} { - p := KafkaParser{connection: connection} - return &p -} - -func (p *KafkaParser) OnData(reply bool, reader *Reader) (OpType, int) { - length := reader.Length() - if length == 0 { - return NOP, 0 - } - - correlationID := int32(0) - framelength := 4 // account for the length field - lenbuf := make([]byte, 8) // Peek the first eight bytes - n, err := reader.PeekFull(lenbuf) - if err == nil { - framelength += int(binary.BigEndian.Uint32(lenbuf[:4])) - correlationID = int32(binary.BigEndian.Uint32(lenbuf[4:])) - } else { - // Need more data - return MORE, 8 - n - } - - if reply { - // Replies are always passed as-is. No need to parse them - // on top of the frame length and correlation ID. - p.connection.Log(cilium.EntryType_Response, - &cilium.LogEntry_Kafka{Kafka: &cilium.KafkaLogEntry{ - CorrelationId: correlationID, - }}) - return PASS, framelength - } - - // Ask for more if full frame has not been received yet - if length < framelength { - // Not enough data, ask for more and try again - return MORE, framelength - length - } - - req, err := kafkalib.ReadRequest(reader) - if err != nil { - logrus.WithError(err).Debug("Unable to parse Kafka request; closing Kafka connection") - p.connection.Log(cilium.EntryType_Denied, - &cilium.LogEntry_Kafka{Kafka: &cilium.KafkaLogEntry{ - CorrelationId: correlationID, - ErrorCode: kafkalib.ErrInvalidMessage, - }}) - return ERROR, int(ERROR_INVALID_FRAME_TYPE) - } - - logEntry := &cilium.LogEntry_Kafka{Kafka: &cilium.KafkaLogEntry{ - CorrelationId: correlationID, - ApiVersion: int32(req.GetVersion()), - ApiKey: int32(req.GetAPIKey()), - Topics: req.GetTopics(), - }} - if p.connection.Matches(req) { - p.connection.Log(cilium.EntryType_Request, logEntry) - return PASS, framelength - } - logEntry.Kafka.ErrorCode = kafkalib.ErrTopicAuthorizationFailed - - resp, err := req.CreateAuthErrorResponse() - if err != nil { - logrus.WithError(err).Debug("Unable to create Kafka response") - } else { - // inject response - p.connection.Inject(!reply, resp.GetRaw()) - } - - p.connection.Log(cilium.EntryType_Denied, logEntry) - return DROP, framelength -} diff --git a/proxylib/kafka/parser_test.go b/proxylib/kafka/parser_test.go deleted file mode 100644 index 1e7cc5058..000000000 --- a/proxylib/kafka/parser_test.go +++ /dev/null @@ -1,471 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package kafka - -import ( - "encoding/hex" - "testing" - - "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" - - "github.com/cilium/proxy/proxylib/accesslog" - "github.com/cilium/proxy/proxylib/proxylib" - "github.com/cilium/proxy/proxylib/test" -) - -type KafkaSuite struct { - logServer *test.AccessLogServer - ins *proxylib.Instance -} - -// Set up access log server and Library instance for all the test cases -func setUpKafkaSuite(tb testing.TB) *KafkaSuite { - logrus.SetLevel(logrus.DebugLevel) - s := &KafkaSuite{} - s.logServer = test.StartAccessLogServer("access_log.sock", 10) - require.NotNil(tb, s.logServer) - s.ins = proxylib.NewInstance("node1", accesslog.NewClient(s.logServer.Path)) - require.NotNil(tb, s.ins) - tb.Cleanup(func() { - s.logServer.Clear() - s.logServer.Close() - }) - return s -} - -func (s *KafkaSuite) checkAccessLogs(tb testing.TB, expPasses, expDrops int) { - passes, drops := s.logServer.Clear() - require.Equal(tb, expPasses, passes, "Unxpected number of passed access log messages") - require.Equal(tb, expDrops, drops, "Unxpected number of dropped access log messages") -} - -// util function used for Kafka tests, as we may have Kafka requests -// as hex strings -func hexData(tb testing.TB, dataHex ...string) [][]byte { - data := make([][]byte, 0, len(dataHex)) - for i := range dataHex { - dataRaw, err := hex.DecodeString(dataHex[i]) - require.NoError(tb, err) - data = append(data, dataRaw) - } - return data -} - -func TestKafkaOnDataNoHeader(t *testing.T) { - s := setUpKafkaSuite(t) - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "no-policy") - data := hexData(t, "") - conn.CheckOnDataOK(t, false, false, &data, []byte{}) - data = hexData(t, "00") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.MORE, 7) - data = hexData(t, "0000") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.MORE, 6) - data = hexData(t, "000001") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.MORE, 5) - data = hexData(t, "00000100") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.MORE, 4) - data = hexData(t, "00010000010203") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.MORE, 1) - data = hexData(t, "000100000102030405060708") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.MORE, 65536-8) -} - -var testMessage1 = "0000" // length = 42 (0x2a), first half - -var testMessage2 = "002a" + // length = 42 (0x2a), 2nd half - "0000" + // APIkey = 0 (Produce) - "0003" + // Version = 3 (KafkaV3) - "00010001" + // CorrelationID = 65537 - "0003414243" + // ClientID (string) "ABC" - "000144" + // TransactionalID (string) "D" - "0000" + // RequiredAcks = 0 - "000003" // Timeout = 1000 ms, first 3 bytes - -var testMessage3 = "E8" + // Timeout = 1000 ms, last byte - "00000002" + // Array length = 2 - "00024546" + // - TopicName (string) "EF" - "00000000" + // ProduceReqPartition array length = 0 - "00024748" + // - TopicName (string) "GH" - "00000000" // ProduceReqPartition array length = 0 - -var testMessage3Fail = "E8" + // Timeout = 1000 ms, last byte - "20000002" + // Array length = 0x20000002 (should cause failure - "00024546" + // - TopicName (string) "EF" - "00000000" + // ProduceReqPartition array length = 0 - "00024748" + // - TopicName (string) "GH" - "00000000" // ProduceReqPartition array length = 0 - -func TestKafkaOnDataSimpleHeaderMinimalPolicy(t *testing.T) { - s := setUpKafkaSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "face::feed" - endpoint_ips: "1.1.1.1" - endpoint_id: 2000 - ingress_per_port_policies: < - port: 80 - > - `}) - - data := hexData(t, testMessage1, testMessage2, testMessage3) - - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1000, 2000, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.PASS, 4+42) -} - -func TestKafkaOnDataInvalidMessage(t *testing.T) { - s := setUpKafkaSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2000 - ingress_per_port_policies: < - port: 80 - > - `}) - - data := hexData(t, testMessage1, testMessage2, testMessage3Fail) - - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1000, 2000, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.ERROR, int(proxylib.ERROR_INVALID_FRAME_TYPE)) - s.checkAccessLogs(t, 0, 1) -} - -func TestKafkaOnDataSimpleHeaderSimplePolicy(t *testing.T) { - s := setUpKafkaSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2000 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1000 - l7_proto: "kafka" - > - > - `}) - - data := hexData(t, testMessage1, testMessage2, testMessage3) - - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1000, 2000, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.PASS, 4+42) - s.checkAccessLogs(t, 1, 0) -} - -func TestKafkaOnDataSimpleHeaderWithPolicyDrop(t *testing.T) { - s := setUpKafkaSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2000 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1000 - l7_proto: "kafka" - kafka_rules: < - kafka_rules: < - api_version: -1 - topic: "EF" - > - > - > - > - `}) - - data := hexData(t, testMessage1, testMessage2, testMessage3, "0000") - - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1000, 2000, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - conn.CheckOnDataOK(t, false, false, &data, - // Error response: - []byte{0x0, 0x0, 0x0, 0x1c, // length - 0x0, 0x1, 0x0, 0x1, // Correlation ID (65537) - 0x0, 0x0, 0x0, 0x2, // 2 topics - 0x0, 0x2, 0x45, 0x46, // name: "EF" - 0x0, 0x0, 0x0, 0x0, // 0 partitions - 0x0, 0x2, 0x47, 0x48, // name: "GH" - 0x0, 0x0, 0x0, 0x0, // 0 partitions - 0x0, 0x0, 0x0, 0x0}, // ThrottleTime - proxylib.DROP, 4+42, - proxylib.MORE, 6) - s.checkAccessLogs(t, 0, 1) -} - -func TestKafkaOnDataSimpleHeaderWithPolicyAllow(t *testing.T) { - s := setUpKafkaSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2000 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1000 - l7_proto: "kafka" - kafka_rules: < - kafka_rules: < - api_version: -1 - topic: "EF" - > - kafka_rules: < - api_version: -1 - topic: "GH" - > - > - > - > - `}) - - data := hexData(t, testMessage1, testMessage2, testMessage3) - - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1000, 2000, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.PASS, 4+42) - s.checkAccessLogs(t, 1, 0) -} - -func TestKafkaOnDataSimpleHeaderWithClientIDAllow(t *testing.T) { - s := setUpKafkaSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2000 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1000 - l7_proto: "kafka" - kafka_rules: < - kafka_rules: < - api_version: -1 - topic: "EF" - client_id: "ABC" - > - kafka_rules: < - api_version: -1 - topic: "GH" - > - > - > - > - `}) - - data := hexData(t, testMessage1, testMessage2, testMessage3) - - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1000, 2000, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.PASS, 4+42) - s.checkAccessLogs(t, 1, 0) -} - -func TestKafkaOnDataSimpleHeaderWithClientID(t *testing.T) { - s := setUpKafkaSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2000 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1000 - l7_proto: "kafka" - kafka_rules: < - kafka_rules: < - api_version: -1 - client_id: "ABC" - > - > - > - > - `}) - - data := hexData(t, testMessage1, testMessage2, testMessage3) - - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1000, 2000, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.PASS, 4+42) - s.checkAccessLogs(t, 1, 0) -} - -func TestKafkaOnDataSimpleHeaderWithApiKeys(t *testing.T) { - s := setUpKafkaSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2000 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1000 - l7_proto: "kafka" - kafka_rules: < - kafka_rules: < - api_version: -1 - api_keys: 0 - client_id: "ABC" - > - > - > - > - `}) - - data := hexData(t, testMessage1, testMessage2, testMessage3) - - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1000, 2000, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.PASS, 4+42) - s.checkAccessLogs(t, 1, 0) -} - -func TestKafkaOnDataSimpleHeaderWithApiKeysMismatch(t *testing.T) { - s := setUpKafkaSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2000 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1000 - l7_proto: "kafka" - kafka_rules: < - kafka_rules: < - api_version: -1 - api_keys: 1 - client_id: "ABC" - > - > - > - > - `}) - - data := hexData(t, testMessage1, testMessage2, testMessage3) - - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1000, 2000, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - conn.CheckOnDataOK(t, false, false, &data, - // Error response: - []byte{0x0, 0x0, 0x0, 0x1c, // length - 0x0, 0x1, 0x0, 0x1, // Correlation ID (65537) - 0x0, 0x0, 0x0, 0x2, // 2 topics - 0x0, 0x2, 0x45, 0x46, // name: "EF" - 0x0, 0x0, 0x0, 0x0, // 0 partitions - 0x0, 0x2, 0x47, 0x48, // name: "GH" - 0x0, 0x0, 0x0, 0x0, // 0 partitions - 0x0, 0x0, 0x0, 0x0}, // ThrottleTime - proxylib.DROP, 4+42) - s.checkAccessLogs(t, 0, 1) -} - -func TestKafkaOnDataSimpleHeaderWithApiVersion(t *testing.T) { - s := setUpKafkaSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2000 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1000 - l7_proto: "kafka" - kafka_rules: < - kafka_rules: < - api_version: 3 - client_id: "ABC" - > - > - > - > - `}) - - data := hexData(t, testMessage1, testMessage2, testMessage3) - - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1000, 2000, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.PASS, 4+42) - s.checkAccessLogs(t, 1, 0) -} - -func TestKafkaOnDataSimpleHeaderWithApiVersionMismatch(t *testing.T) { - s := setUpKafkaSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2000 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1000 - l7_proto: "kafka" - kafka_rules: < - kafka_rules: < - api_version: 0 - client_id: "ABC" - > - > - > - > - `}) - - data := hexData(t, testMessage1, testMessage2, testMessage3) - - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1000, 2000, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - conn.CheckOnDataOK(t, false, false, &data, - // Error response: - []byte{0x0, 0x0, 0x0, 0x1c, // length - 0x0, 0x1, 0x0, 0x1, // Correlation ID (65537) - 0x0, 0x0, 0x0, 0x2, // 2 topics - 0x0, 0x2, 0x45, 0x46, // name: "EF" - 0x0, 0x0, 0x0, 0x0, // 0 partitions - 0x0, 0x2, 0x47, 0x48, // name: "GH" - 0x0, 0x0, 0x0, 0x0, // 0 partitions - 0x0, 0x0, 0x0, 0x0}, // ThrottleTime - proxylib.DROP, 4+42) - s.checkAccessLogs(t, 0, 1) -} - -func TestKafkaOnDataSimpleHeaderWithClientIDDeny(t *testing.T) { - s := setUpKafkaSuite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2000 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1000 - l7_proto: "kafka" - kafka_rules: < - kafka_rules: < - api_version: -1 - topic: "EF" - client_id: "ABCD" - > - kafka_rules: < - api_version: -1 - topic: "GH" - > - > - > - > - `}) - - data := hexData(t, testMessage1, testMessage2, testMessage3) - - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1000, 2000, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - conn.CheckOnDataOK(t, false, false, &data, - // Error response: - []byte{0x0, 0x0, 0x0, 0x1c, // length - 0x0, 0x1, 0x0, 0x1, // Correlation ID (65537) - 0x0, 0x0, 0x0, 0x2, // 2 topics - 0x0, 0x2, 0x45, 0x46, // name: "EF" - 0x0, 0x0, 0x0, 0x0, // 0 partitions - 0x0, 0x2, 0x47, 0x48, // name: "GH" - 0x0, 0x0, 0x0, 0x0, // 0 partitions - 0x0, 0x0, 0x0, 0x0}, // ThrottleTime - proxylib.DROP, 4+42) - s.checkAccessLogs(t, 0, 1) -} - -func TestKafkaOnDataResponse(t *testing.T) { - s := setUpKafkaSuite(t) - data := [][]byte{ - {0x0, 0x0, 0x0, 0x1c}, // length - {0x0, 0x1, 0x0, 0x1}, // Correlation ID (65537) - {0x0, 0x0, 0x0, 0x2}, // 2 topics - {0x0, 0x2, 0x45, 0x46, // name: "EF" - 0x0, 0x0, 0x0, 0x0}, // 0 partitions - {0x0, 0x2, 0x47, 0x48, // name: "GH" - 0x0, 0x0, 0x0, 0x0}, // 0 partitions - {0x0, 0x0, 0x0, 0x0}, // ThrottleTime - } - - conn := s.ins.CheckNewConnectionOK(t, "kafka", true, 1000, 2000, "1.1.1.1:34567", "10.0.0.2:80", "") - conn.CheckOnDataOK(t, true, false, &data, []byte{}, proxylib.PASS, 4+28) - s.checkAccessLogs(t, 1, 0) -} diff --git a/proxylib/libcilium.h b/proxylib/libcilium.h deleted file mode 100644 index 181b3466b..000000000 --- a/proxylib/libcilium.h +++ /dev/null @@ -1,135 +0,0 @@ -/* Code generated by cmd/cgo; DO NOT EDIT. */ - -/* package github.com/cilium/proxy/proxylib */ - - -#line 1 "cgo-builtin-export-prolog" - -#include - -#ifndef GO_CGO_EXPORT_PROLOGUE_H -#define GO_CGO_EXPORT_PROLOGUE_H - -#ifndef GO_CGO_GOSTRING_TYPEDEF -typedef struct { const char *p; ptrdiff_t n; } _GoString_; -extern size_t _GoStringLen(_GoString_ s); -extern const char *_GoStringPtr(_GoString_ s); -#endif - -#endif - -/* Start of preamble from import "C" comments. */ - - -#line 9 "proxylib.go" - -#include "types.h" - -#line 1 "cgo-generated-wrapper" - - -/* End of preamble from import "C" comments. */ - - -/* Start of boilerplate cgo prologue. */ -#line 1 "cgo-gcc-export-header-prolog" - -#ifndef GO_CGO_PROLOGUE_H -#define GO_CGO_PROLOGUE_H - -typedef signed char GoInt8; -typedef unsigned char GoUint8; -typedef short GoInt16; -typedef unsigned short GoUint16; -typedef int GoInt32; -typedef unsigned int GoUint32; -typedef long long GoInt64; -typedef unsigned long long GoUint64; -typedef GoInt64 GoInt; -typedef GoUint64 GoUint; -typedef size_t GoUintptr; -typedef float GoFloat32; -typedef double GoFloat64; -#ifdef _MSC_VER -#if !defined(__cplusplus) || _MSVC_LANG <= 201402L -#include -typedef _Fcomplex GoComplex64; -typedef _Dcomplex GoComplex128; -#else -#include -typedef std::complex GoComplex64; -typedef std::complex GoComplex128; -#endif -#else -typedef float _Complex GoComplex64; -typedef double _Complex GoComplex128; -#endif - -/* - static assertion to make sure the file is being used on architecture - at least with matching size of GoInt. -*/ -typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1]; - -#ifndef GO_CGO_GOSTRING_TYPEDEF -typedef _GoString_ GoString; -#endif -typedef void *GoMap; -typedef void *GoChan; -typedef struct { void *t; void *v; } GoInterface; -typedef struct { void *data; GoInt len; GoInt cap; } GoSlice; - -#endif - -/* End of boilerplate cgo prologue. */ - -#ifdef __cplusplus -extern "C" { -#endif - - -// OnNewConnection is used to register a new connection of protocol 'proto'. -// Note that the 'origBuf' and replyBuf' type '*[]byte' corresponds to 'InjectBuf' type, but due to -// cgo export restrictions we can't use the go type in the prototype. -// -extern FilterResult OnNewConnection(GoUint64 instanceId, GoString proto, GoUint64 connectionId, GoUint8 ingress, GoUint32 srcId, GoUint32 dstId, GoString srcAddr, GoString dstAddr, GoString policyName, GoSlice* origBuf, GoSlice* replyBuf); - -// Each connection is assumed to be called from a single thread, so accessing connection metadata -// does not need protection. -// -// OnData gets all the unparsed data the datapath has received so far. The data is provided to the parser -// associated with the connection, and the parser is expected to find if the data frame contains enough data -// to make a PASS/DROP decision for the whole data frame. Note that the whole data frame need not be received, -// if the decision including the length of the data frame in bytes can be determined based on the beginning of -// the data frame only (e.g., headers including the length of the data frame). The parser returns a decision -// with the number of bytes on which the decision applies. If more data is available, then the parser will be -// called again with the remaining data. Parser needs to return MORE if a decision can't be made with -// the available data, including the minimum number of additional bytes that is needed before the parser is -// called again. -// -// The parser can also inject at arbitrary points in the data stream. This is indecated by an INJECT operation -// with the number of bytes to be injected. The actual bytes to be injected are provided via an Inject() -// callback prior to returning the INJECT operation. The Inject() callback operates on a limited size buffer -// provided by the datapath, and multiple INJECT operations may be needed to inject large amounts of data. -// Since we get the data on one direction at a time, any frames to be injected in the reverse direction -// are placed in the reverse direction buffer, from where the datapath injects the data before calling -// us again for the reverse direction input. -// -extern FilterResult OnData(GoUint64 connectionId, GoUint8 reply, GoUint8 endStream, GoSlice* data, GoSlice* filterOps); - -// Make this more general connection event callback -// -extern void Close(GoUint64 connectionId); - -// OpenModule is called before any other APIs. -// Called concurrently by different filter instances. -// Returns a library instance ID that must be passed to all other API calls. -// Calls with the same parameters will return the same instance. -// Zero return value indicates an error. -// -extern GoUint64 OpenModule(GoSlice params, GoUint8 debug); -extern void CloseModule(GoUint64 id); - -#ifdef __cplusplus -} -#endif diff --git a/proxylib/libcilium/helpers_test.go b/proxylib/libcilium/helpers_test.go deleted file mode 100644 index 7370ff5c9..000000000 --- a/proxylib/libcilium/helpers_test.go +++ /dev/null @@ -1,133 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package libcilium - -// These helpers must be defined in the main package so that the exported shared library functions -// can be called, as the C types used in the prototypes are only available from within the main -// package. -// -// These can not be defined in '_test.go' files, as Go test is not compatible with Cgo. - -import ( - "testing" - - . "github.com/cilium/proxy/proxylib/proxylib" -) - -func numConnections() int { - mutex.Lock() - defer mutex.Unlock() - return len(connections) -} - -func checkConnectionCount(t *testing.T, expConns int) { - t.Helper() - nConns := numConnections() - if nConns != expConns { - t.Errorf("Number of connections does not match (have %d, but should be %d)", nConns, expConns) - } -} - -func checkConnections(t *testing.T, res, expected FilterResult, expConns int) { - t.Helper() - if res != expected { - t.Errorf("OnNewConnection(): Invalid result, have %s, expected %s", res.Error(), expected.Error()) - } - checkConnectionCount(t, expConns) -} - -func CheckOnNewConnection(t *testing.T, instanceId uint64, proto string, connectionId uint64, ingress bool, srcId, dstId uint32, srcAddr, dstAddr, policyName string, bufSize int, expResult FilterResult, expNumConnections int) *byte { - t.Helper() - origBuf := make([]byte, 0, bufSize) - replyBuf := make([]byte, 1, bufSize) - replyBufAddr := &replyBuf[0] - replyBuf = replyBuf[:0] // make the buffer empty again - - res := FilterResult(OnNewConnection(instanceId, proto, connectionId, ingress, srcId, dstId, srcAddr, dstAddr, policyName, &origBuf, &replyBuf)) - checkConnections(t, res, expResult, expNumConnections) - - return replyBufAddr -} - -func CheckClose(t *testing.T, connectionId uint64, replyBufAddr *byte, n int) { - t.Helper() - checkConnectionCount(t, n) - - // Find the connection - mutex.Lock() - connection, ok := connections[connectionId] - mutex.Unlock() - if !ok { - t.Errorf("OnData(): Connection %d not found!", connectionId) - } else if replyBufAddr != nil && len(*connection.ReplyBuf) > 0 && replyBufAddr != &(*connection.ReplyBuf)[0] { - t.Error("OnData(): Reply injection buffer reallocated while it must not be!") - } - - Close(connectionId) - - checkConnectionCount(t, n-1) -} - -type ExpFilterOp struct { - op OpType - n_bytes int -} - -func checkOps(ops [][2]int64, exp []ExpFilterOp) bool { - if len(ops) != len(exp) { - return false - } else { - for i, op := range ops { - if op[0] != int64(exp[i].op) || op[1] != int64(exp[i].n_bytes) { - return false - } - } - } - return true -} - -func checkBuf(t *testing.T, buf InjectBuf, expected string) { - t.Helper() - if len(*buf) < len(expected) { - t.Log("Inject buffer too small, data truncated") - expected = expected[:len(*buf)] // truncate to buffer length - } - if string(*buf) != expected { - t.Errorf("OnData(): Expected inject buffer to be %s, buf have: %s", expected, *buf) - } -} - -func checkOnData(t *testing.T, res, expected FilterResult, ops [][2]int64, expOps []ExpFilterOp) { - t.Helper() - if res != expected { - t.Errorf("OnData(): Invalid result, have %s, expected %s", res.Error(), expected.Error()) - } - if !checkOps(ops, expOps) { - t.Errorf("OnData(): Unexpected filter operations: %v, expected %v", ops, expOps) - } -} - -func CheckOnData(t *testing.T, connectionId uint64, reply, endStream bool, data *[][]byte, expOps []ExpFilterOp, expResult FilterResult, expReplyBuf string) { - t.Helper() - - // Find the connection - mutex.Lock() - connection, ok := connections[connectionId] - mutex.Unlock() - if !ok && expResult != UNKNOWN_CONNECTION { - t.Errorf("OnData(): Connection %d not found!", connectionId) - } - - ops := make([][2]int64, 0, 1+len(expOps)*2) - - res := FilterResult(OnData(connectionId, reply, endStream, data, &ops)) - - checkOnData(t, res, expResult, ops, expOps) - - if ok { - replyBuf := connection.ReplyBuf - checkBuf(t, replyBuf, expReplyBuf) - *replyBuf = (*replyBuf)[:0] // make empty again - } -} diff --git a/proxylib/libcilium/proxylib.go b/proxylib/libcilium/proxylib.go deleted file mode 100644 index 6ee1e29b9..000000000 --- a/proxylib/libcilium/proxylib.go +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package libcilium - -import ( - "sync" - - "github.com/sirupsen/logrus" - - "github.com/cilium/proxy/proxylib/accesslog" - _ "github.com/cilium/proxy/proxylib/cassandra" - _ "github.com/cilium/proxy/proxylib/kafka" - _ "github.com/cilium/proxy/proxylib/memcached" - "github.com/cilium/proxy/proxylib/npds" - "github.com/cilium/proxy/proxylib/proxylib" - _ "github.com/cilium/proxy/proxylib/r2d2" - _ "github.com/cilium/proxy/proxylib/testparsers" -) - -var ( - // mutex protects connections - mutex sync.RWMutex - // Key uint64 is a connection ID allocated by Envoy, practically a monotonically increasing number - connections map[uint64]*proxylib.Connection = make(map[uint64]*proxylib.Connection) -) - -// Copy value string from C-memory to Go-memory. -// Go strings are immutable, but byte slices are not. Converting to a byte slice will thus -// copy the memory. -func strcpy(str string) string { - return string(([]byte(str))[0:]) -} - -func OnNewConnection(instanceId uint64, proto string, connectionId uint64, ingress bool, srcId, dstId uint32, srcAddr, dstAddr, policyName string, origBuf, replyBuf *[]byte) proxylib.FilterResult { - instance := proxylib.FindInstance(instanceId) - if instance == nil { - return proxylib.INVALID_INSTANCE - } - - err, conn := proxylib.NewConnection(instance, strcpy(proto), connectionId, ingress, srcId, dstId, strcpy(srcAddr), strcpy(dstAddr), strcpy(policyName), origBuf, replyBuf) - if err == nil { - mutex.Lock() - connections[connectionId] = conn - mutex.Unlock() - return proxylib.OK - } - if res, ok := err.(proxylib.FilterResult); ok { - return res - } - return proxylib.UNKNOWN_ERROR -} - -func OnData(connectionId uint64, reply, endStream bool, data *[][]byte, filterOps *[][2]int64) proxylib.FilterResult { - // Find the connection - mutex.RLock() - connection, ok := connections[connectionId] - mutex.RUnlock() - if !ok { - return proxylib.UNKNOWN_CONNECTION - } - - return connection.OnData(reply, endStream, data, filterOps) -} - -func Close(connectionId uint64) { - mutex.Lock() - delete(connections, connectionId) - mutex.Unlock() -} - -func OpenModule(params [][2]string, debug bool) uint64 { - var accessLogPath, xdsPath, nodeID string - for i := range params { - key := params[i][0] - value := strcpy(params[i][1]) - - switch key { - case "access-log-path": - accessLogPath = value - case "xds-path": - xdsPath = value - case "node-id": - nodeID = value - default: - return 0 - } - } - - if debug { - mutex.Lock() - logrus.SetLevel(logrus.DebugLevel) - mutex.Unlock() - } - // Copy strings from C-memory to Go-memory so that the string remains valid - // also after this function returns - return proxylib.OpenInstance(nodeID, xdsPath, npds.NewClient, accessLogPath, accesslog.NewClient) -} - -func CloseModule(id uint64) { - proxylib.CloseInstance(id) -} diff --git a/proxylib/libcilium/proxylib_memcached_test.go b/proxylib/libcilium/proxylib_memcached_test.go deleted file mode 100644 index a1a2a1b22..000000000 --- a/proxylib/libcilium/proxylib_memcached_test.go +++ /dev/null @@ -1,718 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package libcilium - -import ( - "fmt" - "testing" - - _ "github.com/cilium/proxy/proxylib/memcached" - binarymemcache "github.com/cilium/proxy/proxylib/memcached/binary" - textmemcache "github.com/cilium/proxy/proxylib/memcached/text" - "github.com/cilium/proxy/proxylib/proxylib" - "github.com/cilium/proxy/proxylib/test" -) - -var setHelloText = []byte("set key 0 0 5\r\nhello\r\n") - -var getKeysText = []byte("get key1 key2 key3\r\n") -var gatKeysText = []byte("gat 5 key1 key2 key3\r\n") -var getResponse = []byte( - "VALUE key3 0 4\r\n" + - "xDDD\r\n" + - "VALUE key4 0 3\r\n" + - "xDD\r\n" + - "END\r\n") - -var deleteText = []byte("delete key\r\n") -var incrText = []byte("incr key 5\r\n") -var touchText = []byte("touch key 55\r\n") -var slabsText = []byte("slabs automove 1\r\n") -var okText = []byte("OK\r\n") -var lruCrawlerText = []byte("lru_crawler metadump all\r\n") -var statsText = []byte("stats\r\n") -var flushAllText = []byte("flush_all 15\r\n") -var watchText = []byte("watch mutations\r\n") - -var watchReply = []byte( - "OK\r\n" + - "ts=1538135970.404892 gid=5 type=item_store key=key3 status=stored cmd=set ttl=500 clsid=1\r\n" + - "ts=1538135970.404898 gid=6 type=item_store key=key4 status=stored cmd=set ttl=500 clsid=1\r\n" + - "ts=1538135974.340708 gid=7 type=item_store key=key3 status=stored cmd=set ttl=500 clsid=1\r\n" + - "ts=1538135974.340714 gid=8 type=item_store key=key4 status=stored cmd=set ttl=500 clsid=1\r\n" + - "ts=1538135976.436863 gid=9 type=item_store key=key3 status=stored cmd=set ttl=500 clsid=1\r\n") - -var lruCrawlerResponse = []byte( - "key=key3 exp=1538047402 la=1538046902 cas=1 fetch=no cls=1 size=67\r\n" + - "key=key4 exp=1538047402 la=1538046902 cas=2 fetch=no cls=1 size=66\r\n" + - "END\r\n") - -var statsResponse = []byte( - "STAT evictions 0\r\n" + - "STAT reclaimed 2\r\n" + - "STAT crawler_reclaimed\r\n" + - "STAT crawler_items_checked 18\r\n" + - "STAT lrutail_reflocked 0\r\n" + - "STAT moves_to_cold 6\r\n" + - "STAT moves_to_warm 0\r\n" + - "STAT moves_within_lru 0\r\n" + - "STAT direct_reclaims 0\r\n" + - "STAT lru_bumps_dropped 0\r\n" + - "END\r\n") - -var notFound = []byte("NOT_FOUND\r\n") - -var stored = []byte("STORED\r\n") - -// binary packets -var getHello = []byte{ - 128, 0, 0, 5, - 0, 0, 0, 0, - 0, 0, 0, 5, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 'H', 'e', 'l', 'l', - 'o', -} - -var getHelloResp = []byte{ - 129, 0, 0, 0, - 4, 0, 0, 0, - 0, 0, 0, 9, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 'W', 'o', 'r', 'l', - 'd', -} - -var setHello = []byte{ - 128, 1, 0, 5, - 8, 0, 0, 0, - 0, 0, 0, 18, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 'H', 'e', 'l', 'l', - 'o', 'W', 'o', 'r', - 'l', 'd', -} - -func TestMemcache(t *testing.T) { - for _, tc := range append(textTestCases, binaryTestCases...) { - t.Run(tc.name, func(t *testing.T) { - - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, false) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - insertPolicyText(t, mod, "1", []string{fmt.Sprintf(` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "memcache" - l7_rules: < - l7_allow_rules: < -%s - > - > - > - > - `, tc.policy)}) - - buf := CheckOnNewConnection(t, mod, "memcache", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", - 30, proxylib.OK, 1) - - tc.onDataChecks(t) - - CheckClose(t, 1, buf, 1) - }) - } -} - -type testCase struct { - name string - policy string - onDataChecks func(*testing.T) -} - -var textTestCases = []testCase{ - { - "text set pass", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "set" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{setHelloText}, []ExpFilterOp{ - {proxylib.PASS, len(setHelloText)}, {proxylib.MORE, 2}, - }, proxylib.OK, "") - - CheckOnData(t, 1, true, false, &[][]byte{stored}, []ExpFilterOp{ - {proxylib.PASS, len(stored)}, - }, proxylib.OK, "") - }, - }, - { - "text set drop", - ` rule: < - key: "keyExact" - value: "trolo" - > - rule: < - key: "command" - value: "set" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{setHelloText}, []ExpFilterOp{ - {proxylib.DROP, len(setHelloText)}, {proxylib.MORE, 2}, - }, proxylib.OK, string(textmemcache.DeniedMsg)) - }, - }, - { - "text get pass", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "get" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{getKeysText, getKeysText}, []ExpFilterOp{ - {proxylib.PASS, len(getKeysText)}, {proxylib.PASS, len(getKeysText)}, {proxylib.MORE, 2}, - }, proxylib.OK, "") - CheckOnData(t, 1, true, false, &[][]byte{getResponse, getResponse}, []ExpFilterOp{ - {proxylib.PASS, len(getResponse)}, {proxylib.PASS, len(getResponse)}, - }, proxylib.OK, "") - }, - }, - { - "text get more", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "get" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{getResponse[:5]}, []ExpFilterOp{ - {proxylib.MORE, 2}, - }, proxylib.OK, "") - }, - }, - { - "text get drop", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "set" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{getKeysText}, []ExpFilterOp{ - {proxylib.DROP, len(getKeysText)}, {proxylib.MORE, 2}, - }, proxylib.OK, string(textmemcache.DeniedMsg)) - }, - }, - { - "text gat pass", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "gat" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{gatKeysText, gatKeysText}, []ExpFilterOp{ - {proxylib.PASS, len(gatKeysText)}, {proxylib.PASS, len(gatKeysText)}, {proxylib.MORE, 2}, - }, proxylib.OK, "") - CheckOnData(t, 1, true, false, &[][]byte{getResponse, getResponse}, []ExpFilterOp{ - {proxylib.PASS, len(getResponse)}, {proxylib.PASS, len(getResponse)}, - }, proxylib.OK, "") - }, - }, - { - "text gat more", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "gat" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{getResponse[:5]}, []ExpFilterOp{ - {proxylib.MORE, 2}, - }, proxylib.OK, "") - }, - }, - { - "text gat drop", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "set" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{gatKeysText}, []ExpFilterOp{ - {proxylib.DROP, len(gatKeysText)}, {proxylib.MORE, 2}, - }, proxylib.OK, string(textmemcache.DeniedMsg)) - }, - }, - { - "text delete pass", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "delete" - > - `, - func(t *testing.T) { - - CheckOnData(t, 1, false, false, &[][]byte{deleteText}, []ExpFilterOp{ - {proxylib.PASS, len(deleteText)}, {proxylib.MORE, 2}, - }, proxylib.OK, "") - - CheckOnData(t, 1, true, false, &[][]byte{notFound}, []ExpFilterOp{ - {proxylib.PASS, len(notFound)}, - }, proxylib.OK, "") - }, - }, - { - "text delete drop", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "set" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{deleteText}, []ExpFilterOp{ - {proxylib.DROP, len(deleteText)}, {proxylib.MORE, 2}, - }, proxylib.OK, string(textmemcache.DeniedMsg)) - }, - }, - { - "text incr pass", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "incr" - > - `, - func(t *testing.T) { - - CheckOnData(t, 1, false, false, &[][]byte{incrText}, []ExpFilterOp{ - {proxylib.PASS, len(incrText)}, {proxylib.MORE, 2}, - }, proxylib.OK, "") - - CheckOnData(t, 1, true, false, &[][]byte{notFound}, []ExpFilterOp{ - {proxylib.PASS, len(notFound)}, - }, proxylib.OK, "") - }, - }, - { - "text incr drop", - ` rule: < - key: "keyExact" - value: "otherKey" - > - rule: < - key: "command" - value: "incr" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{incrText}, []ExpFilterOp{ - {proxylib.DROP, len(incrText)}, {proxylib.MORE, 2}, - }, proxylib.OK, string(textmemcache.DeniedMsg)) - }, - }, - { - "text touch pass", - ` rule: < - key: "keyExact" - value: "key" - > - rule: < - key: "command" - value: "touch" - > - `, - func(t *testing.T) { - - CheckOnData(t, 1, false, false, &[][]byte{touchText}, []ExpFilterOp{ - {proxylib.PASS, len(touchText)}, {proxylib.MORE, 2}, - }, proxylib.OK, "") - - CheckOnData(t, 1, true, false, &[][]byte{notFound}, []ExpFilterOp{ - {proxylib.PASS, len(notFound)}, - }, proxylib.OK, "") - }, - }, - { - "text touch drop", - ` rule: < - key: "keyExact" - value: "otherKey" - > - rule: < - key: "command" - value: "touch" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{touchText}, []ExpFilterOp{ - {proxylib.DROP, len(touchText)}, {proxylib.MORE, 2}, - }, proxylib.OK, string(textmemcache.DeniedMsg)) - }, - }, - { - "text slabs pass", - ` rule: < - key: "command" - value: "slabs" - > - `, - func(t *testing.T) { - - CheckOnData(t, 1, false, false, &[][]byte{slabsText}, []ExpFilterOp{ - {proxylib.PASS, len(slabsText)}, {proxylib.MORE, 2}, - }, proxylib.OK, "") - - CheckOnData(t, 1, true, false, &[][]byte{okText}, []ExpFilterOp{ - {proxylib.PASS, len(okText)}, - }, proxylib.OK, "") - }, - }, - { - "text slabs drop", - ` rule: < - key: "keyExact" - value: "otherKey" - > - rule: < - key: "command" - value: "touch" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{slabsText}, []ExpFilterOp{ - {proxylib.DROP, len(slabsText)}, {proxylib.MORE, 2}, - }, proxylib.OK, string(textmemcache.DeniedMsg)) - }, - }, - { - "text lru_crawler response req more and pass", - ` rule: < - key: "command" - value: "lru_crawler" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{lruCrawlerText}, []ExpFilterOp{ - {proxylib.PASS, len(lruCrawlerText)}, {proxylib.MORE, 2}, - }, proxylib.OK, "") - - CheckOnData(t, 1, true, false, &[][]byte{lruCrawlerResponse[:5]}, []ExpFilterOp{ - {proxylib.MORE, 2}, - }, proxylib.OK, "") - CheckOnData(t, 1, true, false, &[][]byte{lruCrawlerResponse}, []ExpFilterOp{ - {proxylib.PASS, len(lruCrawlerResponse)}, - }, proxylib.OK, "") - }, - }, - { - "text stats response req more and pass", - ` rule: < - key: "command" - value: "stats" - > - `, - func(t *testing.T) { - - CheckOnData(t, 1, false, false, &[][]byte{statsText}, []ExpFilterOp{ - {proxylib.PASS, len(statsText)}, {proxylib.MORE, 2}, - }, proxylib.OK, "") - - CheckOnData(t, 1, true, false, &[][]byte{statsResponse[:5]}, []ExpFilterOp{ - {proxylib.MORE, 2}, - }, proxylib.OK, "") - CheckOnData(t, 1, true, false, &[][]byte{statsResponse}, []ExpFilterOp{ - {proxylib.PASS, len(statsResponse)}, - }, proxylib.OK, "") - }, - }, - { - "text flush_all pass", - ` rule: < - key: "command" - value: "flush_all" - > - `, - func(t *testing.T) { - - CheckOnData(t, 1, false, false, &[][]byte{flushAllText}, []ExpFilterOp{ - {proxylib.PASS, len(flushAllText)}, {proxylib.MORE, 2}, - }, proxylib.OK, "") - - }, - }, - { - "text flush_all denied", - ` rule: < - key: "command" - value: "get" - > - `, - func(t *testing.T) { - - CheckOnData(t, 1, false, false, &[][]byte{flushAllText}, []ExpFilterOp{ - {proxylib.DROP, len(flushAllText)}, {proxylib.MORE, 2}, - }, proxylib.OK, string(textmemcache.DeniedMsg)) - - }, - }, - { - "text watch passed", - ` rule: < - key: "command" - value: "watch" - > - `, - func(t *testing.T) { - - CheckOnData(t, 1, false, false, &[][]byte{watchText}, []ExpFilterOp{ - {proxylib.PASS, len(watchText)}, {proxylib.MORE, 2}, - }, proxylib.OK, "") - - CheckOnData(t, 1, true, false, &[][]byte{watchReply}, []ExpFilterOp{ - {proxylib.PASS, 4}, {proxylib.PASS, 91}, {proxylib.PASS, 91}, {proxylib.PASS, 91}, {proxylib.PASS, 91}, {proxylib.PASS, 91}, - }, proxylib.OK, "") - }, - }, - { - "text partial linefeed", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "set" - > - `, - func(t *testing.T) { - - CheckOnData(t, 1, false, false, &[][]byte{getKeysText[:len(getKeysText)-1]}, []ExpFilterOp{ - {proxylib.MORE, 1}, - }, proxylib.OK, "") - }, - }, - { - "text set pass on empty rule", - "", - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{setHelloText}, []ExpFilterOp{ - {proxylib.PASS, len(setHelloText)}, {proxylib.MORE, 2}, - }, proxylib.OK, "") - - CheckOnData(t, 1, true, false, &[][]byte{stored}, []ExpFilterOp{ - {proxylib.PASS, len(stored)}, - }, proxylib.OK, "") - }, - }, -} - -var binaryTestCases = []testCase{ - { - "bin get pass exact key", - ` rule: < - key: "keyExact" - value: "Hello" - > - rule: < - key: "command" - value: "get" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{getHello}, []ExpFilterOp{ - {proxylib.PASS, len(getHello)}, {proxylib.MORE, 24}, - }, proxylib.OK, "") - }, - }, - { - "bin get pass prefix key", - ` rule: < - key: "keyPrefix" - value: "Hell" - > - rule: < - key: "command" - value: "get" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{getHello}, []ExpFilterOp{ - {proxylib.PASS, len(getHello)}, {proxylib.MORE, 24}, - }, proxylib.OK, "") - }, - }, - { - "bin get pass regex key", - ` rule: < - key: "keyRegex" - value: "^.el.o$" - > - rule: < - key: "command" - value: "get" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{getHello}, []ExpFilterOp{ - {proxylib.PASS, len(getHello)}, {proxylib.MORE, 24}, - }, proxylib.OK, "") - }, - }, - { - "bin get drop", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "set" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{getHello}, []ExpFilterOp{ - {proxylib.DROP, len(getHello)}, {proxylib.MORE, 24}, - }, proxylib.OK, string(binarymemcache.DeniedMsgBase)) - }, - }, - { - "bin get more", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "get" - > - `, - func(t *testing.T) { - data := getHello[:10] - CheckOnData(t, 1, false, false, &[][]byte{data}, []ExpFilterOp{{proxylib.MORE, 14}}, proxylib.OK, "") - }, - }, - { - "bin get split", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "get" - > - `, - func(t *testing.T) { - data := getHello - CheckOnData(t, 1, false, false, &[][]byte{data[:10], data[10:]}, []ExpFilterOp{ - {proxylib.PASS, len(data)}, {proxylib.MORE, 24}, - }, proxylib.OK, "") - }, - }, - { - "bin get remaining key", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "get" - > - `, - func(t *testing.T) { - data := getHello[:26] - CheckOnData(t, 1, false, false, &[][]byte{data}, []ExpFilterOp{ - {proxylib.MORE, 3}, - }, proxylib.OK, "") - }, - }, - { - "bin set drop and allow", - ` rule: < - key: "keyExact" - value: "" - > - rule: < - key: "command" - value: "set" - > - `, - func(t *testing.T) { - CheckOnData(t, 1, false, false, &[][]byte{setHello, getHello}, []ExpFilterOp{ - {proxylib.PASS, len(setHello)}, {proxylib.DROP, len(getHello)}, {proxylib.MORE, 24}, - }, proxylib.OK, string(binarymemcache.DeniedMsgBase)) - - CheckOnData(t, 1, true, false, &[][]byte{getHelloResp}, []ExpFilterOp{ - {proxylib.PASS, len(getHelloResp)}, {proxylib.INJECT, len(binarymemcache.DeniedMsgBase)}, - }, proxylib.OK, string(binarymemcache.DeniedMsgBase)) - }, - }, -} diff --git a/proxylib/libcilium/proxylib_test.go b/proxylib/libcilium/proxylib_test.go deleted file mode 100644 index 4aa8b021b..000000000 --- a/proxylib/libcilium/proxylib_test.go +++ /dev/null @@ -1,834 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package libcilium - -import ( - "fmt" - "testing" - "time" - - "github.com/sirupsen/logrus" - - cilium "github.com/cilium/proxy/go/cilium/api" - "github.com/cilium/proxy/proxylib/proxylib" - "github.com/cilium/proxy/proxylib/test" - _ "github.com/cilium/proxy/proxylib/testparsers" -) - -const debug = false - -func TestOpenModule(t *testing.T) { - mod1 := OpenModule([][2]string{}, debug) - if mod1 == 0 { - t.Error("OpenModule() with empty params failed") - } else { - defer CloseModule(mod1) - } - mod2 := OpenModule([][2]string{}, debug) - if mod2 == 0 { - t.Error("OpenModule() with empty params failed") - } else { - defer CloseModule(mod2) - } - if mod2 != mod1 { - t.Error("OpenModule() with empty params called again opened a new module") - } - - mod3 := OpenModule([][2]string{{"dummy-key", "dummy-value"}, {"key2", "value2"}}, debug) - if mod3 != 0 { - t.Error("OpenModule() with unknown params accepted") - defer CloseModule(mod3) - } - - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod4 := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod4 == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod4) - } - if mod4 == mod1 { - t.Error("OpenModule() should have returned a different module") - } - - mod5 := OpenModule([][2]string{{"access-log-path", logServer.Path}, {"node-id", "host~127.0.0.1~libcilium~localdomain"}}, debug) - if mod5 == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod5) - } - if mod5 == mod1 || mod5 == mod2 || mod5 == mod3 || mod5 == mod4 { - t.Error("OpenModule() should have returned a different module") - } -} - -func TestOnNewConnection(t *testing.T) { - mod := OpenModule([][2]string{}, debug) - if mod == 0 { - t.Error("OpenModule() with empty params failed") - } else { - defer CloseModule(mod) - } - - // Unkhown parser - CheckOnNewConnection(t, mod, "invalid-parser-should-not-exist", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", 80, proxylib.UNKNOWN_PARSER, 0) - - // Non-numeric destination port - CheckOnNewConnection(t, mod, "test.passer", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:XYZ", "1.1.1.1", - 80, proxylib.INVALID_ADDRESS, 0) - - // Missing Destination port - CheckOnNewConnection(t, mod, "test.passer", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2", "1.1.1.1", - 80, proxylib.INVALID_ADDRESS, 0) - - // Zero Destination port is reserved for wildcarding - CheckOnNewConnection(t, mod, "test.passer", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:0", "1.1.1.1", - 80, proxylib.INVALID_ADDRESS, 0) - - // L7 parser rejecting the connection based on connection metadata - CheckOnNewConnection(t, mod, "test.passer", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "invalid-policy", - 80, proxylib.POLICY_DROP, 0) - - // Using test parser - CheckOnNewConnection(t, mod, "test.passer", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", - 80, proxylib.OK, 1) - - // 2nd connection - CheckOnNewConnection(t, mod, "test.passer", 12345678901234567890, false, 2, 1, "10.0.0.2:80", "1.1.1.1:34567", "2.2.2.2", - 80, proxylib.OK, 2) - - CheckClose(t, 1, nil, 2) - - CheckClose(t, 12345678901234567890, nil, 1) -} - -func checkAccessLogs(t *testing.T, logServer *test.AccessLogServer, expPasses, expDrops int) { - t.Helper() - passes, drops := 0, 0 - nWaits := 0 - done := false - // Loop until done or when the timeout has ticked 100 times without any logs being received - for !done && nWaits < 100 { - select { - case entryType := <-logServer.Logs: - if entryType == cilium.EntryType_Denied { - drops++ - } else { - passes++ - } - // Start the timeout again (for upto 5 seconds) - nWaits = 0 - case <-time.After(50 * time.Millisecond): - // Count the number of times we have waited since the last log was received - nWaits++ - // Finish when expected number of passes and drops have been collected - // and there are no more logs in the channel for 50 milliseconds - if passes == expPasses && drops == expDrops { - done = true - } - } - } - - if !(passes == expPasses && drops == expDrops) { - t.Errorf("OnData: Unexpected access log entries, expected %d passes (got %d) and %d drops (got %d).", expPasses, passes, expDrops, drops) - } -} - -func TestOnDataNoPolicy(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - // Using headertester parser - buf := CheckOnNewConnection(t, mod, "test.headerparser", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", - 30, proxylib.OK, 1) - - // Original direction data, drops with remaining data - line1, line2, line3 := "No policy\n", "Dropped\n", "foo" - CheckOnData(t, 1, false, false, &[][]byte{[]byte(line1), []byte(line2 + line3)}, []ExpFilterOp{ - {proxylib.DROP, len(line1)}, - {proxylib.DROP, len(line2)}, - {proxylib.MORE, 1}, - }, proxylib.OK, "Line dropped: "+line1+"Line dropped: "+line2) - - // No new input - CheckOnData(t, 1, false, false, &[][]byte{[]byte(line3)}, []ExpFilterOp{ - {proxylib.MORE, 1}, - }, proxylib.OK, "") - - // Empty - CheckOnData(t, 1, false, false, &[][]byte{}, []ExpFilterOp{}, proxylib.OK, "") - - expPasses, expDrops := 0, 2 - checkAccessLogs(t, logServer, expPasses, expDrops) - - CheckClose(t, 1, buf, 1) -} - -type PanicParserFactory struct{} - -var panicParserFactory *PanicParserFactory - -type PanicParser struct { - connection *proxylib.Connection -} - -func (p *PanicParserFactory) Create(connection *proxylib.Connection) interface{} { - logrus.Debugf("PanicParserFactory: Create: %v", connection) - return &PanicParser{connection: connection} -} - -// Parses individual lines and verifies them against the policy -func (p *PanicParser) OnData(reply, endStream bool, data [][]byte) (proxylib.OpType, int) { - if !reply { - panic(fmt.Errorf("PanicParser OnData(reply=%t, endStream=%t, data=%v) panicing...", reply, endStream, data)) - } - return proxylib.NOP, 0 -} - -func TestOnDataPanic(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - // This registation will remain after this test. - proxylib.RegisterParserFactory("test.panicparser", panicParserFactory) - - // Using headertester parser - buf := CheckOnNewConnection(t, mod, "test.panicparser", 11, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", - 30, proxylib.OK, 1) - - // Original direction data, drops with remaining data - CheckOnData(t, 11, false, false, &[][]byte{[]byte("foo")}, []ExpFilterOp{}, proxylib.PARSER_ERROR, "") - - expPasses, expDrops := 0, 1 - checkAccessLogs(t, logServer, expPasses, expDrops) - - CheckClose(t, 11, buf, 1) -} - -func insertPolicyText(t *testing.T, mod uint64, version string, policies []string) bool { - return insertPolicyTextRaw(t, mod, version, policies, "") == nil -} - -func insertPolicyTextRaw(t *testing.T, mod uint64, version string, policies []string, expectFail string) error { - instance := proxylib.FindInstance(mod) - if instance == nil { - t.Errorf("Policy Update failed to get the library instance.") - } else { - return instance.InsertPolicyText(version, policies, expectFail) - } - return nil -} - -func TestUnsupportedL7Drops(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - insertPolicyText(t, mod, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - kafka_rules: < - kafka_rules: < - topic: "Topic" - > - > - > - > - `}) - - // Using headertester parser - buf := CheckOnNewConnection(t, mod, "test.headerparser", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", - 256, proxylib.OK, 1) - - // Original direction data, drops with remaining data - line1, line2, line3, line4 := "Beginning----\n", "foo\n", "----End\n", "\n" - data := line1 + line2 + line3 + line4 - CheckOnData(t, 1, false, false, &[][]byte{[]byte(data)}, []ExpFilterOp{ - {proxylib.DROP, len(line1)}, - {proxylib.DROP, len(line2)}, - {proxylib.DROP, len(line3)}, - {proxylib.DROP, len(line4)}, - }, proxylib.OK, "Line dropped: "+line1+"Line dropped: "+line2+"Line dropped: "+line3+"Line dropped: "+line4) - - expPasses, expDrops := 0, 4 - checkAccessLogs(t, logServer, expPasses, expDrops) - - CheckClose(t, 1, buf, 1) -} - -func TestUnsupportedL7DropsGeneric(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - insertPolicyText(t, mod, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "this-parser-does-not-exist" - l7_rules: < - l7_allow_rules: < - rule: < - key: "prefix" - value: "Beginning" - > - > - > - > - > - `}) - - // Using headertester parser - buf := CheckOnNewConnection(t, mod, "test.headerparser", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", - 256, proxylib.OK, 1) - - // Original direction data, drops with remaining data - line1, line2, line3, line4 := "Beginning----\n", "foo\n", "----End\n", "\n" - data := line1 + line2 + line3 + line4 - CheckOnData(t, 1, false, false, &[][]byte{[]byte(data)}, []ExpFilterOp{ - {proxylib.DROP, len(line1)}, - {proxylib.DROP, len(line2)}, - {proxylib.DROP, len(line3)}, - {proxylib.DROP, len(line4)}, - }, proxylib.OK, "Line dropped: "+line1+"Line dropped: "+line2+"Line dropped: "+line3+"Line dropped: "+line4) - - expPasses, expDrops := 0, 4 - checkAccessLogs(t, logServer, expPasses, expDrops) - - CheckClose(t, 1, buf, 1) -} - -func TestEnvoyL7DropsGeneric(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - insertPolicyText(t, mod, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "envoy.filter.network.test" - l7_rules: < - l7_allow_rules: < - rule: < - key: "action" - value: "drop" - > - > - > - > - > - `}) - - // Using headertester parser - buf := CheckOnNewConnection(t, mod, "test.headerparser", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", - 256, proxylib.OK, 1) - - // Original direction data, drops with remaining data - line1, line2, line3, line4 := "Beginning----\n", "foo\n", "----End\n", "\n" - data := line1 + line2 + line3 + line4 - CheckOnData(t, 1, false, false, &[][]byte{[]byte(data)}, []ExpFilterOp{ - {proxylib.DROP, len(line1)}, - {proxylib.DROP, len(line2)}, - {proxylib.DROP, len(line3)}, - {proxylib.DROP, len(line4)}, - }, proxylib.OK, "Line dropped: "+line1+"Line dropped: "+line2+"Line dropped: "+line3+"Line dropped: "+line4) - - expPasses, expDrops := 0, 4 - checkAccessLogs(t, logServer, expPasses, expDrops) - - CheckClose(t, 1, buf, 1) -} - -func TestTwoRulesOnSamePortFirstNoL7(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - insertPolicyText(t, mod, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 11 - > - rules: < - remote_policies: 11 - http_rules: < - http_rules: < - headers: < - name: ":path" - exact_match: "/allowed" - > - > - > - > - > - `}) -} - -func TestTwoRulesOnSamePortFirstNoL7Generic(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - insertPolicyText(t, mod, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 11 - > - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "test.headerparser" - l7_rules: < - l7_allow_rules: < - rule: < - key: "prefix" - value: "Beginning" - > - > - l7_allow_rules: < - rule: < - key: "suffix" - value: "End" - > - > - > - > - > - `}) -} - -func TestTwoRulesOnSamePortMismatchingL7(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - // This registation will remain after this test. - proxylib.RegisterL7RuleParser("PortNetworkPolicyRule_HttpRules", func(*cilium.PortNetworkPolicyRule) []proxylib.L7NetworkPolicyRule { - return nil - }) - - err := insertPolicyTextRaw(t, mod, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 11 - http_rules: < - http_rules: < - headers: < - name: ":path" - exact_match: "/allowed" - > - > - > - > - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "test.headerparser" - l7_rules: < - l7_allow_rules: < - rule: < - key: "prefix" - value: "Beginning" - > - > - l7_allow_rules: < - rule: < - key: "suffix" - value: "End" - > - > - > - > - > - `}, "update") - if err == nil { - t.Errorf("Expected Policy Update to fail due to mismatching L7 protocols on the same port, but it succeeded") - } else { - logrus.Debugf("Expected error: %s", err) - } -} - -func TestSimplePolicy(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - insertPolicyText(t, mod, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - remote_policies: 3 - remote_policies: 4 - l7_proto: "test.headerparser" - l7_rules: < - l7_allow_rules: < - rule: < - key: "prefix" - value: "Beginning" - > - > - l7_allow_rules: < - rule: < - key: "suffix" - value: "End" - > - > - > - > - > - `}) - - // Using headertester parser - buf := CheckOnNewConnection(t, mod, "test.headerparser", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", - 80, proxylib.OK, 1) - - // Original direction data, drops with remaining data - line1, line2, line3, line4 := "Beginning----\n", "foo\n", "----End\n", "\n" - data := line1 + line2 + line3 + line4 - CheckOnData(t, 1, false, false, &[][]byte{[]byte(data)}, []ExpFilterOp{ - {proxylib.PASS, len(line1)}, - {proxylib.DROP, len(line2)}, - {proxylib.PASS, len(line3)}, - {proxylib.DROP, len(line4)}, - }, proxylib.OK, "Line dropped: "+line2+"Line dropped: "+line4) - - expPasses, expDrops := 2, 2 - checkAccessLogs(t, logServer, expPasses, expDrops) - - CheckClose(t, 1, buf, 1) -} - -func TestAllowAllPolicy(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - insertPolicyText(t, mod, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - l7_proto: "test.headerparser" - l7_rules: < - l7_allow_rules: <> - > - > - > - `}) - - // Using headertester parser - buf := CheckOnNewConnection(t, mod, "test.headerparser", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", - 80, proxylib.OK, 1) - - // Original direction data, drops with remaining data - line1, line2, line3, line4 := "Beginning----\n", "foo\n", "----End\n", "\n" - data := line1 + line2 + line3 + line4 - CheckOnData(t, 1, false, false, &[][]byte{[]byte(data)}, []ExpFilterOp{ - {proxylib.PASS, len(line1)}, - {proxylib.PASS, len(line2)}, - {proxylib.PASS, len(line3)}, - {proxylib.PASS, len(line4)}, - }, proxylib.OK, "") - - expPasses, expDrops := 4, 0 - checkAccessLogs(t, logServer, expPasses, expDrops) - - CheckClose(t, 1, buf, 1) -} - -// L3 drops happen before calling into proxylib, but here we test that the policy update does not -// accidentally treat deny rules as allow rules. -func TestDenyAllPolicy(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - insertPolicyText(t, mod, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - l7_proto: "test.headerparser" - l7_rules: < - l7_allow_rules: <> - > - > - rules: < - deny: true - > - > - `}) - - // Using headertester parser - buf := CheckOnNewConnection(t, mod, "test.headerparser", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", - 80, proxylib.OK, 1) - - // Original direction data, drops with remaining data - line1, line2, line3, line4 := "Beginning----\n", "foo\n", "----End\n", "\n" - data := line1 + line2 + line3 + line4 - CheckOnData(t, 1, false, false, &[][]byte{[]byte(data)}, []ExpFilterOp{ - {proxylib.DROP, len(line1)}, - {proxylib.DROP, len(line2)}, - {proxylib.DROP, len(line3)}, - {proxylib.DROP, len(line4)}, - }, proxylib.OK, "Line dropped: "+line1+"Line dropped: "+line2+"Line dropped: "+line3+"Line dropped: "+line4) - - expPasses, expDrops := 0, 4 - checkAccessLogs(t, logServer, expPasses, expDrops) - - CheckClose(t, 1, buf, 1) -} - -func TestDenyPolicy(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - insertPolicyText(t, mod, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - remote_policies: 1 - l7_proto: "test.headerparser" - l7_rules: < - l7_allow_rules: <> - > - > - rules: < - remote_policies: 42 - deny: true - > - > - `}) - - // deny on ID 42 has no effect on traffic from 1 - // Using headertester parser - buf := CheckOnNewConnection(t, mod, "test.headerparser", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", - 80, proxylib.OK, 1) - - // Original direction data, drops with remaining data - line1, line2, line3, line4 := "Beginning----\n", "foo\n", "----End\n", "\n" - data := line1 + line2 + line3 + line4 - CheckOnData(t, 1, false, false, &[][]byte{[]byte(data)}, []ExpFilterOp{ - {proxylib.PASS, len(line1)}, - {proxylib.PASS, len(line2)}, - {proxylib.PASS, len(line3)}, - {proxylib.PASS, len(line4)}, - }, proxylib.OK, "") - - expPasses, expDrops := 4, 0 - checkAccessLogs(t, logServer, expPasses, expDrops) - - CheckClose(t, 1, buf, 1) -} - -func TestAllowEmptyPolicy(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - insertPolicyText(t, mod, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - l7_proto: "test.headerparser" - > - > - `}) - - // Using headertester parser, policy name matches the policy - buf := CheckOnNewConnection(t, mod, "test.headerparser", 1, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", - 80, proxylib.OK, 1) - - // Original direction data, drops with remaining data - line1, line2, line3, line4 := "Beginning----\n", "foo\n", "----End\n", "\n" - CheckOnData(t, 1, false, false, &[][]byte{[]byte(line1), []byte(line2), []byte(line3), []byte(line4)}, []ExpFilterOp{ - {proxylib.PASS, len(line1)}, - {proxylib.PASS, len(line2)}, - {proxylib.PASS, len(line3)}, - {proxylib.PASS, len(line4)}, - }, proxylib.OK, "") - - // Connection using a different policy name still drops - CheckOnNewConnection(t, mod, "test.headerparser", 2, true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "2.2.2.2", - 80, proxylib.OK, 2) - CheckOnData(t, 2, false, false, &[][]byte{[]byte(line1)}, []ExpFilterOp{ - {proxylib.DROP, len(line1)}, - }, proxylib.OK, "Line dropped: "+line1) - - expPasses, expDrops := 4, 1 - checkAccessLogs(t, logServer, expPasses, expDrops) - - CheckClose(t, 2, buf, 2) - CheckClose(t, 1, buf, 1) -} - -func TestAllowAllPolicyL3Egress(t *testing.T) { - logServer := test.StartAccessLogServer("access_log.sock", 10) - defer logServer.Close() - - mod := OpenModule([][2]string{{"access-log-path", logServer.Path}}, debug) - if mod == 0 { - t.Errorf("OpenModule() with access log path %s failed", logServer.Path) - } else { - defer CloseModule(mod) - } - - // logging.ToggleDebugLogs(true) - // logrus.SetLevel(logrus.DebugLevel) - - insertPolicyText(t, mod, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 42 - egress_per_port_policies: < - port: 80 - rules: < - remote_policies: 2 - l7_proto: "test.headerparser" - l7_rules: < - l7_allow_rules: <> - > - > - > - `}) - - // Using headertester parser - buf := CheckOnNewConnection(t, mod, "test.headerparser", 1, false, 42, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1", - 80, proxylib.OK, 1) - - // Original direction data, drops with remaining data - line1, line2, line3, line4 := "Beginning----\n", "foo\n", "----End\n", "\n" - data := line1 + line2 + line3 + line4 - CheckOnData(t, 1, false, false, &[][]byte{[]byte(data)}, []ExpFilterOp{ - {proxylib.PASS, len(line1)}, - {proxylib.PASS, len(line2)}, - {proxylib.PASS, len(line3)}, - {proxylib.PASS, len(line4)}, - }, proxylib.OK, "") - - expPasses, expDrops := 4, 0 - checkAccessLogs(t, logServer, expPasses, expDrops) - - CheckClose(t, 1, buf, 1) -} diff --git a/proxylib/memcached/binary/parser.go b/proxylib/memcached/binary/parser.go deleted file mode 100644 index 0cb8ce936..000000000 --- a/proxylib/memcached/binary/parser.go +++ /dev/null @@ -1,194 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package binary - -import ( - "bytes" - "encoding/binary" - "strconv" - - "github.com/sirupsen/logrus" - - cilium "github.com/cilium/proxy/go/cilium/api" - "github.com/cilium/proxy/proxylib/memcached/meta" - "github.com/cilium/proxy/proxylib/proxylib" -) - -// ParserFactory implements proxylib.ParserFactory -type ParserFactory struct{} - -// Create creates binary memcached parser -func (p *ParserFactory) Create(connection *proxylib.Connection) interface{} { - logrus.Debugf("ParserFactory: Create: %v", connection) - return &Parser{connection: connection, injectQueue: make([]queuedInject, 0)} -} - -// compile time check for interface implementation -var _ proxylib.ParserFactory = &ParserFactory{} - -// ParserFactoryInstance creates binary parser for unified parser -var ParserFactoryInstance *ParserFactory - -// Parser implements proxylib.Parser -type Parser struct { - connection *proxylib.Connection - - requestCount uint32 - replyCount uint32 - injectQueue []queuedInject -} - -var _ proxylib.Parser = &Parser{} - -const headerSize = 24 - -// OnData parses binary memcached data -func (p *Parser) OnData(reply, endStream bool, dataBuffers [][]byte) (proxylib.OpType, int) { - if reply { - if p.injectFromQueue() { - return proxylib.INJECT, len(DeniedMsgBase) - } - if len(dataBuffers) == 0 { - return proxylib.NOP, 0 - } - } - - //TODO don't copy data from buffers - data := bytes.Join(dataBuffers, []byte{}) - logrus.Debugf("Data length: %d", len(data)) - - if headerSize > len(data) { - headerMissing := headerSize - len(data) - logrus.Debugf("Did not receive needed header data, need %d more bytes", headerMissing) - return proxylib.MORE, headerMissing - } - - bodyLength := binary.BigEndian.Uint32(data[8:12]) - - keyLength := binary.BigEndian.Uint16(data[2:4]) - extrasLength := data[4] - - if keyLength > 0 { - neededData := headerSize + int(keyLength) + int(extrasLength) - if neededData > len(data) { - keyMissing := neededData - len(data) - logrus.Debugf("Did not receive enough bytes for key, need %d more bytes", keyMissing) - return proxylib.MORE, keyMissing - } - } - - opcode, key, err := p.getOpcodeAndKey(data, extrasLength, keyLength) - if err != 0 { - return proxylib.ERROR, int(err) - } - - logEntry := &cilium.LogEntry_GenericL7{ - GenericL7: &cilium.L7LogEntry{ - Proto: "binarymemcached", - Fields: map[string]string{ - "opcode": strconv.Itoa(int(opcode)), - "key": string(key), - }, - }, - } - - // we don't filter reply traffic - if reply { - logrus.Debugf("reply, passing %d bytes", len(data)) - p.connection.Log(cilium.EntryType_Response, logEntry) - p.replyCount++ - return proxylib.PASS, int(bodyLength + headerSize) - } - - p.requestCount++ - - matches := p.connection.Matches(meta.MemcacheMeta{ - Opcode: opcode, - Keys: [][]byte{key}, - }) - if matches { - p.connection.Log(cilium.EntryType_Request, logEntry) - return proxylib.PASS, int(bodyLength + headerSize) - } - - magic := ResponseMagic | data[0] - - // This is done to ensure in-order replies - if p.requestCount == p.replyCount+1 { - p.injectDeniedMessage(magic) - } else { - p.injectQueue = append(p.injectQueue, queuedInject{magic, p.requestCount}) - } - - p.injectQueue = append(p.injectQueue, queuedInject{magic, p.requestCount}) - - p.connection.Log(cilium.EntryType_Denied, logEntry) - return proxylib.DROP, int(bodyLength + headerSize) -} - -type queuedInject struct { - magic byte - requestID uint32 -} - -func (p *Parser) injectDeniedMessage(magic byte) { - deniedMsg := make([]byte, len(DeniedMsgBase)) - copy(deniedMsg, DeniedMsgBase) - - deniedMsg[0] = magic - - p.connection.Inject(true, deniedMsg) - p.replyCount++ -} - -func (p *Parser) injectFromQueue() bool { - if len(p.injectQueue) > 0 { - if p.injectQueue[0].requestID == p.replyCount+1 { - p.injectDeniedMessage(p.injectQueue[0].magic) - p.injectQueue = p.injectQueue[1:] - return true - } - } - return false -} - -const ( - // RequestMagic says that memcache frame is a request - RequestMagic = 0x80 - // ResponseMagic says that memcache frame is a response - ResponseMagic = 0x81 -) - -func (p *Parser) getOpcodeAndKey(data []byte, extrasLength byte, keyLength uint16) (byte, []byte, proxylib.OpError) { - if data[0]&RequestMagic != RequestMagic { - logrus.Warnf("Direction bit is 'response', but memcached parser only parses requests") - return 0, []byte{}, proxylib.ERROR_INVALID_FRAME_TYPE - } - - opcode := data[1] - key := getMemcacheKey(data, extrasLength, keyLength) - - return opcode, key, 0 -} - -func getMemcacheKey(packet []byte, extrasLength byte, keyLength uint16) []byte { - if keyLength == 0 { - return []byte{} - } - return packet[headerSize+int(extrasLength) : headerSize+int(extrasLength)+int(keyLength)] -} - -// DeniedMsgBase is sent if policy denies the request. Exported for tests -var DeniedMsgBase = []byte{ - 0x81, 0, 0, 0, - 0, 0, 0, 8, - 0, 0, 0, 0x0d, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 'a', 'c', 'c', - 'e', 's', 's', - ' ', 'd', 'e', - 'n', 'i', 'e', - 'd'} diff --git a/proxylib/memcached/binary/parser_test.go b/proxylib/memcached/binary/parser_test.go deleted file mode 100644 index c81a1dadb..000000000 --- a/proxylib/memcached/binary/parser_test.go +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package binary - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestMemcacheGetKey(c *testing.T) { - packet := []byte{ - 0x80, 0, 0, 0x5, - 0, 0, 0, 0, - 0, 0, 0, 0x5, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 'T', 'e', 's', 't', - '1', - } - - key := getMemcacheKey(packet, 0, 5) - - require.Equal(c, "Test1", string(key)) - - packet = []byte{ - 0x80, 0, 0, 0x5, - 0x4, 0, 0, 0, - 0, 0, 0, 0x5, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 'e', 'x', 't', 'r', - 'T', 'e', 's', 't', - '1', - } - - key = getMemcacheKey(packet, 4, 5) - - require.Equal(c, "Test1", string(key)) - - packet = []byte{ - 0x80, 0x8, 0, 0x0, - 0x4, 0, 0, 0, - 0, 0, 0, 0x4, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0x1c, 0x20, - } - - key = getMemcacheKey(packet, 4, 0) - - require.Equal(c, "", string(key)) -} diff --git a/proxylib/memcached/meta/meta.go b/proxylib/memcached/meta/meta.go deleted file mode 100644 index 222709148..000000000 --- a/proxylib/memcached/meta/meta.go +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -// text memcache protocol parser based on https://github.com/memcached/memcached/blob/master/doc/protocol.txt - -package meta - -// MemcacheMeta gathers information about memcache frame for L7 rules matching -type MemcacheMeta struct { - // for text protocol - Command string - // for binary protocol - Opcode byte - Keys [][]byte -} - -// IsBinary tells whether meta instance is for text or binary protocol -func (m *MemcacheMeta) IsBinary() bool { - return len(m.Command) == 0 -} diff --git a/proxylib/memcached/parser.go b/proxylib/memcached/parser.go deleted file mode 100644 index 114dec9e5..000000000 --- a/proxylib/memcached/parser.go +++ /dev/null @@ -1,464 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -// text memcache protocol parser based on https://github.com/memcached/memcached/blob/master/doc/protocol.txt - -package memcache - -import ( - "bytes" - "fmt" - "regexp" - - "github.com/sirupsen/logrus" - - cilium "github.com/cilium/proxy/go/cilium/api" - - "github.com/cilium/proxy/proxylib/memcached/binary" - "github.com/cilium/proxy/proxylib/memcached/meta" - "github.com/cilium/proxy/proxylib/memcached/text" - "github.com/cilium/proxy/proxylib/proxylib" -) - -// Rule matches against memcached requests -type Rule struct { - // allowed commands - commands memcacheCommandSet - // compiled regex - keyExact []byte - keyPrefix []byte - regex *regexp.Regexp - - empty bool -} - -// Matches returns true if the Rule matches -func (rule *Rule) Matches(data interface{}) bool { - logrus.Debugf("memcache checking rule %v", *rule) - - packetMeta, ok := data.(meta.MemcacheMeta) - - if !ok { - logrus.Debugf("Wrong type supplied to Rule.Matches") - return false - } - - if rule.empty { - return true - } - - if packetMeta.IsBinary() { - if !rule.matchOpcode(packetMeta.Opcode) { - return false - } - } else { - if !rule.matchCommand(packetMeta.Command) { - return false - } - } - - if len(rule.keyExact) > 0 { - for _, key := range packetMeta.Keys { - if !bytes.Equal(rule.keyExact, key) { - return false - } - } - return true - } - - if len(rule.keyPrefix) > 0 { - for _, key := range packetMeta.Keys { - if !bytes.HasPrefix(key, rule.keyPrefix) { - return false - } - } - return true - } - - if rule.regex != nil { - for _, key := range packetMeta.Keys { - if !rule.regex.Match(key) { - return false - } - } - return true - } - - logrus.Debugf("No key rule specified, accepted by command match") - return true -} - -func (rule *Rule) matchCommand(cmd string) bool { - _, ok := rule.commands.text[cmd] - return ok -} - -func (rule *Rule) matchOpcode(code byte) bool { - _, ok := rule.commands.binary[code] - return ok -} - -// L7RuleParser parses protobuf L7 rules to and array of Rule -// May panic -func L7RuleParser(rule *cilium.PortNetworkPolicyRule) []proxylib.L7NetworkPolicyRule { - l7Rules := rule.GetL7Rules() - if l7Rules == nil { - return nil - } - - allowRules := l7Rules.GetL7AllowRules() - rules := make([]proxylib.L7NetworkPolicyRule, 0, len(allowRules)) - for _, l7Rule := range allowRules { - var br Rule - var commandFound = false - for k, v := range l7Rule.Rule { - switch k { - case "command": - br.commands, commandFound = MemcacheOpCodeMap[v] - case "keyExact": - br.keyExact = []byte(v) - case "keyPrefix": - br.keyPrefix = []byte(v) - case "keyRegex": - br.regex = regexp.MustCompile(v) - default: - proxylib.ParseError(fmt.Sprintf("Unsupported key: %s", k), rule) - } - } - if !commandFound { - if len(br.keyExact) > 0 || len(br.keyPrefix) > 0 || br.regex != nil { - proxylib.ParseError("command not specified but key was provided", rule) - } else { - br.empty = true - } - } - logrus.Debugf("Parsed Rule pair: %v", br) - rules = append(rules, &br) - } - return rules -} - -// ParserFactory implements proxylib.ParserFactory -type ParserFactory struct{} - -// Create creates memcached parser -func (p *ParserFactory) Create(connection *proxylib.Connection) interface{} { - logrus.Debugf("ParserFactory: Create: %v", connection) - return &Parser{ - connection: connection, - } -} - -// compile time check for interface implementation -var _ proxylib.ParserFactory = &ParserFactory{} - -var memcacheParserFactory *ParserFactory - -const ( - parserName = "memcache" -) - -func init() { - logrus.Debug("init(): Registering memcacheParserFactory") - proxylib.RegisterParserFactory(parserName, memcacheParserFactory) - proxylib.RegisterL7RuleParser(parserName, L7RuleParser) -} - -// Parser implements proxylib.Parser -type Parser struct { - connection *proxylib.Connection - parser proxylib.Parser -} - -var _ proxylib.Parser = &Parser{} - -// OnData parses memcached data -func (p *Parser) OnData(reply, endStream bool, dataBuffers [][]byte) (proxylib.OpType, int) { - if p.parser == nil { - var magicByte byte - if len(dataBuffers) > 0 && len(dataBuffers[0]) > 0 { - magicByte = dataBuffers[0][0] - } else { - return proxylib.NOP, 0 - } - - if magicByte >= 128 { - p.parser = binary.ParserFactoryInstance.Create(p.connection).(proxylib.Parser) - } else { - p.parser = text.ParserFactoryInstance.Create(p.connection).(proxylib.Parser) - } - } - return p.parser.OnData(reply, endStream, dataBuffers) -} - -type memcacheCommandSet struct { - text map[string]struct{} - binary map[byte]struct{} -} - -// empty var for filling map below which will be used as set -var e = struct{}{} - -// MemcacheOpCodeMap maps operation names and groups used in policy rules to sets of operation names and opcodes that are allowed in such a policy rule. -// for more information on protocol check https://github.com/memcached/memcached/wiki/Protocols -var MemcacheOpCodeMap = map[string]memcacheCommandSet{ - "add": { - text: map[string]struct{}{"add": e}, - binary: map[byte]struct{}{2: e, 18: e}, - }, - "set": { - text: map[string]struct{}{"set": e}, - binary: map[byte]struct{}{1: e, 17: e}, - }, - "replace": { - text: map[string]struct{}{"replace": e}, - binary: map[byte]struct{}{3: e, 19: e}, - }, - "append": { - text: map[string]struct{}{"append": e}, - binary: map[byte]struct{}{14: e, 25: e}, - }, - "prepend": { - text: map[string]struct{}{"prepend": e}, - binary: map[byte]struct{}{15: e, 26: e}, - }, - "cas": { - text: map[string]struct{}{"cas": e}, - binary: map[byte]struct{}{}, - }, - "incr": { - text: map[string]struct{}{"incr": e}, - binary: map[byte]struct{}{5: e, 21: e}, - }, - "decr": { - text: map[string]struct{}{"decr": e}, - binary: map[byte]struct{}{6: e, 22: e}, - }, - "storage": { - text: map[string]struct{}{ - "add": e, - "set": e, - "replace": e, - "append": e, - "prepend": e, - "cas": e, - "incr": e, - "decr": e, - }, - binary: map[byte]struct{}{ - 1: e, - 2: e, - 3: e, - 5: e, - 6: e, - 17: e, - 18: e, - 19: e, - 21: e, - 22: e, - 25: e, - 26: e, - }, - }, - - "get": { - text: map[string]struct{}{"get": e, "gets": e}, - binary: map[byte]struct{}{ - 0: e, - 9: e, - 12: e, - 13: e, - }, - }, - - "delete": { - text: map[string]struct{}{"delete": e}, - binary: map[byte]struct{}{ - 4: e, - 20: e, - }, - }, - - "touch": { - text: map[string]struct{}{"touch": e}, - binary: map[byte]struct{}{28: e}, - }, - - "gat": { - text: map[string]struct{}{"gat": e, "gats": e}, - binary: map[byte]struct{}{29: e, 30: e}, - }, - - "writeGroup": { - text: map[string]struct{}{ - "add": e, - "set": e, - "replace": e, - "append": e, - "prepend": e, - "cas": e, - "incr": e, - "decr": e, - "delete": e, - "touch": e, - }, - binary: map[byte]struct{}{ - 1: e, - 2: e, - 3: e, - 4: e, - 5: e, - 6: e, - 17: e, - 18: e, - 19: e, - 20: e, - 21: e, - 22: e, - 25: e, - 26: e, - 28: e, - }, - }, - - "slabs": { - text: map[string]struct{}{"slabs": e}, - binary: map[byte]struct{}{}, - }, - - "lru": { - text: map[string]struct{}{"lru": e}, - binary: map[byte]struct{}{}, - }, - - "lru_crawler": { - text: map[string]struct{}{"lru_crawler": e}, - binary: map[byte]struct{}{}, - }, - - "watch": { - text: map[string]struct{}{"watch": e}, - binary: map[byte]struct{}{}, - }, - - "stats": { - text: map[string]struct{}{"stats": e}, - binary: map[byte]struct{}{16: e}, - }, - - "flush_all": { - text: map[string]struct{}{"flush_all": e}, - binary: map[byte]struct{}{8: e, 24: e}, - }, - - "cache_memlimit": { - text: map[string]struct{}{"cache_memlimit": e}, - binary: map[byte]struct{}{}, - }, - - "version": { - text: map[string]struct{}{"version": e}, - binary: map[byte]struct{}{11: e}, - }, - - "misbehave": { - text: map[string]struct{}{"misbehave": e}, - binary: map[byte]struct{}{}, - }, - - "quit": { - text: map[string]struct{}{"quit": e}, - binary: map[byte]struct{}{7: e, 23: e}, - }, - - "noop": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{10: e}, - }, - "verbosity": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{27: e}, - }, - "sasl-list-mechs": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{32: e}, - }, - "sasl-auth": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{33: e}}, - "sasl-step": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{34: e}}, - "rget": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{48: e}}, - "rset": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{49: e}}, - "rsetq": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{50: e}}, - "rappend": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{51: e}}, - "rappendq": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{52: e}}, - "rprepend": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{53: e}}, - "rprependq": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{54: e}}, - "rdelete": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{55: e}}, - "rdeleteq": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{56: e}}, - "rincr": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{57: e}}, - "rincrq": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{58: e}}, - "rdecr": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{59: e}}, - "rdecrq": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{60: e}}, - "set-vbucket": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{61: e}}, - "get-vbucket": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{62: e}}, - "del-vbucket": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{63: e}}, - "tap-connect": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{64: e}}, - "tap-mutation": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{65: e}}, - "tap-delete": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{66: e}}, - "tap-flush": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{67: e}}, - "tap-opaque": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{68: e}}, - "tap-vbucket-set": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{69: e}}, - "tap-checkpoint-start": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{70: e}}, - "tap-checkpoint-end": { - text: map[string]struct{}{}, - binary: map[byte]struct{}{71: e}}, -} diff --git a/proxylib/memcached/text/parser.go b/proxylib/memcached/text/parser.go deleted file mode 100644 index c7ab986c4..000000000 --- a/proxylib/memcached/text/parser.go +++ /dev/null @@ -1,320 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -// text memcache protocol parser based on https://github.com/memcached/memcached/blob/master/doc/protocol.txt - -package text - -import ( - "bytes" - "strconv" - - "github.com/sirupsen/logrus" - - cilium "github.com/cilium/proxy/go/cilium/api" - - "github.com/cilium/proxy/proxylib/memcached/meta" - "github.com/cilium/proxy/proxylib/proxylib" -) - -// ParserFactory implements proxylib.ParserFactory -type ParserFactory struct{} - -// Create creates memcached parser -func (p *ParserFactory) Create(connection *proxylib.Connection) interface{} { - logrus.Debugf("ParserFactory: Create: %v", connection) - return &Parser{connection: connection, replyQueue: make([]*replyIntent, 0)} -} - -// compile time check for interface implementation -var _ proxylib.ParserFactory = &ParserFactory{} - -// ParserFactoryInstance creates text parser for unified memcached parser -var ParserFactoryInstance *ParserFactory - -// Parser implements proxylib.Parser -type Parser struct { - connection *proxylib.Connection - - replyQueue []*replyIntent - - //set to true when watch command is observed - watching bool -} - -type replyIntent struct { - command []byte - denied bool -} - -var _ proxylib.Parser = &Parser{} - -// consts indicating number of tokens in memcache command that indicates noreply command -const ( - casWithNoreplyFields = 7 - storageWithNoreplyFields = 6 - deleteWithNoreplyFields = 3 - incrWithNoreplyFields = 4 - touchWithNoreplyFields = 4 -) - -// OnData parses text memcached data -func (p *Parser) OnData(reply, endStream bool, dataBuffers [][]byte) (proxylib.OpType, int) { - if reply { - injected := p.injectFromQueue() - if injected > 0 { - return proxylib.INJECT, injected - } - if len(dataBuffers) == 0 { - return proxylib.NOP, 0 - } - } - - // TODO: don't copy data to new slices - data := (bytes.Join(dataBuffers, []byte{})) - logrus.Debugf("Data length: %d", len(data)) - - linefeed := bytes.Index(data, []byte("\r\n")) - if linefeed < 0 { - logrus.Debugf("Did not receive full first line") - if len(data) > 0 && data[len(data)-1] == '\r' { - return proxylib.MORE, 1 - } - return proxylib.MORE, 2 - } - - // TODO: iterate over data without copying it to new slices - // Tokenizing in memcached is done by spaces: https://github.com/memcached/memcached/blob/master/memcached.c#L2978 - tokens := bytes.Fields(data[:linefeed]) - - if !reply { - meta := meta.MemcacheMeta{ - Command: string(tokens[0]), - } - command := tokens[0] - - frameLength := linefeed + 2 - hasNoreply := false - switch { - case p.isCommandRetrieval(command): - // get, gets, gat, gats - if bytes.HasPrefix(command, []byte("get")) { - meta.Keys = tokens[1:] - } else if bytes.HasPrefix(command, []byte("gat")) { - meta.Keys = tokens[2:] - } - case p.isCommandStorage(command): - // storage commands - meta.Keys = tokens[1:2] - nBytes, err := strconv.Atoi(string(tokens[4])) - if err != nil { - logrus.Error("Failed to parse storage payload length") - return proxylib.ERROR, 0 - } - // 2 additional bytes for terminating linefeed - frameLength += nBytes + 2 - - if command[0] == 'c' { //storage command is "cas" - hasNoreply = len(tokens) == casWithNoreplyFields - } else { - hasNoreply = len(tokens) == storageWithNoreplyFields - } - case p.isCommandDelete(command): - meta.Keys = tokens[1:2] - hasNoreply = len(tokens) == deleteWithNoreplyFields - case p.isCommandIncrDecr(command): - meta.Keys = tokens[1:2] - hasNoreply = len(tokens) == incrWithNoreplyFields - case bytes.Equal(command, []byte("touch")): - meta.Keys = tokens[1:2] - hasNoreply = len(tokens) == touchWithNoreplyFields - case bytes.Equal(command, []byte("slabs")), - bytes.Equal(command, []byte("lru")), - bytes.Equal(command, []byte("lru_crawler")), - bytes.Equal(command, []byte("stats")), - bytes.Equal(command, []byte("version")), - bytes.Equal(command, []byte("misbehave")): - - meta.Keys = [][]byte{} - case bytes.Equal(command, []byte("flush_all")), - bytes.Equal(command, []byte("cache_memlimit")): - meta.Keys = [][]byte{} - hasNoreply = bytes.Equal(tokens[len(tokens)-1], []byte("noreply")) - case bytes.Equal(command, []byte("quit")): - meta.Keys = [][]byte{} - hasNoreply = true - case bytes.Equal(command, []byte("watch")): - meta.Keys = [][]byte{} - p.watching = true - default: - logrus.Error("Could not parse text memcache frame") - return proxylib.ERROR, 0 - } - logEntry := &cilium.LogEntry_GenericL7{ - GenericL7: &cilium.L7LogEntry{ - Proto: "textmemcached", - Fields: map[string]string{ - "command": meta.Command, - "keys": string(bytes.Join(meta.Keys, []byte(", "))), - }, - }, - } - - r := &replyIntent{ - command: command, - } - - matches := p.connection.Matches(meta) - - if matches { - r.denied = false - if !hasNoreply { - p.replyQueue = append(p.replyQueue, r) - } - p.connection.Log(cilium.EntryType_Request, logEntry) - return proxylib.PASS, frameLength - } - - r.denied = true - if !hasNoreply { - if len(p.replyQueue) == 0 { - p.injectDeniedMessage() - } else { - p.replyQueue = append(p.replyQueue, r) - } - } - p.connection.Log(cilium.EntryType_Denied, logEntry) - return proxylib.DROP, frameLength - } - - //reply - logrus.Debugf("reply, parsing to figure out if we have it all") - - intent := p.replyQueue[0] - - logEntry := &cilium.LogEntry_GenericL7{ - GenericL7: &cilium.L7LogEntry{ - Proto: "textmemcached", - Fields: map[string]string{ - "command": string(intent.command), - }, - }, - } - if p.watching { - // in watch mode we pass all replied lines - return proxylib.PASS, linefeed + 2 - } - - switch { - case p.isErrorReply(tokens[0]), - p.isCommandStorage(intent.command), - p.isCommandDelete(intent.command), - p.isCommandIncrDecr(intent.command), - bytes.Equal(intent.command, []byte("touch")), - bytes.Equal(intent.command, []byte("slabs")), - bytes.Equal(intent.command, []byte("lru")), - bytes.Equal(intent.command, []byte("flush_all")), - bytes.Equal(intent.command, []byte("cache_memlimit")), - bytes.Equal(intent.command, []byte("version")), - bytes.Equal(intent.command, []byte("misbehave")): - - // passing one line of reply - p.connection.Log(cilium.EntryType_Response, logEntry) - p.replyQueue = p.replyQueue[1:] - return proxylib.PASS, linefeed + 2 - case p.isCommandRetrieval(intent.command), - bytes.Equal(intent.command, []byte("stats")): - t, nBytes := p.untilEnd(data) - if t == proxylib.PASS { - p.connection.Log(cilium.EntryType_Response, logEntry) - p.replyQueue = p.replyQueue[1:] - } - return t, nBytes - case bytes.Equal(intent.command, []byte("lru_crawler")): - // check if it's response line - if bytes.Equal(tokens[0], []byte("OK")) || - bytes.Equal(tokens[0], []byte("BUSY")) || - bytes.Equal(tokens[0], []byte("BADCLASS")) { - p.connection.Log(cilium.EntryType_Response, logEntry) - p.replyQueue = p.replyQueue[1:] - return proxylib.PASS, linefeed + 2 - } - - t, nBytes := p.untilEnd(data) - if t == proxylib.PASS { - p.connection.Log(cilium.EntryType_Response, logEntry) - p.replyQueue = p.replyQueue[1:] - } - return t, nBytes - } - logrus.Error("Could not parse text memcache frame") - return proxylib.ERROR, 0 -} - -const payloadEnd = "\r\nEND\r\n" - -func (p *Parser) untilEnd(data []byte) (proxylib.OpType, int) { - // TODO: optimise this to not ask per byte, but take VALUES lines into account - endIndex := bytes.Index(data, []byte(payloadEnd)) - if endIndex > 0 { - return proxylib.PASS, endIndex + len(payloadEnd) - } - return proxylib.MORE, 1 -} - -func (p *Parser) isCommandRetrieval(cmd []byte) bool { - return bytes.HasPrefix(cmd, []byte("get")) || - bytes.HasPrefix(cmd, []byte("gat")) -} - -func (p *Parser) isCommandStorage(cmd []byte) bool { - return bytes.Equal(cmd, []byte("set")) || - bytes.Equal(cmd, []byte("add")) || - bytes.Equal(cmd, []byte("replace")) || - bytes.Equal(cmd, []byte("append")) || - bytes.Equal(cmd, []byte("prepend")) || - bytes.Equal(cmd, []byte("cas")) -} - -func (p *Parser) isCommandDelete(cmd []byte) bool { - return bytes.Equal(cmd, []byte("delete")) -} - -func (p *Parser) isCommandIncrDecr(cmd []byte) bool { - return bytes.Equal(cmd, []byte("incr")) || - bytes.Equal(cmd, []byte("decr")) -} - -func (p *Parser) isErrorReply(firstToken []byte) bool { - return bytes.Equal(firstToken, []byte("ERROR")) || - bytes.Equal(firstToken, []byte("CLIENT_ERROR")) || - bytes.Equal(firstToken, []byte("SERVER_ERROR")) -} - -// returns injected bytes -func (p *Parser) injectFromQueue() int { - injected := 0 - for _, rep := range p.replyQueue { - if rep.denied { - injected++ - p.injectDeniedMessage() - } else { - break - } - - } - if injected > 0 { - p.replyQueue = p.replyQueue[injected:] - } - return injected * len(DeniedMsg) -} - -func (p *Parser) injectDeniedMessage() { - p.connection.Inject(true, DeniedMsg) -} - -// DeniedMsg is sent if policy denies the request. Exported for tests -var DeniedMsg = []byte("CLIENT_ERROR access denied\r\n") - -// ErrorMsg is standard memcached error line -var ErrorMsg = []byte("ERROR\r\n") diff --git a/proxylib/npds/backoff.go b/proxylib/npds/backoff.go deleted file mode 100644 index 26b2cbe01..000000000 --- a/proxylib/npds/backoff.go +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package npds - -import ( - "context" - "fmt" - "math" - "time" - - "github.com/sirupsen/logrus" -) - -// exponentialBackoff implements an exponential backoff -type exponentialBackoff struct { - // Min is the minimal backoff time, if unspecified, 1 second will be - // used - Min time.Duration - - // Max is the maximum backoff time, if unspecified, no maximum time is - // applied - Max time.Duration - - // Name is a free form string describing the operation subject to the - // backoff, if unspecified, a UUID is generated. This string is used - // for logging purposes. - Name string - - lastBackoffStart time.Time - - attempt int -} - -// calculateDuration calculates the backoff duration based on minimum base -// interval, exponential factor and number of failures. -func calculateDuration(min, max time.Duration, factor float64, failures int) time.Duration { - minFloat := float64(min) - maxFloat := float64(max) - - t := minFloat * math.Pow(factor, float64(failures)) - if max != time.Duration(0) && t > maxFloat { - t = maxFloat - } - - return time.Duration(t) -} - -// Reset backoff attempt counter -func (b *exponentialBackoff) Reset() { - b.attempt = 0 -} - -// Wait waits for the required time using an exponential backoff -func (b *exponentialBackoff) Wait(ctx context.Context) error { - if b.Name == "" { - panic("no name provided") - } - - b.lastBackoffStart = time.Now() - b.attempt++ - t := b.duration(b.attempt) - - logrus.WithFields(logrus.Fields{ - "subsys": "backoff", - "time": t, - "attempt": b.attempt, - "name": b.Name, - }).Debug("Sleeping with exponential backoff") - - select { - case <-ctx.Done(): - return fmt.Errorf("exponential backoff cancelled via context: %s", ctx.Err()) - case <-time.After(t): - } - - return nil -} - -// duration returns the wait duration for the nth attempt -func (b *exponentialBackoff) duration(attempt int) time.Duration { - min := time.Duration(1) * time.Second - if b.Min != time.Duration(0) { - min = b.Min - } - - t := calculateDuration(min, b.Max, 2, attempt) - - if b.Max != time.Duration(0) && t > b.Max { - t = b.Max - } - - return t -} diff --git a/proxylib/npds/client.go b/proxylib/npds/client.go deleted file mode 100644 index 67236b4b8..000000000 --- a/proxylib/npds/client.go +++ /dev/null @@ -1,209 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package npds - -import ( - "context" - "errors" - "fmt" - "io" - "sync" - "time" - - "github.com/sirupsen/logrus" - "google.golang.org/genproto/googleapis/rpc/status" - "google.golang.org/grpc" - - cilium "github.com/cilium/proxy/go/cilium/api" - "github.com/cilium/proxy/proxylib/proxylib" - envoy_config_core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" - envoy_service_discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" -) - -const ( - DialDelay = 100 * time.Millisecond - BackOffLimit = 100 // Max 100 times DialDelay - NPDSTypeURL = "type.googleapis.com/cilium.NetworkPolicy" -) - -type Client struct { - updater proxylib.PolicyUpdater - mutex sync.Mutex - nodeId string - path string - conn *grpc.ClientConn - stream grpc.ClientStream - closing bool -} - -func (c *Client) Close() { - c.mutex.Lock() - defer c.mutex.Unlock() - if !c.closing { - logrus.Debugf("NPDS: Client %s closing on %s", c.nodeId, c.path) - c.closing = true - if c.stream != nil { - c.stream.CloseSend() - } - if c.conn != nil { - c.conn.Close() - } - } -} - -func (c *Client) Path() string { - return c.path -} - -func NewClient(path, nodeId string, updater proxylib.PolicyUpdater) proxylib.PolicyClient { - if path == "" { - return nil - } - c := &Client{ - updater: updater, - path: path, - nodeId: nodeId, - } - logrus.Debugf("NPDS: Client %s starting on %s", c.nodeId, c.path) - - // These are used to return error if the 1st try fails - // Only used for testing and logging, as we keep on trying anyway. - startErr := make(chan error) // Channel open as long as 'starting == true' - - go func() { - starting := true - backOff := exponentialBackoff{ - Min: DialDelay, - Max: BackOffLimit * DialDelay, - Name: "proxylib NPDS client", - } - for { - err := c.Run(func() { - // Report successful start on the first try by closing the channel - if starting { - close(startErr) - starting = false - } - logrus.Debugf("NPDS: Client %s connected on %s", c.nodeId, c.path) - }) - c.mutex.Lock() - closing := c.closing - c.mutex.Unlock() - - if err != nil { - logrus.Debug(err) - if starting { - startErr <- err - close(startErr) - starting = false - } - } else { - // Reset backoff after successful start - backOff.Reset() - } - - if closing { - break - } - - // Back off before retrying - backOff.Wait(context.TODO()) - } - }() - - // Block until we know if the first connection try succeeded or failed - _ = <-startErr - return c -} - -func (c *Client) Run(connected func()) (err error) { - unixPath := "unix://" + c.path - - defer func() { - // Recover from any possible panics - if r := recover(); r != nil { - err = fmt.Errorf("NPDS Client %s: Panic: %v", c.nodeId, r) - } - }() - - // - // WithInsecure() is safe here because we are connecting to a Unix-domain socket, - // data of whch is never on the wire and security for which can be managed with file permissions. - // - conn, err := grpc.Dial(unixPath, grpc.WithInsecure()) - if err != nil { - return fmt.Errorf("NPDS: Client %s grpc.Dial() on %s failed: %s", c.nodeId, c.path, err) - } - client := cilium.NewNetworkPolicyDiscoveryServiceClient(conn) - stream, err := client.StreamNetworkPolicies(context.Background()) - if err != nil { - conn.Close() - return fmt.Errorf("NPDS: Client %s stream failed on %s: %s", c.nodeId, c.path, err) - } - c.mutex.Lock() - c.conn = conn - c.stream = stream - c.mutex.Unlock() - defer func() { - c.mutex.Lock() - c.stream.CloseSend() - c.conn.Close() - c.mutex.Unlock() - }() - - // VersionInfo must be empty as we have not received anything yet. - // ResourceNames is empty to request for all policies. - // ResponseNonce is copied from the response, initially empty. - req := envoy_service_discovery.DiscoveryRequest{ - TypeUrl: NPDSTypeURL, - VersionInfo: "", - Node: &envoy_config_core.Node{Id: c.nodeId}, - ResourceNames: nil, - ResponseNonce: "", - } - err = stream.Send(&req) - if err != nil { - return fmt.Errorf("NPDS: Client %s stream.Send() failed on %s: %s", c.nodeId, c.path, err) - } - - connected() - - for { - // Receive next policy configuration. This will block until the - // server has a new version to send, which may take a long time. - resp, err := stream.Recv() - if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { - logrus.Debugf("NPDS: Client %s stream on %s closed.", c.nodeId, c.path) - break - } - if err != nil { - return fmt.Errorf("NPDS: Client %s stream.Recv() on %s failed: %s", c.nodeId, c.path, err) - } - - // Validate the response - if resp.TypeUrl != req.TypeUrl { - msg := fmt.Sprintf("NPDS: Client %s rejecting mismatching resource type on %s: %s", c.nodeId, c.path, resp.TypeUrl) - req.ErrorDetail = &status.Status{Message: msg} - logrus.Warning(msg) - } else { - err = c.updater.PolicyUpdate(resp) - if err != nil { - msg := fmt.Sprintf("NPDS: Client %s rejecting invalid policy on %s: %s", c.nodeId, c.path, err) - req.ErrorDetail = &status.Status{Message: msg} - logrus.Warning(msg) - } else { - // Success, update the last applied version - logrus.Debugf("NPDS: Client %s acking new policy version on %s: %s", c.nodeId, c.path, resp.VersionInfo) - req.ErrorDetail = nil - req.VersionInfo = resp.VersionInfo - } - } - req.ResponseNonce = resp.Nonce - err = stream.Send(&req) - if err != nil { - return fmt.Errorf("NPDS: Client %s stream.Send() failed on %s: %s", c.nodeId, c.path, err) - } - } - return nil -} diff --git a/proxylib/proxylib.go b/proxylib/proxylib.go deleted file mode 100644 index 21779d16e..000000000 --- a/proxylib/proxylib.go +++ /dev/null @@ -1,83 +0,0 @@ -// nolint:goheader -// CGo injects a 'Code generated by ...' header here before AST parsing, ignore it. - -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package main - -/* -#include "types.h" -*/ -import "C" - -import ( - "github.com/sirupsen/logrus" - - "github.com/cilium/proxy/proxylib/libcilium" -) - -func init() { - logrus.Info("proxylib: Initializing library") -} - -// OnNewConnection is used to register a new connection of protocol 'proto'. -// Note that the 'origBuf' and replyBuf' type '*[]byte' corresponds to 'InjectBuf' type, but due to -// cgo export restrictions we can't use the go type in the prototype. -// -//export OnNewConnection -func OnNewConnection(instanceId uint64, proto string, connectionId uint64, ingress bool, srcId, dstId uint32, srcAddr, dstAddr, policyName string, origBuf, replyBuf *[]byte) C.FilterResult { - return C.FilterResult(libcilium.OnNewConnection(instanceId, proto, connectionId, ingress, srcId, dstId, srcAddr, dstAddr, policyName, origBuf, replyBuf)) -} - -// Each connection is assumed to be called from a single thread, so accessing connection metadata -// does not need protection. -// -// OnData gets all the unparsed data the datapath has received so far. The data is provided to the parser -// associated with the connection, and the parser is expected to find if the data frame contains enough data -// to make a PASS/DROP decision for the whole data frame. Note that the whole data frame need not be received, -// if the decision including the length of the data frame in bytes can be determined based on the beginning of -// the data frame only (e.g., headers including the length of the data frame). The parser returns a decision -// with the number of bytes on which the decision applies. If more data is available, then the parser will be -// called again with the remaining data. Parser needs to return MORE if a decision can't be made with -// the available data, including the minimum number of additional bytes that is needed before the parser is -// called again. -// -// The parser can also inject at arbitrary points in the data stream. This is indecated by an INJECT operation -// with the number of bytes to be injected. The actual bytes to be injected are provided via an Inject() -// callback prior to returning the INJECT operation. The Inject() callback operates on a limited size buffer -// provided by the datapath, and multiple INJECT operations may be needed to inject large amounts of data. -// Since we get the data on one direction at a time, any frames to be injected in the reverse direction -// are placed in the reverse direction buffer, from where the datapath injects the data before calling -// us again for the reverse direction input. -// -//export OnData -func OnData(connectionId uint64, reply, endStream bool, data *[][]byte, filterOps *[][2]int64) C.FilterResult { - return C.FilterResult(libcilium.OnData(connectionId, reply, endStream, data, filterOps)) -} - -// Make this more general connection event callback -// -//export Close -func Close(connectionId uint64) { - libcilium.Close(connectionId) -} - -// OpenModule is called before any other APIs. -// Called concurrently by different filter instances. -// Returns a library instance ID that must be passed to all other API calls. -// Calls with the same parameters will return the same instance. -// Zero return value indicates an error. -// -//export OpenModule -func OpenModule(params [][2]string, debug bool) uint64 { - return libcilium.OpenModule(params, debug) -} - -//export CloseModule -func CloseModule(id uint64) { - libcilium.CloseModule(id) -} - -// Must have empty main -func main() {} diff --git a/proxylib/proxylib/connection.go b/proxylib/proxylib/connection.go deleted file mode 100644 index 810e18964..000000000 --- a/proxylib/proxylib/connection.go +++ /dev/null @@ -1,259 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package proxylib - -import ( - "fmt" - "net" - "strconv" - "time" - - "github.com/sirupsen/logrus" - - cilium "github.com/cilium/proxy/go/cilium/api" -) - -// A parser sees data from the underlying stream in both directions -// (original, connection open direction and the opposite, the reply -// direction). Each call to the filter returns an ordered set of -// operations to be performed on the data in that direction. Any data -// left over after the returned operations must be buffered by the -// caller and passed in again when more data has been received on the -// connection. - -// InjectBuf is a pointer to a slice header for an inject buffer allocated by -// the proxylib caller. As data is placed into the buffer, the length -// of the buffer in the slice header is increased correspondingly. To make -// the the injected data visible to the caller we need to pass the slice header -// by reference rather than by value, hence the pointer in the type. -// As the caller is typically in a differnent memory management domain (not -// subject to Go runtime garbage collection), the underlying buffer may never -// be expanded or otherwise reallocated. -type InjectBuf *[]byte - -// Connection holds the connection metadata that is used both for -// policy enforcement and access logging. -type Connection struct { - Instance *Instance // Holder of Policy protocol and access logging clients - Id uint64 // Unique connection ID allocated by the caller - Ingress bool // 'true' for ingress, 'false' for egress - SrcId uint32 // Source security ID, may be mapped from the source IP address - DstId uint32 // Destination security ID, may be mapped from the destination IP address - SrcAddr string // Source IP address in "a.b.c.d:port" or "[A:...:C]:port" format - DstAddr string // Original destination IP address - PolicyName string // Identifies which policy instance applies to this connection - Port uint32 // (original) destination port number in numeric format - - ParserName string // Name of the parser - Parser interface{} // Parser instance used on this connection - Reader Reader - OrigBuf InjectBuf // Buffer for injected frames in original direction - ReplyBuf InjectBuf // Buffer for injected frames in reply direction -} - -func NewConnection(instance *Instance, proto string, connectionId uint64, ingress bool, srcId, dstId uint32, srcAddr, dstAddr, policyName string, origBuf, replyBuf *[]byte) (error, *Connection) { - // Find the parser for the proto - parserFactory := GetParserFactory(proto) - if parserFactory == nil { - return UNKNOWN_PARSER, nil - } - _, port, err := net.SplitHostPort(dstAddr) - if err != nil { - return INVALID_ADDRESS, nil - } - dstPort, err := strconv.ParseUint(port, 10, 32) - if err != nil || dstPort == 0 { - return INVALID_ADDRESS, nil - } - - connection := &Connection{ - Instance: instance, - Id: connectionId, - Ingress: ingress, - SrcId: srcId, - DstId: dstId, - SrcAddr: srcAddr, - DstAddr: dstAddr, - Port: uint32(dstPort), - PolicyName: policyName, - ParserName: proto, - OrigBuf: origBuf, - ReplyBuf: replyBuf, - } - connection.Parser = parserFactory.Create(connection) - if connection.Parser == nil { - // Parser rejected the new connection based on the connection metadata - return POLICY_DROP, nil - } - - return nil, connection -} - -// Skip bytes in input, or exhaust the input. -func advanceInput(input [][]byte, bytes int) [][]byte { - for bytes > 0 && len(input) > 0 { - rem := len(input[0]) // this much data left in the first slice - if bytes < rem { - input[0] = input[0][bytes:] // skip 'bytes' bytes - bytes = 0 - } else { // go to the beginning of the next unit - bytes -= rem - input = input[1:] // may result in an empty slice - } - } - return input -} - -func (connection *Connection) OnData(reply, endStream bool, data *[][]byte, filterOps *[][2]int64) (res FilterResult) { - defer func() { - // Recover from any possible parser datapath panics - if r := recover(); r != nil { - // Log the Panic into accesslog - connection.Log(cilium.EntryType_Denied, - &cilium.LogEntry_GenericL7{ - GenericL7: &cilium.L7LogEntry{ - Proto: connection.ParserName, - Fields: map[string]string{ - // "status" is shown in Cilium monitor - "status": fmt.Sprintf("Panic: %s", r), - }, - }, - }) - res = PARSER_ERROR // Causes the connection to be dropped - } - }() - - if parser, ok := connection.Parser.(Parser); ok { - input := *data - // Loop until `filterOps` becomes full, or parser is done with the data. - for len(*filterOps) < cap(*filterOps) { - op, bytes := parser.OnData(reply, endStream, input) - if op == NOP { - break // No operations after NOP - } - if bytes == 0 { - return PARSER_ERROR - } - *filterOps = append(*filterOps, [2]int64{int64(op), int64(bytes)}) - - if op == MORE { - // Need more data before can parse ahead. - // Parser will see the unused data again in the next call, which will take place - // after there are at least 'bytes' of additional data to parse. - break - } - - if op == PASS || op == DROP { - input = advanceInput(input, bytes) - // Loop back to parser even if have no more data to allow the parser to - // inject frames at the end of the input. - } - - // Injection does not advance input data, but instructs the datapath to - // send data the parser has placed in the inject buffer. We need to stop processing - // if inject buffer becomes full as the parser in this case can't inject any more - // data. - if op == INJECT && connection.IsInjectBufFull(reply) { - // return if inject buffer becomes full - break - } - } - } else if parser, ok := connection.Parser.(ReaderParser); ok { - connection.Reader = NewReader(*data, endStream) - // Loop until `filterOps` becomes full, or parser is done with the data. - for len(*filterOps) < cap(*filterOps) { - op, bytes := parser.OnData(reply, &connection.Reader) - if op == NOP { - break // No operations after NOP - } - if bytes == 0 { - return PARSER_ERROR - } - *filterOps = append(*filterOps, [2]int64{int64(op), int64(bytes)}) - - if op == MORE { - // Need more data before can parse ahead. - // Parser will see the unused data again in the next call, which will take place - // after there are at least 'bytes' of additional data to parse. - break - } - - // Get the current read count && reset for the next round - read := connection.Reader.Reset() - - if op == PASS || op == DROP { - // Andvance input if needed - if bytes > read { - connection.Reader.AdvanceInput(bytes - read) - } - // Loop back to parser even if have no more data to allow the parser to - // inject frames at the end of the input. - } - - // Injection does not advance input data, but instructs the datapath to - // send data the parser has placed in the inject buffer. We need to stop processing - // if inject buffer becomes full as the parser in this case can't inject any more - // data. - if op == INJECT && connection.IsInjectBufFull(reply) { - // return if inject buffer becomes full - break - } - } - } - return OK -} - -func (connection *Connection) Matches(l7 interface{}) bool { - logrus.Debugf("proxylib: Matching policy on connection %v", connection) - remoteID := connection.DstId - if connection.Ingress { - remoteID = connection.SrcId - } - return connection.Instance.PolicyMatches(connection.PolicyName, connection.Ingress, connection.Port, remoteID, l7) -} - -// getInjectBuf return the pointer to the inject buffer slice header for the indicated direction -func (connection *Connection) getInjectBuf(reply bool) InjectBuf { - if reply { - return connection.ReplyBuf - } - return connection.OrigBuf -} - -// inject buffers data to be injected into the connection at the point of INJECT -func (connection *Connection) Inject(reply bool, data []byte) int { - buf := connection.getInjectBuf(reply) - // append data to C-provided buffer - offset := len(*buf) - n := copy((*buf)[offset:cap(*buf)], data) - *buf = (*buf)[:offset+n] // update the buffer length - - logrus.Debugf("proxylib: Injected %d bytes: %s (given: %s)", n, string((*buf)[offset:offset+n]), string(data)) - - // return the number of bytes injected. This may be less than the length of `data` is - // the buffer becomes full. - // Parser may opt dropping the connection via parser error in this case! - return n -} - -// isInjectBufFull return true if the inject buffer for the indicated direction is full -func (connection *Connection) IsInjectBufFull(reply bool) bool { - buf := connection.getInjectBuf(reply) - return len(*buf) == cap(*buf) -} - -func (conn *Connection) Log(entryType cilium.EntryType, l7 cilium.IsLogEntry_L7) { - pblog := &cilium.LogEntry{ - Timestamp: uint64(time.Now().UnixNano()), - IsIngress: conn.Ingress, - EntryType: entryType, - PolicyName: conn.PolicyName, - SourceSecurityId: conn.SrcId, - DestinationSecurityId: conn.DstId, - SourceAddress: conn.SrcAddr, - DestinationAddress: conn.DstAddr, - L7: l7, - } - conn.Instance.Log(pblog) -} diff --git a/proxylib/proxylib/input_test.go b/proxylib/proxylib/input_test.go deleted file mode 100644 index f1e477da7..000000000 --- a/proxylib/proxylib/input_test.go +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package proxylib - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestAdvanceInput(t *testing.T) { - input := [][]byte{[]byte("ABCD"), []byte("1234567890"), []byte("abcdefghij")} - - require.Equal(t, byte('A'), input[0][0]) - require.Len(t, input, 3) // Three slices in input - - // Advance to one byte before the end of the first slice - input = advanceInput(input, 3) - require.Len(t, input, 3) // Still in the first slice - require.Len(t, input[0], 1) - require.Equal(t, byte('D'), input[0][0]) - - // Advance to the beginning of the next slice - input = advanceInput(input, 1) - require.Len(t, input, 2) // Moved to the next slice - require.Equal(t, byte('1'), input[0][0]) - - // Advance 11 bytes, crossing to the next slice - input = advanceInput(input, 11) - require.Len(t, input, 1) // Moved to the 3rd slice - require.Equal(t, byte('b'), input[0][0]) - - // Try to advance 11 bytes when only 9 remmain - input = advanceInput(input, 11) - require.Len(t, input, 0) // All data exhausted - - // Try advance on an empty slice - input = advanceInput(input, 1) - require.Len(t, input, 0) -} diff --git a/proxylib/proxylib/instance.go b/proxylib/proxylib/instance.go deleted file mode 100644 index 4370fdacb..000000000 --- a/proxylib/proxylib/instance.go +++ /dev/null @@ -1,221 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package proxylib - -import ( - "fmt" - "sync" - "sync/atomic" - - "google.golang.org/protobuf/proto" - "github.com/sirupsen/logrus" - - cilium "github.com/cilium/proxy/go/cilium/api" - envoy_service_discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" -) - -type PolicyClient interface { - Close() - Path() string -} - -type AccessLogger interface { - Log(pblog *cilium.LogEntry) - Close() - Path() string -} - -type PolicyUpdater interface { - PolicyUpdate(resp *envoy_service_discovery.DiscoveryResponse) error -} - -type Instance struct { - id uint64 - openCount uint64 - nodeID string - accessLogger AccessLogger - policyClient PolicyClient - - policyMap atomic.Value // holds PolicyMap -} - -var ( - // mutex protects instances - mutex sync.RWMutex - // Key uint64 is a monotonically increasing instance ID - instances map[uint64]*Instance = make(map[uint64]*Instance) - // Last instance ID used - instanceId uint64 = 0 -) - -func NewInstance(nodeID string, accessLogger AccessLogger) *Instance { - instanceId++ - - if nodeID == "" { - nodeID = fmt.Sprintf("host~127.0.0.2~libcilium-%d~localdomain", instanceId) - } - - ins := &Instance{ - id: instanceId, - openCount: 1, - nodeID: nodeID, - accessLogger: accessLogger, - } - ins.setPolicyMap(newPolicyMap()) - - return ins -} - -// OpenInstance creates a new instance or finds an existing one with equivalent parameters. -// returns the instance id. -func OpenInstance(nodeID string, xdsPath string, newPolicyClient func(path, nodeID string, updater PolicyUpdater) PolicyClient, - accessLogPath string, newAccessLogger func(accessLogPath string) AccessLogger, -) uint64 { - mutex.Lock() - defer mutex.Unlock() - - // Check if have an instance with these params already - for id, old := range instances { - oldXdsPath := "" - if old.policyClient != nil { - oldXdsPath = old.policyClient.Path() - } - oldAccessLogPath := "" - if old.accessLogger != nil { - oldAccessLogPath = old.accessLogger.Path() - } - if (nodeID == "" || old.nodeID == nodeID) && xdsPath == oldXdsPath && accessLogPath == oldAccessLogPath { - old.openCount++ - logrus.Debugf("Opened existing library instance %d, open count: %d", id, old.openCount) - return id - } - } - - ins := NewInstance(nodeID, newAccessLogger(accessLogPath)) - // policy client needs the instance so we set it after instance has been created - ins.policyClient = newPolicyClient(xdsPath, ins.nodeID, ins) - - instances[instanceId] = ins - - logrus.Debugf("Opened new library instance %d", instanceId) - - return instanceId -} - -func FindInstance(id uint64) *Instance { - mutex.RLock() - defer mutex.RUnlock() - return instances[id] -} - -// Close returns the new open count -func CloseInstance(id uint64) uint64 { - mutex.Lock() - defer mutex.Unlock() - - count := uint64(0) - if ins, ok := instances[id]; ok { - ins.openCount-- - count = ins.openCount - if count == 0 { - if ins.policyClient != nil { - ins.policyClient.Close() - } - if ins.accessLogger != nil { - ins.accessLogger.Close() - } - delete(instances, id) - } - logrus.Debugf("CloseInstance(%d): Remaining open count: %d", id, count) - } else { - logrus.Debugf("CloseInstance(%d): Not found (closed already?)", id) - } - return count -} - -func (ins *Instance) getPolicyMap() PolicyMap { - return ins.policyMap.Load().(PolicyMap) -} - -func (ins *Instance) setPolicyMap(newMap PolicyMap) { - ins.policyMap.Store(newMap) -} - -func (ins *Instance) PolicyMatches(endpointPolicyName string, ingress bool, port, remoteId uint32, l7 interface{}) bool { - // Policy maps are never modified once published - policy, found := ins.getPolicyMap()[endpointPolicyName] - if !found { - logrus.Debugf("NPDS: Policy for %s not found", endpointPolicyName) - } - - return found && policy.Matches(ingress, port, remoteId, l7) -} - -// Update the PolicyMap from a protobuf. PolicyMap is only ever changed if the whole update is successful. -func (ins *Instance) PolicyUpdate(resp *envoy_service_discovery.DiscoveryResponse) (err error) { - defer func() { - if r := recover(); r != nil { - var ok bool - if err, ok = r.(error); !ok { - err = fmt.Errorf("NPDS: Panic: %v", r) - } - } - }() - - logrus.Debugf("NPDS: Updating policy for version %s", resp.VersionInfo) - - oldMap := ins.getPolicyMap() - newMap := newPolicyMap() - - for _, any := range resp.Resources { - if any.TypeUrl != resp.TypeUrl { - return fmt.Errorf("NPDS: Mismatching TypeUrls: %s != %s", any.TypeUrl, resp.TypeUrl) - } - var config cilium.NetworkPolicy - if err = proto.Unmarshal(any.Value, &config); err != nil { - return fmt.Errorf("NPDS: Policy unmarshal error: %v", err) - } - - ips := config.GetEndpointIps() - if len(ips) == 0 { - return fmt.Errorf("NPDS: Policy has no endpoint_ips") - } - for _, ip := range ips { - logrus.Debugf("NPDS: Endpoint IP: %s", ip) - } - // Locate the old version, if any - oldPolicy, found := oldMap[ips[0]] - if found { - // Check if the new policy is the same as the old one - if proto.Equal(&config, oldPolicy.protobuf) { - logrus.Debugf("NPDS: New policy for Endpoint %d is equal to the old one, no need to change", config.GetEndpointId()) - for _, ip := range ips { - newMap[ip] = oldPolicy - } - continue - } - } - - // Validate new config - if err = config.Validate(); err != nil { - return fmt.Errorf("NPDS: Policy validation error for Endpoint %d: %v", config.GetEndpointId(), err) - } - - // Create new PolicyInstance, may panic. Takes ownership of 'config'. - newPolicy := newPolicyInstance(&config) - for _, ip := range ips { - newMap[ip] = newPolicy - } - } - - // Store the new policy map - ins.setPolicyMap(newMap) - - logrus.Debugf("NPDS: Policy Update completed for instance %d: %v", ins.id, newMap) - return -} - -func (ins *Instance) Log(pblog *cilium.LogEntry) { - ins.accessLogger.Log(pblog) -} diff --git a/proxylib/proxylib/parserfactory.go b/proxylib/proxylib/parserfactory.go deleted file mode 100644 index 7b0779f14..000000000 --- a/proxylib/proxylib/parserfactory.go +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package proxylib - -import ( - "github.com/sirupsen/logrus" -) - -// Parser is a paser instance used for each connection. OnData will be called from a single thread only. -type Parser interface { - // OnData is called when input is available on the underlying connection. The Parser - // instance is only ever used for processing data of a single connection, which allows - // the parser instance to keep connection specific state. All OnData() calls for a - // single connection (both directions) are made from a single thread, so that - // no locking is needed for the parser instance if no other goroutines need to access - // the parser instance. (Note that any L7 policy protocol rule parsing happens in - // other goroutine so any such parsing should not access parser instances directly.) - // - // OnData() parameters are as follows: - // 'reply' is 'false' for original direction of the connection, 'true' otherwise. - // 'endStream' is true if there is no more data after 'data' in this direction. - // 'data' is the available data in the current direction. The datapath buffers - // partial frames as instructed by the operations returned by the parser - // so that the 'data' always starts on a frame boundary. That is, whenever - // the parser returns `MORE` indicating it needs more input, the bytes - // not 'PASS'ed or 'DROP'ped are retained in a datapath buffer and those - // same bytes are passed to the parser again when more input is available. - // 'data' may be an empty slice, but the slices contained are never empty. - // - // OnData() returns an operation and the number of bytes ('N') the operation applies. - // The possible values for 'op' are: - // 'MORE' - Data currently in 'data' is to be retained by the datapath and passed - // again to OnData() after 'N' bytes more data is available. - // 'PASS' - Allow 'N' bytes. - // 'DROP' - Drop 'N' bytes and call OnData() again for the remaining data. - // 'INJECT' - Insert 'N' bytes of data placed into the inject buffer in to the - // data stream in this direction. - // 'NOP' - Do nothing, to be used when it is known if no more input - // is to be expected. - // 'ERROR' - Protocol parsing failed and the connection should be closed. - // - // OnData() is called again after 'PASS', 'DROP', and 'INJECT' with the remaining - // data even if none remains. - OnData(reply, endStream bool, data [][]byte) (op OpType, N int) -} - -// ReaderParser is an alternate parser instance is used for each connection. OnData will be called from a single thread only. -type ReaderParser interface { - // OnData is called when input is available on the underlying connection. The Parser - // instance is only ever used for processing data of a single connection, which allows - // the parser instance to keep connection specific state. All OnData() calls for a - // single connection (both directions) are made from a single thread, so that - // no locking is needed for the parser instance if no other goroutines need to access - // the parser instance. (Note that any L7 policy protocol rule parsing happens in - // other goroutine so any such parsing should not access parser instances directly.) - // - // OnData() parameters are as follows: - // 'reply' is 'false' for original direction of the connection, 'true' otherwise. - // 'endStream' is true if there is no more data after 'data' in this direction. - // 'data' is the available data in the current direction. The datapath buffers - // partial frames as instructed by the operations returned by the parser - // so that the 'data' always starts on a frame boundary. That is, whenever - // the parser returns `MORE` indicating it needs more input, the bytes - // not 'PASS'ed or 'DROP'ped are retained in a datapath buffer and those - // same bytes are passed to the parser again when more input is available. - // 'data' may be an empty slice, but the slices contained are never empty. - // - // OnData() returns an operation and the number of bytes ('N') the operation applies. - // The possible values for 'op' are: - // 'MORE' - Data currently in 'data' is to be retained by the datapath and passed - // again to OnData() after 'N' bytes more data is available. - // 'PASS' - Allow 'N' bytes. - // 'DROP' - Drop 'N' bytes and call OnData() again for the remaining data. - // 'INJECT' - Insert 'N' bytes of data placed into the inject buffer in to the - // data stream in this direction. - // 'NOP' - Do nothing, to be used when it is known if no more input - // is to be expected. - // 'ERROR' - Protocol parsing failed and the connection should be closed. - // - // OnData() is called again after 'PASS', 'DROP', and 'INJECT' with the remaining - // data even if none remains. - OnData(reply bool, reader *Reader) (op OpType, N int) -} - -type ParserFactory interface { - Create(connection *Connection) interface{} // must be thread safe! -} - -// const after initialization -var parserFactories map[string]ParserFactory = make(map[string]ParserFactory) - -// RegisterParserFactory adds a protocol parser factory to the map of known parsers. -// This is called from parser init() functions while we are still single-threaded -func RegisterParserFactory(name string, parserFactory ParserFactory) { - logrus.Debugf("proxylib: Registering L7 parser: %v", name) - parserFactories[name] = parserFactory -} - -func GetParserFactory(name string) ParserFactory { - return parserFactories[name] -} diff --git a/proxylib/proxylib/policymap.go b/proxylib/proxylib/policymap.go deleted file mode 100644 index e3cc702eb..000000000 --- a/proxylib/proxylib/policymap.go +++ /dev/null @@ -1,286 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package proxylib - -import ( - "fmt" - "reflect" - "strings" - - "github.com/sirupsen/logrus" - - cilium "github.com/cilium/proxy/go/cilium/api" - core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" -) - -// L7NetworkPolicyRule is the interface, which each L7 rule implements this interface -type L7NetworkPolicyRule interface { - Matches(interface{}) bool -} - -// L7RuleParser takes the protobuf and converts the one of relevant for the given L7 to an array -// of L7 rules. A packet matches if the 'Matches' method of any of these rules matches the -// 'l7' interface passed by the L7 implementation to PolicyMap.Matches() as the last parameter. -type L7RuleParser func(rule *cilium.PortNetworkPolicyRule) []L7NetworkPolicyRule - -// const after initialization -var l7RuleParsers map[string]L7RuleParser = make(map[string]L7RuleParser) - -// RegisterL7RuleParser adds a l7 policy protocol parser to the map of known l7 policy parsers. -// This is called from parser init() functions while we are still single-threaded -func RegisterL7RuleParser(l7PolicyTypeName string, parserFunc L7RuleParser) { - logrus.Debugf("NPDS: Registering L7 rule parser: %s", l7PolicyTypeName) - l7RuleParsers[l7PolicyTypeName] = parserFunc -} - -// ParseError may be issued by Policy parsing code. The policy configuration change will -// be graciously rejected by recovering from the panic. -func ParseError(reason string, config interface{}) { - panic(fmt.Errorf("NPDS: %s (config: %v)", reason, config)) -} - -type PortNetworkPolicyRule struct { - Deny bool - Remotes map[uint32]struct{} - L7Rules []L7NetworkPolicyRule // only used when not denied -} - -func newPortNetworkPolicyRule(config *cilium.PortNetworkPolicyRule) (PortNetworkPolicyRule, string, bool) { - rule := PortNetworkPolicyRule{ - Deny: config.GetDeny(), - Remotes: make(map[uint32]struct{}, len(config.RemotePolicies)), - } - action := "Allowing" - if rule.Deny { - action = "Denying" - } - for _, remote := range config.GetRemotePolicies() { - logrus.Debugf("NPDS::PortNetworkPolicyRule: %s remote %d", action, remote) - rule.Remotes[remote] = struct{}{} - } - - // Each parser registers a parsing function to parse it's L7 rules - // The registered name must match 'l7_proto', if included in the message, - // or one of the oneof type names - l7Name := config.L7Proto - if l7Name == "" { - typeOf := reflect.TypeOf(config.L7) - if typeOf != nil { - l7Name = typeOf.Elem().Name() - } - } - if strings.HasPrefix(l7Name, "envoy.") { - return rule, "", false // Silently drop Envoy filter traffic to this port if forwarded to proxylib - } - if l7Name != "" { - l7Parser, ok := l7RuleParsers[l7Name] - if ok { - if logrus.IsLevelEnabled(logrus.DebugLevel) { - logrus.Debugf("NPDS::PortNetworkPolicyRule: Calling L7Parser %s on %v", l7Name, config.String()) - } - rule.L7Rules = l7Parser(config) - } else { - logrus.Debugf("NPDS::PortNetworkPolicyRule: Unknown L7 (%s), should drop everything.", l7Name) - } - // Unknown parsers are expected, but will result in drop-all policy - return rule, l7Name, ok - } - return rule, "", true // No L7 is ok -} - -func (p *PortNetworkPolicyRule) Matches(remoteId uint32, l7 interface{}) (allowed, denied bool) { - // Remote ID must match if we have any. - if len(p.Remotes) > 0 { - _, found := p.Remotes[remoteId] - if !found { - if logrus.IsLevelEnabled(logrus.DebugLevel) { - logrus.Debugf("NPDS::PortNetworkPolicyRule: No L3 match on (%v)", *p) - } - // no remote ID match, does not allow or deny explicitly - return false, false - } - if p.Deny { - // Explicit deny, not allowed even if another rule would allow. - return false, true - } - } else if p.Deny { - // Deny with empty remotes denies all remotes explicitly - return false, true - } - if len(p.L7Rules) > 0 { - for _, rule := range p.L7Rules { - if rule.Matches(l7) { - if logrus.IsLevelEnabled(logrus.DebugLevel) { - logrus.Debugf("NPDS::PortNetworkPolicyRule: L7 rule matches (%v)", *p) - } - return true, false - } - } - return false, false - } - // Empty set matches any payload - if logrus.IsLevelEnabled(logrus.DebugLevel) { - logrus.Debugf("NPDS::PortNetworkPolicyRule: Empty L7Rules matches (%v)", *p) - } - return true, false -} - -type PortNetworkPolicyRules struct { - Rules []PortNetworkPolicyRule -} - -func newPortNetworkPolicyRules(config []*cilium.PortNetworkPolicyRule, port uint32) (PortNetworkPolicyRules, bool) { - rules := PortNetworkPolicyRules{ - Rules: make([]PortNetworkPolicyRule, 0, len(config)), - } - if len(config) == 0 { - logrus.Debugf("NPDS::PortNetworkPolicyRules: No rules, will allow everything.") - } - var firstTypeName string - for _, rule := range config { - newRule, typeName, ok := newPortNetworkPolicyRule(rule) - if !ok { - // Unknown L7 parser, must drop all traffic - return PortNetworkPolicyRules{}, false - } - if typeName != "" { - if firstTypeName == "" { - firstTypeName = typeName - } else if typeName != firstTypeName { - ParseError("Mismatching L7 types on the same port", config) - } - } - rules.Rules = append(rules.Rules, newRule) - } - return rules, true -} - -func (p *PortNetworkPolicyRules) Matches(remoteId uint32, l7 interface{}) bool { - // Empty set matches any payload from anyone - if len(p.Rules) == 0 { - if logrus.IsLevelEnabled(logrus.DebugLevel) { - logrus.Debugf("NPDS::PortNetworkPolicyRules: No Rules; matches (%v)", p) - } - return true - } - var allowed bool - for _, rule := range p.Rules { - allow, deny := rule.Matches(remoteId, l7) - if deny { - // explicit deny - return false - } - if allow { - // allowed if no other rule denies - allowed = true - } - } - if allowed { - if logrus.IsLevelEnabled(logrus.DebugLevel) { - logrus.Debugf("NPDS::PortNetworkPolicyRules(remoteId=%d): rule matches (%v)", remoteId, p) - } - return true - } - return false -} - -type PortNetworkPolicies struct { - Rules map[uint32]PortNetworkPolicyRules -} - -func newPortNetworkPolicies(config []*cilium.PortNetworkPolicy, dir string) PortNetworkPolicies { - policy := PortNetworkPolicies{ - Rules: make(map[uint32]PortNetworkPolicyRules, len(config)), - } - for _, rule := range config { - // Ignore UDP policies - if rule.GetProtocol() == core.SocketAddress_UDP { - continue - } - - port := rule.GetPort() - if _, found := policy.Rules[port]; found { - ParseError(fmt.Sprintf("Duplicate port number %d in (rule: %v)", port, rule), config) - } - - if rule.GetProtocol() != core.SocketAddress_TCP { - ParseError(fmt.Sprintf("Invalid transport protocol %v", rule.GetProtocol()), config) - } - - // Skip the port if not 'ok' - rules, ok := newPortNetworkPolicyRules(rule.GetRules(), port) - if ok { - logrus.Debugf("NPDS::PortNetworkPolicies(): installed %s TCP policy for port %d", dir, port) - policy.Rules[port] = rules - } else { - logrus.Debugf("NPDS::PortNetworkPolicies(): Skipped %s port due to unsupported L7: %d", dir, port) - } - } - return policy -} - -func (p *PortNetworkPolicies) Matches(port, remoteId uint32, l7 interface{}) bool { - rules, found := p.Rules[port] - if found { - if rules.Matches(remoteId, l7) { - if logrus.IsLevelEnabled(logrus.DebugLevel) { - logrus.Debugf("NPDS::PortNetworkPolicies(port=%d, remoteId=%d): rule matches (%v)", port, remoteId, p) - } - return true - } - } - // No exact port match, try wildcard - rules, foundWc := p.Rules[0] - if foundWc { - if rules.Matches(remoteId, l7) { - if logrus.IsLevelEnabled(logrus.DebugLevel) { - logrus.Debugf("NPDS::PortNetworkPolicies(port=*, remoteId=%d): rule matches (%v)", remoteId, p) - } - return true - } - } - - // No policy for the port was found. Cilium always creates a policy for redirects it - // creates, so the host proxy never gets here. - // TODO: Change back to false only when non-bpf datapath is supported? - - // logrus.Debugf("NPDS::PortNetworkPolicies(port=%d, remoteId=%d): allowing traffic on port for which there is no policy, assuming L3/L4 has passed it! (%v)", port, remoteId, p) - // return !(found || foundWc) - if !(found || foundWc) { - logrus.Debugf("NPDS::PortNetworkPolicies(port=%d, remoteId=%d): Dropping traffic on port for which there is no policy! (%v)", port, remoteId, p) - } - return false -} - -type PolicyInstance struct { - protobuf *cilium.NetworkPolicy - Ingress PortNetworkPolicies - Egress PortNetworkPolicies -} - -func newPolicyInstance(config *cilium.NetworkPolicy) *PolicyInstance { - logrus.Debugf("NPDS::PolicyInstance: Inserting policy for %v", config.EndpointIps) - return &PolicyInstance{ - protobuf: config, - Ingress: newPortNetworkPolicies(config.GetIngressPerPortPolicies(), "ingress"), - Egress: newPortNetworkPolicies(config.GetEgressPerPortPolicies(), "egress"), - } -} - -func (p *PolicyInstance) Matches(ingress bool, port, remoteId uint32, l7 interface{}) bool { - if logrus.IsLevelEnabled(logrus.DebugLevel) { - logrus.Debugf("NPDS::PolicyInstance::Matches(ingress: %v, port: %d, remoteId: %d, l7: %v (policy: %s)", ingress, port, remoteId, l7, p.protobuf.String()) - } - if ingress { - return p.Ingress.Matches(port, remoteId, l7) - } - return p.Egress.Matches(port, remoteId, l7) -} - -// Network policies keyed by endpoint IPs -type PolicyMap map[string]*PolicyInstance - -func newPolicyMap() PolicyMap { - return make(PolicyMap) -} diff --git a/proxylib/proxylib/reader.go b/proxylib/proxylib/reader.go deleted file mode 100644 index 8a26db630..000000000 --- a/proxylib/proxylib/reader.go +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package proxylib - -import ( - "io" -) - -type Reader struct { - buf [][]byte // buffer that shrinks as data is being read - read int // Number of byte read since last reset - endStream bool // connection is known to end (in this direction) after the current input -} - -func NewReader(input [][]byte, endStream bool) Reader { - return Reader{ - buf: input, - endStream: endStream, - } -} - -func (r *Reader) Reset() int { - read := r.read - r.read = 0 - return read -} - -func (r *Reader) Length() int { - length := 0 - for i := 0; i < len(r.buf); i++ { - length += len(r.buf[i]) - } - return length -} - -func (r *Reader) PeekFull(p []byte) (n int, err error) { - n = 0 - slice := 0 - index := 0 - for n < len(p) && slice < len(r.buf) { - bytes := len(r.buf[slice][index:]) - nc := copy(p[n:], r.buf[slice][index:]) - if nc == bytes { - // next slice please - slice++ - index = 0 - } else { - // move ahead in the same slice - index += nc - } - n += nc - } - if n < len(p) { - return n, io.EOF - } - return n, nil -} - -func (r *Reader) Read(p []byte) (n int, err error) { - n = 0 - for n < len(p) && len(r.buf) > 0 { - nc := copy(p[n:], r.buf[0]) - if nc == len(r.buf[0]) { - // next slice please - r.buf = r.buf[1:] - } else { - // move ahead in the same slice - r.buf[0] = r.buf[0][nc:] - } - n += nc - } - if n == 0 { - return 0, io.EOF - } - r.read += n - return n, nil -} - -// Skip bytes in input, or exhaust the input. -func (r *Reader) AdvanceInput(bytes int) { - for bytes > 0 && len(r.buf) > 0 { - rem := len(r.buf[0]) // this much data left in the first slice - if bytes < rem { - r.buf[0] = r.buf[0][bytes:] // skip 'bytes' bytes - return - } else { // go to the beginning of the next unit - bytes -= rem - r.buf = r.buf[1:] // may result in an empty slice - } - } -} diff --git a/proxylib/proxylib/test_util.go b/proxylib/proxylib/test_util.go deleted file mode 100644 index a546fc658..000000000 --- a/proxylib/proxylib/test_util.go +++ /dev/null @@ -1,122 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package proxylib - -import ( - "testing" - - "google.golang.org/protobuf/encoding/prototext" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/anypb" - "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" - - envoy_service_discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" - - cilium "github.com/cilium/proxy/go/cilium/api" -) - -var LogFatal = func(format string, args ...interface{}) { - logrus.Fatalf(format, args...) -} - -func (ins *Instance) CheckInsertPolicyText(tb testing.TB, version string, policies []string) { - err := ins.InsertPolicyText(version, policies, "") - require.NoError(tb, err) -} - -func (ins *Instance) InsertPolicyText(version string, policies []string, expectFail string) error { - typeUrl := "type.googleapis.com/cilium.NetworkPolicy" - resources := make([]*anypb.Any, 0, len(policies)) - - for _, policy := range policies { - pb := new(cilium.NetworkPolicy) - err := prototext.Unmarshal([]byte(policy), pb) - if err != nil { - if expectFail != "unmarshal" { - LogFatal("Policy UnmarshalText failed: %v", err) - } - return err - } - logrus.Debugf("Text -> proto.Message: %s -> %v", policy, pb) - data, err := proto.Marshal(pb) - if err != nil { - if expectFail != "marshal" { - LogFatal("Policy marshal failed: %v", err) - } - return err - } - - resources = append(resources, &anypb.Any{ - TypeUrl: typeUrl, - Value: data, - }) - } - - msg := &envoy_service_discovery.DiscoveryResponse{ - VersionInfo: version, - Canary: false, - TypeUrl: typeUrl, - Nonce: "randomNonce1", - Resources: resources, - } - - err := ins.PolicyUpdate(msg) - if err != nil { - if expectFail != "update" { - LogFatal("Policy Update failed: %v", err) - } - } - return err -} - -var connectionID uint64 - -func (ins *Instance) CheckNewConnectionOK(tb testing.TB, proto string, ingress bool, srcId, dstId uint32, srcAddr, dstAddr, policyName string) *Connection { - err, conn := ins.CheckNewConnection(proto, ingress, srcId, dstId, srcAddr, dstAddr, policyName) - require.NoError(tb, err) - require.NotNil(tb, conn) - return conn -} - -func (ins *Instance) CheckNewConnection(proto string, ingress bool, srcId, dstId uint32, srcAddr, dstAddr, policyName string) (error, *Connection) { - connectionID++ - bufSize := 1024 - origBuf := make([]byte, 0, bufSize) - replyBuf := make([]byte, 0, bufSize) - - return NewConnection(ins, proto, connectionID, ingress, srcId, dstId, srcAddr, dstAddr, policyName, &origBuf, &replyBuf) -} - -func (conn *Connection) CheckOnDataOK(tb testing.TB, reply, endStream bool, data *[][]byte, expReplyBuf []byte, expOps ...interface{}) { - conn.CheckOnData(tb, reply, endStream, data, OK, expReplyBuf, expOps...) -} - -func (conn *Connection) CheckOnData(tb testing.TB, reply, endStream bool, data *[][]byte, expResult FilterResult, expReplyBuf []byte, expOps ...interface{}) { - ops := make([][2]int64, 0, len(expOps)/2) - - res := conn.OnData(reply, endStream, data, &ops) - require.Equal(tb, expResult, res) - require.Equal(tb, len(expOps)/2, len(ops), "Unexpected number of filter operations") - - for i, op := range ops { - if i*2+1 < len(expOps) { - expOp, ok := expOps[i*2].(OpType) - require.Truef(tb, ok, "Invalid expected operation type") - require.Equal(tb, int64(expOp), op[0], "Unexpected filter operation") - expN, ok := expOps[i*2+1].(int) - require.Truef(tb, ok, "Invalid expected operation length (must be int)") - require.Equal(tb, int64(expN), op[1], "Unexpected operation length") - } - } - - buf := conn.ReplyBuf - require.ElementsMatch(tb, expReplyBuf, *buf) - *buf = (*buf)[:0] // make empty again - - // Clear the same-direction inject buffer, simulating the datapath forwarding the injected data - injectBuf := conn.getInjectBuf(reply) - *injectBuf = (*injectBuf)[:0] - logrus.Debugf("proxylib test helper: Cleared inject buf, used %d/%d", len(*injectBuf), cap(*injectBuf)) -} diff --git a/proxylib/proxylib/types.go b/proxylib/proxylib/types.go deleted file mode 100644 index ddbd736f3..000000000 --- a/proxylib/proxylib/types.go +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package proxylib - -import "fmt" - -// OpType mirrors enum FilterOpType in types.h. -type OpType int64 - -const ( - MORE OpType = iota - PASS - DROP - INJECT - ERROR - - // Internal types not exposed to Caller - NOP OpType = 256 -) - -// OpError mirrors enum FilterOpError in types.h. -type OpError int64 - -const ( - ERROR_INVALID_OP_LENGTH OpError = iota + 1 - ERROR_INVALID_FRAME_TYPE - ERROR_INVALID_FRAME_LENGTH -) - -func (op OpType) String() string { - switch op { - case MORE: - return "MORE" - case PASS: - return "PASS" - case DROP: - return "DROP" - case INJECT: - return "INJECT" - case ERROR: - return "ERROR" - case NOP: - return "NOP" - } - return "UNKNOWN_OP" -} - -func (opErr OpError) String() string { - switch opErr { - case ERROR_INVALID_OP_LENGTH: - return "ERROR_INVALID_OP_LENGTH" - case ERROR_INVALID_FRAME_TYPE: - return "ERROR_INVALID_FRAME_TYPE" - case ERROR_INVALID_FRAME_LENGTH: - return "ERROR_INVALID_FRAME_LENGTH" - } - return "UNKNOWN_OP_ERROR" -} - -// FilterResult mirrors enum FilterResult in types.h. -type FilterResult int - -const ( - OK FilterResult = iota - POLICY_DROP - PARSER_ERROR - UNKNOWN_PARSER - UNKNOWN_CONNECTION - INVALID_ADDRESS - INVALID_INSTANCE - UNKNOWN_ERROR -) - -// Error() implements the error interface for FilterResult -func (r FilterResult) Error() string { - switch r { - case OK: - return "OK" - case POLICY_DROP: - return "POLICY_DROP" - case PARSER_ERROR: - return "PARSER_ERROR" - case UNKNOWN_PARSER: - return "UNKNOWN_PARSER" - case UNKNOWN_CONNECTION: - return "UNKNOWN_CONNECTION" - case INVALID_ADDRESS: - return "INVALID_ADDRESS" - case INVALID_INSTANCE: - return "INVALID_INSTANCE" - case UNKNOWN_ERROR: - return "UNKNOWN_ERROR" - } - - return fmt.Sprintf("%d", r) -} diff --git a/proxylib/r2d2/r2d2parser.go b/proxylib/r2d2/r2d2parser.go deleted file mode 100644 index 57df43e1a..000000000 --- a/proxylib/r2d2/r2d2parser.go +++ /dev/null @@ -1,196 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package r2d2 - -import ( - "bytes" - "fmt" - "regexp" - "strings" - - "github.com/sirupsen/logrus" - - cilium "github.com/cilium/proxy/go/cilium/api" - "github.com/cilium/proxy/proxylib/proxylib" -) - -// -// R2D2 Parser -// -// This is a toy protocol to teach people how to build a Cilium golang proxy parser. -// - -// Current R2D2 parser supports filtering on a basic text protocol with 4 request-types: -// "READ \r\n" - Read a file from the Droid -// "WRITE \r\n" - Write a file to the Droid -// "HALT\r\n" - Shutdown the Droid -// "RESET\r\n" - Reset the Droid to factory settings -// -// Replies include a status of either "OK\r\n", "ERROR\r\n" for "WRITE", "HALT", or "RESET". -// Replies for "READ" are either "OK \r\n" or "ERROR\r\n". -// -// -// Policy Examples: -// {cmd : "READ"} - Allow all reads, no other commands. -// {cmd : "READ", file : "/public/.*" } - Allow reads that are in the public directory -// {file : "/public/.*" } - Allow read/write on the public directory. -// {cmd : "HALT"} - Allow shutdown, but no other actions. - -type r2d2Rule struct { - cmdExact string - fileRegexCompiled *regexp.Regexp -} - -type r2d2RequestData struct { - cmd string - file string -} - -func (rule *r2d2Rule) Matches(data interface{}) bool { - // Cast 'data' to the type we give to 'Matches()' - - reqData, ok := data.(r2d2RequestData) - regexStr := "" - if rule.fileRegexCompiled != nil { - regexStr = rule.fileRegexCompiled.String() - } - - if !ok { - logrus.Warning("Matches() called with type other than R2d2RequestData") - return false - } - if len(rule.cmdExact) > 0 && rule.cmdExact != reqData.cmd { - logrus.Debugf("R2d2Rule: cmd mismatch %s, %s", rule.cmdExact, reqData.cmd) - return false - } - if rule.fileRegexCompiled != nil && - !rule.fileRegexCompiled.MatchString(reqData.file) { - logrus.Debugf("R2d2Rule: file mismatch %s, %s", rule.fileRegexCompiled.String(), reqData.file) - return false - } - logrus.Debugf("policy match for rule: '%s' '%s'", rule.cmdExact, regexStr) - return true -} - -// ruleParser parses protobuf L7 rules to enforcement objects -// May panic -func ruleParser(rule *cilium.PortNetworkPolicyRule) []proxylib.L7NetworkPolicyRule { - l7Rules := rule.GetL7Rules() - if l7Rules == nil { - return nil - } - - allowRules := l7Rules.GetL7AllowRules() - rules := make([]proxylib.L7NetworkPolicyRule, 0, len(allowRules)) - for _, l7Rule := range allowRules { - var rr r2d2Rule - for k, v := range l7Rule.Rule { - switch k { - case "cmd": - rr.cmdExact = v - case "file": - if v != "" { - rr.fileRegexCompiled = regexp.MustCompile(v) - } - default: - proxylib.ParseError(fmt.Sprintf("Unsupported key: %s", k), rule) - } - } - if rr.cmdExact != "" && - rr.cmdExact != "READ" && - rr.cmdExact != "WRITE" && - rr.cmdExact != "HALT" && - rr.cmdExact != "RESET" { - proxylib.ParseError(fmt.Sprintf("Unable to parse L7 r2d2 rule with invalid cmd: '%s'", rr.cmdExact), rule) - } - if (rr.fileRegexCompiled != nil) && !(rr.cmdExact == "" || rr.cmdExact == "READ" || rr.cmdExact == "WRITE") { - proxylib.ParseError(fmt.Sprintf("Unable to parse L7 r2d2 rule, cmd '%s' is not compatible with 'file'", rr.cmdExact), rule) - } - regexStr := "" - if rr.fileRegexCompiled != nil { - regexStr = rr.fileRegexCompiled.String() - } - logrus.Debugf("Parsed rule '%s' '%s'", rr.cmdExact, regexStr) - rules = append(rules, &rr) - } - return rules -} - -type factory struct{} - -func init() { - logrus.Debug("init(): Registering r2d2ParserFactory") - proxylib.RegisterParserFactory("r2d2", &factory{}) - proxylib.RegisterL7RuleParser("r2d2", ruleParser) -} - -type parser struct { - connection *proxylib.Connection -} - -func (f *factory) Create(connection *proxylib.Connection) interface{} { - logrus.Debugf("R2d2ParserFactory: Create: %v", connection) - - return &parser{connection: connection} -} - -func (p *parser) OnData(reply, endStream bool, dataArray [][]byte) (proxylib.OpType, int) { - - // inefficient, but simple - data := string(bytes.Join(dataArray, []byte{})) - - logrus.Debugf("OnData: '%s'", data) - msgLen := strings.Index(data, "\r\n") - if msgLen < 0 { - // No delimiter, request more data - logrus.Debugf("No delimiter found, requesting more bytes") - return proxylib.MORE, 1 - } - - msgStr := data[:msgLen] // read single request - msgLen += 2 // include "\r\n" - logrus.Debugf("Request = '%s'", msgStr) - - // we don't process reply traffic for now - if reply { - logrus.Debugf("reply, passing %d bytes", msgLen) - return proxylib.PASS, msgLen - } - - fields := strings.Split(msgStr, " ") - if len(fields) < 1 { - return proxylib.ERROR, int(proxylib.ERROR_INVALID_FRAME_TYPE) - } - reqData := r2d2RequestData{cmd: fields[0]} - if len(fields) == 2 { - reqData.file = fields[1] - } - - matches := true - access_log_entry_type := cilium.EntryType_Request - - if !p.connection.Matches(reqData) { - matches = false - access_log_entry_type = cilium.EntryType_Denied - } - - p.connection.Log(access_log_entry_type, - &cilium.LogEntry_GenericL7{ - GenericL7: &cilium.L7LogEntry{ - Proto: "r2d2", - Fields: map[string]string{ - "cmd": reqData.cmd, - "file": reqData.file, - }, - }, - }) - - if !matches { - p.connection.Inject(true, []byte("ERROR\r\n")) - logrus.Debugf("Policy mismatch, dropping %d bytes", msgLen) - return proxylib.DROP, msgLen - } - - return proxylib.PASS, msgLen -} diff --git a/proxylib/r2d2/r2d2parser_test.go b/proxylib/r2d2/r2d2parser_test.go deleted file mode 100644 index 7c05f842d..000000000 --- a/proxylib/r2d2/r2d2parser_test.go +++ /dev/null @@ -1,149 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package r2d2 - -import ( - "testing" - - "github.com/stretchr/testify/require" - - "github.com/cilium/proxy/proxylib/accesslog" - "github.com/cilium/proxy/proxylib/proxylib" - "github.com/cilium/proxy/proxylib/test" -) - -type R2d2Suite struct { - logServer *test.AccessLogServer - ins *proxylib.Instance -} - -// Set up access log server and Library instance for all the test cases -func setUpR2d2Suite(tb testing.TB) *R2d2Suite { - s := &R2d2Suite{} - s.logServer = test.StartAccessLogServer("access_log.sock", 10) - require.NotNil(tb, s.logServer) - s.ins = proxylib.NewInstance("node1", accesslog.NewClient(s.logServer.Path)) - require.NotNil(tb, s.ins) - tb.Cleanup(func() { - s.logServer.Clear() - s.logServer.Close() - }) - return s -} - -func TestR2d2OnDataIncomplete(t *testing.T) { - s := setUpR2d2Suite(t) - conn := s.ins.CheckNewConnectionOK(t, "r2d2", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "no-policy") - data := [][]byte{[]byte("READ xssss")} - conn.CheckOnDataOK(t, false, false, &data, []byte{}, proxylib.MORE, 1) -} - -func TestR2d2OnDataBasicPass(t *testing.T) { - s := setUpR2d2Suite(t) - // allow all rule - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - l7_proto: "r2d2" - > - > - `}) - conn := s.ins.CheckNewConnectionOK(t, "r2d2", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - msg1 := "READ sssss\r\n" - msg2 := "WRITE sssss\r\n" - msg3 := "HALT\r\n" - msg4 := "RESET\r\n" - data := [][]byte{[]byte(msg1 + msg2 + msg3 + msg4)} - conn.CheckOnDataOK(t, false, false, &data, []byte{}, - proxylib.PASS, len(msg1), - proxylib.PASS, len(msg2), - proxylib.PASS, len(msg3), - proxylib.PASS, len(msg4), - proxylib.MORE, 1) -} - -func TestR2d2OnDataMultipleReq(t *testing.T) { - s := setUpR2d2Suite(t) - // allow all rule - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - l7_proto: "r2d2" - > - > - `}) - conn := s.ins.CheckNewConnectionOK(t, "r2d2", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - msg1Part1 := "RE" - msg1Part2 := "SET\r\n" - data := [][]byte{[]byte(msg1Part1), []byte(msg1Part2)} - conn.CheckOnDataOK(t, false, false, &data, []byte{}, - proxylib.PASS, len(msg1Part1+msg1Part2), - proxylib.MORE, 1) -} - -func TestR2d2OnDataAllowDenyCmd(t *testing.T) { - s := setUpR2d2Suite(t) - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - l7_proto: "r2d2" - l7_rules: < - l7_allow_rules: < - rule: < - key: "cmd" - value: "READ" - > - > - > - > - > - `}) - conn := s.ins.CheckNewConnectionOK(t, "r2d2", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - msg1 := "READ xssss\r\n" - msg2 := "WRITE xssss\r\n" - data := [][]byte{[]byte(msg1 + msg2)} - conn.CheckOnDataOK(t, false, false, &data, []byte("ERROR\r\n"), - proxylib.PASS, len(msg1), - proxylib.DROP, len(msg2), - proxylib.MORE, 1) -} - -func (s *R2d2Suite) TestR2d2OnDataAllowDenyRegex(t *testing.T) { - - s.ins.CheckInsertPolicyText(t, "1", []string{` - endpoint_ips: "1.1.1.1" - endpoint_id: 2 - ingress_per_port_policies: < - port: 80 - rules: < - l7_proto: "r2d2" - l7_rules: < - l7_allow_rules: < - rule: < - key: "file" - value: "s.*" - > - > - > - > - > - `}) - conn := s.ins.CheckNewConnectionOK(t, "r2d2", true, 1, 2, "1.1.1.1:34567", "10.0.0.2:80", "1.1.1.1") - msg1 := "READ ssss\r\n" - msg2 := "WRITE yyyyy\r\n" - data := [][]byte{[]byte(msg1 + msg2)} - conn.CheckOnDataOK(t, false, false, &data, []byte("ERROR\r\n"), - proxylib.PASS, len(msg1), - proxylib.DROP, len(msg2), - proxylib.MORE, 1) -} diff --git a/proxylib/test/accesslog_server.go b/proxylib/test/accesslog_server.go deleted file mode 100644 index 52de015ea..000000000 --- a/proxylib/test/accesslog_server.go +++ /dev/null @@ -1,169 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package test - -import ( - "errors" - "io" - "net" - "os" - "path/filepath" - "sync" - "syscall" - "time" - - "google.golang.org/protobuf/proto" - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" - - cilium "github.com/cilium/proxy/go/cilium/api" -) - -type AccessLogServer struct { - Path string - Logs chan cilium.EntryType - done chan struct{} - listener *net.UnixListener - mu sync.Mutex // protects conns - conns []*net.UnixConn -} - -// Close removes the unix domain socket from the filesystem -func (s *AccessLogServer) Close() { - if s != nil { - close(s.done) - s.listener.Close() - s.mu.Lock() - for _, conn := range s.conns { - conn.Close() - } - s.mu.Unlock() - os.Remove(s.Path) - } -} - -func (s *AccessLogServer) isClosing() bool { - select { - case <-s.done: - return true - default: - return false - } -} - -// Clear empties the access log server buffer, counting the passes and drops -func (s *AccessLogServer) Clear() (passed, drops int) { - passes, drops := 0, 0 - empty := false - for !empty { - select { - case entryType := <-s.Logs: - if entryType == cilium.EntryType_Denied { - drops++ - } else { - passes++ - } - case <-time.After(10 * time.Millisecond): - empty = true - } - } - return passes, drops -} - -// StartAccessLogServer starts the access log server. -func StartAccessLogServer(accessLogName string, bufSize int) *AccessLogServer { - accessLogPath := filepath.Join(Tmpdir, accessLogName) - - server := &AccessLogServer{ - Path: accessLogPath, - Logs: make(chan cilium.EntryType, bufSize), - done: make(chan struct{}), - } - - // Create the access log listener - os.Remove(accessLogPath) // Remove/Unlink the old unix domain socket, if any. - var err error - server.listener, err = net.ListenUnix("unixpacket", &net.UnixAddr{Name: accessLogPath, Net: "unixpacket"}) - if err != nil { - logrus.Fatalf("Failed to open access log listen socket at %s: %v", accessLogPath, err) - } - server.listener.SetUnlinkOnClose(true) - - // Make the socket accessible by non-root Envoy proxies. - if err = os.Chmod(accessLogPath, 0777); err != nil { - logrus.Fatalf("Failed to change mode of access log listen socket at %s: %v", accessLogPath, err) - } - - logrus.Debug("Starting Access Log Server") - go func() { - for { - // Each Envoy listener opens a new connection over the Unix domain socket. - // Multiple worker threads serving the listener share that same connection - uc, err := server.listener.AcceptUnix() - if err != nil { - // These errors are expected when we are closing down - if server.isClosing() || - errors.Is(err, net.ErrClosed) || - errors.Is(err, syscall.EINVAL) { - break - } - logrus.WithError(err).Warn("Failed to accept access log connection") - continue - } - - if server.isClosing() { - break - } - - logrus.Debug("Accepted access log connection") - - server.mu.Lock() - server.conns = append(server.conns, uc) - server.mu.Unlock() - // Serve this access log socket in a goroutine, so we can serve multiple - // connections concurrently. - go server.accessLogger(uc) - } - }() - - return server -} - -// isEOF returns true if the error message ends in "EOF". ReadMsgUnix returns extra info in the beginning. -func isEOF(err error) bool { - strerr := err.Error() - errlen := len(strerr) - return errlen >= 3 && strerr[errlen-3:] == io.EOF.Error() -} - -func (s *AccessLogServer) accessLogger(conn *net.UnixConn) { - defer func() { - logrus.Debug("Closing access log connection") - conn.Close() - }() - - buf := make([]byte, 4096) - for { - n, _, flags, _, err := conn.ReadMsgUnix(buf, nil) - if err != nil { - if !isEOF(err) && !s.isClosing() { - logrus.WithError(err).Error("Error while reading from access log connection") - } - break - } - if flags&unix.MSG_TRUNC != 0 { - logrus.Warning("Discarded truncated access log message") - continue - } - pblog := cilium.LogEntry{} - err = proto.Unmarshal(buf[:n], &pblog) - if err != nil { - logrus.WithError(err).Warning("Discarded invalid access log message") - continue - } - - logrus.Debugf("Access log message: %s", pblog.String()) - s.Logs <- pblog.EntryType - } -} diff --git a/proxylib/test/tmpdir.go b/proxylib/test/tmpdir.go deleted file mode 100644 index ce96347ec..000000000 --- a/proxylib/test/tmpdir.go +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package test - -import ( - "os" - - "github.com/sirupsen/logrus" -) - -var Tmpdir string - -func init() { - var err error - Tmpdir, err = os.MkdirTemp("", "cilium_envoy_go_test") - if err != nil { - logrus.Fatal("Failed to create a temporary directory for testing") - } -} diff --git a/proxylib/testparsers/blockparser.go b/proxylib/testparsers/blockparser.go deleted file mode 100644 index fea26e00e..000000000 --- a/proxylib/testparsers/blockparser.go +++ /dev/null @@ -1,178 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package testparsers - -import ( - "bytes" - "fmt" - "math" - "strconv" - - "github.com/sirupsen/logrus" - - cilium "github.com/cilium/proxy/go/cilium/api" - . "github.com/cilium/proxy/proxylib/proxylib" -) - -// -// Block parser used for testing -// - -type BlockParserFactory struct{} - -var blockParserFactory *BlockParserFactory - -const ( - blockParserName = "test.blockparser" -) - -func init() { - logrus.Debug("init(): Registering blockParserFactory") - RegisterParserFactory(blockParserName, blockParserFactory) -} - -type BlockParser struct { - connection *Connection - inserted int -} - -func (p *BlockParserFactory) Create(connection *Connection) interface{} { - logrus.Debugf("BlockParserFactory: Create: %v", connection) - return &BlockParser{connection: connection} -} - -func getBlock(data [][]byte) ([]byte, int, int, error) { - var block bytes.Buffer - - offset := 0 - blockLen := 0 - haveLength := false - missing := 0 - - for _, s := range data { - if !haveLength { - index := bytes.IndexByte(s[offset:], ':') - if index < 0 { - block.Write(s[offset:]) - if block.Len() > 0 { - missing = 1 // require at least one more if something was received - } - } else { - block.Write(s[offset : offset+index]) - offset += index - - // Now 'block' contains everything before the ':', parse it as a decimal number - // indicating the length of the frame AFTER the ':' - if lenUint64, err := strconv.ParseUint(block.String(), 10, 64); err != nil { - return block.Bytes(), 0, 0, err - } else if lenUint64 > math.MaxInt { - return block.Bytes(), 0, 0, fmt.Errorf("block length overflow") - } else { - blockLen = int(lenUint64) - } - if blockLen <= block.Len() { - return block.Bytes(), 0, 0, fmt.Errorf("block length too short") - } - haveLength = true - missing = blockLen - block.Len() - } - } - if haveLength { - s_len := len(s) - offset - - if missing <= s_len { - block.Write(s[offset : offset+missing]) - return block.Bytes(), blockLen, 0, nil - } else { - block.Write(s[offset:]) - missing -= s_len - } - } - offset = 0 - } - - return block.Bytes(), blockLen, missing, nil -} - -// Parses individual blocks that must start with one of: -// "PASS" the block is passed -// "DROP" the block is dropped -// "INJECT" the block is injected in reverse direction -// "INSERT" the block is injected in current direction -func (p *BlockParser) OnData(reply, endStream bool, data [][]byte) (OpType, int) { - block, block_len, missing, err := getBlock(data) - if err != nil { - logrus.WithError(err).Warnf("BlockParser: Invalid frame length") - return ERROR, int(ERROR_INVALID_FRAME_LENGTH) - } - - if p.inserted > 0 { - if p.inserted == block_len { - p.inserted = 0 - return DROP, block_len - } - // partial insert in progress - n := p.connection.Inject(reply, []byte(block)[p.inserted:]) - // Drop the INJECT block in the current direction - p.inserted += n - return INJECT, n - } - - if !reply { - logrus.Debugf("BlockParser: Request: %s", block) - } else { - logrus.Debugf("BlockParser: Response: %s", block) - } - - if missing == 0 && block_len == 0 { - // Nothing received, don't know if more will be coming; do nothing - return NOP, 0 - } - - logrus.Debugf("BlockParser: missing: %d", missing) - - if bytes.Contains(block, []byte("PASS")) { - p.connection.Log(cilium.EntryType_Request, &cilium.LogEntry_GenericL7{ - GenericL7: &cilium.L7LogEntry{ - Proto: blockParserName, - Fields: map[string]string{ - "status": "200", - }, - }, - }) - return PASS, block_len - } - if bytes.Contains(block, []byte("DROP")) { - p.connection.Log(cilium.EntryType_Denied, &cilium.LogEntry_GenericL7{ - GenericL7: &cilium.L7LogEntry{ - Proto: blockParserName, - Fields: map[string]string{ - "status": "503", - }, - }, - }) - return DROP, block_len - } - - if missing > 0 { - // Partial block received, ask for more - return MORE, missing - } - - if bytes.Contains(block, []byte("INJECT")) { - // Inject block in the reverse direction - p.connection.Inject(!reply, []byte(block)) - // Drop the INJECT block in the current direction - return DROP, block_len - } - if bytes.Contains(block, []byte("INSERT")) { - // Inject the block in the current direction - n := p.connection.Inject(reply, []byte(block)) - // Drop the INJECT block in the current direction - p.inserted = n - return INJECT, n - } - - return ERROR, int(ERROR_INVALID_FRAME_TYPE) -} diff --git a/proxylib/testparsers/headerparser.go b/proxylib/testparsers/headerparser.go deleted file mode 100644 index a216f678c..000000000 --- a/proxylib/testparsers/headerparser.go +++ /dev/null @@ -1,159 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -// -// Accompanying file `headerparser.policy` contains an example policy -// for this protocol. Install it with: -// $ cilium policy import proxylib/testparsers/headerparser.policy -// - -package testparsers - -import ( - "bytes" - "fmt" - - "github.com/sirupsen/logrus" - - cilium "github.com/cilium/proxy/go/cilium/api" - . "github.com/cilium/proxy/proxylib/proxylib" -) - -// -// Header parser used for testing -// - -type HeaderRule struct { - hasPrefix []byte - contains []byte - hasSuffix []byte -} - -// Matches returns true if the HeaderRule matches -func (rule *HeaderRule) Matches(data interface{}) bool { - logrus.Debugf("headerparser checking rule %v", *rule) - - // Trim whitespace from both ends - bs := bytes.TrimSpace(data.([]byte)) - - if len(rule.hasPrefix) > 0 && !bytes.HasPrefix(bs, rule.hasPrefix) { - logrus.Debugf("headerparser HasPrefix %s does not match %s", bs, rule.hasPrefix) - return false - } - - if len(rule.contains) > 0 && !bytes.Contains(bs, rule.contains) { - logrus.Debugf("headerparser Contains %s does not match %s", bs, rule.contains) - return false - } - - if len(rule.hasSuffix) > 0 && !bytes.HasSuffix(bs, rule.hasSuffix) { - logrus.Debugf("headerparser HasSuffix %s does not match %s", bs, rule.hasSuffix) - return false - } - logrus.Debug("headerparser rule matched!") - - return true -} - -// L7HeaderRuleParser parses protobuf L7 rules to and array of HeaderRules -func L7HeaderRuleParser(rule *cilium.PortNetworkPolicyRule) []L7NetworkPolicyRule { - l7Rules := rule.GetL7Rules() - if l7Rules == nil { - return nil - } - - allowRules := l7Rules.GetL7AllowRules() - rules := make([]L7NetworkPolicyRule, 0, len(allowRules)) - for _, l7Rule := range allowRules { - var hr HeaderRule - for k, v := range l7Rule.Rule { - switch k { - case "prefix": - hr.hasPrefix = []byte(v) - case "contains": - hr.contains = []byte(v) - case "suffix": - hr.hasSuffix = []byte(v) - default: - ParseError(fmt.Sprintf("Unsupported key: %s", k), rule) - } - } - logrus.Debugf("Parsed HeaderRule pair: %v", hr) - rules = append(rules, &hr) - } - return rules -} - -type HeaderParserFactory struct{} - -var headerParserFactory *HeaderParserFactory - -const ( - parserName = "test.headerparser" -) - -func init() { - logrus.Debug("init(): Registering headerParserFactory") - RegisterParserFactory(parserName, headerParserFactory) - RegisterL7RuleParser(parserName, L7HeaderRuleParser) -} - -type HeaderParser struct { - connection *Connection -} - -func (p *HeaderParserFactory) Create(connection *Connection) interface{} { - logrus.Debugf("HeaderParserFactory: Create: %v", connection) - return &HeaderParser{connection: connection} -} - -// Parses individual lines and verifies them against the policy -func (p *HeaderParser) OnData(reply, endStream bool, data [][]byte) (OpType, int) { - line, ok := getLine(data) - line_len := len(line) - - if !reply { - logrus.Debugf("HeaderParser: Request: %s", line) - } else { - logrus.Debugf("HeaderParser: Response: %s", line) - } - - if !ok { - if line_len > 0 { - // Partial line received, but no newline, ask for more - return MORE, 1 - } else { - // Nothing received, don't know if more will be coming; do nothing - return NOP, 0 - } - } - - // Replies pass unconditionally - if reply || p.connection.Matches(line) { - p.connection.Log(cilium.EntryType_Request, - &cilium.LogEntry_GenericL7{ - GenericL7: &cilium.L7LogEntry{ - Proto: parserName, - Fields: map[string]string{ - "status": "PASS", - }, - }, - }) - return PASS, line_len - } - - // Inject Error response to the reverse direction - p.connection.Inject(!reply, []byte(fmt.Sprintf("Line dropped: %s", line))) - // Drop the line in the current direction - p.connection.Log(cilium.EntryType_Denied, - &cilium.LogEntry_GenericL7{ - GenericL7: &cilium.L7LogEntry{ - Proto: parserName, - Fields: map[string]string{ - "status": "DROP", - }, - }, - }) - - return DROP, line_len -} diff --git a/proxylib/testparsers/headerparser.policy b/proxylib/testparsers/headerparser.policy deleted file mode 100644 index cd9dda63b..000000000 --- a/proxylib/testparsers/headerparser.policy +++ /dev/null @@ -1,36 +0,0 @@ -[{ - "endpointSelector": {"matchLabels":{"id.echoserver":""}}, - "ingress": [{ - "fromEndpoints": [ - {"matchLabels":{"reserved:host":""}}, - {"matchLabels":{"id.client":""}} - ], - "toPorts": [{ - "ports": [{"port": "2701", "protocol": "tcp"}], - "rules": { - "l7proto": "test.headerparser", - "l7": [{ - "prefix": "foo" - }] - } - }] - }] -},{ - "endpointSelector": {"matchLabels":{"id.echoserver":""}}, - "ingress": [{ - "fromEndpoints": [ - {"matchLabels":{"reserved:host":""}}, - {"matchLabels":{"id.client":""}} - ], - "toPorts": [{ - "ports": [{"port": "2701", "protocol": "tcp"}], - "rules": { - "l7proto": "test.headerparser", - "l7": [ - {"prefix": "bar", "contains": "beer"}, - {"suffix": "end"} - ] - } - }] - }] -}] diff --git a/proxylib/testparsers/lineparser.go b/proxylib/testparsers/lineparser.go deleted file mode 100644 index cbff22fa7..000000000 --- a/proxylib/testparsers/lineparser.go +++ /dev/null @@ -1,103 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package testparsers - -import ( - "bytes" - - "github.com/sirupsen/logrus" - - . "github.com/cilium/proxy/proxylib/proxylib" -) - -// -// Line parser used for testing -// - -type LineParserFactory struct{} - -var lineParserFactory *LineParserFactory - -func init() { - logrus.Debug("init(): Registering lineParserFactory") - RegisterParserFactory("test.lineparser", lineParserFactory) -} - -type LineParser struct { - connection *Connection - inserted bool -} - -func (p *LineParserFactory) Create(connection *Connection) interface{} { - logrus.Debugf("LineParserFactory: Create: %v", connection) - return &LineParser{connection: connection} -} - -func getLine(data [][]byte) ([]byte, bool) { - var line bytes.Buffer - for i, s := range data { - index := bytes.IndexByte(s, '\n') - if index < 0 { - line.Write(s) - } else { - logrus.Debugf("getLine: unit: %d length: %d index: %d", i, len(s), index) - line.Write(s[:index+1]) - return line.Bytes(), true - } - } - return line.Bytes(), false -} - -// Parses individual lines that must start with one of: -// "PASS" the line is passed -// "DROP" the line is dropped -// "INJECT" the line is injected in reverse direction -// "INSERT" the line is injected in current direction -func (p *LineParser) OnData(reply, endStream bool, data [][]byte) (OpType, int) { - line, ok := getLine(data) - line_len := len(line) - - if p.inserted { - p.inserted = false - return DROP, line_len - } - - if !reply { - logrus.Debugf("LineParser: Request: %s", line) - } else { - logrus.Debugf("LineParser: Response: %s", line) - } - - if !ok { - if line_len > 0 { - // Partial line received, but no newline, ask for more - return MORE, 1 - } else { - // Nothing received, don't know if more will be coming; do nothing - return NOP, 0 - } - } - - if bytes.HasPrefix(line, []byte("PASS")) { - return PASS, line_len - } - if bytes.HasPrefix(line, []byte("DROP")) { - return DROP, line_len - } - if bytes.HasPrefix(line, []byte("INJECT")) { - // Inject line in the reverse direction - p.connection.Inject(!reply, []byte(line)) - // Drop the INJECT line in the current direction - return DROP, line_len - } - if bytes.HasPrefix(line, []byte("INSERT")) { - // Inject the line in the current direction - p.connection.Inject(reply, []byte(line)) - // Drop the INJECT line in the current direction - p.inserted = true - return INJECT, line_len - } - - return ERROR, int(ERROR_INVALID_FRAME_TYPE) -} diff --git a/proxylib/testparsers/passer.go b/proxylib/testparsers/passer.go deleted file mode 100644 index 1f30cfa55..000000000 --- a/proxylib/testparsers/passer.go +++ /dev/null @@ -1,46 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Authors of Cilium - -package testparsers - -import ( - "github.com/sirupsen/logrus" - - . "github.com/cilium/proxy/proxylib/proxylib" -) - -type PasserParserFactory struct{} - -func init() { - logrus.Debug("init(): Registering PasserParserFactory") - RegisterParserFactory("test.passer", &PasserParserFactory{}) -} - -type PasserParser struct{} - -func (p *PasserParserFactory) Create(connection *Connection) interface{} { - // Reject invalid policy name for testing purposes - if connection.PolicyName == "invalid-policy" { - return nil - } - - logrus.Debugf("PasserParserFactory: Create: %v", connection) - return &PasserParser{} -} - -// OnData simply passes all data in either direction. -func (p *PasserParser) OnData(reply, endStream bool, data [][]byte) (OpType, int) { - n_bytes := 0 - for _, s := range data { - n_bytes += len(s) - } - if n_bytes == 0 { - return NOP, 0 - } - if !reply { - logrus.Debugf("PasserParser: Request: %d bytes", n_bytes) - } else { - logrus.Debugf("PasserParser: Response: %d bytes", n_bytes) - } - return PASS, n_bytes -} diff --git a/proxylib/types.h b/proxylib/types.h deleted file mode 100644 index f01b80ca2..000000000 --- a/proxylib/types.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2018 Authors of Cilium - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PROXYLIB_TYPES_H -#define PROXYLIB_TYPES_H - -#include - -typedef enum { - FILTEROP_MORE, // Need more data - FILTEROP_PASS, // Pass N bytes - FILTEROP_DROP, // Drop N bytes - FILTEROP_INJECT, // Inject N>0 bytes - FILTEROP_ERROR, // Protocol parsing error -} FilterOpType; - -typedef enum { - FILTEROP_ERROR_INVALID_OP_LENGTH = 1, // Parser returned invalid operation length - FILTEROP_ERROR_INVALID_FRAME_TYPE, - FILTEROP_ERROR_INVALID_FRAME_LENGTH, -} FilterOpError; - -typedef struct { - uint64_t op; // FilterOpType - int64_t n_bytes; // >0 -} FilterOp; - -typedef enum { - FILTER_OK, // Operation was successful - FILTER_POLICY_DROP, // Connection needs to be dropped due to (L3/L4) policy - FILTER_PARSER_ERROR, // Connection needs to be dropped due to parser error - FILTER_UNKNOWN_PARSER, // Connection needs to be dropped due to unknown parser - FILTER_UNKNOWN_CONNECTION, // Connection needs to be dropped due to it being unknown - FILTER_INVALID_ADDRESS, // Destination address in invalid format - FILTER_INVALID_INSTANCE, // Destination address in invalid format - FILTER_UNKNOWN_ERROR, // Error type could not be cast to an error code -} FilterResult; - -#endif diff --git a/starter/privileged_service_protocol.h b/starter/privileged_service_protocol.h index c7eaa6f3b..e4b48b5d5 100644 --- a/starter/privileged_service_protocol.h +++ b/starter/privileged_service_protocol.h @@ -79,7 +79,7 @@ struct MessageHeader { // Note that file descriptor return value is passed using the message control channel (ref. man 2 // recvmsg). struct Response { - struct MessageHeader hdr_{}; + struct MessageHeader hdr_; int return_value_ = 0; int errno_ = 0; }; diff --git a/tests/BUILD b/tests/BUILD index a567969e8..75e4a3739 100644 --- a/tests/BUILD +++ b/tests/BUILD @@ -24,7 +24,6 @@ envoy_cc_test_library( name = "accesslog_server_lib", srcs = ["accesslog_server.cc"], hdrs = ["accesslog_server.h"], - repository = "@envoy", deps = [ ":uds_server_lib", "//cilium/api:accesslog_proto_cc_proto", @@ -36,7 +35,6 @@ envoy_cc_test_library( name = "uds_server_lib", srcs = ["uds_server.cc"], hdrs = ["uds_server.h"], - repository = "@envoy", deps = [ "@envoy//source/common/common:logger_lib", "@envoy//source/common/common:thread_lib", @@ -48,7 +46,6 @@ envoy_cc_test_library( envoy_cc_test_library( name = "cilium_test_peer_lib", hdrs = ["cilium_test_peer.h"], - repository = "@envoy", deps = [ "//cilium:bpf_metadata_lib", "//cilium:network_policy_lib", @@ -59,7 +56,6 @@ envoy_cc_test_library( name = "bpf_metadata_lib", srcs = ["bpf_metadata.cc"], hdrs = ["bpf_metadata.h"], - repository = "@envoy", deps = [ ":bpf_metadata_cc_proto", ":cilium_test_peer_lib", @@ -75,7 +71,6 @@ envoy_cc_test_library( name = "cilium_http_integration_lib", srcs = ["cilium_http_integration.cc"], hdrs = ["cilium_http_integration.h"], - repository = "@envoy", deps = [ ":accesslog_server_lib", ":bpf_metadata_lib", @@ -94,7 +89,6 @@ envoy_cc_test_library( data = [ "@envoy//test/config/integration/certs", ], - repository = "@envoy", deps = [ "@envoy//source/extensions/clusters/logical_dns:logical_dns_cluster_lib", "@envoy//source/extensions/clusters/original_dst:original_dst_cluster_lib", @@ -110,7 +104,6 @@ envoy_cc_test_library( name = "cilium_tcp_integration_lib", srcs = ["cilium_tcp_integration.cc"], hdrs = ["cilium_tcp_integration.h"], - repository = "@envoy", deps = [ ":accesslog_server_lib", ":bpf_metadata_lib", @@ -127,7 +120,6 @@ envoy_cc_test_library( envoy_cc_test( name = "cilium_network_policy_test", srcs = ["cilium_network_policy_test.cc"], - repository = "@envoy", deps = [ ":bpf_metadata_lib", ":cilium_test_peer_lib", @@ -142,7 +134,6 @@ envoy_cc_benchmark_binary( srcs = ["cilium_network_policy_benchmark.cc"], data = ["@envoy//test/config/integration/certs:upstreamcacert.pem"], external_deps = ["bazel_runfiles"], - repository = "@envoy", deps = [ ":bpf_metadata_lib", ":cilium_test_peer_lib", @@ -159,13 +150,11 @@ envoy_cc_benchmark_binary( envoy_benchmark_test( name = "cilium_network_policy_benchmark_test", benchmark_binary = "cilium_network_policy_benchmark", - repository = "@envoy", ) envoy_cc_test( name = "bpf_metadata_config_test", srcs = ["bpf_metadata_config_test.cc"], - repository = "@envoy", deps = [ ":bpf_metadata_lib", "@envoy//envoy/network:filter_interface", @@ -176,7 +165,6 @@ envoy_cc_test( envoy_cc_test( name = "accesslog_test", srcs = ["accesslog_test.cc"], - repository = "@envoy", deps = [ "//cilium:accesslog_lib", "@envoy//test/mocks/network:connection_mocks", @@ -188,7 +176,6 @@ envoy_cc_test( envoy_cc_test( name = "network_filter_test", srcs = ["network_filter_test.cc"], - repository = "@envoy", deps = [ "//cilium:network_filter_lib", "@envoy//test/mocks/network:network_mocks", @@ -199,7 +186,6 @@ envoy_cc_test( envoy_cc_test( name = "cilium_websocket_codec_test", srcs = ["cilium_websocket_codec_test.cc"], - repository = "@envoy", deps = [ "//cilium:websocket_lib", "@envoy//source/common/buffer:buffer_lib", @@ -211,10 +197,6 @@ envoy_cc_test( envoy_cc_test( name = "cilium_tcp_integration_test", srcs = ["cilium_tcp_integration_test.cc"], - data = [ - "//proxylib:libcilium.so", - ], - repository = "@envoy", deps = [ ":bpf_metadata_lib", ":cilium_tcp_integration_lib", @@ -233,7 +215,6 @@ envoy_cc_test( data = [ "@envoy//test/config/integration/certs", ], - repository = "@envoy", deps = [ ":bpf_metadata_lib", ":cilium_http_integration_lib", @@ -252,10 +233,8 @@ envoy_cc_test( name = "cilium_tls_tcp_integration_test", srcs = ["cilium_tls_tcp_integration_test.cc"], data = [ - "//proxylib:libcilium.so", "@envoy//test/config/integration/certs", ], - repository = "@envoy", deps = [ ":bpf_metadata_lib", ":cilium_tcp_integration_lib", @@ -273,10 +252,6 @@ envoy_cc_test( envoy_cc_test( name = "cilium_http_integration_test", srcs = ["cilium_http_integration_test.cc"], - data = [ - "//proxylib:libcilium.so", - ], - repository = "@envoy", deps = [ ":bpf_metadata_lib", ":cilium_http_integration_lib", @@ -293,10 +268,6 @@ envoy_cc_test( envoy_cc_test( name = "cilium_http_upstream_integration_test", srcs = ["cilium_http_upstream_integration_test.cc"], - data = [ - "//proxylib:libcilium.so", - ], - repository = "@envoy", deps = [ ":bpf_metadata_lib", ":cilium_http_integration_lib", @@ -315,10 +286,6 @@ envoy_cc_test( envoy_cc_test( name = "cilium_websocket_decap_integration_test", srcs = ["cilium_websocket_decap_integration_test.cc"], - data = [ - "//proxylib:libcilium.so", - ], - repository = "@envoy", deps = [ ":bpf_metadata_lib", ":cilium_http_integration_lib", @@ -335,10 +302,6 @@ envoy_cc_test( envoy_cc_test( name = "cilium_websocket_codec_integration_test", srcs = ["cilium_websocket_codec_integration_test.cc"], - data = [ - "//proxylib:libcilium.so", - ], - repository = "@envoy", deps = [ ":bpf_metadata_lib", ":cilium_tcp_integration_lib", @@ -354,10 +317,6 @@ envoy_cc_test( envoy_cc_test( name = "cilium_websocket_policy_integration_test", srcs = ["cilium_websocket_policy_integration_test.cc"], - data = [ - "//proxylib:libcilium.so", - ], - repository = "@envoy", deps = [ ":bpf_metadata_lib", ":cilium_http_integration_lib", @@ -376,10 +335,6 @@ envoy_cc_test( envoy_cc_test( name = "cilium_websocket_encap_integration_test", srcs = ["cilium_websocket_encap_integration_test.cc"], - data = [ - "//proxylib:libcilium.so", - ], - repository = "@envoy", deps = [ ":bpf_metadata_lib", ":cilium_tcp_integration_lib", @@ -395,7 +350,6 @@ envoy_cc_test( envoy_cc_test( name = "bpf_metadata_integration_test", srcs = ["bpf_metadata_integration_test.cc"], - repository = "@envoy", deps = [ "//cilium:bpf_metadata_lib", "//cilium/api:bpf_metadata_cc_proto", @@ -419,7 +373,6 @@ envoy_cc_test( "health_check_sink_server.h", "health_check_sink_test.cc", ], - repository = "@envoy", deps = [ ":uds_server_lib", "//cilium:health_check_sink_lib", diff --git a/tests/bpf_metadata_config_test.cc b/tests/bpf_metadata_config_test.cc index da8479774..543a13fd3 100644 --- a/tests/bpf_metadata_config_test.cc +++ b/tests/bpf_metadata_config_test.cc @@ -1,3 +1,4 @@ +#include "gmock/gmock.h" #include #include #include @@ -397,11 +398,8 @@ TEST_F(MetadataConfigTest, NorthSouthL7LbIngressEnforcedMetadata) { log_entry.entry_.set_policy_name("pod"); // Expect policy accepts security ID 12345678 on ingress on port 80 - bool use_proxy_lib; std::string l7_proto; - EXPECT_TRUE( - policy_fs->enforceNetworkPolicy(conn_, 12345678, 80, "", use_proxy_lib, l7_proto, log_entry)); - EXPECT_FALSE(use_proxy_lib); + EXPECT_TRUE(policy_fs->enforceNetworkPolicy(conn_, 12345678, 80, "", l7_proto, log_entry)); EXPECT_EQ("", l7_proto); EXPECT_NE("pod", log_entry.entry_.policy_name()); @@ -467,29 +465,22 @@ TEST_F(MetadataConfigTest, NorthSouthL7LbPodAndIngressEnforcedMetadata) { log_entry.entry_.set_policy_name("pod"); // Expect pod policy denies security ID 12345678 on port 80 (only 222 allowed) - bool use_proxy_lib; std::string l7_proto; - EXPECT_FALSE( - policy_fs->enforceNetworkPolicy(conn_, 12345678, 80, "", use_proxy_lib, l7_proto, log_entry)); - EXPECT_FALSE(use_proxy_lib); + EXPECT_FALSE(policy_fs->enforceNetworkPolicy(conn_, 12345678, 80, "", l7_proto, log_entry)); EXPECT_EQ("", l7_proto); EXPECT_EQ("pod", log_entry.entry_.policy_name()); // Expect pod policy allows egress to security ID 222 on port 80 // Ingress policy allows ingress from 9999 (pod's security ID) // Ingress policy allows 222 egress - EXPECT_TRUE( - policy_fs->enforceNetworkPolicy(conn_, 222, 80, "", use_proxy_lib, l7_proto, log_entry)); - EXPECT_FALSE(use_proxy_lib); + EXPECT_TRUE(policy_fs->enforceNetworkPolicy(conn_, 222, 80, "", l7_proto, log_entry)); EXPECT_EQ("", l7_proto); EXPECT_NE("pod", log_entry.entry_.policy_name()); // Expect pod policy allows egress to security ID 333 on port 80 // Ingress policy allows ingress from 9999 // Ingress policy denies 333 egress - EXPECT_FALSE( - policy_fs->enforceNetworkPolicy(conn_, 333, 80, "", use_proxy_lib, l7_proto, log_entry)); - EXPECT_FALSE(use_proxy_lib); + EXPECT_FALSE(policy_fs->enforceNetworkPolicy(conn_, 333, 80, "", l7_proto, log_entry)); EXPECT_EQ("", l7_proto); EXPECT_NE("pod", log_entry.entry_.policy_name()); @@ -538,11 +529,8 @@ TEST_F(MetadataConfigTest, NorthSouthL7LbIngressEnforcedCIDRMetadata) { log_entry.entry_.set_policy_name("pod"); // Expect policy does not accept security ID 2 on port 80 - bool use_proxy_lib; std::string l7_proto; - EXPECT_FALSE( - policy_fs->enforceNetworkPolicy(conn_, 2, 80, "", use_proxy_lib, l7_proto, log_entry)); - EXPECT_FALSE(use_proxy_lib); + EXPECT_FALSE(policy_fs->enforceNetworkPolicy(conn_, 2, 80, "", l7_proto, log_entry)); EXPECT_EQ("", l7_proto); EXPECT_NE("pod", log_entry.entry_.policy_name()); diff --git a/tests/cilium_network_policy_benchmark.cc b/tests/cilium_network_policy_benchmark.cc index 21e65af6c..0c1655337 100644 --- a/tests/cilium_network_policy_benchmark.cc +++ b/tests/cilium_network_policy_benchmark.cc @@ -156,11 +156,11 @@ void processNpdsUpdateWith1000Policies(benchmark::State& state, bool policy_secr return; } - ON_CALL(secret_manager, findOrCreateGenericSecretProvider(_, _, _, _)) + ON_CALL(secret_manager, findOrCreateGenericSecretProvider(_, _, _, _, _)) .WillByDefault(Invoke([generic_secret_provider](const envoy::config::core::v3::ConfigSource&, const std::string&, Server::Configuration::ServerFactoryContext&, - OptRef init_manager) { + OptRef init_manager, bool) { if (init_manager.has_value()) { init_manager->add(*generic_secret_provider->initTarget()); } else { diff --git a/tests/cilium_network_policy_test.cc b/tests/cilium_network_policy_test.cc index 26d9c8c56..cb9774553 100644 --- a/tests/cilium_network_policy_test.cc +++ b/tests/cilium_network_policy_test.cc @@ -59,7 +59,7 @@ auto createSdsSecretProvider(const envoy::config::core::v3::ConfigSource& sds_co } // findOrCreate*Provider signatures are not uniform: TlsCertificate and GenericSecret take an -// OptRef (and TlsCertificate an extra bool warm), the rest take Init::Manager&. +// OptRef and a bool warm, the rest take Init::Manager&. // Hence one macro per shape, all sharing createSdsSecretProvider() above. #define ON_CALL_SDS_SECRET_PROVIDER(SECRET_MANAGER, PROVIDER_TYPE, API_TYPE) \ ON_CALL(SECRET_MANAGER, findOrCreate##PROVIDER_TYPE##Provider(_, _, _, _)) \ @@ -72,17 +72,7 @@ auto createSdsSecretProvider(const envoy::config::core::v3::ConfigSource& sds_co })) #define ON_CALL_SDS_SECRET_PROVIDER_OPT_INIT(SECRET_MANAGER, PROVIDER_TYPE, API_TYPE) \ - ON_CALL(SECRET_MANAGER, findOrCreate##PROVIDER_TYPE##Provider(_, _, _, _)) \ - .WillByDefault(Invoke([](const envoy::config::core::v3::ConfigSource& sds_config_source, \ - const std::string& config_name, \ - Server::Configuration::ServerFactoryContext& server_context, \ - OptRef init_manager) { \ - return createSdsSecretProvider(sds_config_source, config_name, \ - server_context, init_manager); \ - })) - -#define ON_CALL_SDS_TLS_CERTIFICATE_PROVIDER(SECRET_MANAGER, API_TYPE) \ - ON_CALL(SECRET_MANAGER, findOrCreateTlsCertificateProvider(_, _, _, _, _)) \ + ON_CALL(SECRET_MANAGER, findOrCreate##PROVIDER_TYPE##Provider(_, _, _, _, _)) \ .WillByDefault(Invoke([](const envoy::config::core::v3::ConfigSource& sds_config_source, \ const std::string& config_name, \ Server::Configuration::ServerFactoryContext& server_context, \ @@ -106,7 +96,7 @@ class CiliumNetworkPolicyTest : public ::testing::Test { ON_CALL(factory_context_.server_factory_context_, secretManager()) .WillByDefault(ReturnRef(secret_manager_)); - ON_CALL_SDS_TLS_CERTIFICATE_PROVIDER(secret_manager_, TlsCertificate); + ON_CALL_SDS_SECRET_PROVIDER_OPT_INIT(secret_manager_, TlsCertificate, TlsCertificate); ON_CALL_SDS_SECRET_PROVIDER(secret_manager_, CertificateValidationContext, CertificateValidationContext); ON_CALL_SDS_SECRET_PROVIDER(secret_manager_, TlsSessionTicketKeysContext, TlsSessionTicketKeys); @@ -2939,7 +2929,8 @@ TEST_F(CiliumNetworkPolicyTest, TlsContextsAreDeduplicatedWithinStream) { } TEST_F(CiliumNetworkPolicyTest, SecretWatchersAreDeduplicatedWithinStream) { - EXPECT_CALL(secret_manager_, findOrCreateGenericSecretProvider(_, "shared-header-secret", _, _)); + EXPECT_CALL(secret_manager_, + findOrCreateGenericSecretProvider(_, "shared-header-secret", _, _, _)); EXPECT_NO_THROW(updateFromYaml(R"EOF(version_info: "1" resources: @@ -2979,7 +2970,7 @@ TEST_F(CiliumNetworkPolicyTest, SecretWatchersAreDeduplicatedWithinStream) { } TEST_F(CiliumNetworkPolicyTest, SecretWatcherCacheIsResetForNewStream) { - EXPECT_CALL(secret_manager_, findOrCreateGenericSecretProvider(_, "header-secret", _, _)) + EXPECT_CALL(secret_manager_, findOrCreateGenericSecretProvider(_, "header-secret", _, _, _)) .Times(2); const auto policy_yaml = R"EOF(version_info: "1" diff --git a/tests/cilium_tcp_integration_test.cc b/tests/cilium_tcp_integration_test.cc index f804363d7..948927fb4 100644 --- a/tests/cilium_tcp_integration_test.cc +++ b/tests/cilium_tcp_integration_test.cc @@ -13,8 +13,6 @@ #include "test/test_common/environment.h" #include "test/test_common/utility.h" -#include "absl/time/clock.h" -#include "absl/time/time.h" #include "tests/cilium_tcp_integration.h" namespace Envoy { @@ -67,7 +65,6 @@ const std::string cilium_tcp_proxy_config_fmt = R"EOF( - name: cilium.network typed_config: "@type": type.googleapis.com/cilium.NetworkFilter - proxylib: "proxylib/libcilium.so" - name: envoy.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy @@ -288,485 +285,5 @@ TEST_P(CiliumTcpProxyIntegrationTest, CiliumTcpProxyUpstreamFlushEnvoyExit) { // // params: is_ingress ("true", "false") -const std::string cilium_linetester_config_fmt = R"EOF( -admin: - address: - socket_address: - address: 127.0.0.1 - port_value: 0 -static_resources: - clusters: - - name: cluster1 - type: ORIGINAL_DST - lb_policy: CLUSTER_PROVIDED - connect_timeout: - seconds: 1 - - name: xds-grpc-cilium - connect_timeout: - seconds: 5 - type: STATIC - lb_policy: ROUND_ROBIN - http2_protocol_options: - load_assignment: - cluster_name: xds-grpc-cilium - endpoints: - - lb_endpoints: - - endpoint: - address: - pipe: - path: /var/run/cilium/xds.sock - listeners: - name: listener_0 - address: - socket_address: - address: 127.0.0.1 - port_value: 0 - listener_filters: - name: test_bpf_metadata - typed_config: - "@type": type.googleapis.com/cilium.TestBpfMetadata - is_ingress: {0} - filter_chains: - filters: - - name: cilium.network - typed_config: - "@type": type.googleapis.com/cilium.NetworkFilter - proxylib: "proxylib/libcilium.so" - - name: envoy.tcp_proxy - typed_config: - "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy - stat_prefix: tcp_stats - cluster: cluster1 -)EOF"; - -const std::string TCP_POLICY_LINEPARSER_fmt = R"EOF(version_info: "0" -resources: -- "@type": type.googleapis.com/cilium.NetworkPolicy - endpoint_ips: - - '{{ ntop_ip_loopback_address }}' - endpoint_id: 42 - policy: 3 - ingress_per_port_policies: - - port: 1 - end_port: {0} - rules: - - remote_policies: [ 1 ] - l7_proto: "test.lineparser" - egress_per_port_policies: - - port: 1 - end_port: {0} - rules: - - remote_policies: [ 1 ] - l7_proto: "test.lineparser" -)EOF"; - -class CiliumGoLinetesterIntegrationTest : public CiliumTcpIntegrationTest { -public: - CiliumGoLinetesterIntegrationTest() - : CiliumTcpIntegrationTest(fmt::format( - fmt::runtime(TestEnvironment::substitute(cilium_linetester_config_fmt, GetParam())), - "true")) {} - - std::string testPolicyFmt() override { - return TestEnvironment::substitute(TCP_POLICY_LINEPARSER_fmt, GetParam()); - } -}; - -INSTANTIATE_TEST_SUITE_P(IpVersions, CiliumGoLinetesterIntegrationTest, - testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), - TestUtility::ipTestParamsToString); - -static FakeRawConnection::ValidatorFunction noMatch(const char* data_to_not_match) { - return [data_to_not_match](const std::string& data) -> bool { - auto found = data.find(data_to_not_match); - return found == std::string::npos; - }; -} - -TEST_P(CiliumGoLinetesterIntegrationTest, CiliumGoLineParserUpstreamWritesFirst) { - initialize(); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("tcp_proxy")); - FakeRawConnectionPtr fake_upstream_connection; - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - - ASSERT_TRUE(fake_upstream_connection->write("DROP reply direction\n")); - ASSERT_TRUE(fake_upstream_connection->write("PASS reply direction\n")); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::StartsWith("PASS reply direction\n")); - - ASSERT_TRUE(tcp_client->write("PASS original direction\n")); - ASSERT_TRUE( - fake_upstream_connection->waitForData(FakeRawConnection::waitForInexactMatch("PASS"))); - - ASSERT_TRUE(fake_upstream_connection->write("", true)); - tcp_client->waitForHalfClose(); - ASSERT_TRUE(tcp_client->write("", true)); - ASSERT_TRUE(fake_upstream_connection->waitForHalfClose()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); -} - -TEST_P(CiliumGoLinetesterIntegrationTest, CiliumGoLineParserPartialLines) { - initialize(); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("tcp_proxy")); - FakeRawConnectionPtr fake_upstream_connection; - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - - ASSERT_TRUE(fake_upstream_connection->write("DROP reply ")); - absl::SleepFor(absl::Milliseconds(10)); - ASSERT_TRUE(fake_upstream_connection->write("direction\nPASS")); - absl::SleepFor(absl::Milliseconds(10)); - ASSERT_TRUE(fake_upstream_connection->write(" reply direction\n")); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::StartsWith("PASS reply direction\n")); - - ASSERT_TRUE(tcp_client->write("PASS original direction\n")); - ASSERT_TRUE(fake_upstream_connection->waitForData( - FakeRawConnection::waitForInexactMatch("PASS original direction\n"))); - - ASSERT_TRUE(fake_upstream_connection->write("", true)); - tcp_client->waitForHalfClose(); - ASSERT_TRUE(tcp_client->write("", true)); - ASSERT_TRUE(fake_upstream_connection->waitForHalfClose()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); -} - -TEST_P(CiliumGoLinetesterIntegrationTest, CiliumGoLineParserInject) { - initialize(); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("tcp_proxy")); - FakeRawConnectionPtr fake_upstream_connection; - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - - ASSERT_TRUE(tcp_client->write("INJECT reply direction\n")); - ASSERT_TRUE(tcp_client->write("PASS original direction\n")); - ASSERT_TRUE(fake_upstream_connection->write("PASS reply direction\n")); - - // These can in principle arrive in either order - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("PASS reply direction\n")); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("INJECT reply direction\n")); - - ASSERT_TRUE(fake_upstream_connection->waitForData( - FakeRawConnection::waitForInexactMatch("PASS original direction\n"))); - - ASSERT_TRUE(fake_upstream_connection->write("", true)); - tcp_client->waitForHalfClose(); - ASSERT_TRUE(tcp_client->write("", true)); - ASSERT_TRUE(fake_upstream_connection->waitForHalfClose()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); -} - -TEST_P(CiliumGoLinetesterIntegrationTest, CiliumGoLineParserInjectPartial) { - initialize(); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("tcp_proxy")); - FakeRawConnectionPtr fake_upstream_connection; - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - - ASSERT_TRUE(fake_upstream_connection->write("PASS reply")); - ASSERT_TRUE(tcp_client->write("INJECT reply direction\n")); - ASSERT_TRUE(tcp_client->write("PASS original direction\n")); - - ASSERT_TRUE(fake_upstream_connection->write(" direction\n")); - - // These can in principle arrive in either order - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("PASS reply direction\n")); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("INJECT reply direction\n")); - - ASSERT_TRUE(fake_upstream_connection->waitForData( - FakeRawConnection::waitForInexactMatch("PASS original direction\n"))); - - ASSERT_TRUE(fake_upstream_connection->write("", true)); - tcp_client->waitForHalfClose(); - ASSERT_TRUE(tcp_client->write("", true)); - ASSERT_TRUE(fake_upstream_connection->waitForHalfClose()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); -} - -TEST_P(CiliumGoLinetesterIntegrationTest, CiliumGoLineParserInjectPartialMultiple) { - initialize(); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("tcp_proxy")); - FakeRawConnectionPtr fake_upstream_connection; - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - - ASSERT_TRUE(fake_upstream_connection->write("PASS reply")); - ASSERT_TRUE(tcp_client->write("INJECT reply direction\n")); - ASSERT_TRUE(tcp_client->write("DROP original direction\n")); - ASSERT_TRUE(tcp_client->write("INSERT original direction\n")); - - ASSERT_TRUE(fake_upstream_connection->write(" direction\n")); - - // These can in principle arrive in either order - absl::SleepFor(absl::Milliseconds(10)); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("PASS reply direction\n")); - absl::SleepFor(absl::Milliseconds(10)); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("INJECT reply direction\n")); - - ASSERT_TRUE(fake_upstream_connection->waitForData( - FakeRawConnection::waitForInexactMatch("INSERT original direction\n"))); - ASSERT_TRUE(fake_upstream_connection->waitForData(noMatch("DROP"))); - - ASSERT_TRUE(fake_upstream_connection->write("DROP reply direction\n")); - ASSERT_TRUE(fake_upstream_connection->write("PASS2 reply direction\n")); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("PASS2 reply direction\n")); - - ASSERT_TRUE(fake_upstream_connection->write("", true)); - tcp_client->waitForHalfClose(); - ASSERT_TRUE(tcp_client->write("", true)); - ASSERT_TRUE(fake_upstream_connection->waitForHalfClose()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); -} - -// -// Cilium Go test parser "blocktester" with TCP proxy -// - -// params: is_ingress ("true", "false") -const std::string cilium_blocktester_config_fmt = R"EOF( -admin: - address: - socket_address: - address: 127.0.0.1 - port_value: 0 -static_resources: - clusters: - - name: cluster1 - type: ORIGINAL_DST - lb_policy: CLUSTER_PROVIDED - connect_timeout: - seconds: 1 - - name: xds-grpc-cilium - connect_timeout: - seconds: 5 - type: STATIC - lb_policy: ROUND_ROBIN - http2_protocol_options: - load_assignment: - cluster_name: xds-grpc-cilium - endpoints: - - lb_endpoints: - - endpoint: - address: - pipe: - path: /var/run/cilium/xds.sock - listeners: - name: listener_0 - address: - socket_address: - address: 127.0.0.1 - port_value: 0 - listener_filters: - name: test_bpf_metadata - typed_config: - "@type": type.googleapis.com/cilium.TestBpfMetadata - is_ingress: {0} - filter_chains: - filters: - - name: cilium.network - typed_config: - "@type": type.googleapis.com/cilium.NetworkFilter - proxylib: "proxylib/libcilium.so" - proxylib_params: - access-log-path: "{{ test_udsdir }}/access_log.sock" - - name: envoy.tcp_proxy - typed_config: - "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy - stat_prefix: tcp_stats - cluster: cluster1 -)EOF"; - -const std::string TCP_POLICY_BLOCKPARSER_fmt = R"EOF(version_info: "0" -resources: -- "@type": type.googleapis.com/cilium.NetworkPolicy - endpoint_ips: - - '{{ ntop_ip_loopback_address }}' - endpoint_id: 42 - policy: 3 - ingress_per_port_policies: - - port: 1 - end_port: 65535 - rules: - - remote_policies: [ 1 ] - l7_proto: "test.blockparser" - egress_per_port_policies: - - port: 1 - end_port: 65535 - rules: - - remote_policies: [ 1 ] - l7_proto: "test.blockparser" -)EOF"; - -class CiliumGoBlocktesterIntegrationTest : public CiliumTcpIntegrationTest { -public: - CiliumGoBlocktesterIntegrationTest() - : CiliumTcpIntegrationTest(fmt::format( - fmt::runtime(TestEnvironment::substitute(cilium_blocktester_config_fmt, GetParam())), - "true")) {} - - std::string testPolicyFmt() override { - return TestEnvironment::substitute(TCP_POLICY_BLOCKPARSER_fmt, GetParam()); - } -}; - -INSTANTIATE_TEST_SUITE_P(IpVersions, CiliumGoBlocktesterIntegrationTest, - testing::ValuesIn(TestEnvironment::getIpVersionsForTest()), - TestUtility::ipTestParamsToString); - -TEST_P(CiliumGoBlocktesterIntegrationTest, CiliumGoBlockParserUpstreamWritesFirst) { - initialize(); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("tcp_proxy")); - FakeRawConnectionPtr fake_upstream_connection; - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - - ASSERT_TRUE(fake_upstream_connection->write("24:DROP reply direction\n")); - ASSERT_TRUE(fake_upstream_connection->write("24:PASS reply direction\n")); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::StartsWith("24:PASS reply direction\n")); - - ASSERT_TRUE(tcp_client->write("27:PASS original direction\n")); - ASSERT_TRUE( - fake_upstream_connection->waitForData(FakeRawConnection::waitForInexactMatch("PASS"))); - - ASSERT_TRUE(fake_upstream_connection->write("", true)); - tcp_client->waitForHalfClose(); - ASSERT_TRUE(tcp_client->write("", true)); - ASSERT_TRUE(fake_upstream_connection->waitForHalfClose()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); -} - -TEST_P(CiliumGoBlocktesterIntegrationTest, CiliumGoBlockParserPartialBlocks) { - initialize(); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("tcp_proxy")); - FakeRawConnectionPtr fake_upstream_connection; - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - - ASSERT_TRUE(fake_upstream_connection->write("24:DROP reply ")); - ASSERT_TRUE(fake_upstream_connection->write("direction\n24:PASS")); - ASSERT_TRUE(fake_upstream_connection->write(" reply direction\n")); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::StartsWith("24:PASS reply direction\n")); - - ASSERT_TRUE(tcp_client->write("27:PASS original direction\n")); - ASSERT_TRUE(fake_upstream_connection->waitForData( - FakeRawConnection::waitForInexactMatch("27:PASS original direction\n"))); - - ASSERT_TRUE(fake_upstream_connection->write("", true)); - tcp_client->waitForHalfClose(); - ASSERT_TRUE(tcp_client->write("", true)); - ASSERT_TRUE(fake_upstream_connection->waitForHalfClose()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); -} - -TEST_P(CiliumGoBlocktesterIntegrationTest, CiliumGoBlockParserInject) { - initialize(); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("tcp_proxy")); - FakeRawConnectionPtr fake_upstream_connection; - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - - ASSERT_TRUE(tcp_client->write("26:INJECT reply direction\n")); - ASSERT_TRUE(tcp_client->write("27:PASS original direction\n")); - ASSERT_TRUE(fake_upstream_connection->write("24:PASS reply direction\n")); - - // These can in principle arrive in either order - absl::SleepFor(absl::Milliseconds(10)); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("24:PASS reply direction\n")); - absl::SleepFor(absl::Milliseconds(10)); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("26:INJECT reply direction\n")); - - ASSERT_TRUE(fake_upstream_connection->waitForData( - FakeRawConnection::waitForInexactMatch("27:PASS original direction\n"))); - - ASSERT_TRUE(fake_upstream_connection->write("", true)); - tcp_client->waitForHalfClose(); - ASSERT_TRUE(tcp_client->write("", true)); - ASSERT_TRUE(fake_upstream_connection->waitForHalfClose()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); -} - -TEST_P(CiliumGoBlocktesterIntegrationTest, CiliumGoBlockParserInjectPartial) { - initialize(); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("tcp_proxy")); - FakeRawConnectionPtr fake_upstream_connection; - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - - ASSERT_TRUE(fake_upstream_connection->write("24:PASS reply")); - ASSERT_TRUE(tcp_client->write("26:INJECT reply direction\n")); - ASSERT_TRUE(tcp_client->write("27:PASS original direction\n")); - - ASSERT_TRUE(fake_upstream_connection->write(" direction\n")); - - // These can in principle arrive in either order - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("24:PASS reply direction\n")); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("26:INJECT reply direction\n")); - - ASSERT_TRUE(fake_upstream_connection->waitForData( - FakeRawConnection::waitForInexactMatch("27:PASS original direction\n"))); - - ASSERT_TRUE(fake_upstream_connection->write("", true)); - tcp_client->waitForHalfClose(); - ASSERT_TRUE(tcp_client->write("", true)); - ASSERT_TRUE(fake_upstream_connection->waitForHalfClose()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); -} - -TEST_P(CiliumGoBlocktesterIntegrationTest, CiliumGoBlockParserInjectPartialMultiple) { - initialize(); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("tcp_proxy")); - FakeRawConnectionPtr fake_upstream_connection; - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - - ASSERT_TRUE(fake_upstream_connection->write("24:PASS reply")); - ASSERT_TRUE(tcp_client->write("26:INJECT reply direction\n")); - ASSERT_TRUE(tcp_client->write("27:DROP original direction\n")); - ASSERT_TRUE(tcp_client->write("29:INSERT original direction\n")); - - absl::SleepFor(absl::Milliseconds(100)); - ASSERT_TRUE(fake_upstream_connection->write(" dire")); - - absl::SleepFor(absl::Milliseconds(100)); - ASSERT_TRUE(fake_upstream_connection->write("ction\n")); - - // These can in principle arrive in either order - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("24:PASS reply direction\n")); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("26:INJECT reply direction\n")); - - ASSERT_TRUE(fake_upstream_connection->waitForData( - FakeRawConnection::waitForInexactMatch("29:INSERT original direction\n"))); - ASSERT_TRUE(fake_upstream_connection->waitForData(noMatch("DROP"))); - - ASSERT_TRUE(fake_upstream_connection->write("24:DROP reply direction\n")); - ASSERT_TRUE(fake_upstream_connection->write("25:PASS2 reply direction\n")); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("25:PASS2 reply direction\n")); - - ASSERT_TRUE(fake_upstream_connection->write("", true)); - tcp_client->waitForHalfClose(); - ASSERT_TRUE(tcp_client->write("", true)); - ASSERT_TRUE(fake_upstream_connection->waitForHalfClose()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); -} - -TEST_P(CiliumGoBlocktesterIntegrationTest, CiliumGoBlockParserInjectBufferOverflow) { - initialize(); - IntegrationTcpClientPtr tcp_client = makeTcpConnection(lookupPort("tcp_proxy")); - FakeRawConnectionPtr fake_upstream_connection; - ASSERT_TRUE(fake_upstreams_[0]->waitForRawConnection(fake_upstream_connection)); - - ASSERT_TRUE(tcp_client->write("26:INJECT reply direction\n")); - ASSERT_TRUE(tcp_client->write("27:DROP original direction\n")); - - std::string buf(5000, 'A'); - buf.replace(0, 30, "5000:INSERT original direction"); - buf.back() = '\n'; - - ASSERT_TRUE(tcp_client->write(buf)); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("26:INJECT reply direction\n")); - - ASSERT_TRUE(fake_upstream_connection->waitForData( - FakeRawConnection::waitForInexactMatch("INSERT original direction"))); - ASSERT_TRUE(fake_upstream_connection->waitForData(noMatch("DROP"))); - - ASSERT_TRUE(fake_upstream_connection->write("24:DROP reply direction\n")); - ASSERT_TRUE(fake_upstream_connection->write("25:PASS2 reply direction\n")); - CILIUM_ASSERT_TCP_RESPONSE(tcp_client, testing::HasSubstr("25:PASS2 reply direction\n")); - - ASSERT_TRUE(fake_upstream_connection->write("", true)); - tcp_client->waitForHalfClose(); - ASSERT_TRUE(tcp_client->write("", true)); - ASSERT_TRUE(fake_upstream_connection->waitForHalfClose()); - ASSERT_TRUE(fake_upstream_connection->waitForDisconnect()); -} } // namespace Envoy diff --git a/tests/cilium_tls_http_integration_test.cc b/tests/cilium_tls_http_integration_test.cc index 58ee44564..46c8704b1 100644 --- a/tests/cilium_tls_http_integration_test.cc +++ b/tests/cilium_tls_http_integration_test.cc @@ -15,7 +15,6 @@ #include "envoy/network/transport_socket.h" #include "source/common/common/logger.h" -#include "source/common/stats/isolated_store_impl.h" #include "source/common/tls/server_context_config_impl.h" #include "source/common/tls/server_ssl_socket.h" @@ -243,7 +242,8 @@ class CiliumHttpTLSIntegrationTest : public CiliumHttpIntegrationTest { // Set up the SSL client. Network::Address::InstanceConstSharedPtr address = Ssl::getSslAddress(version_, lookupPort("http")); - context_ = createClientSslTransportSocketFactory(context_manager_, *api_); + context_ = createClientSslTransportSocketFactory(context_manager_, *api_, + server_factory_context_.serverScope()); Network::ClientConnectionPtr ssl_client = dispatcher_->createClientConnection( address, Network::Address::InstanceConstSharedPtr(), context_->createTransportSocket(nullptr, nullptr), nullptr, nullptr); @@ -283,9 +283,8 @@ class CiliumHttpTLSIntegrationTest : public CiliumHttpIntegrationTest { THROW_IF_NOT_OK(server_config_or_error.status()); auto cfg = std::move(server_config_or_error.value()); - static auto* upstream_stats_store = new Stats::IsolatedStoreImpl(); auto factory_or_error = Extensions::TransportSockets::Tls::ServerSslSocketFactory::create( - std::move(cfg), context_manager_, *upstream_stats_store->rootScope()); + std::move(cfg), context_manager_, factory_context_.serverFactoryContext().serverScope()); // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) THROW_IF_NOT_OK(factory_or_error.status()); return std::move(factory_or_error.value()); diff --git a/tests/cilium_tls_integration.cc b/tests/cilium_tls_integration.cc index 19fb648a4..b559205ac 100644 --- a/tests/cilium_tls_integration.cc +++ b/tests/cilium_tls_integration.cc @@ -11,11 +11,11 @@ #include "envoy/extensions/transport_sockets/tls/v3/tls.pb.h" #include "envoy/network/transport_socket.h" #include "envoy/ssl/context_manager.h" +#include "envoy/stats/scope.h" #include "source/common/tls/client_ssl_socket.h" #include "source/common/tls/context_config_impl.h" -#include "test/integration/server.h" #include "test/mocks/server/admin.h" #include "test/mocks/server/server_factory_context.h" #include "test/test_common/environment.h" @@ -25,7 +25,8 @@ namespace Envoy { namespace Cilium { Network::UpstreamTransportSocketFactoryPtr -createClientSslTransportSocketFactory(Ssl::ContextManager& context_manager, Api::Api& api) { +createClientSslTransportSocketFactory(Ssl::ContextManager& context_manager, Api::Api& api, + Stats::Scope& stats_scope) { std::string yaml_plain = R"EOF( common_tls_context: validation_context: @@ -43,9 +44,11 @@ createClientSslTransportSocketFactory(Ssl::ContextManager& context_manager, Api: // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) THROW_IF_NOT_OK(cfg_or_error.status()); auto cfg = std::move(cfg_or_error.value()); - static auto* client_stats_store = new Stats::TestIsolatedStoreImpl(); + // The TLS context interns its stat names in the symbol table of the factory context owned by + // 'context_manager', so 'stats_scope' must share that symbol table (e.g. be the server factory + // context scope of the test) rather than an isolated store with its own symbol table. auto factory_or_error = Extensions::TransportSockets::Tls::ClientSslSocketFactory::create( - std::move(cfg), context_manager, *client_stats_store->rootScope()); + std::move(cfg), context_manager, stats_scope); // NOLINTNEXTLINE(performance-unnecessary-copy-initialization) THROW_IF_NOT_OK(factory_or_error.status()); return std::move(factory_or_error.value()); diff --git a/tests/cilium_tls_integration.h b/tests/cilium_tls_integration.h index 09ff20e51..6d765f9e4 100644 --- a/tests/cilium_tls_integration.h +++ b/tests/cilium_tls_integration.h @@ -3,12 +3,14 @@ #include "envoy/api/api.h" #include "envoy/network/transport_socket.h" #include "envoy/ssl/context_manager.h" +#include "envoy/stats/scope.h" namespace Envoy { namespace Cilium { Network::UpstreamTransportSocketFactoryPtr -createClientSslTransportSocketFactory(Ssl::ContextManager& context_manager, Api::Api& api); +createClientSslTransportSocketFactory(Ssl::ContextManager& context_manager, Api::Api& api, + Stats::Scope& stats_scope); } // namespace Cilium } // namespace Envoy diff --git a/tests/cilium_tls_tcp_integration_test.cc b/tests/cilium_tls_tcp_integration_test.cc index 92a7d60aa..412872487 100644 --- a/tests/cilium_tls_tcp_integration_test.cc +++ b/tests/cilium_tls_tcp_integration_test.cc @@ -95,7 +95,6 @@ const std::string cilium_tls_tcp_proxy_config_fmt = R"EOF( - name: cilium.network typed_config: "@type": type.googleapis.com/cilium.NetworkFilter - proxylib: "proxylib/libcilium.so" - name: envoy.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy @@ -219,7 +218,8 @@ class CiliumTLSIntegrationTest : public CiliumTcpIntegrationTest { // Set up the SSL client. Network::Address::InstanceConstSharedPtr address = Ssl::getSslAddress(version_, lookupPort("tcp_proxy")); - context_ = createClientSslTransportSocketFactory(context_manager_, *api_); + context_ = createClientSslTransportSocketFactory(context_manager_, *api_, + server_factory_context_.serverScope()); ssl_client_ = dispatcher_->createClientConnection( address, Network::Address::InstanceConstSharedPtr(), context_->createTransportSocket(nullptr, nullptr), nullptr, nullptr); @@ -620,7 +620,6 @@ const std::string cilium_tls_downstream_tcp_proxy_config_fmt = R"EOF( - name: cilium.network typed_config: "@type": type.googleapis.com/cilium.NetworkFilter - proxylib: "proxylib/libcilium.so" - name: envoy.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy @@ -636,7 +635,6 @@ const std::string cilium_tls_downstream_tcp_proxy_config_fmt = R"EOF( - name: cilium.network typed_config: "@type": type.googleapis.com/cilium.NetworkFilter - proxylib: "proxylib/libcilium.so" - name: envoy.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy diff --git a/tests/cilium_websocket_encap_integration_test.cc b/tests/cilium_websocket_encap_integration_test.cc index dc86e54aa..0ba349abd 100644 --- a/tests/cilium_websocket_encap_integration_test.cc +++ b/tests/cilium_websocket_encap_integration_test.cc @@ -83,7 +83,6 @@ const std::string cilium_tcp_proxy_config_fmt = R"EOF( - name: cilium.network typed_config: "@type": type.googleapis.com/cilium.NetworkFilter - proxylib: "proxylib/libcilium.so" - name: envoy.tcp_proxy typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy diff --git a/tests/uds_server.cc b/tests/uds_server.cc index 62ce5eb5c..5531c4acb 100644 --- a/tests/uds_server.cc +++ b/tests/uds_server.cc @@ -1,6 +1,7 @@ #include "tests/uds_server.h" #include +#include #include #include diff --git a/tools/code_format/config.yaml b/tools/code_format/config.yaml index 0ec1e61b2..baf03d4bc 100644 --- a/tools/code_format/config.yaml +++ b/tools/code_format/config.yaml @@ -2,7 +2,6 @@ suffixes: # Suffixes to include in checking included: - BUILD - - WORKSPACE - .bzl - .cc - .h @@ -29,17 +28,19 @@ suffixes: proto: - .proto - repositories_bzl: - - bazel/repositories.bzl - paths: # Path prefixes to exclude from checking # TODO(alyssawilk) unexclude mobile excluded: - . + - bazel/external/c-ares/ + - bazel/external/cargo/remote/ - bazel/external/http_parser/ - bazel/rbe/toolchains/configs/ + - bazel/tests/codeql/ + - bazel/tests/external/ - bazel- + - compat/openssl/ - build - contrib/contrib_build_config.bzl - examples/wasm-cc @@ -65,23 +66,7 @@ paths: - bazel/BUILD - bazel/external/ - bazel/toolchains/ - - tools/clang_tools - - # `build_urls`: - # We want all URL references to exist in repository_locations.bzl files and have - # metadata that conforms to the schema in ./api/bazel/external_deps.bzl. Below - # we have some exceptions for either infrastructure files or places we fall - # short today (Rust). - # - # NB: Please DO NOT extend the `build_urls` allow list without consulting - # @envoyproxy/dependency-shepherds. - build_urls: - include: - - api/bazel/envoy_git_repository.bzl - - api/bazel/envoy_http_archive.bzl - - api/bazel/repository_locations.bzl - - bazel/external/cargo/crates.bzl - - bazel/repository_locations.bzl + - docs exception: include: @@ -89,42 +74,45 @@ paths: # valid situation identified so far is template functions used for config # processing. - envoy/common/exception.h + - source/common/access_log/access_log_impl.cc - source/common/filter/config_discovery_impl.h - source/common/config/utility.h - source/common/matcher/matcher.h - - source/extensions/common/matcher/trie_matcher.h + - source/extensions/common/matcher/ip_range_matcher.h - envoy/common/exception.h - source/common/protobuf/utility.h + - source/common/rds/common/route_config_provider_manager_impl.h + - source/common/rds/route_config_provider_manager.h # legacy core files which throw exceptions. We can add to this list but strongly prefer - # StausOr where possible. + # StatusOr where possible. - source/common/watchdog/abort_action_config.cc + - source/extensions/watchdog/backtrace_action/config.cc - source/extensions/watchdog/profile_action/config.cc - source/common/router/route_config_update_receiver_impl.cc - source/common/upstream/upstream_impl.cc + - source/common/matcher/actions/string_returning_action.cc - source/common/network/listen_socket_impl.cc - source/common/network/io_socket_handle_base_impl.cc - source/common/network/address_impl.cc - - source/common/formatter/http_specific_formatter.cc - - source/common/formatter/stream_info_formatter.cc - - source/common/formatter/substitution_formatter.h - - source/common/formatter/substitution_formatter.cc - source/common/stats/tag_extractor_impl.cc - source/common/protobuf/yaml_utility.cc - source/common/protobuf/utility.cc - source/common/grpc/google_grpc_utils.cc - source/common/tcp_proxy/tcp_proxy.cc - source/common/listener_manager/lds_api.cc - - source/common/rds/common/route_config_provider_manager_impl.h - - source/common/rds/route_config_provider_manager.h + - source/common/listener_manager/filter_chain_manager_impl.cc - source/common/json/json_internal.cc - source/common/router/scoped_rds.cc - source/common/router/config_impl.cc - source/common/router/weighted_cluster_specifier.cc - source/common/router/scoped_config_impl.cc - source/common/common/utility.cc + - source/common/secret/sds_api.h + - source/common/secret/sds_api.cc - source/exe/stripped_main_base.cc - source/common/http/header_utility.cc - - source/common/common/matchers.h + - source/common/http/http_service_headers.cc + - source/common/common/matchers.cc - source/server/options_impl.cc - source/server/config_validation/server.cc - source/server/admin/html/active_stats.js @@ -135,18 +123,23 @@ paths: - source/common/upstream/health_discovery_service.cc - source/common/upstream/prod_cluster_info_factory.cc - source/common/secret/sds_api.cc - - source/common/config/config_provider_impl.h + - source/common/config/config_provider_impl.cc - source/common/grpc/google_grpc_creds_impl.cc - source/server/drain_manager_impl.cc - source/common/router/rds_impl.cc + - source/common/router/static_route_provider_impl.cc - source/server/hot_restarting_parent.cc - source/common/io/io_uring_worker_impl.cc - source/common/event/file_event_impl.cc - source/common/http/async_client_impl.cc - source/common/grpc/google_async_client_impl.cc + - source/common/tracing/tracer_config_impl.cc # Extensions can exempt entire directories but new extensions # points should ideally use StatusOr - source/extensions/access_loggers + # Bootstrap extension factories must throw per interface documentation. + - source/extensions/bootstrap/dynamic_modules/factory.cc + - source/extensions/network/socket_interface/sockmap/socket_interface.cc - source/extensions/clusters/eds/ - source/extensions/clusters/logical_dns - source/extensions/clusters/original_dst @@ -159,41 +152,20 @@ paths: - source/extensions/common/matcher - source/extensions/common/tap - source/extensions/common/wasm + # Config validator interfaces reject updates by throwing per interface documentation. + - source/extensions/config/validators/dynamic_modules/config.cc + - source/extensions/config/validators/dynamic_modules/config_validator.cc - source/extensions/config/validators/minimum_clusters/minimum_clusters_validator.cc - source/extensions/config_subscription + - source/extensions/content_parsers/json/config.cc + - source/extensions/content_parsers/json/json_content_parser_impl.cc - source/extensions/compression/zstd/common/dictionary_manager.h - - source/extensions/filters/http/adaptive_concurrency/controller - - source/extensions/filters/http/basic_auth - - source/extensions/filters/http/cache - - source/extensions/filters/http/common - - source/extensions/filters/http/composite - - source/extensions/filters/http/ext_authz - - source/extensions/filters/http/ext_proc - - source/extensions/filters/http/file_system_buffer - - source/extensions/filters/http/gcp_authn - - source/extensions/filters/http/grpc_field_extraction - - source/extensions/filters/http/grpc_json_reverse_transcoder - - source/extensions/filters/http/grpc_json_transcoder - - source/extensions/filters/http/grpc_stats - - source/extensions/filters/http/health_check - - source/extensions/filters/http/json_to_metadata - - source/extensions/filters/http/jwt_authn - - source/extensions/filters/http/local_ratelimit - - source/extensions/filters/http/file_system_buffer - - source/extensions/filters/http/on_demand - - source/extensions/filters/http/json_to_metadata - - source/extensions/filters/http/json_to_metadata - - source/extensions/filters/http/thrift_to_metadata - - source/extensions/filters/http/lua - - source/extensions/filters/http/proto_message_extraction - - source/extensions/filters/http/rate_limit_quota - - source/extensions/filters/http/oauth2 - - source/extensions/filters/http/wasm + - source/extensions/filters/http/composite/action.cc + - source/extensions/filters/http/json_to_metadata/filter.cc + - source/extensions/filters/http/oauth2/filter.h - source/extensions/filters/network/dubbo_proxy - - source/extensions/filters/network/rbac - source/extensions/filters/network/common - source/extensions/filters/network/redis_proxy - - source/extensions/filters/network/zookeeper_proxy - source/extensions/filters/network/ext_authz - source/extensions/filters/network/ext_proc - source/extensions/filters/network/mongo_proxy @@ -205,6 +177,7 @@ paths: - source/extensions/filters/udp - source/extensions/filters/listener - source/extensions/formatter + - source/extensions/geoip_providers/maxmind/config.cc - source/extensions/geoip_providers/maxmind/geoip_provider.cc - source/extensions/grpc_credentials - source/extensions/health_check/event_sinks/file/file_sink_impl.h @@ -212,6 +185,8 @@ paths: - source/extensions/http/cache/file_system_http_cache/config.cc - source/extensions/http/custom_response - source/extensions/http/early_header_mutation + - source/extensions/http/header_formatters/dynamic_modules + - source/extensions/http/ext_proc/processing_request_modifiers/mapped_attribute_builder/mapped_attribute_builder_factory.cc - source/extensions/http/injected_credentials - source/extensions/http/stateful_session - source/extensions/io_socket/user_space @@ -221,15 +196,18 @@ paths: - source/extensions/load_balancing_policies/subset - source/extensions/matching - source/extensions/network/dns_resolver/cares/ + - source/extensions/queue_policy/common/ + - source/extensions/queue_policy/fifo/ - source/extensions/quic/server_preferred_address - source/extensions/quic/connection_id_generator - - source/extensions/resource_monitors + - source/extensions/router/cluster_specifiers/dynamic_modules/config.cc - source/extensions/router/cluster_specifiers/lua/lua_cluster_specifier.cc - source/extensions/string_matcher/lua/match.cc - source/extensions/tracers - source/extensions/transport_sockets/internal_upstream - source/extensions/transport_sockets/tls/cert_validator - source/extensions/transport_sockets/tcp_stats/config.cc + - source/common/tracing/custom_tag_impl.cc # Only one C++ file should instantiate grpc_init grpc_init: @@ -239,6 +217,8 @@ paths: # Files in these paths can use Protobuf::util::JsonStringToMessage json_string_to_message: include: + - source/common/jwt/jwt.cc + - source/common/jwt/jwks.cc - source/common/protobuf/utility.cc - source/common/protobuf/protobuf.h - source/common/protobuf/yaml_utility.cc @@ -265,6 +245,7 @@ paths: - source/extensions/filters/http/grpc_field_extraction - source/extensions/filters/http/proto_message_extraction/extraction_util - test/extensions/bootstrap/wasm/test_data + - bazel/external/cargo/remote # Files that are allowed to use try without main thread assertion. raw_try: @@ -281,11 +262,13 @@ paths: - source/common/common/utility.h - source/common/event/real_time_system.cc - source/common/event/real_time_system.h + - source/common/jwt/simple_lru_cache_inl.h - source/exe/main_common.cc - source/exe/main_common.h - source/extensions/common/aws/utility.cc - source/server/config_validation/server.cc - test/common/common/log_macros_test.cc + - test/common/jwt/simple_lru_cache_test.cc - test/common/protobuf/utility_test.cc - test/integration/integration.h - test/test_common/simulated_time_system.cc @@ -313,10 +296,17 @@ paths: include: - api/bazel/cc_proto_descriptor_library/file_descriptor_generator.cc - contrib/config/source/kv_store_xds_delegate.cc + - contrib/kafka/stat_sinks/source/kafka_stats_sink_impl.cc + - contrib/istio/filters/network/metadata_exchange/source/metadata_exchange.cc + - contrib/istio/filters/network/metadata_exchange/test/metadata_exchange_test.cc + - contrib/istio/filters/http/peer_metadata/source/peer_metadata.cc + - contrib/istio/filters/network/peer_metadata/source/peer_metadata.cc + - contrib/istio/filters/network/peer_metadata/test/peer_metadata_test.cc - source/common/protobuf/utility.h - source/common/protobuf/utility.cc - source/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter.cc - source/extensions/http/cache/file_system_http_cache/cache_file_header_proto_util.cc + - source/extensions/http/cache_v2/file_system_http_cache/cache_file_header_proto_util.cc - test/common/grpc/codec_fuzz_test.cc - test/common/grpc/codec_test.cc - test/common/protobuf/utility_test.cc @@ -325,7 +315,11 @@ paths: - test/extensions/filters/common/expr/context_test.cc - test/extensions/filters/http/common/fuzz/uber_filter.h - test/extensions/http/cache/file_system_http_cache/cache_file_header_proto_util_test.cc + - test/extensions/http/cache_v2/file_system_http_cache/cache_file_header_proto_util_test.cc - test/tools/router_check/router_check.cc + - source/extensions/bootstrap/reverse_tunnel/downstream_socket_interface/rc_connection_wrapper.cc + - test/extensions/bootstrap/reverse_tunnel/downstream_socket_interface/rc_connection_wrapper_test.cc + - test/extensions/router/cluster_specifiers/dynamic_modules/cluster_specifier_test.cc # Files in these paths can use std::regex std_regex: @@ -356,6 +350,9 @@ paths: - source/extensions/common/wasm/context.h - source/extensions/common/wasm/context.cc - source/extensions/common/wasm/foreign.cc + - contrib/stat_sinks/wasm_filter/source/wasm_filter_stat_sink_impl.cc + - contrib/stat_sinks/wasm_filter/test/test_data/stats_filter_plugin.cc + - contrib/stat_sinks/wasm_filter/test/wasm_filter_stat_sink_integration_test.cc - source/extensions/common/wasm/wasm.h - source/extensions/common/wasm/wasm.cc - source/extensions/common/wasm/wasm_vm.h @@ -363,9 +360,20 @@ paths: - test/extensions/bootstrap/wasm/wasm_speed_test.cc - test/extensions/bootstrap/wasm/wasm_test.cc - test/extensions/common/wasm/wasm_test.cc + - test/extensions/dynamic_modules/test_data/cpp/early_header_mutation_integration_test.cc + - test/extensions/dynamic_modules/test_data/cpp/header_formatter_integration_test.cc + - test/extensions/dynamic_modules/test_data/cpp/http_integration_test.cc + - test/extensions/dynamic_modules/test_data/cpp/http.cc + - test/extensions/dynamic_modules/test_data/cpp/listener_integration_test.cc + - test/extensions/dynamic_modules/test_data/cpp/network_integration_test.cc - test/extensions/stats_sinks/wasm/wasm_stat_sink_test.cc - test/test_common/wasm_base.h + # Files that can use std::optional> instead of OptRef + optional_reference_wrapper: + include: + - test/common/common/optref_test.cc + dir_order: - envoy - common @@ -379,7 +387,6 @@ re: codeowners_contrib: (/contrib/[^@]*\s+)(@.*) codeowners_extensions: .*(extensions[^@]*\s+)(@.*) comment: //|\* - designated_initializer: \{\s*\.\w+\s*\= # Check for punctuation in a terminal ref clause, e.g. # :ref:`panic mode. ` dot_multi_space: \. + @@ -391,6 +398,7 @@ re: mangled_protobuf_name: envoy::[a-z0-9_:]+::[A-Z][a-z]\w*_\w*_[A-Z]{2} maintainers: .*github.com.(.*)\)\) old_mock_method: MOCK_METHOD\d + optional_reference_wrapper: \bstd::optional<\s*(std::)?reference_wrapper\b owner: "@\\S+" runtime_guard_flag: RUNTIME_GUARD\((.*)\); test_name_starting_lc: TEST(_.\(.*,\s|\()[a-z].*\)\s\{ @@ -416,9 +424,6 @@ replacements: "absl::make_unique<": "std::make_unique<" protobuf_type_errors: - # Other common mis-namespacing of protobuf types. - "ProtobufWkt::Map": "Protobuf::Map" - "ProtobufWkt::MapPair": "Protobuf::MapPair" "ProtobufUtil::MessageDifferencer": "Protobuf::util::MessageDifferencer" include_angle: "#include <" @@ -431,16 +436,19 @@ unsorted_flags: # https://github.com/envoyproxy/envoy/issues/9953 # PLEASE DO NOT ADD FILES TO THIS LIST WITHOUT SENIOR MAINTAINER APPROVAL visibility_excludes: +- source/extensions/access_loggers/open_telemetry/BUILD - source/extensions/clusters/eds/ - source/extensions/clusters/strict_dns/ - source/extensions/clusters/static/ - source/extensions/clusters/original_dst/ - source/extensions/clusters/logical_dns/ - source/extensions/clusters/dns/ +- source/extensions/dynamic_modules/ - source/extensions/early_data/BUILD - source/extensions/filters/http/buffer/BUILD - source/extensions/filters/network/common/BUILD - source/extensions/filters/network/generic_proxy/interface/BUILD +- source/extensions/formatter/file_content/BUILD - source/extensions/http/header_validators/envoy_default/BUILD - source/extensions/transport_sockets/common/BUILD - source/extensions/transport_sockets/tap/BUILD @@ -467,4 +475,5 @@ visibility_excludes: - source/extensions/load_balancing_policies/random/ - source/extensions/load_balancing_policies/cluster_provided/ - source/extensions/filters/http/match_delegate/ +- source/extensions/stat_sinks/metrics_service/BUILD - source/extensions/transport_sockets/tls/ diff --git a/tools/gen_compilation_database.py b/tools/gen_compilation_database.py index b9c55656c..52ae707cf 100755 --- a/tools/gen_compilation_database.py +++ b/tools/gen_compilation_database.py @@ -3,6 +3,7 @@ import argparse import json import os +import re import shlex import subprocess from pathlib import Path @@ -23,7 +24,7 @@ def generate_compilation_database(args): source_dir_targets.remove("//contrib/...") subprocess.check_call(["bazel", *bazel_startup_options, "build"] + bazel_options + [ - "--aspects=@bazel_compdb//:aspects.bzl%compilation_database_aspect", + "--aspects=@bazel-compdb//:aspects.bzl%compilation_database_aspect", "--output_groups=compdb_files,header_files" ] + source_dir_targets) @@ -92,6 +93,13 @@ def modify_compile_command(target, args): if args.system_clang: if cc.find("clang"): cc = "clang++" + elif cc.endswith("/cc_wrapper.sh"): + # The hermetic toolchain compiles through a wrapper script. clang-tidy and clangd derive + # the C++ standard library include directory from the compiler path, so point them at the + # clang binary of the LLVM distribution the resource directory belongs to. + resource_dir = re.search(r"(?:^|\s)-resource-dir\s+(\S+)/lib/clang/", options) + if resource_dir: + cc = resource_dir.group(1) + "/bin/clang" if is_header(target["file"]): options += " -Wno-pragma-once-outside-header -Wno-unused-const-variable" diff --git a/tools/run_clang_tidy.sh b/tools/run_clang_tidy.sh new file mode 100755 index 000000000..5ee509611 --- /dev/null +++ b/tools/run_clang_tidy.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# +# Minimal stand-in for LLVM's run-clang-tidy driver, which the hermetic LLVM +# toolchain does not ship. Runs clang-tidy on the given files in parallel and, +# with -fix, applies the collected fixes with clang-apply-replacements. +# +# Usage: run_clang_tidy.sh [-fix] [-format] [-style=