diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 8c36e89..07f74b0 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,7 +1,9 @@ -name: Build & publish +name: Build & publish image on: workflow_dispatch: + release: + types: [published] jobs: push_to_registry: diff --git a/.github/workflows/run_long_integration_tests.yml b/.github/workflows/run_long_integration_tests.yml new file mode 100644 index 0000000..acbe245 --- /dev/null +++ b/.github/workflows/run_long_integration_tests.yml @@ -0,0 +1,25 @@ +name: Long integration tests + +on: + workflow_dispatch: + pull_request: + +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build image + run: | + docker buildx build --output type=docker --no-cache . -t sdk-rust-contract-builder:next -f ./Dockerfile + + - name: Build + run: | + export PYTHONPATH=. + python ./integration_tests/test_previous_builds_are_reproducible.py --selected-builds "a.1" "a.2" "a.3" "b.1" "b.2" "b.3" "c.1" "c.2" "c.3" "c.4" "c.5" "d.1" "e.1" diff --git a/.github/workflows/run_regular_integration_tests.yml b/.github/workflows/run_regular_integration_tests.yml new file mode 100644 index 0000000..6ba7a62 --- /dev/null +++ b/.github/workflows/run_regular_integration_tests.yml @@ -0,0 +1,25 @@ +name: Regular integration tests + +on: + workflow_dispatch: + pull_request: + +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build image + run: | + docker buildx build --output type=docker --no-cache . -t sdk-rust-contract-builder:next -f ./Dockerfile + + - name: Build + run: | + export PYTHONPATH=. + python ./integration_tests/test_project_folder_and_packaged_src_are_equivalent.py diff --git a/.gitignore b/.gitignore index a356615..df9b3cd 100644 --- a/.gitignore +++ b/.gitignore @@ -132,4 +132,6 @@ dmypy.json typings/** # Test data -testdata/**/output +testdata/input/extracted +testdata/output +testdata/rust diff --git a/Dockerfile b/Dockerfile index c3ef430..548e5b0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,22 @@ FROM ubuntu:22.04 # Constants -ARG VERSION_RUST="nightly-2022-12-08" +ARG VERSION_RUST="nightly-2022-10-16" ARG VERSION_BINARYEN="105-1" ARG VERSION_WABT="1.0.27-1" +# Normally, this should be "multiversx/sdk-rust-contract-builder:{{pyproject.toml:project:version}}" +ARG CONTEXT="multiversx/sdk-rust-contract-builder:v4.1.0" # Install dependencies (including binaryen and wabt) RUN apt-get update && apt-get install -y \ wget \ build-essential \ - python3.10 python-is-python3 \ + python3.11 python-is-python3 python3-pip \ binaryen=${VERSION_BINARYEN} \ wabt=${VERSION_WABT} +RUN pip3 install tomlkit==0.11.6 + # Install rust RUN wget -O rustup.sh https://sh.rustup.rs && \ chmod +x rustup.sh && \ @@ -25,6 +29,7 @@ COPY "multiversx_sdk_rust_contract_builder" "/multiversx_sdk_rust_contract_build ENV PATH="/rust/bin:${PATH}" ENV CARGO_HOME="/rust" ENV RUSTUP_HOME="/rust" +ENV CONTEXT=${CONTEXT} ENV PYTHONPATH=/ # Additional arguments (must be provided at "docker run"): diff --git a/README.md b/README.md index 601465f..05da2b2 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,66 @@ -# mx-sdk-build-contract +# mx-sdk-rust-contract-builder Docker image (and wrappers) for reproducible contract builds (Rust). See [docs.multiversx.com](https://docs.multiversx.com/developers/reproducible-contract-builds/). ## Build the Docker image +We use `docker buildx` to build the image: + +``` +docker buildx build --output type=docker --no-cache . -t sdk-rust-contract-builder:next -f ./Dockerfile ``` -docker buildx build --no-cache . -t sdk-rust-contract-builder:experimental -f ./Dockerfile + +Maintainers can publish the image as follows: + +``` +docker buildx create --name multiarch --use + +docker buildx build --no-cache --push --platform=linux/amd64,linux/arm64 . -t multiversx/sdk-rust-contract-builder:next -f ./Dockerfile + +docker buildx rm multiarch ``` +For the above to work properly, make sure to install `tonistiigi/binfmt` beforehand. Please follow the official Docker documentation [here](https://docs.docker.com/build/building/multi-platform/). + +Though, note that currently (January 2023) we recommend against using the `linux/arm64` image for performing reproducible contract builds. This is because, in some (possibly rare) circumstances, a WASM binary generated on the `linux/amd64` image _might_ differ (at the bytecode level) from one generated on the `linux/arm64` image - probably due to distinct (unfortunate) bytecode-emitting logic in the Rust compiler. + ## Build contract using the wrapper -Without providing `cargo-target-dir`: +If you are using a Mac with ARM64, we _recommend_ setting the following variable beforehand (contract builds will be slower, but this eliminates the risk of not being able to reproduce the build on Linux): ``` -python3 ./build_with_docker.py --image=sdk-rust-contract-builder:experimental \ - --project=~/contracts/reproducible-contract-build-example \ - --output=~/contracts/output-from-docker +export DOCKER_DEFAULT_PLATFORM=linux/amd64 ``` -With providing `cargo-target-dir`: +Building from a project folder: ``` -python3 ./build_with_docker.py --image=sdk-rust-contract-builder:experimental \ - --project=~/contracts/reproducible-contract-build-example \ - --output=~/contracts/output-from-docker \ - --cargo-target-dir=~/cargo-target-dir-docker +python3 ./build_with_docker.py --image=sdk-rust-contract-builder:next \ + --project=~/contracts/example \ + --output=~/contracts/output-from-docker ``` Building from a packaged source code: ``` -python3 ./build_with_docker.py --image=sdk-rust-contract-builder:experimental \ +python3 ./build_with_docker.py --image=sdk-rust-contract-builder:next \ --packaged-src=~/contracts/example-0.0.0.source.json \ --output=~/contracts/output-from-docker ``` -## Build contract using the Docker inner script - -This is useful for useful for testing, debugging and reviewing the script. +## Run unit tests (without Docker) ``` -export PROJECT=${HOME}/contracts/reproducible-contract-build-example -export OUTPUT=${HOME}/contracts/output -export CARGO_TARGET_DIR=${HOME}/cargo-target-dir export PATH=${HOME}/multiversx-sdk/vendor-rust/bin:${HOME}/multiversx-sdk/wabt/latest/bin:${PATH} export RUSTUP_HOME=${HOME}/multiversx-sdk/vendor-rust export CARGO_HOME=${HOME}/multiversx-sdk/vendor-rust + +pytest . ``` -Build a project: +## Run integration tests (with Docker) ``` -python3 ./build_within_docker.py --project=${PROJECT} --output=${OUTPUT} \ - --cargo-target-dir=${CARGO_TARGET_DIR} +python3 ./integration_tests/test_previous_builds_are_reproducible.py --selected-builds "a.1" [...] +python3 ./integration_tests/test_project_folder_and_packaged_src_are_equivalent.py ``` diff --git a/build_with_docker.py b/build_with_docker.py index d7d539f..0057a74 100644 --- a/build_with_docker.py +++ b/build_with_docker.py @@ -75,7 +75,7 @@ def run_docker( docker_mount_args.extend(["--volume", f"{packaged_src_path}:/packaged-src.json"]) if cargo_target_dir: - docker_mount_args += ["--volume", f"{cargo_target_dir}:/cargo-target-dir"] + docker_mount_args += ["--volume", f"{cargo_target_dir}:/rust/cargo-target-dir"] docker_args = ["docker", "run"] diff --git a/integration_tests/__init__.py b/integration_tests/__init__.py new file mode 100644 index 0000000..a9a2c5b --- /dev/null +++ b/integration_tests/__init__.py @@ -0,0 +1 @@ +__all__ = [] diff --git a/integration_tests/config.py b/integration_tests/config.py new file mode 100644 index 0000000..b2eb57f --- /dev/null +++ b/integration_tests/config.py @@ -0,0 +1,9 @@ +from pathlib import Path + +DOWNLOADS_FOLDER = Path("./testdata/downloads").resolve() +EXTRACTED_FOLDER = Path("./testdata/input/extracted").resolve() +PARENT_OUTPUT_FOLDER = Path("./testdata/output").resolve() +CARGO_TARGET_DIR = Path("./testdata/rust/cargo_target_dir").resolve() +RUST_REGISTRY = Path("./testdata/rust/registry").resolve() +RUST_GIT = Path("./testdata/rust/git").resolve() +RUST_TMP = Path("./testdata/rust/tmp").resolve() diff --git a/integration_tests/previous_builds.py b/integration_tests/previous_builds.py new file mode 100644 index 0000000..0bfcf13 --- /dev/null +++ b/integration_tests/previous_builds.py @@ -0,0 +1,263 @@ + +from typing import Dict, List, Optional + + +class PreviousBuild: + def __init__(self, name: str, + project_archive_url: Optional[str], + project_relative_path_in_archive: Optional[str], + packaged_src_url: Optional[str], + contract_name: Optional[str], + expected_code_hashes: Dict[str, str], + docker_image: str) -> None: + self.name = name + self.project_zip_url = project_archive_url + self.project_relative_path_in_archive = project_relative_path_in_archive + self.packaged_src_url = packaged_src_url + self.contract_name = contract_name + self.expected_code_hashs = expected_code_hashes + self.docker_image = docker_image + + +previous_builds: List[PreviousBuild] = [ + PreviousBuild( + name="a.1", + project_archive_url="https://github.com/multiversx/mx-reproducible-contract-build-example-sc/archive/refs/tags/v0.1.5.zip", + project_relative_path_in_archive=None, + packaged_src_url=None, + contract_name=None, + expected_code_hashes={ + "adder": "58c6e78f40bd6ccc30d8a01f952b34a13ebfdad796a2526678be17c5d7820174" + }, + docker_image="sdk-rust-contract-builder:next" + ), + PreviousBuild( + name="a.2", + project_archive_url="https://github.com/multiversx/mx-reproducible-contract-build-example-sc/archive/refs/tags/v0.1.5.zip", + project_relative_path_in_archive=None, + packaged_src_url=None, + contract_name=None, + expected_code_hashes={ + "adder": "58c6e78f40bd6ccc30d8a01f952b34a13ebfdad796a2526678be17c5d7820174" + }, + docker_image="sdk-rust-contract-builder:next" + ), + PreviousBuild( + name="a.3", + project_archive_url="https://github.com/multiversx/mx-reproducible-contract-build-example-sc/archive/refs/tags/v0.1.5.zip", + project_relative_path_in_archive=None, + packaged_src_url=None, + contract_name=None, + expected_code_hashes={ + "adder": "58c6e78f40bd6ccc30d8a01f952b34a13ebfdad796a2526678be17c5d7820174" + }, + docker_image="sdk-rust-contract-builder:next" + ), + PreviousBuild( + name="b.1", + project_archive_url="https://github.com/multiversx/mx-exchange-sc/archive/refs/tags/v1.5.4-metabonding-unbond.zip", + project_relative_path_in_archive="mx-exchange-sc-1.5.4-metabonding-unbond", + packaged_src_url=None, + contract_name=None, + expected_code_hashes={ + "metabonding-staking": "4a9b2afa13eca738b1804c48b82a961afd67adcbbf2aa518052fa124ac060bea" + }, + docker_image="sdk-rust-contract-builder:next" + ), + PreviousBuild( + name="b.2", + project_archive_url="https://github.com/multiversx/mx-exchange-sc/archive/refs/tags/v1.5.4-metabonding-unbond.zip", + project_relative_path_in_archive="mx-exchange-sc-1.5.4-metabonding-unbond", + packaged_src_url=None, + contract_name="metabonding-staking", + expected_code_hashes={ + "metabonding-staking": "4a9b2afa13eca738b1804c48b82a961afd67adcbbf2aa518052fa124ac060bea" + }, + docker_image="sdk-rust-contract-builder:next" + ), + PreviousBuild( + name="b.3", + project_archive_url="https://github.com/multiversx/mx-exchange-sc/archive/refs/tags/v1.5.4-metabonding-unbond.zip", + project_relative_path_in_archive="mx-exchange-sc-1.5.4-metabonding-unbond", + packaged_src_url=None, + contract_name="metabonding-staking", + expected_code_hashes={ + "metabonding-staking": "4a9b2afa13eca738b1804c48b82a961afd67adcbbf2aa518052fa124ac060bea" + }, + docker_image="sdk-rust-contract-builder:next" + ), + PreviousBuild( + name="c.1", + project_archive_url="https://github.com/multiversx/mx-exchange-sc/archive/refs/heads/reproducible-v2.1.1-staking-upgrade.zip", + project_relative_path_in_archive="mx-exchange-sc-reproducible-v2.1.1-staking-upgrade", + packaged_src_url=None, + contract_name=None, + expected_code_hashes={ + "distribution": "17a30ad44291af84f6dbd84fdaf0a9a56ed7145d544c54fd74088bb544c4f98f", + "energy-factory": "241600c055df605cafd85b75d40b21316a6b35713485201b156d695b23c66a2f", + "energy-factory-mock": "83b2f26a52e3fe74953f2a8cfd81f169664a4e59dae4e5d5bb1d89956fd81d43", + "energy-update": "8523bf84ac56626c70c31342487445bf8123e3ef5f906dcb39e8b5f16c4145b7", + "factory": "df06465b651594605466e817bfe9d8d7c68eef0f87df4a8d3266bcfb1bef6d83", + "farm": "931ca233826ff9dacd889967365db1cde9ed8402eb553de2a3b9d58b6ff1098d", + "farm-staking": "6dc7c587b2cc4b177a192b709c092f3752b3dcf9ce1b484e69fe64dc333a9e0a", + "farm-staking-proxy": "56468a6ae726693a71edcf96cf44673466dd980412388e1e4b073a0b4ee592d7", + "farm-with-locked-rewards": "437b2a665e643b5885cf50ee865c467371ca6faa20a8ff14a4b626c775f49971", + "fees-collector": "c46767232cd8551f8b0f4aa94dc419ddefc13eaaa5aa4b422749a300621149f3", + "governance": "959388eadaf71ff106252c601ae2767a5c62d7bd0ab119381c28dc679975685e", + "governance-v2": "786a6cf08f1d961814ebb062f149c9a943d39d7db93d8f53aa1fc42b8e652f49", + "lkmex-transfer": "995311e0dbd75ddc51a5c0c71ab896245c996b9b3993d3118a153bfb5531e123", + "locked-token-wrapper": "f9ee63d96163e3fac52a164c76d91c85fd77968393a50d4a96a7080e648d0a6c", + "metabonding-staking": "f508c5643b3d5f5e79b68762a9ca9e247c753acd305a29009328c5ec5d153bdd", + "pair": "f3f08ebd758fada871c113c18017d9761f157d00b19c4d3beaba530e6c53afc2", + "pair-mock": "a54495375db964cf924391433605d602940174d4d28111b89b8689564d90e662", + "pause-all": "2ad8aa911555b41e397541eb46cd1a7fa87186146f8c2b295e3916303833f3cd", + "price-discovery": "6df095b15272b189c2e7b3628a21e17c1a6b26e5ed03e9a7bddac61be29d162f", + "proxy-deployer": "5108e7419546872d235f0b7db5e01c5d04fec243bfa599c666629ead13bab0aa", + "proxy_dex": "988dd8b632e1b4bb9b43e5636ef4c363dd4066186f64f6f783f9cd043aa906c1", + "router": "c21ab56ef24b0719c101677170557e5aa61e1d17c1052ed7b2290cb26a5bdcd6", + "simple-lock": "303290b7a08b091c29315dd6979c1f745fc05467467d7de64e252592074890a7", + "simple-lock-whitelist": "c576c6106234e5f7978efb1885afe36c5d6da6a13c12b459fd7fe95967646d13", + "token-unstake": "463e49892f64726450d0df5ab4ba26559ad882525ce5e93173a26fde8437266e", + }, + docker_image="sdk-rust-contract-builder:next" + ), + PreviousBuild( + name="c.2", + project_archive_url="https://github.com/multiversx/mx-exchange-sc/archive/refs/heads/reproducible-v2.0-rc6.zip", + project_relative_path_in_archive="mx-exchange-sc-reproducible-v2.0-rc6", + packaged_src_url=None, + contract_name=None, + expected_code_hashes={ + "distribution": "17a30ad44291af84f6dbd84fdaf0a9a56ed7145d544c54fd74088bb544c4f98f", + "energy-factory": "62d60c8dec649614dd9cf04fb20b884c7658b12759fa14bf7e9c7be3880a5edd", + "energy-factory-mock": "83b2f26a52e3fe74953f2a8cfd81f169664a4e59dae4e5d5bb1d89956fd81d43", + "energy-update": "8523bf84ac56626c70c31342487445bf8123e3ef5f906dcb39e8b5f16c4145b7", + "factory": "df06465b651594605466e817bfe9d8d7c68eef0f87df4a8d3266bcfb1bef6d83", + "farm": "69f95b5f9a4d5b6bb101d5d2cf7495264a4d04de2b36653e0c8088cf6fad492a", + "farm-staking": "ca0a8ceed8b8807b0fb078153c15167a3a235a61a76edc5023dfcacae0446125", + "farm-staking-proxy": "56468a6ae726693a71edcf96cf44673466dd980412388e1e4b073a0b4ee592d7", + "farm-with-locked-rewards": "c18d75ea788ece457788ad8849722a42dd4a12e6e23ab87f0cdffcc0116b61be", + "fees-collector": "c46767232cd8551f8b0f4aa94dc419ddefc13eaaa5aa4b422749a300621149f3", + "governance": "959388eadaf71ff106252c601ae2767a5c62d7bd0ab119381c28dc679975685e", + "governance-v2": "786a6cf08f1d961814ebb062f149c9a943d39d7db93d8f53aa1fc42b8e652f49", + "lkmex-transfer": "995311e0dbd75ddc51a5c0c71ab896245c996b9b3993d3118a153bfb5531e123", + "locked-token-wrapper": "f9ee63d96163e3fac52a164c76d91c85fd77968393a50d4a96a7080e648d0a6c", + "metabonding-staking": "f508c5643b3d5f5e79b68762a9ca9e247c753acd305a29009328c5ec5d153bdd", + "pair": "23ce1e8910c105410b4a417153e4b38c550ab78b38b899ea786f0c78500caf21", + "pair-mock": "a54495375db964cf924391433605d602940174d4d28111b89b8689564d90e662", + "pause-all": "2ad8aa911555b41e397541eb46cd1a7fa87186146f8c2b295e3916303833f3cd", + "price-discovery": "6df095b15272b189c2e7b3628a21e17c1a6b26e5ed03e9a7bddac61be29d162f", + "proxy-deployer": "5108e7419546872d235f0b7db5e01c5d04fec243bfa599c666629ead13bab0aa", + "proxy_dex": "988dd8b632e1b4bb9b43e5636ef4c363dd4066186f64f6f783f9cd043aa906c1", + "router": "8429d332fb62b557b3549d3f509a55d6aff8638f53a5ee876358a831107102cf", + "simple-lock": "303290b7a08b091c29315dd6979c1f745fc05467467d7de64e252592074890a7", + "simple-lock-whitelist": "c576c6106234e5f7978efb1885afe36c5d6da6a13c12b459fd7fe95967646d13", + "token-unstake": "463e49892f64726450d0df5ab4ba26559ad882525ce5e93173a26fde8437266e", + }, + docker_image="sdk-rust-contract-builder:next" + ), + PreviousBuild( + name="c.3", + project_archive_url="https://github.com/multiversx/mx-exchange-sc/archive/refs/heads/reproducible-v2.1.3-price-discovery-comp-upgrade.zip", + project_relative_path_in_archive="mx-exchange-sc-reproducible-v2.1.3-price-discovery-comp-upgrade", + packaged_src_url=None, + contract_name=None, + expected_code_hashes={ + "distribution": "c8f6a78ca4007608905484952c88b680afe450203ca89a9e176ff36472eb4e3c", + "energy-factory": "1d444aaae54ab41c04ecf6147cfba16b03e5841382d69c65decb5fbd3bef6b25", + "energy-factory-mock": "a55835cd6992f0c02331ee1b8a21b3163c0efc1a8c1c3fdb1b5e34944a358d66", + "energy-update": "5ecde1bde66e1ccc10ac4bf8dcabfabf0d314ecaac51c72c3a19037256557885", + "factory": "3bcee411030c9426500178f1e92b3a1d7c31a7ed2bbb29ab05d15a4eaac3a955", + "farm": "4029cd4df87f2be4b7d1ed96161c9c3ab6fa44c090a574de4e6f1926ff302ea0", + "farm-staking": "89833609549b085f258b8fac6272014d874918883cf5643b071fb097993cdf03", + "farm-staking-proxy": "afe66cd648e293a98939af01a6b75180f0545ac3049ef26dfd6cfcdc7fcea51c", + "farm-with-locked-rewards": "c1dcd37f29dbc5a810ef1893c07cd3d7af765cb5d7b0c7ac92f5a601df73e033", + "fees-collector": "44a90c28bf35386cd533d22046243e02dc38cec00db948ef0c85392779c20593", + "governance": "956d520e05e97327ce2b8d05872a758c0e88ddce15a298b3fb8b7e0cf4a5ef1c", + "governance-v2": "995add2c509c29f4a8f875019f46831a0f5702fa21ea7a69e6fdad19bb6fda04", + "lkmex-transfer": "1c776af3ec771aba18c1cb2bb567a583ed179d91c8765bfbdc2dd4ddcca65790", + "locked-token-wrapper": "086a9baf3d89a54c2fccd066e36872d75406ac30ff1ed7c5ac9aae3a98b83284", + "metabonding-staking": "c2c5bbed7f35767315c574dedbabdfbd5f18bf6cd2a561e3df08fc46637ef1a8", + "pair": "c5c373155de76e6dfa040386947459d8cbdb4e7cc28d3dfe907922032a05e626", + "pair-mock": "7a631dbc9e2ba07932c21d923292234110859d2ce5335851f0265aeaa37b7687", + "pause-all": "2ad8aa911555b41e397541eb46cd1a7fa87186146f8c2b295e3916303833f3cd", + "price-discovery": "96b51ec9df3eb7a8e72f297aac2c8e4e609e39ac5a5f6d861c0819d010b87fde", + "proxy-deployer": "17e225e07b2ec759c86d70f6b61342f603135ac399b36bc48acab89f0bcfa483", + "proxy_dex": "3cac5e915b9c8f8dfa711b1f4b1cf213380660cbd0afe3695cc73d4989abe301", + "router": "5383bf12ad1ff9134782bd9aa9638bd16260ae7800434d01f853117e3db15c42", + "simple-lock": "4f2747e6952b0e0aaa275e57dbd87afe63b1caf353ba25ff002b1a85185f3927", + "simple-lock-whitelist": "3bc3cecbee78958e65efdaa077974d95d743d962254788d9280839362dc4da8b", + "token-unstake": "2b0f59073bd697d75ec2009a3bf3c350b74ff9b10d6a7bfe1e13f653732ddb1a", + }, + docker_image="sdk-rust-contract-builder:next" + ), + PreviousBuild( + name="c.4", + project_archive_url="https://github.com/multiversx/mx-exchange-sc/archive/refs/heads/reproducible-v2.1.4-locked-token-wrapper.zip", + project_relative_path_in_archive="mx-exchange-sc-reproducible-v2.1.4-locked-token-wrapper", + packaged_src_url=None, + contract_name=None, + expected_code_hashes={ + "distribution": "51c9b6961443e67429ff6206fbb687427f8de739b50f02fb570269569e2c825d", + "energy-factory": "04483a0014d8c633d3966b38a96f2ea85d462cdde84cc3f0ee9ed28932c392ec", + "energy-factory-mock": "e5e95496bbfad534764eb67b3424ccae648353b39f89e41ba6874af6012a059f", + "energy-update": "31fec2ec88c778bb7157519b8f5757ce3aefc8334c7c93834f5c4e1d667bf4b5", + "factory": "91ef660172515fa6c5985f5cea06e96d9dfaae672e17a3cad6b2f4ad82ff2f0e", + "farm": "b406b586b8124a6cb577b91cf970b5acdfee41bbe5e21b87201a27a2f9772fb7", + "farm-staking": "7915b8e7c96f748afdd1a03a53d9c5377b1b11fcd59d4e6070094a5a0d7bff31", + "farm-staking-proxy": "99ad18a0bb49ab45ee5a860ebab10dc964796fd0218752bca38b5666c916c0a2", + "farm-with-locked-rewards": "a79baa1470a6b6232de6279417da046e753f7b9a4b9ae0e7e74f4f62da80a608", + "fees-collector": "fb4f1f63a5bd33184afde0241cb69b9e9d172ed936263d688c65ab96a7fd2d0c", + "governance": "e38189852ed794a6bd408c1147f90b4c47a9c6381c3a84b1b378ab6bfc9f74aa", + "governance-v2": "192570f6866fd109371580f04a1ef7553a98c5603ebd1afd55a42f983c03df3c", + "lkmex-transfer": "f850f9c7f70d3e198fa08e0d64538456b8e8ccdd6a5b8929f7faedd7cca85413", + "locked-token-wrapper": "256d7144713e6875eacde2aaefdf222895bf024f4ab2ea4c7dfb02e60d1efba3", + "metabonding-staking": "5cbcaaa8821db2a902477bce67a18a6f238f933863dded4c66bc5a5c9677dda7", + "pair": "dfb32db0afeb85bdf7bcc02d823a818bf27ce217513ecf6c92f5ccb25425a191", + "pair-mock": "a54495375db964cf924391433605d602940174d4d28111b89b8689564d90e662", + "pause-all": "2ad8aa911555b41e397541eb46cd1a7fa87186146f8c2b295e3916303833f3cd", + "price-discovery": "23deb3a6515a1a524fae6fb03613c042e2225d253da1e04532c66544167ac353", + "proxy-deployer": "9224eb8803a2aba700ec24ad8447ebc55010cb0c200cc55042d9b97dadc0668b", + "proxy_dex": "504f267a114cb46a6f3ba873dcfde43bd92d46fec61c830d45dfda2e368f52dc", + "router": "0a1ce2edc277cd36098e0a44aab618ef30a048db60eb9c67bac251fb43b54aa6", + "simple-lock": "74413279b467b72df4086efecfa0a773de284bfade1d9000106d13d47441daff", + "simple-lock-whitelist": "b8f14e78635ad3894cb78f7d24302d17ee2059b353d1017e4b84f3beef2abc1a", + "token-unstake": "3059ffec6f44259b8f2be56b9e1c67c72342f93c0c6f4b5cadc24364f2ee95e7", + }, + docker_image="sdk-rust-contract-builder:next" + ), + PreviousBuild( + name="c.5", + project_archive_url="https://github.com/multiversx/mx-exchange-sc/archive/refs/heads/reproducible-v2.1.6-energy-factory-convert-for-scs.zip", + project_relative_path_in_archive="mx-exchange-sc-reproducible-v2.1.6-energy-factory-convert-for-scs", + packaged_src_url=None, + contract_name=None, + expected_code_hashes={ + "energy-factory": "529fd987e7702b90044757073f36024d24cbe5cc8810d5abe93c6c5176a0ec53", + }, + docker_image="sdk-rust-contract-builder:next" + ), + PreviousBuild( + name="d.1", + project_archive_url="https://github.com/multiversx/mx-nft-marketplace-sc/archive/refs/heads/reproducible-v2.0.1.zip", + project_relative_path_in_archive="mx-nft-marketplace-sc-reproducible-v2.0.1", + packaged_src_url=None, + contract_name=None, + expected_code_hashes={ + "esdt-nft-marketplace": "aed8f014c914d2910cbb68b61adb757f8dbc8385842e717127482e1a66828bbe", + "seller-contract-mock": "d3f42ae77ec60878ba62146a4209ef08a9400aecf083c96888ede316069985c0" + }, + docker_image="multiversx/sdk-rust-contract-builder:v4.0.3" + ), + PreviousBuild( + name="e.1", + project_archive_url="https://github.com/multiversx/mx-metabonding-sc/archive/refs/heads/reproducible-v1.1.1.zip", + project_relative_path_in_archive="mx-metabonding-sc-reproducible-v1.1.1", + packaged_src_url=None, + contract_name=None, + expected_code_hashes={ + "metabonding": "897b19e1990f7c487c99c12f50722febe1ee4468bcd3a7405641966dfff2791d" + }, + docker_image="sdk-rust-contract-builder:next" + ) +] diff --git a/integration_tests/shared.py b/integration_tests/shared.py new file mode 100644 index 0000000..964aaf2 --- /dev/null +++ b/integration_tests/shared.py @@ -0,0 +1,77 @@ +import os +import shutil +import subprocess +import urllib.request +from pathlib import Path +from typing import List, Optional + +from integration_tests.config import (CARGO_TARGET_DIR, DOWNLOADS_FOLDER, + EXTRACTED_FOLDER, RUST_GIT, + RUST_REGISTRY, RUST_TMP) + + +def download_project_repository(zip_archive_url: str, name: str) -> Path: + DOWNLOADS_FOLDER.mkdir(parents=True, exist_ok=True) + EXTRACTED_FOLDER.mkdir(parents=True, exist_ok=True) + + download_to_path = DOWNLOADS_FOLDER / f"{name}.zip" + extract_to_path = EXTRACTED_FOLDER / name + + urllib.request.urlretrieve(zip_archive_url, download_to_path) + shutil.rmtree(extract_to_path, ignore_errors=True) + shutil.unpack_archive(download_to_path, extract_to_path) + return extract_to_path + + +def download_packaged_src(json_url: str, name: str) -> Path: + downloaded_packaged_src = DOWNLOADS_FOLDER / f"{name}.source.json" + urllib.request.urlretrieve(json_url, downloaded_packaged_src) + return downloaded_packaged_src + + +def run_docker( + project_path: Optional[Path], + packaged_src_path: Optional[Path], + contract_name: Optional[str], + image: str, + output_folder: Path, +): + CARGO_TARGET_DIR.mkdir(parents=True, exist_ok=True) + RUST_REGISTRY.mkdir(parents=True, exist_ok=True) + RUST_GIT.mkdir(parents=True, exist_ok=True) + RUST_TMP.mkdir(parents=True, exist_ok=True) + + docker_mount_args: List[str] = ["--volume", f"{output_folder}:/output"] + + if project_path: + docker_mount_args.extend(["--volume", f"{project_path}:/project"]) + + if packaged_src_path: + docker_mount_args.extend(["--volume", f"{packaged_src_path}:/packaged-src.json"]) + + docker_mount_args += ["--volume", f"{CARGO_TARGET_DIR}:/rust/cargo-target-dir"] + docker_mount_args += ["--volume", f"{RUST_REGISTRY}:/rust/registry"] + docker_mount_args += ["--volume", f"{RUST_GIT}:/rust/git"] + docker_mount_args += ["--volume", f"{RUST_TMP}:/rust/tmp"] + + docker_args = ["docker", "run"] + docker_args += docker_mount_args + docker_args += ["--user", f"{str(os.getuid())}:{str(os.getgid())}"] + docker_args += ["--rm", image] + + entrypoint_args: List[str] = [] + + if project_path: + entrypoint_args.extend(["--project", "project"]) + + if packaged_src_path: + entrypoint_args.extend(["--packaged-src", "packaged-src.json"]) + + if contract_name: + entrypoint_args.extend(["--contract", contract_name]) + + args = docker_args + entrypoint_args + result = subprocess.run(args) + returncode = result.returncode + if returncode != 0: + raise Exception(f"Docker exited with return code {returncode}.") diff --git a/integration_tests/test_previous_builds_are_reproducible.py b/integration_tests/test_previous_builds_are_reproducible.py new file mode 100644 index 0000000..7f37b54 --- /dev/null +++ b/integration_tests/test_previous_builds_are_reproducible.py @@ -0,0 +1,72 @@ +import json +import shutil +import sys +from argparse import ArgumentParser +from pathlib import Path +from typing import List, Optional, Tuple + +from integration_tests.config import (CARGO_TARGET_DIR, DOWNLOADS_FOLDER, + EXTRACTED_FOLDER, PARENT_OUTPUT_FOLDER) +from integration_tests.previous_builds import PreviousBuild, previous_builds +from integration_tests.shared import (download_packaged_src, + download_project_repository, run_docker) + + +def main(cli_args: List[str]): + parser = ArgumentParser() + parser.add_argument("--selected-builds", nargs='+') + parsed_args = parser.parse_args(cli_args) + selected_builds = parsed_args.selected_builds + + shutil.rmtree(DOWNLOADS_FOLDER, ignore_errors=True) + shutil.rmtree(EXTRACTED_FOLDER, ignore_errors=True) + shutil.rmtree(PARENT_OUTPUT_FOLDER, ignore_errors=True) + + DOWNLOADS_FOLDER.mkdir(parents=True, exist_ok=True) + EXTRACTED_FOLDER.mkdir(parents=True, exist_ok=True) + CARGO_TARGET_DIR.mkdir(parents=True, exist_ok=True) + + for build in previous_builds: + if not build.name in selected_builds: + continue + + print("Reproducing build", build.name, "...") + + project_path, packaged_src_path = fetch_source_code(build) + output_folder = PARENT_OUTPUT_FOLDER / build.name + output_folder.mkdir(parents=True, exist_ok=True) + + if project_path and build.project_relative_path_in_archive: + project_path = project_path / build.project_relative_path_in_archive + + run_docker(project_path, packaged_src_path, build.contract_name, build.docker_image, output_folder) + check_code_hashes(build, output_folder) + + +def fetch_source_code(build: PreviousBuild) -> Tuple[Optional[Path], Optional[Path]]: + print("Fetching source code for", build.name, "...") + + if build.project_zip_url: + return download_project_repository(build.project_zip_url, build.name), None + if build.packaged_src_url: + return None, download_packaged_src(build.packaged_src_url, build.name) + + raise Exception("No source code provided") + + +def check_code_hashes(build: PreviousBuild, output_folder: Path): + artifacts_path = output_folder / "artifacts.json" + artifacts_json = artifacts_path.read_text() + artifacts = json.loads(artifacts_json) + + for contract_name, expected_code_hash in build.expected_code_hashs.items(): + print(f"For contract {contract_name}, expecting code hash {expected_code_hash} ...") + + codehash = artifacts[contract_name]["codehash"] + if codehash != expected_code_hash: + raise Exception(f"{build.name}: codehash mismatch for contract {contract_name}! Expected {expected_code_hash}, got {codehash}") + print("OK, codehashes match:", codehash) + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/integration_tests/test_project_folder_and_packaged_src_are_equivalent.py b/integration_tests/test_project_folder_and_packaged_src_are_equivalent.py new file mode 100644 index 0000000..48f2245 --- /dev/null +++ b/integration_tests/test_project_folder_and_packaged_src_are_equivalent.py @@ -0,0 +1,58 @@ +import shutil +import sys +from typing import List + +from integration_tests.config import PARENT_OUTPUT_FOLDER +from integration_tests.shared import download_project_repository, run_docker + + +def main(cli_args: List[str]): + project_path = download_project_repository("https://github.com/multiversx/mx-exchange-sc/archive/refs/heads/main.zip", "mx-exchange-sc-main") + output_using_project = PARENT_OUTPUT_FOLDER / "using-project" + output_using_packaged_src = PARENT_OUTPUT_FOLDER / "using-packaged-src" + + shutil.rmtree(output_using_project, ignore_errors=True) + shutil.rmtree(output_using_packaged_src, ignore_errors=True) + + output_using_project.mkdir(parents=True) + output_using_packaged_src.mkdir(parents=True) + + contracts = ['distribution', 'energy-factory', 'energy-update', 'factory', 'farm', 'farm-staking', 'farm-staking-proxy', 'farm-with-locked-rewards', 'fees-collector', 'governance', 'governance-v2', 'lkmex-transfer', 'locked-token-wrapper', 'metabonding-staking', 'pair', 'pause-all', 'price-discovery', 'proxy-deployer', 'proxy_dex', 'router', 'simple-lock', 'simple-lock-whitelist', 'token-unstake'] + + for contract in contracts: + run_docker( + project_path=project_path, + packaged_src_path=None, + contract_name=contract, + image="sdk-rust-contract-builder:next", + output_folder=output_using_project + ) + + packaged_src_path = output_using_project / f"{contract}/{contract}-0.0.0.source.json" + + run_docker( + project_path=None, + packaged_src_path=packaged_src_path, + contract_name=contract, + image="sdk-rust-contract-builder:next", + output_folder=output_using_packaged_src + ) + + # Check that output folders are identical + using_project_output_files = sorted((output_using_project / contract).rglob("*")) + using_packaged_src_output_files = sorted((output_using_packaged_src / contract).rglob("*")) + + assert len(using_project_output_files) == len(using_packaged_src_output_files) + + for index, file in enumerate(using_project_output_files): + if not file.is_file() or file.suffix == ".zip": + continue + using_project_file_content = file.read_bytes() + using_packaged_src_file_content = using_packaged_src_output_files[index].read_bytes() + + if using_project_file_content != using_packaged_src_file_content: + raise Exception(f"Files differ ({contract}): {file.name}") + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/multiversx_sdk_rust_contract_builder/build_outcome.py b/multiversx_sdk_rust_contract_builder/build_outcome.py index 42154f6..3736a40 100644 --- a/multiversx_sdk_rust_contract_builder/build_outcome.py +++ b/multiversx_sdk_rust_contract_builder/build_outcome.py @@ -9,11 +9,12 @@ class BuildOutcome: - def __init__(self): + def __init__(self, context: str): + self.context = context self.contracts: Dict[str, BuildOutcomeEntry] = dict() - def gather_artifacts(self, contract_name: str, build_directory: Path, output_subdirectory: Path): - self.contracts[contract_name] = BuildOutcomeEntry.from_directories(build_directory, output_subdirectory) + def gather_artifacts(self, contract_name: str, build_folder: Path, output_subfolder: Path): + self.contracts[contract_name] = BuildOutcomeEntry.from_folders(build_folder, output_subfolder) def get_entry(self, contract_name: str) -> 'BuildOutcomeEntry': return self.contracts[contract_name] @@ -25,7 +26,7 @@ def save_to_file(self, file: Path): json.dump(data, f, indent=4) def to_dict(self) -> Dict[str, Any]: - data: Dict[str, Any] = dict() + data: Dict[str, Any] = {"context": self.context} for key, value in self.contracts.items(): data[key] = value.to_dict() @@ -41,14 +42,11 @@ def __init__(self) -> None: self.artifacts = BunchOfBuildArtifacts() @classmethod - def from_directories(cls, build_directory: Path, output_directory: Path) -> 'BuildOutcomeEntry': + def from_folders(cls, build_folder: Path, output_folder: Path) -> 'BuildOutcomeEntry': entry = BuildOutcomeEntry() - _, entry.version = get_contract_name_and_version(build_directory) - - with open(find_file_in_folder(output_directory, "*.codehash.txt")) as file: - entry.codehash = file.read() - - entry.artifacts = BunchOfBuildArtifacts.from_output_directory(output_directory) + _, entry.version = get_contract_name_and_version(build_folder) + entry.codehash = find_file_in_folder(output_folder, "*.codehash.txt").read_text() + entry.artifacts = BunchOfBuildArtifacts.from_output_folder(output_folder) return entry def to_dict(self) -> Dict[str, Any]: @@ -67,19 +65,16 @@ def __init__(self) -> None: self.abi = BuildArtifact(Path("")) self.imports = BuildArtifact(Path("")) self.src_package = BuildArtifact(Path("")) - self.src_archive = BuildArtifact(Path("")) self.output_archive = BuildArtifact(Path("")) @classmethod - def from_output_directory(cls, output_directory: Path) -> 'BunchOfBuildArtifacts': + def from_output_folder(cls, output_folder: Path) -> 'BunchOfBuildArtifacts': artifacts = BunchOfBuildArtifacts() - artifacts.bytecode = BuildArtifact.find_in_output("*.wasm", output_directory) - artifacts.text = BuildArtifact.find_in_output("*.wat", output_directory) - artifacts.abi = BuildArtifact.find_in_output("*.abi.json", output_directory) - artifacts.imports = BuildArtifact.find_in_output("*.imports.json", output_directory) - artifacts.src_package = BuildArtifact.find_in_output("*.source.json", output_directory) - artifacts.src_archive = BuildArtifact.find_in_output("*-src-*.zip", output_directory) - artifacts.src_archive = BuildArtifact.find_in_output("*-output-*.zip", output_directory) + artifacts.bytecode = BuildArtifact.find_in_output("*.wasm", output_folder) + artifacts.text = BuildArtifact.find_in_output("*.wat", output_folder) + artifacts.abi = BuildArtifact.find_in_output("*.abi.json", output_folder) + artifacts.imports = BuildArtifact.find_in_output("*.imports.json", output_folder) + artifacts.src_package = BuildArtifact.find_in_output("*.source.json", output_folder) return artifacts @@ -90,7 +85,6 @@ def to_dict(self) -> Dict[str, str]: "abi": self.abi.path.name, "imports": self.imports.path.name, "srcPackage": self.src_package.path.name, - "srcArchive": self.src_archive.path.name, "outputArchive": self.output_archive.path.name } @@ -100,8 +94,8 @@ def __init__(self, path: Path) -> None: self.path = path @classmethod - def find_in_output(cls, name_pattern: str, output_directory: Path) -> 'BuildArtifact': - path = find_file_in_folder(output_directory, name_pattern) + def find_in_output(cls, name_pattern: str, output_folder: Path) -> 'BuildArtifact': + path = find_file_in_folder(output_folder, name_pattern) return BuildArtifact(path) def read(self) -> bytes: diff --git a/multiversx_sdk_rust_contract_builder/builder.py b/multiversx_sdk_rust_contract_builder/builder.py index 9e58bf5..ab014ef 100644 --- a/multiversx_sdk_rust_contract_builder/builder.py +++ b/multiversx_sdk_rust_contract_builder/builder.py @@ -1,106 +1,109 @@ import logging -import os import shutil import subprocess from pathlib import Path -from typing import List, Union +from typing import List, Optional +from multiversx_sdk_rust_contract_builder import cargo_toml, source_code from multiversx_sdk_rust_contract_builder.build_outcome import BuildOutcome from multiversx_sdk_rust_contract_builder.cargo_toml import ( - get_contract_name_and_version, promote_cargo_lock_to_contract_directory) + get_contract_name_and_version, promote_cargo_lock_to_contract_folder) from multiversx_sdk_rust_contract_builder.codehash import \ generate_code_hash_artifact from multiversx_sdk_rust_contract_builder.constants import ( - HARDCODED_BUILD_DIRECTORY, MAX_OUTPUT_ARTIFACTS_ARCHIVE_SIZE, - MAX_SOURCE_CODE_ARCHIVE_SIZE) + CONTRACT_CONFIG_FILENAME, HARDCODED_BUILD_FOLDER, + MAX_OUTPUT_ARTIFACTS_ARCHIVE_SIZE, MAX_PACKAGED_SOURCE_CODE_SIZE, + OLD_CONTRACT_CONFIG_FILENAME) +from multiversx_sdk_rust_contract_builder.errors import ErrKnown from multiversx_sdk_rust_contract_builder.filesystem import ( - archive_directory, find_file_in_folder) + archive_folder, find_file_in_folder) from multiversx_sdk_rust_contract_builder.packaged_source_code import \ PackagedSourceCode -from multiversx_sdk_rust_contract_builder.source_code import \ - is_source_code_file from multiversx_sdk_rust_contract_builder.wabt import generate_wabt_artifacts def build_project( - project_path: Path, - parent_output_directory: Path, - specific_contract: Union[Path, None], + project_folder: Path, + parent_output_folder: Path, + specific_contract: Optional[str], cargo_target_dir: Path, - no_wasm_opt: bool) -> BuildOutcome: - project_path = project_path.expanduser().resolve() - parent_output_directory = parent_output_directory.expanduser().resolve() + no_wasm_opt: bool, + context: str) -> BuildOutcome: + project_folder = project_folder.expanduser().resolve() + parent_output_folder = parent_output_folder.expanduser().resolve() cargo_target_dir = cargo_target_dir.expanduser().resolve() - outcome = BuildOutcome() - contracts_directories = get_contracts_directories(project_path) + outcome = BuildOutcome(context) + contracts_folders = get_contracts_folders(project_folder) # We copy the whole project folder to the build path, to ensure that all local dependencies are available. - project_within_build_directory = copy_project_directory_to_build_directory(project_path) + project_within_build_folder = copy_project_folder_to_build_folder(project_folder) - for contract_directory in sorted(contracts_directories): - contract_name, contract_version = get_contract_name_and_version(contract_directory) - logging.info(f"Contract = {contract_name}, version = {contract_version}") - - output_subdirectory = parent_output_directory / f"{contract_name}" - output_subdirectory.mkdir(parents=True, exist_ok=True) + cargo_toml.remove_dev_dependencies_sections_from_all(project_within_build_folder) + source_code.replace_all_test_content_with_noop(project_within_build_folder) - relative_contract_directory = contract_directory.relative_to(project_path) - build_directory = project_within_build_directory / relative_contract_directory + for contract_folder in sorted(contracts_folders): + contract_name, contract_version = get_contract_name_and_version(contract_folder) + logging.info(f"Contract = {contract_name}, version = {contract_version}") if specific_contract and contract_name != specific_contract: logging.info(f"Skipping {contract_name}.") continue - # Clean directory - useful if it contains externally-generated build artifacts - clean_contract(build_directory) - build_contract(build_directory, output_subdirectory, cargo_target_dir, no_wasm_opt) + output_subfolder = parent_output_folder / f"{contract_name}" + output_subfolder.mkdir(parents=True, exist_ok=True) + + relative_contract_folder = contract_folder.relative_to(project_folder) + contract_build_subfolder = project_within_build_folder / relative_contract_folder + + # Clean folder - it may contain externally-generated build artifacts + clean_contract(contract_build_subfolder) + build_contract(contract_build_subfolder, output_subfolder, cargo_target_dir, no_wasm_opt) # We do not clean the "output" folder, since it will be included in one of the generated archives. - clean_contract(build_directory, clean_output=False) + clean_contract(contract_build_subfolder, clean_output=False) - promote_cargo_lock_to_contract_directory(build_directory, contract_directory) + promote_cargo_lock_to_contract_folder(contract_build_subfolder, contract_folder) # The archives are created after build, so that Cargo.lock files are included (if previously missing). - create_archives(contract_name, contract_version, build_directory, output_subdirectory) - create_packaged_source_code(contract_name, contract_version, build_directory, output_subdirectory) + create_archives(contract_name, contract_version, contract_build_subfolder, output_subfolder) + create_packaged_source_code(project_within_build_folder, contract_name, contract_version, contract_build_subfolder, output_subfolder) - outcome.gather_artifacts(contract_name, build_directory, output_subdirectory) + outcome.gather_artifacts(contract_name, contract_build_subfolder, output_subfolder) return outcome -def get_contracts_directories(project_path: Path) -> List[Path]: - directories = [project_config_json.parent for project_config_json in project_path.glob("**/elrond.json")] - return sorted(directories) +def get_contracts_folders(project_path: Path) -> List[Path]: + old_markers = list(project_path.glob(f"**/{OLD_CONTRACT_CONFIG_FILENAME}")) + new_markers = list(project_path.glob(f"**/{CONTRACT_CONFIG_FILENAME}")) + marker_files = old_markers + new_markers + folders = [marker_file.parent for marker_file in marker_files] + return sorted(folders) -def copy_project_directory_to_build_directory(project_directory: Path): - shutil.rmtree(HARDCODED_BUILD_DIRECTORY, ignore_errors=True) - HARDCODED_BUILD_DIRECTORY.mkdir() - shutil.copytree(project_directory, HARDCODED_BUILD_DIRECTORY, dirs_exist_ok=True) - return HARDCODED_BUILD_DIRECTORY +def copy_project_folder_to_build_folder(project_folder: Path): + shutil.rmtree(HARDCODED_BUILD_FOLDER, ignore_errors=True) + HARDCODED_BUILD_FOLDER.mkdir() + shutil.copytree(project_folder, HARDCODED_BUILD_FOLDER, dirs_exist_ok=True) + return HARDCODED_BUILD_FOLDER -def clean_contract(directory: Path, clean_output: bool = True): - logging.info(f"Cleaning: {directory}") +def clean_contract(folder: Path, clean_output: bool = True): + logging.info(f"Cleaning: {folder}") - # On a best-effort basis, remove directories that (usually) hold build artifacts - shutil.rmtree(directory / "wasm" / "target", ignore_errors=True) - shutil.rmtree(directory / "meta" / "target", ignore_errors=True) + # On a best-effort basis, remove folders that (usually) hold build artifacts + shutil.rmtree(folder / "wasm" / "target", ignore_errors=True) + shutil.rmtree(folder / "meta" / "target", ignore_errors=True) if clean_output: - shutil.rmtree(directory / "output", ignore_errors=True) - + shutil.rmtree(folder / "output", ignore_errors=True) -def build_contract(build_directory: Path, output_directory: Path, cargo_target_dir: Path, no_wasm_opt: bool): - cargo_output_directory = build_directory / "output" - meta_directory = build_directory / "meta" - cargo_lock = build_directory / "wasm" / "Cargo.lock" - # Best-effort on passing CARGO_TARGET_DIR: both as environment variable and as meta-crate parameter. - env = os.environ.copy() - env["CARGO_TARGET_DIR"] = str(cargo_target_dir) +def build_contract(build_folder: Path, output_folder: Path, cargo_target_dir: Path, no_wasm_opt: bool): + cargo_output_folder = build_folder / "output" + meta_folder = build_folder / "meta" + cargo_lock = build_folder / "wasm" / "Cargo.lock" args = ["cargo", "run", "build"] args.extend(["--target-dir", str(cargo_target_dir)]) @@ -110,39 +113,37 @@ def build_contract(build_directory: Path, output_directory: Path, cargo_target_d args.extend(["--locked"] if cargo_lock.exists() else []) logging.info(f"Building: {args}") - return_code = subprocess.run(args, cwd=meta_directory, env=env).returncode + return_code = subprocess.run(args, cwd=meta_folder).returncode if return_code != 0: - exit(return_code) + raise ErrKnown(f"Failed to build contract {build_folder}. Return code: {return_code}.") - wasm_file = find_file_in_folder(cargo_output_directory, "*.wasm") + wasm_file = find_file_in_folder(cargo_output_folder, "*.wasm") generate_wabt_artifacts(wasm_file) generate_code_hash_artifact(wasm_file) - shutil.copytree(cargo_output_directory, output_directory, dirs_exist_ok=True) + shutil.copytree(cargo_output_folder, output_folder, dirs_exist_ok=True) -def create_archives(contract_name: str, contract_version: str, input_directory: Path, output_directory: Path): - source_code_archive_file = output_directory / f"{contract_name}-src-{contract_version}.zip" - output_artifacts_archive_file = output_directory / f"{contract_name}-output-{contract_version}.zip" +def create_archives(contract_name: str, contract_version: str, input_folder: Path, output_folder: Path): + output_artifacts_archive_file = output_folder / f"{contract_name}-output-{contract_version}.zip" - archive_directory(source_code_archive_file, input_directory, is_source_code_file) - archive_directory(output_artifacts_archive_file, input_directory / "output") + archive_folder(output_artifacts_archive_file, input_folder / "output") - size_of_source_code_archive = source_code_archive_file.stat().st_size size_of_output_artifacts_archive = output_artifacts_archive_file.stat().st_size - - if size_of_source_code_archive > MAX_SOURCE_CODE_ARCHIVE_SIZE: - warn_file_too_large(source_code_archive_file, size_of_source_code_archive, MAX_SOURCE_CODE_ARCHIVE_SIZE) if size_of_output_artifacts_archive > MAX_OUTPUT_ARTIFACTS_ARCHIVE_SIZE: warn_file_too_large(output_artifacts_archive_file, size_of_output_artifacts_archive, MAX_OUTPUT_ARTIFACTS_ARCHIVE_SIZE) -def warn_file_too_large(path: Path, size: int, max_size: int): - logging.warning(f"""File is too large (this might cause issues with using downstream applications, such as the contract build verification services): -file = {path}, size = {size}, maximum size = {max_size}""") +def create_packaged_source_code(parent_project_folder: Path, contract_name: str, contract_version: str, contract_folder: Path, output_folder: Path): + package = PackagedSourceCode.from_filesystem(parent_project_folder, contract_folder) + package_path = output_folder / f"{contract_name}-{contract_version}.source.json" + package.save_to_file(package_path) + size_of_file = package_path.stat().st_size + if size_of_file > MAX_PACKAGED_SOURCE_CODE_SIZE: + warn_file_too_large(package_path, size_of_file, MAX_PACKAGED_SOURCE_CODE_SIZE) -def create_packaged_source_code(contract_name: str, contract_version: str, input_directory: Path, output_directory: Path): - package = PackagedSourceCode.from_folder(input_directory) - package_path = output_directory / f"{contract_name}-{contract_version}.source.json" - package.save_to_file(package_path) + +def warn_file_too_large(path: Path, size: int, max_size: int): + logging.warning(f"""File is too large (this might cause issues with using downstream applications, such as the contract build verification services): +file = {path}, size = {size}, maximum size = {max_size}""") diff --git a/multiversx_sdk_rust_contract_builder/builder_test.py b/multiversx_sdk_rust_contract_builder/builder_test.py index 88a89d9..3cda318 100644 --- a/multiversx_sdk_rust_contract_builder/builder_test.py +++ b/multiversx_sdk_rust_contract_builder/builder_test.py @@ -1,33 +1,60 @@ from pathlib import Path from multiversx_sdk_rust_contract_builder import builder +from multiversx_sdk_rust_contract_builder.packaged_source_code import \ + PackagedSourceCode +input_folder = Path("./testdata/input") +expected_folder = Path("./testdata/expected") +output_folder = Path("./testdata/output") -def test_build_project(): + +def test_build_project_adder(): outcome = builder.build_project( - project_path=Path("./testdata/input"), - parent_output_directory=Path("./testdata/output"), + project_folder=input_folder / "adder", + parent_output_folder=output_folder, specific_contract=None, cargo_target_dir=Path("/tmp/cargo-target-dir"), - no_wasm_opt=False + no_wasm_opt=False, + context="test" ) - actual_source = outcome.get_entry("adder").artifacts.src_package.read().decode() + actual_src_package = PackagedSourceCode.from_file(outcome.get_entry("adder").artifacts.src_package.path) + expected_src_package = PackagedSourceCode.from_file(expected_folder / "adder-1.2.3.source.json") actual_wat = outcome.get_entry("adder").artifacts.text.read().decode() + assert outcome.context == "test" assert outcome.get_entry("adder").version == "1.2.3" assert outcome.get_entry("adder").codehash == "58c6e78f40bd6ccc30d8a01f952b34a13ebfdad796a2526678be17c5d7820174" - assert actual_source == read_text_file(Path("./testdata/expected/adder-1.2.3.source.json")).strip() - assert actual_wat == read_text_file(Path("./testdata/expected/adder.wat")) + assert_equal_src_package(actual_src_package, expected_src_package) + assert actual_wat == (expected_folder / "adder.wat").read_text() + - actual_source = outcome.get_entry("empty").artifacts.src_package.read().decode() +def test_build_project_empty(): + outcome = builder.build_project( + project_folder=input_folder / "empty", + parent_output_folder=output_folder, + specific_contract=None, + cargo_target_dir=Path("/tmp/cargo-target-dir"), + no_wasm_opt=False, + context="test" + ) + + actual_src_package = PackagedSourceCode.from_file(outcome.get_entry("empty").artifacts.src_package.path) + expected_src_package = PackagedSourceCode.from_file(expected_folder / "empty-4.5.6.source.json") actual_wat = outcome.get_entry("empty").artifacts.text.read().decode() + + assert outcome.context == "test" assert outcome.get_entry("empty").version == "4.5.6" assert outcome.get_entry("empty").codehash == "20df405fa1733a22748c888f6c1571f2c12cc40a8b1de800e0fd105674b426a5" - assert actual_source == read_text_file(Path("./testdata/expected/empty-4.5.6.source.json")).strip() - assert actual_wat == read_text_file(Path("./testdata/expected/empty.wat")) + assert_equal_src_package(actual_src_package, expected_src_package) + assert actual_wat == (expected_folder / "empty.wat").read_text() + +def assert_equal_src_package(actual: PackagedSourceCode, expected: PackagedSourceCode): + assert actual.name == expected.name + assert actual.version == expected.version -def read_text_file(path: Path) -> str: - with open(path, "r") as f: - return f.read() + for actual_entry, expected_entry in zip(actual.entries, expected.entries): + assert actual_entry.path == expected_entry.path, f"actual={actual_entry.path}, expected={expected_entry.path}" + assert actual_entry.content == expected_entry.content, f"content differs for {actual_entry.path}" diff --git a/multiversx_sdk_rust_contract_builder/cargo_toml.py b/multiversx_sdk_rust_contract_builder/cargo_toml.py index 964e2f0..cd1db9a 100644 --- a/multiversx_sdk_rust_contract_builder/cargo_toml.py +++ b/multiversx_sdk_rust_contract_builder/cargo_toml.py @@ -1,24 +1,47 @@ - +import logging import shutil from pathlib import Path from typing import Tuple +import tomlkit + +from multiversx_sdk_rust_contract_builder.filesystem import get_all_files -def get_contract_name_and_version(contract_directory: Path) -> Tuple[str, str]: - # For simplicity and less dependencies installed in the Docker image, we do not rely on an external library - # to parse the metadata from Cargo.toml. - with open(contract_directory / "Cargo.toml") as file: - lines = file.readlines() - line_with_name = next((line for line in lines if line.startswith("name = ")), 'name = "untitled"') - line_with_version = next((line for line in lines if line.startswith("version = ")), 'version = "0.0.0"') +def get_contract_name_and_version(contract_folder: Path) -> Tuple[str, str]: + file = contract_folder / "Cargo.toml" + toml = tomlkit.parse(file.read_text()) - name = line_with_name.split("=")[1].strip().strip('"') - version = line_with_version.split("=")[1].strip().strip('"') + name = toml["package"]["name"] + version = toml["package"]["version"] return name, version -def promote_cargo_lock_to_contract_directory(build_directory: Path, contract_directory: Path): - from_path = build_directory / "wasm" / "Cargo.lock" - to_path = contract_directory / "wasm" / "Cargo.lock" +def promote_cargo_lock_to_contract_folder(build_folder: Path, contract_folder: Path): + from_path = build_folder / "wasm" / "Cargo.lock" + to_path = contract_folder / "wasm" / "Cargo.lock" shutil.copy(from_path, to_path) + + +def remove_dev_dependencies_sections_from_all(folder: Path): + logging.info(f"remove_dev_dependencies_sections_from_all({folder})") + + all_files = get_all_files(folder, lambda file: file.name == "Cargo.toml") + for file in all_files: + remove_dev_dependencies_sections(file) + + +def remove_dev_dependencies_sections(file: Path): + # Workaround: if Cargo.toml contains [dev-dependencies] sections, + # then we'll attempt several times to remove them, + # because tomlkit does not properly handle a few special cases, such as: + # - https://github.com/multiversx/mx-exchange-sc/blob/v2.1-staking/dex/farm/Cargo.toml#L71 + # - https://github.com/multiversx/mx-exchange-sc/blob/v2.1-staking/dex/farm/Cargo.toml#L84 + while True: + toml = tomlkit.parse(file.read_text()) + + if "dev-dependencies" not in toml: + break + + del toml["dev-dependencies"] + file.write_text(tomlkit.dumps(toml)) diff --git a/multiversx_sdk_rust_contract_builder/constants.py b/multiversx_sdk_rust_contract_builder/constants.py index f8d884a..d49d522 100644 --- a/multiversx_sdk_rust_contract_builder/constants.py +++ b/multiversx_sdk_rust_contract_builder/constants.py @@ -1,8 +1,11 @@ from pathlib import Path -HARDCODED_BUILD_DIRECTORY = Path("/tmp/contract") -HARDCODED_UNWRAP_DIRECTORY = Path("/tmp/unwrapped") +HARDCODED_BUILD_FOLDER = Path("/tmp/elrond-contract-rust") +HARDCODED_UNWRAP_FOLDER = Path("/tmp/unwrapped") ONE_KB_IN_BYTES: int = 1024 -MAX_SOURCE_CODE_ARCHIVE_SIZE: int = ONE_KB_IN_BYTES * 1024 +MAX_PACKAGED_SOURCE_CODE_SIZE: int = 2 * ONE_KB_IN_BYTES * 1024 # The output archive contains not only the *.wasm, but also *.wat, *.abi.json files etc. -MAX_OUTPUT_ARTIFACTS_ARCHIVE_SIZE: int = ONE_KB_IN_BYTES * 1024 +MAX_OUTPUT_ARTIFACTS_ARCHIVE_SIZE: int = 2 * ONE_KB_IN_BYTES * 1024 + +CONTRACT_CONFIG_FILENAME = "multiversx.json" +OLD_CONTRACT_CONFIG_FILENAME = "elrond.json" diff --git a/multiversx_sdk_rust_contract_builder/filesystem.py b/multiversx_sdk_rust_contract_builder/filesystem.py index 6964fad..baf76d9 100644 --- a/multiversx_sdk_rust_contract_builder/filesystem.py +++ b/multiversx_sdk_rust_contract_builder/filesystem.py @@ -1,39 +1,25 @@ import logging -import os from pathlib import Path -from typing import Callable, List, Union +from typing import Callable, Union from zipfile import ZIP_DEFLATED, ZipFile from multiversx_sdk_rust_contract_builder.errors import ErrKnown -def archive_directory(archive_file: Path, directory: Path, should_include_file: Union[Callable[[Path], bool], None] = None): - files = get_files_recursively(directory, should_include_file) +def archive_folder(archive_file: Path, folder: Path, should_include_file: Union[Callable[[Path], bool], None] = None): + files = get_all_files(folder, should_include_file) with ZipFile(archive_file, "w", ZIP_DEFLATED) as archive: for full_path in files: - archive.write(full_path, full_path.relative_to(directory)) + archive.write(full_path, full_path.relative_to(folder)) logging.info(f"Created archive: file = {archive_file}, with size = {archive_file.stat().st_size} bytes") -def get_files_recursively(directory: Path, should_include_file: Union[Callable[[Path], bool], None] = None): +def get_all_files(folder: Path, should_include_file: Union[Callable[[Path], bool], None] = None): should_include_file = should_include_file or (lambda _: True) - paths: List[Path] = [] - - for root, _, files in os.walk(directory): - root_path = Path(root) - for file in files: - file_path = Path(file) - full_path = root_path / file_path - - if file_path.is_dir(): - continue - if not should_include_file(file_path): - continue - - paths.append(full_path) - + paths = list(folder.rglob("*")) + paths = [path for path in paths if path.is_file() and should_include_file(path)] return paths diff --git a/multiversx_sdk_rust_contract_builder/main.py b/multiversx_sdk_rust_contract_builder/main.py index 5c2a8f0..d3c454d 100644 --- a/multiversx_sdk_rust_contract_builder/main.py +++ b/multiversx_sdk_rust_contract_builder/main.py @@ -1,5 +1,6 @@ import logging import os +import shutil import sys import time from argparse import ArgumentParser @@ -8,7 +9,7 @@ from multiversx_sdk_rust_contract_builder import builder from multiversx_sdk_rust_contract_builder.constants import \ - HARDCODED_UNWRAP_DIRECTORY + HARDCODED_UNWRAP_FOLDER from multiversx_sdk_rust_contract_builder.errors import ErrKnown from multiversx_sdk_rust_contract_builder.packaged_source_code import \ PackagedSourceCode @@ -20,32 +21,43 @@ def main(cli_args: List[str]): start_time = time.time() parser = ArgumentParser() - parser.add_argument("--project", type=str, required=False, help="source code directory") + parser.add_argument("--project", type=str, required=False, help="source code folder (project)") parser.add_argument("--packaged-src", type=str, required=False, help="source code packaged in a JSON file") - parser.add_argument("--contract", type=str, required=False, help="contract to build from within the source code directory; should be relative to the project path") + parser.add_argument("--contract", type=str, required=False, help="contract to build from within the source code folder; should be relative to the project path") parser.add_argument("--output", type=str, required=True) parser.add_argument("--no-wasm-opt", action="store_true", default=False, help="do not optimize wasm files after the build (default: %(default)s)") parser.add_argument("--cargo-target-dir", type=str, required=True, help="Cargo's target-dir") + parser.add_argument("--context", type=str, required=False, default=os.environ.get("CONTEXT", "unknown"), help="the context of the build (e.g. a Docker image identifier))") parsed_args = parser.parse_args(cli_args) project_path = Path(parsed_args.project).expanduser().resolve() if parsed_args.project else None packaged_src_path = Path(parsed_args.packaged_src).expanduser().resolve() if parsed_args.packaged_src else None - parent_output_directory = Path(parsed_args.output) + parent_output_folder = Path(parsed_args.output) specific_contract = parsed_args.contract cargo_target_dir = Path(parsed_args.cargo_target_dir) no_wasm_opt = parsed_args.no_wasm_opt + context = parsed_args.context if not project_path: if not packaged_src_path: raise ErrKnown("One of the following must be provided: --project, --packaged-src") # We have to unwrap the packaged source code (JSON) - project_path = HARDCODED_UNWRAP_DIRECTORY + project_path = HARDCODED_UNWRAP_FOLDER + shutil.rmtree(HARDCODED_UNWRAP_FOLDER, ignore_errors=True) packaged = PackagedSourceCode.from_file(packaged_src_path) - packaged.unwrap_to_folder(HARDCODED_UNWRAP_DIRECTORY) + packaged.unwrap_to_filesystem(HARDCODED_UNWRAP_FOLDER) - outcome = builder.build_project(project_path, parent_output_directory, specific_contract, cargo_target_dir, no_wasm_opt) - outcome.save_to_file(parent_output_directory / "artifacts.json") + outcome = builder.build_project( + project_path, + parent_output_folder, + specific_contract, + cargo_target_dir, + no_wasm_opt, + context + ) + + outcome.save_to_file(parent_output_folder / "artifacts.json") end_time = time.time() time_elapsed = end_time - start_time @@ -58,3 +70,4 @@ def main(cli_args: List[str]): except ErrKnown as err: print("An error occurred.") print(err) + exit(1) diff --git a/multiversx_sdk_rust_contract_builder/packaged_source_code.py b/multiversx_sdk_rust_contract_builder/packaged_source_code.py index 2fc2bd5..57054f1 100644 --- a/multiversx_sdk_rust_contract_builder/packaged_source_code.py +++ b/multiversx_sdk_rust_contract_builder/packaged_source_code.py @@ -6,10 +6,8 @@ from multiversx_sdk_rust_contract_builder.cargo_toml import \ get_contract_name_and_version -from multiversx_sdk_rust_contract_builder.filesystem import \ - get_files_recursively from multiversx_sdk_rust_contract_builder.source_code import \ - is_source_code_file + get_source_code_files_necessary_for_contract class PackagedSourceCodeEntry: @@ -51,31 +49,32 @@ def from_dict(cls, data: Dict[str, Any]) -> 'PackagedSourceCode': version = data.get("version", "0.0.0") entries_raw: List[Dict[str, Any]] = data.get("entries", []) entries = [PackagedSourceCodeEntry.from_dict(entry) for entry in entries_raw] + _sort_entries(entries) + return PackagedSourceCode(name, version, entries) @classmethod - def from_folder(cls, folder: Path) -> 'PackagedSourceCode': - entries = cls._create_entries_from_folder(folder) - name, version = get_contract_name_and_version(folder) + def from_filesystem(cls, project_folder: Path, contract_folder: Path) -> 'PackagedSourceCode': + name, version = get_contract_name_and_version(contract_folder) + entries = cls._create_entries_from_filesystem(project_folder, contract_folder, name) return PackagedSourceCode(name, version, entries) @classmethod - def _create_entries_from_folder(cls, folder: Path) -> List[PackagedSourceCodeEntry]: - files = get_files_recursively(folder, is_source_code_file) + def _create_entries_from_filesystem(cls, project_folder: Path, contract_folder: Path, contract_name: str) -> List[PackagedSourceCodeEntry]: + source_files = get_source_code_files_necessary_for_contract(contract_folder, contract_name) entries: List[PackagedSourceCodeEntry] = [] - for full_path in files: - with open(full_path, "rb") as f: - content = f.read() - - relative_path = full_path.relative_to(folder) + for full_path in source_files: + content = full_path.read_bytes() + relative_path = full_path.relative_to(project_folder) entries.append(PackagedSourceCodeEntry(relative_path, content)) + _sort_entries(entries) return entries - def unwrap_to_folder(self, folder: Path): + def unwrap_to_filesystem(self, project_folder: Path): for entry in self.entries: - full_path = folder / entry.path + full_path = project_folder / entry.path full_path.parent.mkdir(parents=True, exist_ok=True) with open(full_path, "wb") as f: f.write(entry.content) @@ -94,3 +93,8 @@ def to_dict(self) -> Dict[str, Any]: "version": self.version, "entries": entries } + + +def _sort_entries(entries: List[PackagedSourceCodeEntry]) -> List[PackagedSourceCodeEntry]: + entries.sort(key=lambda entry: entry.path) + return entries diff --git a/multiversx_sdk_rust_contract_builder/source_code.py b/multiversx_sdk_rust_contract_builder/source_code.py index 7b706a0..19a395e 100644 --- a/multiversx_sdk_rust_contract_builder/source_code.py +++ b/multiversx_sdk_rust_contract_builder/source_code.py @@ -1,10 +1,95 @@ +import json +import logging +import subprocess from pathlib import Path +from typing import Any, Dict, List, Set +from multiversx_sdk_rust_contract_builder.constants import ( + CONTRACT_CONFIG_FILENAME, OLD_CONTRACT_CONFIG_FILENAME) +from multiversx_sdk_rust_contract_builder.errors import ErrKnown +from multiversx_sdk_rust_contract_builder.filesystem import get_all_files -def is_source_code_file(path: Path): + +def get_source_code_files_necessary_for_contract(contract_folder: Path, contract_name: str) -> List[Path]: + source_files: List[Path] = [] + + source_files.extend(get_all_source_code_files(contract_folder)) + local_dependencies = get_local_dependencies(contract_folder, contract_name) + + logging.info(f"Found {len(local_dependencies)} local dependencies.") + + for dependency in local_dependencies: + logging.debug(f"Local dependency: {dependency}") + source_files.extend(get_all_files(dependency, is_source_code_file)) + + return sorted(set(source_files)) + + +def get_all_source_code_files(folder: Path) -> List[Path]: + return sorted(get_all_files(folder, is_source_code_file)) + + +def is_source_code_file(path: Path) -> bool: if path.suffix == ".rs": return True - if path.name in ["Cargo.toml", "Cargo.lock", "elrond.json"]: + if path.parent.name == "meta" and path.name == "Cargo.lock": + return False + if path.name in ["Cargo.toml", "Cargo.lock", CONTRACT_CONFIG_FILENAME, OLD_CONTRACT_CONFIG_FILENAME]: return True return False + + +def replace_all_test_content_with_noop(folder: Path): + # At this moment (January 2023) we cannot completely exclude test files from the compilation + # (if we do so, the build throws some errors, in some cases). + # So we replace all test content with a noop function. + # This is not ideal, but it works for now. + + logging.info(f"replace_all_test_content_with_noop({folder})") + test_files = get_all_files(folder, is_test_file) + for file in test_files: + file.write_text("fn nothing() {}") + + +def is_test_file(path: Path) -> bool: + is_in_tests_folder = any(part in ["test", "tests"] for part in path.parts) + return path.suffix == ".rs" and is_in_tests_folder + + +def get_local_dependencies(contract_folder: Path, contract_name: str) -> List[Path]: + args = ["cargo", "metadata", "--format-version=1"] + logging.info(f"get_local_dependencies(), running: {args}, with cwd = {contract_folder}") + metadata_json = subprocess.check_output(args, cwd=contract_folder, shell=False, universal_newlines=True) + metadata = json.loads(metadata_json) + + logging.info(f"get_local_dependencies(), explore metadata recursively for contract {contract_name}") + paths = _get_local_dependencies_recursively(metadata, contract_name, set(), 0) + return list(paths) + + +def _get_local_dependencies_recursively(cargo_metadata: Dict[str, Any], package_name: str, visited: Set[str], indentation: int) -> Set[Path]: + if package_name in visited: + return set() + + visited.add(package_name) + + packages = cargo_metadata.get("packages", []) + package = next((package for package in packages if package["name"] == package_name), None) + if not package: + raise ErrKnown(f"Could not find package {package_name} in project metadata.") + + dependencies = package.get("dependencies", []) + local_dependencies = [dependency for dependency in dependencies if _is_local_dependency(dependency)] + paths = set([Path(dependency["path"]) for dependency in local_dependencies]) + + logging.debug(f"{indentation * 4 * ' '} ({package_name}): {[dependency['name'] for dependency in local_dependencies]}") + + for dependency in local_dependencies: + paths |= _get_local_dependencies_recursively(cargo_metadata, dependency["name"], visited, indentation + 1) + + return paths + + +def _is_local_dependency(dependency: Dict[str, Any]) -> bool: + return "path" in dependency diff --git a/pyproject.toml b/pyproject.toml index 389e0bd..8991b82 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ allow-direct-references = true [project] name = "multiversx-sdk-rust-contract-builder" -version = "4.0.3" +version = "4.1.0" authors = [ { name="MultiversX" }, ] @@ -23,7 +23,13 @@ classifiers = [ [tool.hatch.build] exclude = [ - "testdata/**" + "integration_tests/**", + "testdata/**", + "support/**" +] + +dependencies = [ + "tomlkit==0.11.6" ] [project.urls] diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..cc51f9c --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +tomlkit==0.11.6 diff --git a/testdata/expected/adder-1.2.3.source.json b/testdata/expected/adder-1.2.3.source.json index 700ea21..81cc5e7 100644 --- a/testdata/expected/adder-1.2.3.source.json +++ b/testdata/expected/adder-1.2.3.source.json @@ -11,32 +11,28 @@ "content": "ewogICAgImxhbmd1YWdlIjogInJ1c3QiCn0=" }, { - "path": "src/adder.rs", - "content": "IyFbbm9fc3RkXQoKZWxyb25kX3dhc206OmltcG9ydHMhKCk7CgovLy8gT25lIG9mIHRoZSBzaW1wbGVzdCBzbWFydCBjb250cmFjdHMgcG9zc2libGUsCi8vLyBpdCBob2xkcyBhIHNpbmdsZSB2YXJpYWJsZSBpbiBzdG9yYWdlLCB3aGljaCBhbnlvbmUgY2FuIGluY3JlbWVudC4KI1tlbHJvbmRfd2FzbTo6Y29udHJhY3RdCnB1YiB0cmFpdCBBZGRlciB7CiAgICAjW3ZpZXcoZ2V0U3VtKV0KICAgICNbc3RvcmFnZV9tYXBwZXIoInN1bSIpXQogICAgZm4gc3VtKCZzZWxmKSAtPiBTaW5nbGVWYWx1ZU1hcHBlcjxCaWdVaW50PjsKCiAgICAjW2luaXRdCiAgICBmbiBpbml0KCZzZWxmLCBpbml0aWFsX3ZhbHVlOiBCaWdVaW50KSB7CiAgICAgICAgc2VsZi5zdW0oKS5zZXQoaW5pdGlhbF92YWx1ZSk7CiAgICB9CgogICAgLy8vIEFkZCBkZXNpcmVkIGFtb3VudCB0byB0aGUgc3RvcmFnZSB2YXJpYWJsZS4KICAgICNbZW5kcG9pbnRdCiAgICBmbiBhZGQoJnNlbGYsIHZhbHVlOiBCaWdVaW50KSB7CiAgICAgICAgc2VsZi5zdW0oKS51cGRhdGUofHN1bXwgKnN1bSArPSB2YWx1ZSk7CiAgICB9Cn0K" - }, - { - "path": "wasm/Cargo.toml", - "content": "W3BhY2thZ2VdCm5hbWUgPSAiYWRkZXItd2FzbSIKdmVyc2lvbiA9ICIxLjIuMyIKYXV0aG9ycyA9IFsieW91Il0KZWRpdGlvbiA9ICIyMDE4IgpwdWJsaXNoID0gZmFsc2UKCltsaWJdCmNyYXRlLXR5cGUgPSBbImNkeWxpYiJdCgpbcHJvZmlsZS5yZWxlYXNlXQpjb2RlZ2VuLXVuaXRzID0gMQpvcHQtbGV2ZWwgPSAieiIKbHRvID0gdHJ1ZQpkZWJ1ZyA9IGZhbHNlCnBhbmljID0gImFib3J0IgoKW2RlcGVuZGVuY2llcy5hZGRlcl0KcGF0aCA9ICIuLiIKCltkZXBlbmRlbmNpZXMuZWxyb25kLXdhc20tbm9kZV0KdmVyc2lvbiA9ICIwLjM2LjEiCgpbZGVwZW5kZW5jaWVzLmVscm9uZC13YXNtLW91dHB1dF0KdmVyc2lvbiA9ICIwLjM2LjEiCmZlYXR1cmVzID0gWyJ3YXNtLW91dHB1dC1tb2RlIl0KClt3b3Jrc3BhY2VdCm1lbWJlcnMgPSBbIi4iXQo=" + "path": "meta/Cargo.toml", + "content": "W3BhY2thZ2VdCm5hbWUgPSAiYWRkZXItbWV0YSIKdmVyc2lvbiA9ICIwLjAuMCIKZWRpdGlvbiA9ICIyMDE4IgpwdWJsaXNoID0gZmFsc2UKCltkZXBlbmRlbmNpZXMuYWRkZXJdCnBhdGggPSAiLi4iCgpbZGVwZW5kZW5jaWVzLmVscm9uZC13YXNtLWRlYnVnXQp2ZXJzaW9uID0gIjAuMzYuMSIK" }, { - "path": "wasm/Cargo.lock", - "content": "IyBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSBAZ2VuZXJhdGVkIGJ5IENhcmdvLgojIEl0IGlzIG5vdCBpbnRlbmRlZCBmb3IgbWFudWFsIGVkaXRpbmcuCnZlcnNpb24gPSAzCgpbW3BhY2thZ2VdXQpuYW1lID0gImFkZGVyIgp2ZXJzaW9uID0gIjEuMi4zIgpkZXBlbmRlbmNpZXMgPSBbCiAiZWxyb25kLXdhc20iLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImFkZGVyLXdhc20iCnZlcnNpb24gPSAiMS4yLjMiCmRlcGVuZGVuY2llcyA9IFsKICJhZGRlciIsCiAiZWxyb25kLXdhc20tbm9kZSIsCiAiZWxyb25kLXdhc20tb3V0cHV0IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJhaGFzaCIKdmVyc2lvbiA9ICIwLjcuNiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJmY2I1MWEwNjk1ZDhmODM4YjFlZTAwOWIzZmJmNjZiZGEwNzhjZDY0NTkwMjAyYTg2NGE4ZjNlOGM0MzE1YzQ3IgpkZXBlbmRlbmNpZXMgPSBbCiAiZ2V0cmFuZG9tIiwKICJvbmNlX2NlbGwiLAogInZlcnNpb25fY2hlY2siLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImFycmF5dmVjIgp2ZXJzaW9uID0gIjAuNy4yIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjhkYTUyZDY2YzcwNzFlMmUzZmEyYTFlNWM2ZDA4OGZlYzQ3YjU5MzAzMmIyNTRmNWU5ODBkZThlYTU0NDU0ZDYiCgpbW3BhY2thZ2VdXQpuYW1lID0gImF1dG9jZmciCnZlcnNpb24gPSAiMS4xLjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZDQ2ODgwMmJhYjE3Y2JjMGNjNTc1ZTliMDUzZjQxZTcyYWEzNmJmYTZiN2Y1NWUzNTI5ZmZhNDMxNjFiOTdmYSIKCltbcGFja2FnZV1dCm5hbWUgPSAiYml0ZmxhZ3MiCnZlcnNpb24gPSAiMS4zLjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYmVmMzhkNDUxNjNjMmYxZGRlMDk0YTdkZmQzM2NjZjU5NWM5MjkwNWM4ZjhmNGZkYzE4ZDA2ZmIxMDM3NzE4YSIKCltbcGFja2FnZV1dCm5hbWUgPSAiY2ZnLWlmIgp2ZXJzaW9uID0gIjAuMS4xMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI0Nzg1YmRkMWM5NmIyYTg0NmIyYmQ3Y2MwMmU4NmI2YjNkYmYxNGU3ZTUzNDQ2YzRmNTRjOTJhMzYxMDQwODIyIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJjZmctaWYiCnZlcnNpb24gPSAiMS4wLjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYmFmMWRlNDMzOTc2MTU4OGJjMDYxOWUzY2JjMDEyMGVlNTgyZWJiNzRiNTNiNGVmYmY3OTExN2JkMmRhNDBmZCIKCltbcGFja2FnZV1dCm5hbWUgPSAiZWxyb25kLWNvZGVjIgp2ZXJzaW9uID0gIjAuMTQuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIyYzg1YzU5NTE4NjRkZDQ4MTZlMWRmMmNlYWNjYjBmMjJjNjRmZjExN2RkY2RlMWY1MzM1MWFjZTRkNzg1YzQ3IgpkZXBlbmRlbmNpZXMgPSBbCiAiYXJyYXl2ZWMiLAogImVscm9uZC1jb2RlYy1kZXJpdmUiLAogIndlZV9hbGxvYyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZWxyb25kLWNvZGVjLWRlcml2ZSIKdmVyc2lvbiA9ICIwLjE0LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiMmE4OTg3YTdmNTA2YWU1YjM1MmFkN2FjMjhmYjEzYjlmNjAwMzU1YzhiODhhNDQ0ODgxZjg2YmM1NjVjNzVjZiIKZGVwZW5kZW5jaWVzID0gWwogImhleCIsCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJzeW4iLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImVscm9uZC13YXNtIgp2ZXJzaW9uID0gIjAuMzYuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI5ZmY3ZGQxMGY0YTcxMzNhMmM2ZmViM2Y3OWUwNDk1M2Y5YTNjMWVkYTlmODQ0NGI0M2MxMzAwZjMwMmUwMmZkIgpkZXBlbmRlbmNpZXMgPSBbCiAiYml0ZmxhZ3MiLAogImVscm9uZC1jb2RlYyIsCiAiZWxyb25kLXdhc20tZGVyaXZlIiwKICJnaXQtdmVyc2lvbiIsCiAiaGFzaGJyb3duIiwKICJoZXgtbGl0ZXJhbCIsCiAibnVtLXRyYWl0cyIsCiAid2VlX2FsbG9jIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbHJvbmQtd2FzbS1kZXJpdmUiCnZlcnNpb24gPSAiMC4zNi4xIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjYwMzU4OTg5MTYzYWUxYzI4Yjc5ZDdjNjg3ODY5ODc0Yzc2NTAwMWJiZGZhMTJhMzFkZmQ5MjAzNTBiYzdhMjIiCmRlcGVuZGVuY2llcyA9IFsKICJoZXgiLAogInByb2MtbWFjcm8yIiwKICJxdW90ZSIsCiAicmFkaXhfdHJpZSIsCiAic3luIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbHJvbmQtd2FzbS1ub2RlIgp2ZXJzaW9uID0gIjAuMzYuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI0Y2I0ZDRjMWFjZWQ5NjdmODZkYmMyYTBhMDE5MTBkMWViYjEwY2VhYjQ1OWNiNGEzZDdkMmU0M2I0ZGYyZjliIgpkZXBlbmRlbmNpZXMgPSBbCiAiZWxyb25kLXdhc20iLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImVscm9uZC13YXNtLW91dHB1dCIKdmVyc2lvbiA9ICIwLjM2LjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiMzJhOGMwMjUxNWU0M2VmN2ZkYTBjNzRjYzRhMGE0ZDM1Mzg0NmFmOTk5Y2M4MDJjMjMwNmMzNGZkNzBjZGExMSIKZGVwZW5kZW5jaWVzID0gWwogImVscm9uZC13YXNtLW5vZGUiLAogIndlZV9hbGxvYyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZW5kaWFuLXR5cGUiCnZlcnNpb24gPSAiMC4xLjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYzM0ZjA0NjY2ZDgzNWZmNWQ2MmUwNThjMzk5NTE0N2MwNmY0MmZlODZmZjA1MzMzNzYzMmJjYTgzZTQyNzAyZCIKCltbcGFja2FnZV1dCm5hbWUgPSAiZ2V0cmFuZG9tIgp2ZXJzaW9uID0gIjAuMi44Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImMwNWFlYjZhMjJiOGY2MjU0MGMxOTRhYWM5ODBmMjExNWFmMDY3YmZlMTVhMDczNGQ3Mjc3YTc2OGQzOTZiMzEiCmRlcGVuZGVuY2llcyA9IFsKICJjZmctaWYgMS4wLjAiLAogImxpYmMiLAogIndhc2kiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImdpdC12ZXJzaW9uIgp2ZXJzaW9uID0gIjAuMy41Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImY2YjBkZWNjMDJmNDYzNmI5Y2NhZDM5MGRjYmU3N2I3MjJhNzdlZmVkZmEzOTNjYWY4Mzc5YTUxZDVjNjE4OTkiCmRlcGVuZGVuY2llcyA9IFsKICJnaXQtdmVyc2lvbi1tYWNybyIsCiAicHJvYy1tYWNyby1oYWNrIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJnaXQtdmVyc2lvbi1tYWNybyIKdmVyc2lvbiA9ICIwLjMuNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJmZTY5ZjFjYmRiNmUyOGFmMmJhYzIxNGU5NDNiOTljZThhMGEwNmI0NDdkMTVkM2U2MTE2MWIwNDIzMTM5ZjNmIgpkZXBlbmRlbmNpZXMgPSBbCiAicHJvYy1tYWNyby1oYWNrIiwKICJwcm9jLW1hY3JvMiIsCiAicXVvdGUiLAogInN5biIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiaGFzaGJyb3duIgp2ZXJzaW9uID0gIjAuMTEuMiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJhYjVlZjBkNDkwOWVmMzcyNGNjOGNjZTZjY2M4NTcyYzVjODE3NTkyZTkyODVmNTQ2NGY4ZTg2ZjhiZDM3MjZlIgpkZXBlbmRlbmNpZXMgPSBbCiAiYWhhc2giLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImhleCIKdmVyc2lvbiA9ICIwLjQuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI3ZjI0MjU0YWE5YTU0YjVjODU4ZWFlZTJmNWJjY2RiNDZhYWYwZTQ4NmE1OTVlZDVmZDhmODZiYTU1MjMyYTcwIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJoZXgtbGl0ZXJhbCIKdmVyc2lvbiA9ICIwLjMuNCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI3ZWJkYjI5ZDJlYTllZDAwODNjZDhjZWNlNDliYmQ5NjgwMjFiZDk5YjA4NDllZGI0YTlhN2VlMGZkZjZhNGUwIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJsaWJjIgp2ZXJzaW9uID0gIjAuMi4xMzciCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZmM3ZmNjNjIwYTNiZmY3Y2RkN2EzNjViZTMzNzZjOTcxOTFhZWFjY2MyYTYwM2U2MDA5NTFlNDUyNjE1YmY4OSIKCltbcGFja2FnZV1dCm5hbWUgPSAibWVtb3J5X3VuaXRzIgp2ZXJzaW9uID0gIjAuNC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjg0NTIxMDViYTA0NzA2OGY0MGZmNzA5M2RkMWQ5ZGE5MDg5OGU2M2RkNjE3MzY0NjJlOWNkZGE2YTkwYWQzYzMiCgpbW3BhY2thZ2VdXQpuYW1lID0gIm5pYmJsZV92ZWMiCnZlcnNpb24gPSAiMC4wLjQiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYzhkNzdmM2RiNGJjZTAzM2Y0ZDA0ZGIwODA3OWIyZWYxYzNkMDJiNDRlODZmMjVkMDg4ODZmYWZhNzc1NmZmYSIKCltbcGFja2FnZV1dCm5hbWUgPSAibnVtLXRyYWl0cyIKdmVyc2lvbiA9ICIwLjIuMTUiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNTc4ZWRlMzRjZjAyZjg5MjRhYjk0NDdmNTBjMjgwNzViNGQzZTViMjY5OTcyMzQ1ZTdlMDM3MmIzOGM2Y2RjZCIKZGVwZW5kZW5jaWVzID0gWwogImF1dG9jZmciLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIm9uY2VfY2VsbCIKdmVyc2lvbiA9ICIxLjE2LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiODZmMGIwZDRiZjc5OWVkYmM3NDUwOGMxZThiZjE3MGZmNWY0MTIzOGU1ZjgyMjU2MDNjYTdjYWFhZTJiNzg2MCIKCltbcGFja2FnZV1dCm5hbWUgPSAicHJvYy1tYWNyby1oYWNrIgp2ZXJzaW9uID0gIjAuNS4xOSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJkYmYwYzQ4YmMxZDkxMzc1YWU1YzNjZDgxZTM3MjJkZmYxYWJjZjgxYTMwOTYwMjQwNjQwZDIyM2Y1OWZlMGU1IgoKW1twYWNrYWdlXV0KbmFtZSA9ICJwcm9jLW1hY3JvMiIKdmVyc2lvbiA9ICIxLjAuNDciCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNWVhM2Q5MDhiMGUzNjMxNmNhZjllOWUyYzQ2MjVjZGRlMTkwYTdlNmY0NDBkNzk0NjY3ZWQxN2ExODU1ZTcyNSIKZGVwZW5kZW5jaWVzID0gWwogInVuaWNvZGUtaWRlbnQiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInF1b3RlIgp2ZXJzaW9uID0gIjEuMC4yMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJiYmU0NDhmMzc3YTdkNjk2MWUzMGY1OTU1ZjliOGQxMDZjM2Y1ZTQ0OWQ0OTNlZTFiMTI1YzFkNDNjMmI1MTc5IgpkZXBlbmRlbmNpZXMgPSBbCiAicHJvYy1tYWNybzIiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInJhZGl4X3RyaWUiCnZlcnNpb24gPSAiMC4xLjYiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiM2QzNjgxYjI4Y2Q5NWFjZmIwNTYwZWE5NDQxZjgyZDZhNDUwNGZhM2IxNWI5N2JkN2I2ZTk1MjEzMTgyMGU5NSIKZGVwZW5kZW5jaWVzID0gWwogImVuZGlhbi10eXBlIiwKICJuaWJibGVfdmVjIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJzeW4iCnZlcnNpb24gPSAiMS4wLjEwMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJhODY0MDQyMjI5MTMzYWRhOTVhYmYzYjU0ZmRjNjJlZjVjY2FiZTk1MTViNjQ3MTdiY2I5YTE5MTllNTk0NDVkIgpkZXBlbmRlbmNpZXMgPSBbCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJ1bmljb2RlLWlkZW50IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJ1bmljb2RlLWlkZW50Igp2ZXJzaW9uID0gIjEuMC41Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjZjZWFiMzlkNTllNGM5NDk5ZDRlNWE4ZWUwZTI3MzViODkxYmI3MzA4YWM4M2RmYjRlODBjYWQxOTVjOWY2ZjMiCgpbW3BhY2thZ2VdXQpuYW1lID0gInZlcnNpb25fY2hlY2siCnZlcnNpb24gPSAiMC45LjQiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNDk4NzRiNTE2N2I2NWQ3MTkzYjhhYmExNTY3ZjVjN2Q5M2QwMDFjYWZjMzQ2MDBjZWUwMDNlZGE3ODdlNDgzZiIKCltbcGFja2FnZV1dCm5hbWUgPSAid2FzaSIKdmVyc2lvbiA9ICIwLjExLjArd2FzaS1zbmFwc2hvdC1wcmV2aWV3MSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI5YzhkODdlNzJiNjRhM2I0ZGIyOGQxMWNlMjkyMzdjMjQ2MTg4ZjRmNTEwNTdkNjVhN2VhYjYzYjc5ODdlNDIzIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJ3ZWVfYWxsb2MiCnZlcnNpb24gPSAiMC40LjUiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZGJiM2I1YTZiMmJiMTdjYjZhZDQ0YTJlNjhhNDNlOGQyNzIyYzk5N2RhMTBlOTI4NjY1YzcyZWM2YzBhMGI4ZSIKZGVwZW5kZW5jaWVzID0gWwogImNmZy1pZiAwLjEuMTAiLAogImxpYmMiLAogIm1lbW9yeV91bml0cyIsCiAid2luYXBpIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJ3aW5hcGkiCnZlcnNpb24gPSAiMC4zLjkiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNWM4MzlhNjc0ZmNkN2E5ODk1MmU1OTMyNDJlYTQwMGFiZTkzOTkyNzQ2NzYxZTM4NjQxNDA1ZDI4YjAwZjQxOSIKZGVwZW5kZW5jaWVzID0gWwogIndpbmFwaS1pNjg2LXBjLXdpbmRvd3MtZ251IiwKICJ3aW5hcGkteDg2XzY0LXBjLXdpbmRvd3MtZ251IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJ3aW5hcGktaTY4Ni1wYy13aW5kb3dzLWdudSIKdmVyc2lvbiA9ICIwLjQuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJhYzNiODdjNjM2MjA0MjZkZDliOTkxZTVjZTAzMjllZmY1NDViY2NiYmIzNGYzYmUwOWZmNmZiNmFiNTFiN2I2IgoKW1twYWNrYWdlXV0KbmFtZSA9ICJ3aW5hcGkteDg2XzY0LXBjLXdpbmRvd3MtZ251Igp2ZXJzaW9uID0gIjAuNC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjcxMmUyMjc4NDFkMDU3YzFlZTFjZDJmYjIyZmE3ZTVhNTQ2MWFlOGU0OGZhMmNhNzllYzQyY2ZjMTkzMTE4M2YiCg==" + "path": "meta/src/main.rs", + "content": "Zm4gbWFpbigpIHsKICAgIGVscm9uZF93YXNtX2RlYnVnOjptZXRhOjpwZXJmb3JtOjo8YWRkZXI6OkFiaVByb3ZpZGVyPigpOwp9Cg==" }, { - "path": "wasm/src/lib.rs", - "content": "Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLy8vLy8vLy8vLy8vLy8vLy8gQVVUTy1HRU5FUkFURUQgLy8vLy8vLy8vLy8vLy8vLy8vCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCiMhW25vX3N0ZF0KCmVscm9uZF93YXNtX25vZGU6Ondhc21fZW5kcG9pbnRzISB7CiAgICBhZGRlcgogICAgKAogICAgICAgIGFkZAogICAgICAgIGdldFN1bQogICAgKQp9CgplbHJvbmRfd2FzbV9ub2RlOjp3YXNtX2VtcHR5X2NhbGxiYWNrISB7fQo=" + "path": "src/adder.rs", + "content": "IyFbbm9fc3RkXQoKZWxyb25kX3dhc206OmltcG9ydHMhKCk7CgovLy8gT25lIG9mIHRoZSBzaW1wbGVzdCBzbWFydCBjb250cmFjdHMgcG9zc2libGUsCi8vLyBpdCBob2xkcyBhIHNpbmdsZSB2YXJpYWJsZSBpbiBzdG9yYWdlLCB3aGljaCBhbnlvbmUgY2FuIGluY3JlbWVudC4KI1tlbHJvbmRfd2FzbTo6Y29udHJhY3RdCnB1YiB0cmFpdCBBZGRlciB7CiAgICAjW3ZpZXcoZ2V0U3VtKV0KICAgICNbc3RvcmFnZV9tYXBwZXIoInN1bSIpXQogICAgZm4gc3VtKCZzZWxmKSAtPiBTaW5nbGVWYWx1ZU1hcHBlcjxCaWdVaW50PjsKCiAgICAjW2luaXRdCiAgICBmbiBpbml0KCZzZWxmLCBpbml0aWFsX3ZhbHVlOiBCaWdVaW50KSB7CiAgICAgICAgc2VsZi5zdW0oKS5zZXQoaW5pdGlhbF92YWx1ZSk7CiAgICB9CgogICAgLy8vIEFkZCBkZXNpcmVkIGFtb3VudCB0byB0aGUgc3RvcmFnZSB2YXJpYWJsZS4KICAgICNbZW5kcG9pbnRdCiAgICBmbiBhZGQoJnNlbGYsIHZhbHVlOiBCaWdVaW50KSB7CiAgICAgICAgc2VsZi5zdW0oKS51cGRhdGUofHN1bXwgKnN1bSArPSB2YWx1ZSk7CiAgICB9Cn0K" }, { - "path": "meta/Cargo.toml", - "content": "W3BhY2thZ2VdCm5hbWUgPSAiYWRkZXItbWV0YSIKdmVyc2lvbiA9ICIwLjAuMCIKZWRpdGlvbiA9ICIyMDE4IgpwdWJsaXNoID0gZmFsc2UKCltkZXBlbmRlbmNpZXMuYWRkZXJdCnBhdGggPSAiLi4iCgpbZGVwZW5kZW5jaWVzLmVscm9uZC13YXNtLWRlYnVnXQp2ZXJzaW9uID0gIjAuMzYuMSIK" + "path": "wasm/Cargo.lock", + "content": "IyBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSBAZ2VuZXJhdGVkIGJ5IENhcmdvLgojIEl0IGlzIG5vdCBpbnRlbmRlZCBmb3IgbWFudWFsIGVkaXRpbmcuCnZlcnNpb24gPSAzCgpbW3BhY2thZ2VdXQpuYW1lID0gImFkZGVyIgp2ZXJzaW9uID0gIjEuMi4zIgpkZXBlbmRlbmNpZXMgPSBbCiAiZWxyb25kLXdhc20iLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImFkZGVyLXdhc20iCnZlcnNpb24gPSAiMS4yLjMiCmRlcGVuZGVuY2llcyA9IFsKICJhZGRlciIsCiAiZWxyb25kLXdhc20tbm9kZSIsCiAiZWxyb25kLXdhc20tb3V0cHV0IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJhaGFzaCIKdmVyc2lvbiA9ICIwLjcuNiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJmY2I1MWEwNjk1ZDhmODM4YjFlZTAwOWIzZmJmNjZiZGEwNzhjZDY0NTkwMjAyYTg2NGE4ZjNlOGM0MzE1YzQ3IgpkZXBlbmRlbmNpZXMgPSBbCiAiZ2V0cmFuZG9tIiwKICJvbmNlX2NlbGwiLAogInZlcnNpb25fY2hlY2siLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImFycmF5dmVjIgp2ZXJzaW9uID0gIjAuNy4yIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjhkYTUyZDY2YzcwNzFlMmUzZmEyYTFlNWM2ZDA4OGZlYzQ3YjU5MzAzMmIyNTRmNWU5ODBkZThlYTU0NDU0ZDYiCgpbW3BhY2thZ2VdXQpuYW1lID0gImF1dG9jZmciCnZlcnNpb24gPSAiMS4xLjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZDQ2ODgwMmJhYjE3Y2JjMGNjNTc1ZTliMDUzZjQxZTcyYWEzNmJmYTZiN2Y1NWUzNTI5ZmZhNDMxNjFiOTdmYSIKCltbcGFja2FnZV1dCm5hbWUgPSAiYml0ZmxhZ3MiCnZlcnNpb24gPSAiMS4zLjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYmVmMzhkNDUxNjNjMmYxZGRlMDk0YTdkZmQzM2NjZjU5NWM5MjkwNWM4ZjhmNGZkYzE4ZDA2ZmIxMDM3NzE4YSIKCltbcGFja2FnZV1dCm5hbWUgPSAiY2ZnLWlmIgp2ZXJzaW9uID0gIjAuMS4xMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI0Nzg1YmRkMWM5NmIyYTg0NmIyYmQ3Y2MwMmU4NmI2YjNkYmYxNGU3ZTUzNDQ2YzRmNTRjOTJhMzYxMDQwODIyIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJjZmctaWYiCnZlcnNpb24gPSAiMS4wLjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYmFmMWRlNDMzOTc2MTU4OGJjMDYxOWUzY2JjMDEyMGVlNTgyZWJiNzRiNTNiNGVmYmY3OTExN2JkMmRhNDBmZCIKCltbcGFja2FnZV1dCm5hbWUgPSAiZWxyb25kLWNvZGVjIgp2ZXJzaW9uID0gIjAuMTQuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIyYzg1YzU5NTE4NjRkZDQ4MTZlMWRmMmNlYWNjYjBmMjJjNjRmZjExN2RkY2RlMWY1MzM1MWFjZTRkNzg1YzQ3IgpkZXBlbmRlbmNpZXMgPSBbCiAiYXJyYXl2ZWMiLAogImVscm9uZC1jb2RlYy1kZXJpdmUiLAogIndlZV9hbGxvYyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZWxyb25kLWNvZGVjLWRlcml2ZSIKdmVyc2lvbiA9ICIwLjE0LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiMmE4OTg3YTdmNTA2YWU1YjM1MmFkN2FjMjhmYjEzYjlmNjAwMzU1YzhiODhhNDQ0ODgxZjg2YmM1NjVjNzVjZiIKZGVwZW5kZW5jaWVzID0gWwogImhleCIsCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJzeW4iLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImVscm9uZC13YXNtIgp2ZXJzaW9uID0gIjAuMzYuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI5ZmY3ZGQxMGY0YTcxMzNhMmM2ZmViM2Y3OWUwNDk1M2Y5YTNjMWVkYTlmODQ0NGI0M2MxMzAwZjMwMmUwMmZkIgpkZXBlbmRlbmNpZXMgPSBbCiAiYml0ZmxhZ3MiLAogImVscm9uZC1jb2RlYyIsCiAiZWxyb25kLXdhc20tZGVyaXZlIiwKICJnaXQtdmVyc2lvbiIsCiAiaGFzaGJyb3duIiwKICJoZXgtbGl0ZXJhbCIsCiAibnVtLXRyYWl0cyIsCiAid2VlX2FsbG9jIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbHJvbmQtd2FzbS1kZXJpdmUiCnZlcnNpb24gPSAiMC4zNi4xIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjYwMzU4OTg5MTYzYWUxYzI4Yjc5ZDdjNjg3ODY5ODc0Yzc2NTAwMWJiZGZhMTJhMzFkZmQ5MjAzNTBiYzdhMjIiCmRlcGVuZGVuY2llcyA9IFsKICJoZXgiLAogInByb2MtbWFjcm8yIiwKICJxdW90ZSIsCiAicmFkaXhfdHJpZSIsCiAic3luIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbHJvbmQtd2FzbS1ub2RlIgp2ZXJzaW9uID0gIjAuMzYuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI0Y2I0ZDRjMWFjZWQ5NjdmODZkYmMyYTBhMDE5MTBkMWViYjEwY2VhYjQ1OWNiNGEzZDdkMmU0M2I0ZGYyZjliIgpkZXBlbmRlbmNpZXMgPSBbCiAiZWxyb25kLXdhc20iLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImVscm9uZC13YXNtLW91dHB1dCIKdmVyc2lvbiA9ICIwLjM2LjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiMzJhOGMwMjUxNWU0M2VmN2ZkYTBjNzRjYzRhMGE0ZDM1Mzg0NmFmOTk5Y2M4MDJjMjMwNmMzNGZkNzBjZGExMSIKZGVwZW5kZW5jaWVzID0gWwogImVscm9uZC13YXNtLW5vZGUiLAogIndlZV9hbGxvYyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZW5kaWFuLXR5cGUiCnZlcnNpb24gPSAiMC4xLjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYzM0ZjA0NjY2ZDgzNWZmNWQ2MmUwNThjMzk5NTE0N2MwNmY0MmZlODZmZjA1MzMzNzYzMmJjYTgzZTQyNzAyZCIKCltbcGFja2FnZV1dCm5hbWUgPSAiZ2V0cmFuZG9tIgp2ZXJzaW9uID0gIjAuMi44Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImMwNWFlYjZhMjJiOGY2MjU0MGMxOTRhYWM5ODBmMjExNWFmMDY3YmZlMTVhMDczNGQ3Mjc3YTc2OGQzOTZiMzEiCmRlcGVuZGVuY2llcyA9IFsKICJjZmctaWYgMS4wLjAiLAogImxpYmMiLAogIndhc2kiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImdpdC12ZXJzaW9uIgp2ZXJzaW9uID0gIjAuMy41Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImY2YjBkZWNjMDJmNDYzNmI5Y2NhZDM5MGRjYmU3N2I3MjJhNzdlZmVkZmEzOTNjYWY4Mzc5YTUxZDVjNjE4OTkiCmRlcGVuZGVuY2llcyA9IFsKICJnaXQtdmVyc2lvbi1tYWNybyIsCiAicHJvYy1tYWNyby1oYWNrIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJnaXQtdmVyc2lvbi1tYWNybyIKdmVyc2lvbiA9ICIwLjMuNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJmZTY5ZjFjYmRiNmUyOGFmMmJhYzIxNGU5NDNiOTljZThhMGEwNmI0NDdkMTVkM2U2MTE2MWIwNDIzMTM5ZjNmIgpkZXBlbmRlbmNpZXMgPSBbCiAicHJvYy1tYWNyby1oYWNrIiwKICJwcm9jLW1hY3JvMiIsCiAicXVvdGUiLAogInN5biIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiaGFzaGJyb3duIgp2ZXJzaW9uID0gIjAuMTEuMiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJhYjVlZjBkNDkwOWVmMzcyNGNjOGNjZTZjY2M4NTcyYzVjODE3NTkyZTkyODVmNTQ2NGY4ZTg2ZjhiZDM3MjZlIgpkZXBlbmRlbmNpZXMgPSBbCiAiYWhhc2giLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImhleCIKdmVyc2lvbiA9ICIwLjQuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI3ZjI0MjU0YWE5YTU0YjVjODU4ZWFlZTJmNWJjY2RiNDZhYWYwZTQ4NmE1OTVlZDVmZDhmODZiYTU1MjMyYTcwIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJoZXgtbGl0ZXJhbCIKdmVyc2lvbiA9ICIwLjMuNCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI3ZWJkYjI5ZDJlYTllZDAwODNjZDhjZWNlNDliYmQ5NjgwMjFiZDk5YjA4NDllZGI0YTlhN2VlMGZkZjZhNGUwIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJsaWJjIgp2ZXJzaW9uID0gIjAuMi4xMzciCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZmM3ZmNjNjIwYTNiZmY3Y2RkN2EzNjViZTMzNzZjOTcxOTFhZWFjY2MyYTYwM2U2MDA5NTFlNDUyNjE1YmY4OSIKCltbcGFja2FnZV1dCm5hbWUgPSAibWVtb3J5X3VuaXRzIgp2ZXJzaW9uID0gIjAuNC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjg0NTIxMDViYTA0NzA2OGY0MGZmNzA5M2RkMWQ5ZGE5MDg5OGU2M2RkNjE3MzY0NjJlOWNkZGE2YTkwYWQzYzMiCgpbW3BhY2thZ2VdXQpuYW1lID0gIm5pYmJsZV92ZWMiCnZlcnNpb24gPSAiMC4wLjQiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYzhkNzdmM2RiNGJjZTAzM2Y0ZDA0ZGIwODA3OWIyZWYxYzNkMDJiNDRlODZmMjVkMDg4ODZmYWZhNzc1NmZmYSIKCltbcGFja2FnZV1dCm5hbWUgPSAibnVtLXRyYWl0cyIKdmVyc2lvbiA9ICIwLjIuMTUiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNTc4ZWRlMzRjZjAyZjg5MjRhYjk0NDdmNTBjMjgwNzViNGQzZTViMjY5OTcyMzQ1ZTdlMDM3MmIzOGM2Y2RjZCIKZGVwZW5kZW5jaWVzID0gWwogImF1dG9jZmciLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIm9uY2VfY2VsbCIKdmVyc2lvbiA9ICIxLjE2LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiODZmMGIwZDRiZjc5OWVkYmM3NDUwOGMxZThiZjE3MGZmNWY0MTIzOGU1ZjgyMjU2MDNjYTdjYWFhZTJiNzg2MCIKCltbcGFja2FnZV1dCm5hbWUgPSAicHJvYy1tYWNyby1oYWNrIgp2ZXJzaW9uID0gIjAuNS4xOSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJkYmYwYzQ4YmMxZDkxMzc1YWU1YzNjZDgxZTM3MjJkZmYxYWJjZjgxYTMwOTYwMjQwNjQwZDIyM2Y1OWZlMGU1IgoKW1twYWNrYWdlXV0KbmFtZSA9ICJwcm9jLW1hY3JvMiIKdmVyc2lvbiA9ICIxLjAuNDciCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNWVhM2Q5MDhiMGUzNjMxNmNhZjllOWUyYzQ2MjVjZGRlMTkwYTdlNmY0NDBkNzk0NjY3ZWQxN2ExODU1ZTcyNSIKZGVwZW5kZW5jaWVzID0gWwogInVuaWNvZGUtaWRlbnQiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInF1b3RlIgp2ZXJzaW9uID0gIjEuMC4yMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJiYmU0NDhmMzc3YTdkNjk2MWUzMGY1OTU1ZjliOGQxMDZjM2Y1ZTQ0OWQ0OTNlZTFiMTI1YzFkNDNjMmI1MTc5IgpkZXBlbmRlbmNpZXMgPSBbCiAicHJvYy1tYWNybzIiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInJhZGl4X3RyaWUiCnZlcnNpb24gPSAiMC4xLjYiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiM2QzNjgxYjI4Y2Q5NWFjZmIwNTYwZWE5NDQxZjgyZDZhNDUwNGZhM2IxNWI5N2JkN2I2ZTk1MjEzMTgyMGU5NSIKZGVwZW5kZW5jaWVzID0gWwogImVuZGlhbi10eXBlIiwKICJuaWJibGVfdmVjIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJzeW4iCnZlcnNpb24gPSAiMS4wLjEwMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJhODY0MDQyMjI5MTMzYWRhOTVhYmYzYjU0ZmRjNjJlZjVjY2FiZTk1MTViNjQ3MTdiY2I5YTE5MTllNTk0NDVkIgpkZXBlbmRlbmNpZXMgPSBbCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJ1bmljb2RlLWlkZW50IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJ1bmljb2RlLWlkZW50Igp2ZXJzaW9uID0gIjEuMC41Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjZjZWFiMzlkNTllNGM5NDk5ZDRlNWE4ZWUwZTI3MzViODkxYmI3MzA4YWM4M2RmYjRlODBjYWQxOTVjOWY2ZjMiCgpbW3BhY2thZ2VdXQpuYW1lID0gInZlcnNpb25fY2hlY2siCnZlcnNpb24gPSAiMC45LjQiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNDk4NzRiNTE2N2I2NWQ3MTkzYjhhYmExNTY3ZjVjN2Q5M2QwMDFjYWZjMzQ2MDBjZWUwMDNlZGE3ODdlNDgzZiIKCltbcGFja2FnZV1dCm5hbWUgPSAid2FzaSIKdmVyc2lvbiA9ICIwLjExLjArd2FzaS1zbmFwc2hvdC1wcmV2aWV3MSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI5YzhkODdlNzJiNjRhM2I0ZGIyOGQxMWNlMjkyMzdjMjQ2MTg4ZjRmNTEwNTdkNjVhN2VhYjYzYjc5ODdlNDIzIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJ3ZWVfYWxsb2MiCnZlcnNpb24gPSAiMC40LjUiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZGJiM2I1YTZiMmJiMTdjYjZhZDQ0YTJlNjhhNDNlOGQyNzIyYzk5N2RhMTBlOTI4NjY1YzcyZWM2YzBhMGI4ZSIKZGVwZW5kZW5jaWVzID0gWwogImNmZy1pZiAwLjEuMTAiLAogImxpYmMiLAogIm1lbW9yeV91bml0cyIsCiAid2luYXBpIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJ3aW5hcGkiCnZlcnNpb24gPSAiMC4zLjkiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNWM4MzlhNjc0ZmNkN2E5ODk1MmU1OTMyNDJlYTQwMGFiZTkzOTkyNzQ2NzYxZTM4NjQxNDA1ZDI4YjAwZjQxOSIKZGVwZW5kZW5jaWVzID0gWwogIndpbmFwaS1pNjg2LXBjLXdpbmRvd3MtZ251IiwKICJ3aW5hcGkteDg2XzY0LXBjLXdpbmRvd3MtZ251IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJ3aW5hcGktaTY4Ni1wYy13aW5kb3dzLWdudSIKdmVyc2lvbiA9ICIwLjQuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJhYzNiODdjNjM2MjA0MjZkZDliOTkxZTVjZTAzMjllZmY1NDViY2NiYmIzNGYzYmUwOWZmNmZiNmFiNTFiN2I2IgoKW1twYWNrYWdlXV0KbmFtZSA9ICJ3aW5hcGkteDg2XzY0LXBjLXdpbmRvd3MtZ251Igp2ZXJzaW9uID0gIjAuNC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjcxMmUyMjc4NDFkMDU3YzFlZTFjZDJmYjIyZmE3ZTVhNTQ2MWFlOGU0OGZhMmNhNzllYzQyY2ZjMTkzMTE4M2YiCg==" }, { - "path": "meta/Cargo.lock", - "content": "IyBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSBAZ2VuZXJhdGVkIGJ5IENhcmdvLgojIEl0IGlzIG5vdCBpbnRlbmRlZCBmb3IgbWFudWFsIGVkaXRpbmcuCnZlcnNpb24gPSAzCgpbW3BhY2thZ2VdXQpuYW1lID0gImFkZGVyIgp2ZXJzaW9uID0gIjEuMi4zIgpkZXBlbmRlbmNpZXMgPSBbCiAiZWxyb25kLXdhc20iLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImFkZGVyLW1ldGEiCnZlcnNpb24gPSAiMC4wLjAiCmRlcGVuZGVuY2llcyA9IFsKICJhZGRlciIsCiAiZWxyb25kLXdhc20tZGVidWciLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImFoYXNoIgp2ZXJzaW9uID0gIjAuNy42Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImZjYjUxYTA2OTVkOGY4MzhiMWVlMDA5YjNmYmY2NmJkYTA3OGNkNjQ1OTAyMDJhODY0YThmM2U4YzQzMTVjNDciCmRlcGVuZGVuY2llcyA9IFsKICJnZXRyYW5kb20gMC4yLjgiLAogIm9uY2VfY2VsbCIsCiAidmVyc2lvbl9jaGVjayIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiYXJyYXl2ZWMiCnZlcnNpb24gPSAiMC43LjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiOGRhNTJkNjZjNzA3MWUyZTNmYTJhMWU1YzZkMDg4ZmVjNDdiNTkzMDMyYjI1NGY1ZTk4MGRlOGVhNTQ0NTRkNiIKCltbcGFja2FnZV1dCm5hbWUgPSAiYXV0b2NmZyIKdmVyc2lvbiA9ICIxLjEuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJkNDY4ODAyYmFiMTdjYmMwY2M1NzVlOWIwNTNmNDFlNzJhYTM2YmZhNmI3ZjU1ZTM1MjlmZmE0MzE2MWI5N2ZhIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJiZWNoMzIiCnZlcnNpb24gPSAiMC45LjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZDg2YjkzZjk3MjUyYzQ3YjQxNjYzMzg4ZTZkMTU1NzE0YTlkMGMzOThiOTlmMTAwNWNiYzVmOTc4YjI5ZjQ0NSIKCltbcGFja2FnZV1dCm5hbWUgPSAiYml0ZmxhZ3MiCnZlcnNpb24gPSAiMS4zLjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYmVmMzhkNDUxNjNjMmYxZGRlMDk0YTdkZmQzM2NjZjU5NWM5MjkwNWM4ZjhmNGZkYzE4ZDA2ZmIxMDM3NzE4YSIKCltbcGFja2FnZV1dCm5hbWUgPSAiYmxvY2stYnVmZmVyIgp2ZXJzaW9uID0gIjAuOS4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjQxNTIxMTZmZDZlOWRhZGIyOTFhZTE4ZmMxZWMzNTc1ZWQ2ZDg0YzI5NjQyZDk3ODkwZjRiNGEzNDE3Mjk3ZTQiCmRlcGVuZGVuY2llcyA9IFsKICJibG9jay1wYWRkaW5nIiwKICJnZW5lcmljLWFycmF5IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJibG9jay1wYWRkaW5nIgp2ZXJzaW9uID0gIjAuMi4xIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjhkNjk2YzM3MGM3NTBjOTQ4YWRhNjFjNjlhMGVlMmNiYmI5YzUwYjEwMTlkZGI4NmQ5MzE3MTU3YTk5YzJjYWUiCgpbW3BhY2thZ2VdXQpuYW1lID0gImJ5dGVvcmRlciIKdmVyc2lvbiA9ICIxLjQuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIxNGMxODljNTNkMDk4OTQ1NDk5Y2RmYTdlY2M2MzU2N2NmMzg4NmIzMzMyYjMxMmE1YjQ1ODVkOGQzYTZhNjEwIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJjYXJnb190b21sIgp2ZXJzaW9uID0gIjAuMTAuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIzNjNjN2NmYWExNWYxMDE0MTVjNGFjOWU2ODcwNmNhNGEyMjc3NzczOTMyODI4YjMzZjk2ZTU5ZDI4YzY4ZTYyIgpkZXBlbmRlbmNpZXMgPSBbCiAic2VyZGUiLAogInNlcmRlX2Rlcml2ZSIsCiAidG9tbCIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiY2ZnLWlmIgp2ZXJzaW9uID0gIjAuMS4xMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI0Nzg1YmRkMWM5NmIyYTg0NmIyYmQ3Y2MwMmU4NmI2YjNkYmYxNGU3ZTUzNDQ2YzRmNTRjOTJhMzYxMDQwODIyIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJjZmctaWYiCnZlcnNpb24gPSAiMS4wLjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYmFmMWRlNDMzOTc2MTU4OGJjMDYxOWUzY2JjMDEyMGVlNTgyZWJiNzRiNTNiNGVmYmY3OTExN2JkMmRhNDBmZCIKCltbcGFja2FnZV1dCm5hbWUgPSAiY3B1ZmVhdHVyZXMiCnZlcnNpb24gPSAiMC4yLjUiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiMjhkOTk3YmQ1ZTI0YTU5MjhkZDQzZTQ2ZGM1Mjk4NjdlMjA3OTA3ZmUwYjIzOWMzNDc3ZDkyNGY3ZjJjYTMyMCIKZGVwZW5kZW5jaWVzID0gWwogImxpYmMiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImN1cnZlMjU1MTktZGFsZWsiCnZlcnNpb24gPSAiMy4yLjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiOTBmOWQwNTI5NjdmNTkwYTc2ZTYyZWIzODdiZDBiYmIxYjAwMDE4MmMzY2VmZTUzNjRkYjZiNzIxMTY1MWJjMCIKZGVwZW5kZW5jaWVzID0gWwogImJ5dGVvcmRlciIsCiAiZGlnZXN0IiwKICJyYW5kX2NvcmUgMC41LjEiLAogInN1YnRsZSIsCiAiemVyb2l6ZSIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZGlnZXN0Igp2ZXJzaW9uID0gIjAuOS4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImQzZGQ2MGQxMDgwYTU3YTA1YWIwMzIzNzcwNDllMDU5MTQxNWQyYjMxYWZkNzAyODM1NmRiZjNjYzZkY2IwNjYiCmRlcGVuZGVuY2llcyA9IFsKICJnZW5lcmljLWFycmF5IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlZDI1NTE5Igp2ZXJzaW9uID0gIjEuNS4yIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjFlOWMyODAzNjIwMzJlYTQyMDM2NTlmYzQ4OTgzMmQwMjA0ZWYwOWYyNDdhMDUwNmYxNzBkYWZjYWMwOGMzNjkiCmRlcGVuZGVuY2llcyA9IFsKICJzaWduYXR1cmUiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImVkMjU1MTktZGFsZWsiCnZlcnNpb24gPSAiMS4wLjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYzc2MmJhZTZkY2FmMjRjNGM4NDY2N2I4NTc5Nzg1NDMwOTA4NzIzZDVjODg5ZjQ2OWQ3NmE0MWQ1OWNjN2E5ZCIKZGVwZW5kZW5jaWVzID0gWwogImN1cnZlMjU1MTktZGFsZWsiLAogImVkMjU1MTkiLAogInJhbmQgMC43LjMiLAogInNlcmRlIiwKICJzaGEyIiwKICJ6ZXJvaXplIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlaXRoZXIiCnZlcnNpb24gPSAiMS44LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiOTBlNWMxYzgzNjg4MDMxMTNiZjBjOTU4NGZjNDk1YTU4Yjg2ZGM4YTI5ZWRiZjhmZTg3N2QyMWQ5NTA3ZTc5NyIKCltbcGFja2FnZV1dCm5hbWUgPSAiZWxyb25kLWNvZGVjIgp2ZXJzaW9uID0gIjAuMTQuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIyYzg1YzU5NTE4NjRkZDQ4MTZlMWRmMmNlYWNjYjBmMjJjNjRmZjExN2RkY2RlMWY1MzM1MWFjZTRkNzg1YzQ3IgpkZXBlbmRlbmNpZXMgPSBbCiAiYXJyYXl2ZWMiLAogImVscm9uZC1jb2RlYy1kZXJpdmUiLAogIm51bS1iaWdpbnQiLAogIndlZV9hbGxvYyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZWxyb25kLWNvZGVjLWRlcml2ZSIKdmVyc2lvbiA9ICIwLjE0LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiMmE4OTg3YTdmNTA2YWU1YjM1MmFkN2FjMjhmYjEzYjlmNjAwMzU1YzhiODhhNDQ0ODgxZjg2YmM1NjVjNzVjZiIKZGVwZW5kZW5jaWVzID0gWwogImhleCIsCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJzeW4iLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImVscm9uZC13YXNtIgp2ZXJzaW9uID0gIjAuMzYuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI5ZmY3ZGQxMGY0YTcxMzNhMmM2ZmViM2Y3OWUwNDk1M2Y5YTNjMWVkYTlmODQ0NGI0M2MxMzAwZjMwMmUwMmZkIgpkZXBlbmRlbmNpZXMgPSBbCiAiYml0ZmxhZ3MiLAogImVscm9uZC1jb2RlYyIsCiAiZWxyb25kLXdhc20tZGVyaXZlIiwKICJnaXQtdmVyc2lvbiIsCiAiaGFzaGJyb3duIiwKICJoZXgtbGl0ZXJhbCIsCiAibnVtLXRyYWl0cyIsCiAid2VlX2FsbG9jIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbHJvbmQtd2FzbS1kZWJ1ZyIKdmVyc2lvbiA9ICIwLjM2LjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiMGQ1ZWRmZTg2OTg1OTU2ZjJkZTNhNjQ5YmIxNjE5YzFmOGI3OTRiNTQwZTYyMDQ2MWJhMDhmMDUwODYzNTNmYyIKZGVwZW5kZW5jaWVzID0gWwogImJlY2gzMiIsCiAiY2FyZ29fdG9tbCIsCiAiZWQyNTUxOS1kYWxlayIsCiAiZWxyb25kLXdhc20iLAogImhleCIsCiAiaXRlcnRvb2xzIiwKICJtYW5kb3MiLAogIm51bS1iaWdpbnQiLAogIm51bS10cmFpdHMiLAogInBhdGhkaWZmIiwKICJyYW5kIDAuOC41IiwKICJyYW5kX3BjZyIsCiAicmFuZF9zZWVkZXIiLAogInJ1c3RjX3ZlcnNpb24iLAogInNlcmRlIiwKICJzZXJkZV9qc29uIiwKICJzaGEyIiwKICJzaGEzIiwKICJ0b21sIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbHJvbmQtd2FzbS1kZXJpdmUiCnZlcnNpb24gPSAiMC4zNi4xIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjYwMzU4OTg5MTYzYWUxYzI4Yjc5ZDdjNjg3ODY5ODc0Yzc2NTAwMWJiZGZhMTJhMzFkZmQ5MjAzNTBiYzdhMjIiCmRlcGVuZGVuY2llcyA9IFsKICJoZXgiLAogInByb2MtbWFjcm8yIiwKICJxdW90ZSIsCiAicmFkaXhfdHJpZSIsCiAic3luIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbmRpYW4tdHlwZSIKdmVyc2lvbiA9ICIwLjEuMiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJjMzRmMDQ2NjZkODM1ZmY1ZDYyZTA1OGMzOTk1MTQ3YzA2ZjQyZmU4NmZmMDUzMzM3NjMyYmNhODNlNDI3MDJkIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJnZW5lcmljLWFycmF5Igp2ZXJzaW9uID0gIjAuMTQuNiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJiZmY0OWU5NDcyOTdmMzMxMjQ0N2FiZGNhNzlmNDVmNDczODA5N2NjODJiMDZlNzIwNTRkMjIyM2Y2MDFmMWI5IgpkZXBlbmRlbmNpZXMgPSBbCiAidHlwZW51bSIsCiAidmVyc2lvbl9jaGVjayIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZ2V0cmFuZG9tIgp2ZXJzaW9uID0gIjAuMS4xNiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI4ZmMzY2I0ZDkxZjUzYjUwMTU1YmRjZmQyM2Y2YTRjMzlhZTE5NjljMmFlODU5ODJiMTM1NzUwY2NjYWY1ZmNlIgpkZXBlbmRlbmNpZXMgPSBbCiAiY2ZnLWlmIDEuMC4wIiwKICJsaWJjIiwKICJ3YXNpIDAuOS4wK3dhc2ktc25hcHNob3QtcHJldmlldzEiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImdldHJhbmRvbSIKdmVyc2lvbiA9ICIwLjIuOCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJjMDVhZWI2YTIyYjhmNjI1NDBjMTk0YWFjOTgwZjIxMTVhZjA2N2JmZTE1YTA3MzRkNzI3N2E3NjhkMzk2YjMxIgpkZXBlbmRlbmNpZXMgPSBbCiAiY2ZnLWlmIDEuMC4wIiwKICJsaWJjIiwKICJ3YXNpIDAuMTEuMCt3YXNpLXNuYXBzaG90LXByZXZpZXcxIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJnaXQtdmVyc2lvbiIKdmVyc2lvbiA9ICIwLjMuNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJmNmIwZGVjYzAyZjQ2MzZiOWNjYWQzOTBkY2JlNzdiNzIyYTc3ZWZlZGZhMzkzY2FmODM3OWE1MWQ1YzYxODk5IgpkZXBlbmRlbmNpZXMgPSBbCiAiZ2l0LXZlcnNpb24tbWFjcm8iLAogInByb2MtbWFjcm8taGFjayIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZ2l0LXZlcnNpb24tbWFjcm8iCnZlcnNpb24gPSAiMC4zLjUiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZmU2OWYxY2JkYjZlMjhhZjJiYWMyMTRlOTQzYjk5Y2U4YTBhMDZiNDQ3ZDE1ZDNlNjExNjFiMDQyMzEzOWYzZiIKZGVwZW5kZW5jaWVzID0gWwogInByb2MtbWFjcm8taGFjayIsCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJzeW4iLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImhhc2hicm93biIKdmVyc2lvbiA9ICIwLjExLjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYWI1ZWYwZDQ5MDllZjM3MjRjYzhjY2U2Y2NjODU3MmM1YzgxNzU5MmU5Mjg1ZjU0NjRmOGU4NmY4YmQzNzI2ZSIKZGVwZW5kZW5jaWVzID0gWwogImFoYXNoIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJoZXgiCnZlcnNpb24gPSAiMC40LjMiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiN2YyNDI1NGFhOWE1NGI1Yzg1OGVhZWUyZjViY2NkYjQ2YWFmMGU0ODZhNTk1ZWQ1ZmQ4Zjg2YmE1NTIzMmE3MCIKCltbcGFja2FnZV1dCm5hbWUgPSAiaGV4LWxpdGVyYWwiCnZlcnNpb24gPSAiMC4zLjQiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiN2ViZGIyOWQyZWE5ZWQwMDgzY2Q4Y2VjZTQ5YmJkOTY4MDIxYmQ5OWIwODQ5ZWRiNGE5YTdlZTBmZGY2YTRlMCIKCltbcGFja2FnZV1dCm5hbWUgPSAiaXRlcnRvb2xzIgp2ZXJzaW9uID0gIjAuMTAuNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJiMGZkMjI2MGU4MjliZGRmNGNiNmVhODAyMjg5ZGUyZjg2ZDZhN2E2OTAxOTJmYmU5MWIzZjQ2ZTBmMmM4NDczIgpkZXBlbmRlbmNpZXMgPSBbCiAiZWl0aGVyIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJpdG9hIgp2ZXJzaW9uID0gIjEuMC41Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImZhZDU4MmY0YjllODZiNmNhYTYyMWNhYmViMDk2MzMzMmQ5MmVlYTA0NzI5YWIxMjg5MmMyNTMzOTUxZTY0NDAiCgpbW3BhY2thZ2VdXQpuYW1lID0gImtlY2NhayIKdmVyc2lvbiA9ICIwLjEuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIzYWZlZjNiNmVmZjljZTlkOGZmOWIzNjAxMTI1ZWVjN2YwYzhjYmFjN2FiZDE0ZjM1NWQwNTNmYTU2Yzk4NzY4IgpkZXBlbmRlbmNpZXMgPSBbCiAiY3B1ZmVhdHVyZXMiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImxpYmMiCnZlcnNpb24gPSAiMC4yLjEzOSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIyMDFkZTMyNzUyMGRmMDA3NzU3YzFmMGFkY2U2ZTgyN2ZlODU2MmZiYzI4YmZkOWMxNTU3MWM2NmNhMWY1Zjc5IgoKW1twYWNrYWdlXV0KbmFtZSA9ICJtYW5kb3MiCnZlcnNpb24gPSAiMC4xNy4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjE4NDJlNzRjZmRlODc4ZTg2YWYwODY0ODMzMmMzNTdlNjMxMzU3NjNmNTU0ZmZiZDZlODJmMTEwZGVmZGJlYWYiCmRlcGVuZGVuY2llcyA9IFsKICJiZWNoMzIiLAogImhleCIsCiAibnVtLWJpZ2ludCIsCiAibnVtLXRyYWl0cyIsCiAic2VyZGUiLAogInNlcmRlX2pzb24iLAogInNoYTMiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIm1lbW9yeV91bml0cyIKdmVyc2lvbiA9ICIwLjQuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI4NDUyMTA1YmEwNDcwNjhmNDBmZjcwOTNkZDFkOWRhOTA4OThlNjNkZDYxNzM2NDYyZTljZGRhNmE5MGFkM2MzIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJuaWJibGVfdmVjIgp2ZXJzaW9uID0gIjAuMC40Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImM4ZDc3ZjNkYjRiY2UwMzNmNGQwNGRiMDgwNzliMmVmMWMzZDAyYjQ0ZTg2ZjI1ZDA4ODg2ZmFmYTc3NTZmZmEiCgpbW3BhY2thZ2VdXQpuYW1lID0gIm51bS1iaWdpbnQiCnZlcnNpb24gPSAiMC40LjMiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZjkzYWI2Mjg5YzdiMzQ0YThhOWY2MGY4OGQ4MGFhMjAwMzIzMzZmZTc4ZGEzNDFhZmM5MWM4YTIzNDFmYzc1ZiIKZGVwZW5kZW5jaWVzID0gWwogImF1dG9jZmciLAogIm51bS1pbnRlZ2VyIiwKICJudW0tdHJhaXRzIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJudW0taW50ZWdlciIKdmVyc2lvbiA9ICIwLjEuNDUiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiMjI1ZDMzODlmYjM1MDlhMjRjOTNmNWMyOWViNmJkZTI1ODZiOThkOWYwMTY2MzZkZmY1OGQ3YzZmNzU2OWNkOSIKZGVwZW5kZW5jaWVzID0gWwogImF1dG9jZmciLAogIm51bS10cmFpdHMiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIm51bS10cmFpdHMiCnZlcnNpb24gPSAiMC4yLjE1Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjU3OGVkZTM0Y2YwMmY4OTI0YWI5NDQ3ZjUwYzI4MDc1YjRkM2U1YjI2OTk3MjM0NWU3ZTAzNzJiMzhjNmNkY2QiCmRlcGVuZGVuY2llcyA9IFsKICJhdXRvY2ZnIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJvbmNlX2NlbGwiCnZlcnNpb24gPSAiMS4xNy4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjZmNjFmYmExNzQxZWEyYjNkNmExZTMxNzg3MjE4MDRiYjcxNmE2OGE2YWViYTExNDliNWQ1MmUzZDQ2NGVhNjYiCgpbW3BhY2thZ2VdXQpuYW1lID0gIm9wYXF1ZS1kZWJ1ZyIKdmVyc2lvbiA9ICIwLjMuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI2MjRhODM0MGMzOGMxYjgwZmQ1NDkwODc4NjJkYTRiYTQzZTA4ODU4YWYwMjViMjM2ZTUwOWI2NjQ5ZmMxM2Q1IgoKW1twYWNrYWdlXV0KbmFtZSA9ICJwYXRoZGlmZiIKdmVyc2lvbiA9ICIwLjIuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI4ODM1MTE2YTVjMTc5MDg0YTgzMGVmYjNhZGMxMTdhYjAwNzUxMmI1MzViYzFhMjFjOTkxZDNiMzJhNmI0NGRkIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJwcHYtbGl0ZTg2Igp2ZXJzaW9uID0gIjAuMi4xNyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1YjQwYWY4MDViMzEyMWZlYWI4YTNjMjlmMDRkOGFkMjYyZmE4ZTA1NjE4ODNlNzY1M2UwMjRhZTQ0NzllNmRlIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJwcm9jLW1hY3JvLWhhY2siCnZlcnNpb24gPSAiMC41LjIwK2RlcHJlY2F0ZWQiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZGMzNzVlMTUyNzI0N2ZlMWE5N2Q4YjcxNTY2NzhkZmU3YzFhZjJmYzA3NWM5YTRkYjM2OTBlY2QyYTE0ODA2OCIKCltbcGFja2FnZV1dCm5hbWUgPSAicHJvYy1tYWNybzIiCnZlcnNpb24gPSAiMS4wLjQ5Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjU3YThlY2E5ZjljNGZmZGU0MTcxNDMzNGRlZTc3NzU5NjI2NGM3ODI1NDIwZjUyMWFiYzkyYjViNWRlYjYzYTUiCmRlcGVuZGVuY2llcyA9IFsKICJ1bmljb2RlLWlkZW50IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJxdW90ZSIKdmVyc2lvbiA9ICIxLjAuMjMiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiODg1NmQ4MzY0ZDI1MmExNGQ0NzQwMzZlYTEzNThkNjNjOWU2OTY1YzhlNWMxODg1YzE4ZjczZDcwYmZmOWM3YiIKZGVwZW5kZW5jaWVzID0gWwogInByb2MtbWFjcm8yIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJyYWRpeF90cmllIgp2ZXJzaW9uID0gIjAuMS42Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjNkMzY4MWIyOGNkOTVhY2ZiMDU2MGVhOTQ0MWY4MmQ2YTQ1MDRmYTNiMTViOTdiZDdiNmU5NTIxMzE4MjBlOTUiCmRlcGVuZGVuY2llcyA9IFsKICJlbmRpYW4tdHlwZSIsCiAibmliYmxlX3ZlYyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicmFuZCIKdmVyc2lvbiA9ICIwLjcuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI2YTZiMTY3OWQ0OWIyNGJiZmUwYzgwMzQyOWFhMTg3NDQ3MmY1MGQ5YjM2MzEzMWYwZTg5ZmMzNTZiNTQ0ZDAzIgpkZXBlbmRlbmNpZXMgPSBbCiAiZ2V0cmFuZG9tIDAuMS4xNiIsCiAibGliYyIsCiAicmFuZF9jaGFjaGEgMC4yLjIiLAogInJhbmRfY29yZSAwLjUuMSIsCiAicmFuZF9oYyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicmFuZCIKdmVyc2lvbiA9ICIwLjguNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIzNGFmOGQxYTBlMjU5MjRiYzViN2M0M2MwNzljOTQyMzM5ZDhmMGE4YjU3YzM5MDQ5YmVmNTgxYjQ2MzI3NDA0IgpkZXBlbmRlbmNpZXMgPSBbCiAibGliYyIsCiAicmFuZF9jaGFjaGEgMC4zLjEiLAogInJhbmRfY29yZSAwLjYuNCIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicmFuZF9jaGFjaGEiCnZlcnNpb24gPSAiMC4yLjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZjRjOGVkODU2Mjc5Yzk3MzcyMDZiZjcyNWJmMzY5MzVkODY2NmVhZDdhYTY5YjUyYmU1NWFmMzY5ZDE5MzQwMiIKZGVwZW5kZW5jaWVzID0gWwogInBwdi1saXRlODYiLAogInJhbmRfY29yZSAwLjUuMSIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicmFuZF9jaGFjaGEiCnZlcnNpb24gPSAiMC4zLjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZTZjMTBhNjNhMGZhMzIyNTJiZTQ5ZDIxZTc3MDlkNGQ0YmFmOGQyMzFjMmRiY2UxZWFhODE0MWI5YjEyN2Q4OCIKZGVwZW5kZW5jaWVzID0gWwogInBwdi1saXRlODYiLAogInJhbmRfY29yZSAwLjYuNCIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicmFuZF9jb3JlIgp2ZXJzaW9uID0gIjAuNS4xIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjkwYmRlNTI5NmZjODkxYjBjZWYxMmE2ZDAzZGRjY2MxNjJjZTdiMmFmZjU0MTYwYWY5MzM4ZjhkNDBkZjZkMTkiCmRlcGVuZGVuY2llcyA9IFsKICJnZXRyYW5kb20gMC4xLjE2IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJyYW5kX2NvcmUiCnZlcnNpb24gPSAiMC42LjQiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZWMwYmU0Nzk1ZTJmNmEyODA2OWJlYzBiNWZmM2UyYWM5YmFmYzk5ZTZhOWE3ZGMzNTQ3OTk2YzVjODE2OTIyYyIKZGVwZW5kZW5jaWVzID0gWwogImdldHJhbmRvbSAwLjIuOCIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicmFuZF9oYyIKdmVyc2lvbiA9ICIwLjIuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJjYTMxMjlhZjdiOTJhMTcxMTJkNTlhZDQ5OGM2ZjgxZWFmNDYzMjUzNzY2YjkwMzk2ZDM5ZWE3YTM5ZDY2MTNjIgpkZXBlbmRlbmNpZXMgPSBbCiAicmFuZF9jb3JlIDAuNS4xIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJyYW5kX3BjZyIKdmVyc2lvbiA9ICIwLjIuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIxNmFiZDBjMWI2MzllOWViNGQ3YzUwYzBiODEwMGIwZDBmODQ5YmUyMzQ5ODI5Yzc0MGZlOGU2ZWI0ODE2NDI5IgpkZXBlbmRlbmNpZXMgPSBbCiAicmFuZF9jb3JlIDAuNS4xIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJyYW5kX3NlZWRlciIKdmVyc2lvbiA9ICIwLjIuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJjZjI4OTBhYWVmMGFhODI3MTlhNTBlODA4ZGUyNjRmOTQ4NGI3NGI0NDJlMWEzYTBlNWVlMzgyNDNhYzQwYmRiIgpkZXBlbmRlbmNpZXMgPSBbCiAicmFuZF9jb3JlIDAuNi40IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJydXN0Y192ZXJzaW9uIgp2ZXJzaW9uID0gIjAuNC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImJmYTBmNTg1MjI2ZDJlNjgwOTdkNGY5NWQxMTNiMTViODNhODJlODE5YWIyNTcxN2VjMDU5MGQ5NTg0ZWYzNjYiCmRlcGVuZGVuY2llcyA9IFsKICJzZW12ZXIiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInJ5dSIKdmVyc2lvbiA9ICIxLjAuMTIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiN2I0Yjk3NDNlZDY4N2Q0YjRiY2VkZjlmZjVlYWE3Mzk4NDk1YWUxNGU2MWNiYTBhMjk1NzA0ZWRiYzdkZWNkZSIKCltbcGFja2FnZV1dCm5hbWUgPSAic2VtdmVyIgp2ZXJzaW9uID0gIjEuMC4xNiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1OGJjOTU2NzM3OGZjNzY5MGQ2YjJhZGRhZTRlNjBhYzJlZWVhMDdiZWNiMmM2NGI5ZjIxOGI1Mzg2NWNiYTJhIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJzZXJkZSIKdmVyc2lvbiA9ICIxLjAuMTUyIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImJiN2QxZjBkMzAyMWQzNDdhODNlNTU2ZmM0NjgzZGVhMmVhMDlkODdiY2NkZjg4ZmY1YzEyNTQ1ZDg5ZDVlZmIiCmRlcGVuZGVuY2llcyA9IFsKICJzZXJkZV9kZXJpdmUiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInNlcmRlX2Rlcml2ZSIKdmVyc2lvbiA9ICIxLjAuMTUyIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImFmNDg3ZDExOGVlY2QwOTQwMmQ3MGE1ZDcyNTUxODYwZTc4OGRmODdiNDY0YWYzMGU1ZWE2YTM4Yzc1YzU0MWUiCmRlcGVuZGVuY2llcyA9IFsKICJwcm9jLW1hY3JvMiIsCiAicXVvdGUiLAogInN5biIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAic2VyZGVfanNvbiIKdmVyc2lvbiA9ICIxLjAuOTEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiODc3YzIzNTUzMzcxNDkwN2E4YzI0NjQyMzZmNWM0YjJhMTcyNjJlZjFiZDcxZjM4ZjM1ZWE1OTJjOGRhNjg4MyIKZGVwZW5kZW5jaWVzID0gWwogIml0b2EiLAogInJ5dSIsCiAic2VyZGUiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInNoYTIiCnZlcnNpb24gPSAiMC45LjkiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNGQ1OGExZTFiZjM5NzQ5ODA3ZDg5Y2YyZDk4YWMyZGZhMGZmMWNiM2ZhYTM4ZmJiNjRkZDg4YWM4MDEzZDgwMCIKZGVwZW5kZW5jaWVzID0gWwogImJsb2NrLWJ1ZmZlciIsCiAiY2ZnLWlmIDEuMC4wIiwKICJjcHVmZWF0dXJlcyIsCiAiZGlnZXN0IiwKICJvcGFxdWUtZGVidWciLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInNoYTMiCnZlcnNpb24gPSAiMC45LjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZjgxMTk5NDE3ZDRlNWRlM2YwNGIxZTg3MTAyM2FjZWE3Mzg5NjcyYzQxMzU5MThmMDVhYTljYmYyZjJmYTgwOSIKZGVwZW5kZW5jaWVzID0gWwogImJsb2NrLWJ1ZmZlciIsCiAiZGlnZXN0IiwKICJrZWNjYWsiLAogIm9wYXF1ZS1kZWJ1ZyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAic2lnbmF0dXJlIgp2ZXJzaW9uID0gIjEuNi40Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjc0MjMzZDNiM2IyZjZkNGIwMDZkYzE5ZGVlNzQ1ZTczZTJhNmJmYjZmOTM2MDdjZDNiMDJiZDViMDA3OTdkN2MiCgpbW3BhY2thZ2VdXQpuYW1lID0gInN1YnRsZSIKdmVyc2lvbiA9ICIyLjQuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI2YmRlZjMyZTgxNTBjMmEwODExMTBiNDI3NzJmZmU3ZDdjOTAzMmI2MDZiYzIyNmM4MjYwZmQ5N2UwOTc2NjAxIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJzeW4iCnZlcnNpb24gPSAiMS4wLjEwNyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIxZjQwNjRiNWIxNmUwM2FlNTA5ODRhNWE4ZWQ1ZDRmODgwM2U2YmMxZmQxNzBhM2NkYTkxYTFiZTRiMThlM2Y1IgpkZXBlbmRlbmNpZXMgPSBbCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJ1bmljb2RlLWlkZW50IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJzeW5zdHJ1Y3R1cmUiCnZlcnNpb24gPSAiMC4xMi42Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImYzNmJkYWE2MGE4M2FjYTM5MjFiNTI1OWQ1NDAwY2JmNWU5MGZjNTE5MzEzNzZhOWJkNGEwZWI3OWFhNzIxMGYiCmRlcGVuZGVuY2llcyA9IFsKICJwcm9jLW1hY3JvMiIsCiAicXVvdGUiLAogInN5biIsCiAidW5pY29kZS14aWQiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInRvbWwiCnZlcnNpb24gPSAiMC41LjEwIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjEzMzNjNzY3NDhlODY4YTRkOWQxMDE3YjVhYjUzMTcxZGZkMDk1ZjcwYzcxMmZkYjQ2NTNhNDA2NTQ3ZjU5OGYiCmRlcGVuZGVuY2llcyA9IFsKICJzZXJkZSIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAidHlwZW51bSIKdmVyc2lvbiA9ICIxLjE2LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNDk3OTYxZWY5M2Q5NzRlMjNlYjZmNDMzZWI1ZmUxYjc5MzBiNjU5ZjA2ZDEyZGVjNmZjNDRhOGY1NTRjMGJiYSIKCltbcGFja2FnZV1dCm5hbWUgPSAidW5pY29kZS1pZGVudCIKdmVyc2lvbiA9ICIxLjAuNiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI4NGEyMmI5ZjIxOGI0MDYxNGFkY2IzZjRmZjA4YjcwMzc3M2FkNDRmYTk0MjNlNGUwZDM0NmQ1ZGI4NmU0ZWJjIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJ1bmljb2RlLXhpZCIKdmVyc2lvbiA9ICIwLjIuNCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJmOTYyZGY3NGM4YzA1YTY2N2I1ZWU4YmNmMTYyOTkzMTM0YzEwNGU5NjQ0MGI2NjNjOGRhYTE3NmRjNzcyZDhjIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJ2ZXJzaW9uX2NoZWNrIgp2ZXJzaW9uID0gIjAuOS40Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjQ5ODc0YjUxNjdiNjVkNzE5M2I4YWJhMTU2N2Y1YzdkOTNkMDAxY2FmYzM0NjAwY2VlMDAzZWRhNzg3ZTQ4M2YiCgpbW3BhY2thZ2VdXQpuYW1lID0gIndhc2kiCnZlcnNpb24gPSAiMC45LjArd2FzaS1zbmFwc2hvdC1wcmV2aWV3MSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJjY2NkZGYzMjU1NGZlY2M2YWNiNTg1ZjgyYTMyYTcyZTI4YjQ4ZjhjNGMxODgzZGRmZWVlYWE5NmY3ZDhlNTE5IgoKW1twYWNrYWdlXV0KbmFtZSA9ICJ3YXNpIgp2ZXJzaW9uID0gIjAuMTEuMCt3YXNpLXNuYXBzaG90LXByZXZpZXcxIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjljOGQ4N2U3MmI2NGEzYjRkYjI4ZDExY2UyOTIzN2MyNDYxODhmNGY1MTA1N2Q2NWE3ZWFiNjNiNzk4N2U0MjMiCgpbW3BhY2thZ2VdXQpuYW1lID0gIndlZV9hbGxvYyIKdmVyc2lvbiA9ICIwLjQuNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJkYmIzYjVhNmIyYmIxN2NiNmFkNDRhMmU2OGE0M2U4ZDI3MjJjOTk3ZGExMGU5Mjg2NjVjNzJlYzZjMGEwYjhlIgpkZXBlbmRlbmNpZXMgPSBbCiAiY2ZnLWlmIDAuMS4xMCIsCiAibGliYyIsCiAibWVtb3J5X3VuaXRzIiwKICJ3aW5hcGkiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIndpbmFwaSIKdmVyc2lvbiA9ICIwLjMuOSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1YzgzOWE2NzRmY2Q3YTk4OTUyZTU5MzI0MmVhNDAwYWJlOTM5OTI3NDY3NjFlMzg2NDE0MDVkMjhiMDBmNDE5IgpkZXBlbmRlbmNpZXMgPSBbCiAid2luYXBpLWk2ODYtcGMtd2luZG93cy1nbnUiLAogIndpbmFwaS14ODZfNjQtcGMtd2luZG93cy1nbnUiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIndpbmFwaS1pNjg2LXBjLXdpbmRvd3MtZ251Igp2ZXJzaW9uID0gIjAuNC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImFjM2I4N2M2MzYyMDQyNmRkOWI5OTFlNWNlMDMyOWVmZjU0NWJjY2JiYjM0ZjNiZTA5ZmY2ZmI2YWI1MWI3YjYiCgpbW3BhY2thZ2VdXQpuYW1lID0gIndpbmFwaS14ODZfNjQtcGMtd2luZG93cy1nbnUiCnZlcnNpb24gPSAiMC40LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNzEyZTIyNzg0MWQwNTdjMWVlMWNkMmZiMjJmYTdlNWE1NDYxYWU4ZTQ4ZmEyY2E3OWVjNDJjZmMxOTMxMTgzZiIKCltbcGFja2FnZV1dCm5hbWUgPSAiemVyb2l6ZSIKdmVyc2lvbiA9ICIxLjMuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI0NzU2ZjdkYjNmN2I1NTc0OTM4YzNlYjFjMTE3MDM4YjhlMDdmOTVlZTY3MThjMGVmYWQ0YWMyMTUwOGYxZWZkIgpkZXBlbmRlbmNpZXMgPSBbCiAiemVyb2l6ZV9kZXJpdmUiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInplcm9pemVfZGVyaXZlIgp2ZXJzaW9uID0gIjEuMy4zIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjQ0YmYwN2NiM2U1MGVhMjAwMzM5NjY5NWQ1OGJmNDZiYzk4ODdhMWYzNjIyNjA0NDZmYWQ2YmM0ZTc5YmQzNmMiCmRlcGVuZGVuY2llcyA9IFsKICJwcm9jLW1hY3JvMiIsCiAicXVvdGUiLAogInN5biIsCiAic3luc3RydWN0dXJlIiwKXQo=" + "path": "wasm/Cargo.toml", + "content": "W3BhY2thZ2VdCm5hbWUgPSAiYWRkZXItd2FzbSIKdmVyc2lvbiA9ICIxLjIuMyIKYXV0aG9ycyA9IFsieW91Il0KZWRpdGlvbiA9ICIyMDE4IgpwdWJsaXNoID0gZmFsc2UKCltsaWJdCmNyYXRlLXR5cGUgPSBbImNkeWxpYiJdCgpbcHJvZmlsZS5yZWxlYXNlXQpjb2RlZ2VuLXVuaXRzID0gMQpvcHQtbGV2ZWwgPSAieiIKbHRvID0gdHJ1ZQpkZWJ1ZyA9IGZhbHNlCnBhbmljID0gImFib3J0IgoKW2RlcGVuZGVuY2llcy5hZGRlcl0KcGF0aCA9ICIuLiIKCltkZXBlbmRlbmNpZXMuZWxyb25kLXdhc20tbm9kZV0KdmVyc2lvbiA9ICIwLjM2LjEiCgpbZGVwZW5kZW5jaWVzLmVscm9uZC13YXNtLW91dHB1dF0KdmVyc2lvbiA9ICIwLjM2LjEiCmZlYXR1cmVzID0gWyJ3YXNtLW91dHB1dC1tb2RlIl0KClt3b3Jrc3BhY2VdCm1lbWJlcnMgPSBbIi4iXQo=" }, { - "path": "meta/src/main.rs", - "content": "Zm4gbWFpbigpIHsKICAgIGVscm9uZF93YXNtX2RlYnVnOjptZXRhOjpwZXJmb3JtOjo8YWRkZXI6OkFiaVByb3ZpZGVyPigpOwp9Cg==" + "path": "wasm/src/lib.rs", + "content": "Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLy8vLy8vLy8vLy8vLy8vLy8gQVVUTy1HRU5FUkFURUQgLy8vLy8vLy8vLy8vLy8vLy8vCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCiMhW25vX3N0ZF0KCmVscm9uZF93YXNtX25vZGU6Ondhc21fZW5kcG9pbnRzISB7CiAgICBhZGRlcgogICAgKAogICAgICAgIGFkZAogICAgICAgIGdldFN1bQogICAgKQp9CgplbHJvbmRfd2FzbV9ub2RlOjp3YXNtX2VtcHR5X2NhbGxiYWNrISB7fQo=" } ] } diff --git a/testdata/expected/empty-4.5.6.source.json b/testdata/expected/empty-4.5.6.source.json index b2c9109..e3c84d0 100644 --- a/testdata/expected/empty-4.5.6.source.json +++ b/testdata/expected/empty-4.5.6.source.json @@ -11,32 +11,28 @@ "content": "ewogICAgImxhbmd1YWdlIjogInJ1c3QiCn0=" }, { - "path": "src/empty.rs", - "content": "IyFbbm9fc3RkXQoKZWxyb25kX3dhc206OmltcG9ydHMhKCk7CgovLy8gQW4gZW1wdHkgY29udHJhY3QuIFRvIGJlIHVzZWQgYXMgYSB0ZW1wbGF0ZSB3aGVuIHN0YXJ0aW5nIGEgbmV3IGNvbnRyYWN0IGZyb20gc2NyYXRjaC4KI1tlbHJvbmRfd2FzbTo6Y29udHJhY3RdCnB1YiB0cmFpdCBFbXB0eUNvbnRyYWN0IHsKICAgICNbaW5pdF0KICAgIGZuIGluaXQoJnNlbGYpIHt9Cn0K" - }, - { - "path": "wasm/Cargo.toml", - "content": "W3BhY2thZ2VdCm5hbWUgPSAiZW1wdHktd2FzbSIKdmVyc2lvbiA9ICI0LjUuNiIKZWRpdGlvbiA9ICIyMDE4IgpwdWJsaXNoID0gZmFsc2UKCltsaWJdCmNyYXRlLXR5cGUgPSBbImNkeWxpYiJdCgpbcHJvZmlsZS5yZWxlYXNlXQpjb2RlZ2VuLXVuaXRzID0gMQpvcHQtbGV2ZWwgPSAieiIKbHRvID0gdHJ1ZQpkZWJ1ZyA9IGZhbHNlCnBhbmljID0gImFib3J0IgoKW2RlcGVuZGVuY2llcy5lbXB0eV0KcGF0aCA9ICIuLiIKCltkZXBlbmRlbmNpZXMuZWxyb25kLXdhc20tbm9kZV0KdmVyc2lvbiA9ICIwLjM2LjEiCgpbZGVwZW5kZW5jaWVzLmVscm9uZC13YXNtLW91dHB1dF0KdmVyc2lvbiA9ICIwLjM2LjEiCmZlYXR1cmVzID0gWyJ3YXNtLW91dHB1dC1tb2RlIl0KClt3b3Jrc3BhY2VdCm1lbWJlcnMgPSBbIi4iXQo=" + "path": "meta/Cargo.toml", + "content": "W3BhY2thZ2VdCm5hbWUgPSAiZW1wdHktbWV0YSIKdmVyc2lvbiA9ICIwLjAuMCIKZWRpdGlvbiA9ICIyMDE4IgpwdWJsaXNoID0gZmFsc2UKCltkZXBlbmRlbmNpZXMuZW1wdHldCnBhdGggPSAiLi4iCgpbZGVwZW5kZW5jaWVzLmVscm9uZC13YXNtLWRlYnVnXQp2ZXJzaW9uID0gIjAuMzYuMSIK" }, { - "path": "wasm/Cargo.lock", - "content": "IyBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSBAZ2VuZXJhdGVkIGJ5IENhcmdvLgojIEl0IGlzIG5vdCBpbnRlbmRlZCBmb3IgbWFudWFsIGVkaXRpbmcuCnZlcnNpb24gPSAzCgpbW3BhY2thZ2VdXQpuYW1lID0gImFoYXNoIgp2ZXJzaW9uID0gIjAuNy40Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjQzYmI4MzNmMGJmOTc5ZDg0NzVkMzhmYmYwOWVkM2I4YTU1ZTE4ODVmZTkzYWQzZjkzMjM5ZmM2YTRmMTdiOTgiCmRlcGVuZGVuY2llcyA9IFsKICJnZXRyYW5kb20iLAogIm9uY2VfY2VsbCIsCiAidmVyc2lvbl9jaGVjayIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiYXJyYXl2ZWMiCnZlcnNpb24gPSAiMC43LjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYmU0ZGMwNzEzMWZmYTY5YjgwNzJkMzVmNTAwNzM1MmFmOTQ0MjEzY2RlMDI1NDVlMjEwMzY4MGJhZWQzOGZjZCIKCltbcGFja2FnZV1dCm5hbWUgPSAiYXV0b2NmZyIKdmVyc2lvbiA9ICIxLjEuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJkNDY4ODAyYmFiMTdjYmMwY2M1NzVlOWIwNTNmNDFlNzJhYTM2YmZhNmI3ZjU1ZTM1MjlmZmE0MzE2MWI5N2ZhIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJiaXRmbGFncyIKdmVyc2lvbiA9ICIxLjMuMiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJiZWYzOGQ0NTE2M2MyZjFkZGUwOTRhN2RmZDMzY2NmNTk1YzkyOTA1YzhmOGY0ZmRjMThkMDZmYjEwMzc3MThhIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJjZmctaWYiCnZlcnNpb24gPSAiMC4xLjEwIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjQ3ODViZGQxYzk2YjJhODQ2YjJiZDdjYzAyZTg2YjZiM2RiZjE0ZTdlNTM0NDZjNGY1NGM5MmEzNjEwNDA4MjIiCgpbW3BhY2thZ2VdXQpuYW1lID0gImNmZy1pZiIKdmVyc2lvbiA9ICIxLjAuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJiYWYxZGU0MzM5NzYxNTg4YmMwNjE5ZTNjYmMwMTIwZWU1ODJlYmI3NGI1M2I0ZWZiZjc5MTE3YmQyZGE0MGZkIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbHJvbmQtY29kZWMiCnZlcnNpb24gPSAiMC4xNC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjJjODVjNTk1MTg2NGRkNDgxNmUxZGYyY2VhY2NiMGYyMmM2NGZmMTE3ZGRjZGUxZjUzMzUxYWNlNGQ3ODVjNDciCmRlcGVuZGVuY2llcyA9IFsKICJhcnJheXZlYyIsCiAiZWxyb25kLWNvZGVjLWRlcml2ZSIsCiAid2VlX2FsbG9jIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbHJvbmQtY29kZWMtZGVyaXZlIgp2ZXJzaW9uID0gIjAuMTQuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIyYTg5ODdhN2Y1MDZhZTViMzUyYWQ3YWMyOGZiMTNiOWY2MDAzNTVjOGI4OGE0NDQ4ODFmODZiYzU2NWM3NWNmIgpkZXBlbmRlbmNpZXMgPSBbCiAiaGV4IiwKICJwcm9jLW1hY3JvMiIsCiAicXVvdGUiLAogInN5biIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZWxyb25kLXdhc20iCnZlcnNpb24gPSAiMC4zNi4xIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjlmZjdkZDEwZjRhNzEzM2EyYzZmZWIzZjc5ZTA0OTUzZjlhM2MxZWRhOWY4NDQ0YjQzYzEzMDBmMzAyZTAyZmQiCmRlcGVuZGVuY2llcyA9IFsKICJiaXRmbGFncyIsCiAiZWxyb25kLWNvZGVjIiwKICJlbHJvbmQtd2FzbS1kZXJpdmUiLAogImdpdC12ZXJzaW9uIiwKICJoYXNoYnJvd24iLAogImhleC1saXRlcmFsIiwKICJudW0tdHJhaXRzIiwKICJ3ZWVfYWxsb2MiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImVscm9uZC13YXNtLWRlcml2ZSIKdmVyc2lvbiA9ICIwLjM2LjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNjAzNTg5ODkxNjNhZTFjMjhiNzlkN2M2ODc4Njk4NzRjNzY1MDAxYmJkZmExMmEzMWRmZDkyMDM1MGJjN2EyMiIKZGVwZW5kZW5jaWVzID0gWwogImhleCIsCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJyYWRpeF90cmllIiwKICJzeW4iLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImVscm9uZC13YXNtLW5vZGUiCnZlcnNpb24gPSAiMC4zNi4xIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjRjYjRkNGMxYWNlZDk2N2Y4NmRiYzJhMGEwMTkxMGQxZWJiMTBjZWFiNDU5Y2I0YTNkN2QyZTQzYjRkZjJmOWIiCmRlcGVuZGVuY2llcyA9IFsKICJlbHJvbmQtd2FzbSIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZWxyb25kLXdhc20tb3V0cHV0Igp2ZXJzaW9uID0gIjAuMzYuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIzMmE4YzAyNTE1ZTQzZWY3ZmRhMGM3NGNjNGEwYTRkMzUzODQ2YWY5OTljYzgwMmMyMzA2YzM0ZmQ3MGNkYTExIgpkZXBlbmRlbmNpZXMgPSBbCiAiZWxyb25kLXdhc20tbm9kZSIsCiAid2VlX2FsbG9jIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbXB0eSIKdmVyc2lvbiA9ICI0LjUuNiIKZGVwZW5kZW5jaWVzID0gWwogImVscm9uZC13YXNtIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbXB0eS13YXNtIgp2ZXJzaW9uID0gIjQuNS42IgpkZXBlbmRlbmNpZXMgPSBbCiAiZWxyb25kLXdhc20tbm9kZSIsCiAiZWxyb25kLXdhc20tb3V0cHV0IiwKICJlbXB0eSIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZW5kaWFuLXR5cGUiCnZlcnNpb24gPSAiMC4xLjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYzM0ZjA0NjY2ZDgzNWZmNWQ2MmUwNThjMzk5NTE0N2MwNmY0MmZlODZmZjA1MzMzNzYzMmJjYTgzZTQyNzAyZCIKCltbcGFja2FnZV1dCm5hbWUgPSAiZ2V0cmFuZG9tIgp2ZXJzaW9uID0gIjAuMi4zIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjdmY2Q5OTk0NjM1MjRjNTI2NTk1MTdmZTJjZWE5ODQ5M2NmZTQ4NWQxMDU2NWU3YjBmYjA3ZGJiYTdhZDI3NTMiCmRlcGVuZGVuY2llcyA9IFsKICJjZmctaWYgMS4wLjAiLAogImxpYmMiLAogIndhc2kiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImdpdC12ZXJzaW9uIgp2ZXJzaW9uID0gIjAuMy41Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImY2YjBkZWNjMDJmNDYzNmI5Y2NhZDM5MGRjYmU3N2I3MjJhNzdlZmVkZmEzOTNjYWY4Mzc5YTUxZDVjNjE4OTkiCmRlcGVuZGVuY2llcyA9IFsKICJnaXQtdmVyc2lvbi1tYWNybyIsCiAicHJvYy1tYWNyby1oYWNrIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJnaXQtdmVyc2lvbi1tYWNybyIKdmVyc2lvbiA9ICIwLjMuNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJmZTY5ZjFjYmRiNmUyOGFmMmJhYzIxNGU5NDNiOTljZThhMGEwNmI0NDdkMTVkM2U2MTE2MWIwNDIzMTM5ZjNmIgpkZXBlbmRlbmNpZXMgPSBbCiAicHJvYy1tYWNyby1oYWNrIiwKICJwcm9jLW1hY3JvMiIsCiAicXVvdGUiLAogInN5biIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiaGFzaGJyb3duIgp2ZXJzaW9uID0gIjAuMTEuMiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJhYjVlZjBkNDkwOWVmMzcyNGNjOGNjZTZjY2M4NTcyYzVjODE3NTkyZTkyODVmNTQ2NGY4ZTg2ZjhiZDM3MjZlIgpkZXBlbmRlbmNpZXMgPSBbCiAiYWhhc2giLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImhleCIKdmVyc2lvbiA9ICIwLjQuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI3ZjI0MjU0YWE5YTU0YjVjODU4ZWFlZTJmNWJjY2RiNDZhYWYwZTQ4NmE1OTVlZDVmZDhmODZiYTU1MjMyYTcwIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJoZXgtbGl0ZXJhbCIKdmVyc2lvbiA9ICIwLjMuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1YWYxZjYzNWVmMWJjNTQ1ZDc4MzkyYjEzNmJmZTFjOTgwOWUwMjkwMjNjODRhMzYzOGE4NjRhMTBiODgxOWM4IgoKW1twYWNrYWdlXV0KbmFtZSA9ICJsaWJjIgp2ZXJzaW9uID0gIjAuMi44MSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIxNDgyODIxMzA2MTY5ZWM0ZDA3ZjZhY2EzOTJhNDY4MWY2NmM3NWM5OTE4YWE0OTY0MWEyNTk1ZGI2NDA1M2NiIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJtZW1vcnlfdW5pdHMiCnZlcnNpb24gPSAiMC40LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiODQ1MjEwNWJhMDQ3MDY4ZjQwZmY3MDkzZGQxZDlkYTkwODk4ZTYzZGQ2MTczNjQ2MmU5Y2RkYTZhOTBhZDNjMyIKCltbcGFja2FnZV1dCm5hbWUgPSAibmliYmxlX3ZlYyIKdmVyc2lvbiA9ICIwLjAuNCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJjOGQ3N2YzZGI0YmNlMDMzZjRkMDRkYjA4MDc5YjJlZjFjM2QwMmI0NGU4NmYyNWQwODg4NmZhZmE3NzU2ZmZhIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJudW0tdHJhaXRzIgp2ZXJzaW9uID0gIjAuMi4xNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1NzhlZGUzNGNmMDJmODkyNGFiOTQ0N2Y1MGMyODA3NWI0ZDNlNWIyNjk5NzIzNDVlN2UwMzcyYjM4YzZjZGNkIgpkZXBlbmRlbmNpZXMgPSBbCiAiYXV0b2NmZyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAib25jZV9jZWxsIgp2ZXJzaW9uID0gIjEuOC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjY5MmZjYjYzYjY0YjE3NTgwMjllMGE5NmVlNjNlMDQ5Y2U4YzU5NDg1ODdmMmY3MjA4ZGYwNDYyNWU1ZjZiNTYiCgpbW3BhY2thZ2VdXQpuYW1lID0gInByb2MtbWFjcm8taGFjayIKdmVyc2lvbiA9ICIwLjUuMTkiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZGJmMGM0OGJjMWQ5MTM3NWFlNWMzY2Q4MWUzNzIyZGZmMWFiY2Y4MWEzMDk2MDI0MDY0MGQyMjNmNTlmZTBlNSIKCltbcGFja2FnZV1dCm5hbWUgPSAicHJvYy1tYWNybzIiCnZlcnNpb24gPSAiMS4wLjI0Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjFlMDcwNGVlMWE3ZTAwZDdiYjQxN2QwNzcwZWEzMDNjMWJjY2JhYmYwZWYxNjY3ZGFlOTJiNTk2N2Y1ZjhhNzEiCmRlcGVuZGVuY2llcyA9IFsKICJ1bmljb2RlLXhpZCIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicXVvdGUiCnZlcnNpb24gPSAiMS4wLjgiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiOTkxNDMxYzM1MTlhM2YzNjg2MTg4MmRhOTM2MzBjZTY2YjUyOTE4ZGNmMWI4ZTJmZDY2YjM5N2ZjOTZmMjhkZiIKZGVwZW5kZW5jaWVzID0gWwogInByb2MtbWFjcm8yIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJyYWRpeF90cmllIgp2ZXJzaW9uID0gIjAuMS42Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjNkMzY4MWIyOGNkOTVhY2ZiMDU2MGVhOTQ0MWY4MmQ2YTQ1MDRmYTNiMTViOTdiZDdiNmU5NTIxMzE4MjBlOTUiCmRlcGVuZGVuY2llcyA9IFsKICJlbmRpYW4tdHlwZSIsCiAibmliYmxlX3ZlYyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAic3luIgp2ZXJzaW9uID0gIjEuMC42NyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI2NDk4YTllZmMzNDI4NzFmOTFjYzJkMGQ2OTRjNjc0MzY4YjRjZWI0MGY2MmI2NWE3YTA4YzM3OTI5MzVlNzAyIgpkZXBlbmRlbmNpZXMgPSBbCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJ1bmljb2RlLXhpZCIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAidW5pY29kZS14aWQiCnZlcnNpb24gPSAiMC4yLjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZjdmZTBiYjM0Nzk2NTE0MzljOTExMmY3MmI2YzUwNTAzODU3NGM5ZmJiNTc1ZWQxYmYzYjc5N2ZhMzlkZDU2NCIKCltbcGFja2FnZV1dCm5hbWUgPSAidmVyc2lvbl9jaGVjayIKdmVyc2lvbiA9ICIwLjkuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1ZmVjZGNhOWE1MjkxY2MyYjhkY2Y3ZGMwMjQ1M2ZlZTc5MWEyODBmMzc0M2NiMDkwNWY4ODIyYWU0NjNiM2ZlIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJ3YXNpIgp2ZXJzaW9uID0gIjAuMTAuMit3YXNpLXNuYXBzaG90LXByZXZpZXcxIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImZkNmZiZDlhNzk4MjlkZDFhZDBjYzIwNjI3YmYxZWQ2MDY3NTZhN2Y3N2VkZmY3YjY2YjcwNjRmOWNiMzI3YzYiCgpbW3BhY2thZ2VdXQpuYW1lID0gIndlZV9hbGxvYyIKdmVyc2lvbiA9ICIwLjQuNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJkYmIzYjVhNmIyYmIxN2NiNmFkNDRhMmU2OGE0M2U4ZDI3MjJjOTk3ZGExMGU5Mjg2NjVjNzJlYzZjMGEwYjhlIgpkZXBlbmRlbmNpZXMgPSBbCiAiY2ZnLWlmIDAuMS4xMCIsCiAibGliYyIsCiAibWVtb3J5X3VuaXRzIiwKICJ3aW5hcGkiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIndpbmFwaSIKdmVyc2lvbiA9ICIwLjMuOSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1YzgzOWE2NzRmY2Q3YTk4OTUyZTU5MzI0MmVhNDAwYWJlOTM5OTI3NDY3NjFlMzg2NDE0MDVkMjhiMDBmNDE5IgpkZXBlbmRlbmNpZXMgPSBbCiAid2luYXBpLWk2ODYtcGMtd2luZG93cy1nbnUiLAogIndpbmFwaS14ODZfNjQtcGMtd2luZG93cy1nbnUiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIndpbmFwaS1pNjg2LXBjLXdpbmRvd3MtZ251Igp2ZXJzaW9uID0gIjAuNC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImFjM2I4N2M2MzYyMDQyNmRkOWI5OTFlNWNlMDMyOWVmZjU0NWJjY2JiYjM0ZjNiZTA5ZmY2ZmI2YWI1MWI3YjYiCgpbW3BhY2thZ2VdXQpuYW1lID0gIndpbmFwaS14ODZfNjQtcGMtd2luZG93cy1nbnUiCnZlcnNpb24gPSAiMC40LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNzEyZTIyNzg0MWQwNTdjMWVlMWNkMmZiMjJmYTdlNWE1NDYxYWU4ZTQ4ZmEyY2E3OWVjNDJjZmMxOTMxMTgzZiIK" + "path": "meta/src/main.rs", + "content": "Zm4gbWFpbigpIHsKICAgIGVscm9uZF93YXNtX2RlYnVnOjptZXRhOjpwZXJmb3JtOjo8ZW1wdHk6OkFiaVByb3ZpZGVyPigpOwp9Cg==" }, { - "path": "wasm/src/lib.rs", - "content": "Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLy8vLy8vLy8vLy8vLy8vLy8gQVVUTy1HRU5FUkFURUQgLy8vLy8vLy8vLy8vLy8vLy8vCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCiMhW25vX3N0ZF0KCmVscm9uZF93YXNtX25vZGU6Ondhc21fZW5kcG9pbnRzISB7CiAgICBlbXB0eQogICAgKAogICAgKQp9CgplbHJvbmRfd2FzbV9ub2RlOjp3YXNtX2VtcHR5X2NhbGxiYWNrISB7fQo=" + "path": "src/empty.rs", + "content": "IyFbbm9fc3RkXQoKZWxyb25kX3dhc206OmltcG9ydHMhKCk7CgovLy8gQW4gZW1wdHkgY29udHJhY3QuIFRvIGJlIHVzZWQgYXMgYSB0ZW1wbGF0ZSB3aGVuIHN0YXJ0aW5nIGEgbmV3IGNvbnRyYWN0IGZyb20gc2NyYXRjaC4KI1tlbHJvbmRfd2FzbTo6Y29udHJhY3RdCnB1YiB0cmFpdCBFbXB0eUNvbnRyYWN0IHsKICAgICNbaW5pdF0KICAgIGZuIGluaXQoJnNlbGYpIHt9Cn0K" }, { - "path": "meta/Cargo.toml", - "content": "W3BhY2thZ2VdCm5hbWUgPSAiZW1wdHktbWV0YSIKdmVyc2lvbiA9ICIwLjAuMCIKZWRpdGlvbiA9ICIyMDE4IgpwdWJsaXNoID0gZmFsc2UKCltkZXBlbmRlbmNpZXMuZW1wdHldCnBhdGggPSAiLi4iCgpbZGVwZW5kZW5jaWVzLmVscm9uZC13YXNtLWRlYnVnXQp2ZXJzaW9uID0gIjAuMzYuMSIK" + "path": "wasm/Cargo.lock", + "content": "IyBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSBAZ2VuZXJhdGVkIGJ5IENhcmdvLgojIEl0IGlzIG5vdCBpbnRlbmRlZCBmb3IgbWFudWFsIGVkaXRpbmcuCnZlcnNpb24gPSAzCgpbW3BhY2thZ2VdXQpuYW1lID0gImFoYXNoIgp2ZXJzaW9uID0gIjAuNy40Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjQzYmI4MzNmMGJmOTc5ZDg0NzVkMzhmYmYwOWVkM2I4YTU1ZTE4ODVmZTkzYWQzZjkzMjM5ZmM2YTRmMTdiOTgiCmRlcGVuZGVuY2llcyA9IFsKICJnZXRyYW5kb20iLAogIm9uY2VfY2VsbCIsCiAidmVyc2lvbl9jaGVjayIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiYXJyYXl2ZWMiCnZlcnNpb24gPSAiMC43LjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYmU0ZGMwNzEzMWZmYTY5YjgwNzJkMzVmNTAwNzM1MmFmOTQ0MjEzY2RlMDI1NDVlMjEwMzY4MGJhZWQzOGZjZCIKCltbcGFja2FnZV1dCm5hbWUgPSAiYXV0b2NmZyIKdmVyc2lvbiA9ICIxLjEuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJkNDY4ODAyYmFiMTdjYmMwY2M1NzVlOWIwNTNmNDFlNzJhYTM2YmZhNmI3ZjU1ZTM1MjlmZmE0MzE2MWI5N2ZhIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJiaXRmbGFncyIKdmVyc2lvbiA9ICIxLjMuMiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJiZWYzOGQ0NTE2M2MyZjFkZGUwOTRhN2RmZDMzY2NmNTk1YzkyOTA1YzhmOGY0ZmRjMThkMDZmYjEwMzc3MThhIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJjZmctaWYiCnZlcnNpb24gPSAiMC4xLjEwIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjQ3ODViZGQxYzk2YjJhODQ2YjJiZDdjYzAyZTg2YjZiM2RiZjE0ZTdlNTM0NDZjNGY1NGM5MmEzNjEwNDA4MjIiCgpbW3BhY2thZ2VdXQpuYW1lID0gImNmZy1pZiIKdmVyc2lvbiA9ICIxLjAuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJiYWYxZGU0MzM5NzYxNTg4YmMwNjE5ZTNjYmMwMTIwZWU1ODJlYmI3NGI1M2I0ZWZiZjc5MTE3YmQyZGE0MGZkIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbHJvbmQtY29kZWMiCnZlcnNpb24gPSAiMC4xNC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjJjODVjNTk1MTg2NGRkNDgxNmUxZGYyY2VhY2NiMGYyMmM2NGZmMTE3ZGRjZGUxZjUzMzUxYWNlNGQ3ODVjNDciCmRlcGVuZGVuY2llcyA9IFsKICJhcnJheXZlYyIsCiAiZWxyb25kLWNvZGVjLWRlcml2ZSIsCiAid2VlX2FsbG9jIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbHJvbmQtY29kZWMtZGVyaXZlIgp2ZXJzaW9uID0gIjAuMTQuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIyYTg5ODdhN2Y1MDZhZTViMzUyYWQ3YWMyOGZiMTNiOWY2MDAzNTVjOGI4OGE0NDQ4ODFmODZiYzU2NWM3NWNmIgpkZXBlbmRlbmNpZXMgPSBbCiAiaGV4IiwKICJwcm9jLW1hY3JvMiIsCiAicXVvdGUiLAogInN5biIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZWxyb25kLXdhc20iCnZlcnNpb24gPSAiMC4zNi4xIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjlmZjdkZDEwZjRhNzEzM2EyYzZmZWIzZjc5ZTA0OTUzZjlhM2MxZWRhOWY4NDQ0YjQzYzEzMDBmMzAyZTAyZmQiCmRlcGVuZGVuY2llcyA9IFsKICJiaXRmbGFncyIsCiAiZWxyb25kLWNvZGVjIiwKICJlbHJvbmQtd2FzbS1kZXJpdmUiLAogImdpdC12ZXJzaW9uIiwKICJoYXNoYnJvd24iLAogImhleC1saXRlcmFsIiwKICJudW0tdHJhaXRzIiwKICJ3ZWVfYWxsb2MiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImVscm9uZC13YXNtLWRlcml2ZSIKdmVyc2lvbiA9ICIwLjM2LjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNjAzNTg5ODkxNjNhZTFjMjhiNzlkN2M2ODc4Njk4NzRjNzY1MDAxYmJkZmExMmEzMWRmZDkyMDM1MGJjN2EyMiIKZGVwZW5kZW5jaWVzID0gWwogImhleCIsCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJyYWRpeF90cmllIiwKICJzeW4iLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImVscm9uZC13YXNtLW5vZGUiCnZlcnNpb24gPSAiMC4zNi4xIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjRjYjRkNGMxYWNlZDk2N2Y4NmRiYzJhMGEwMTkxMGQxZWJiMTBjZWFiNDU5Y2I0YTNkN2QyZTQzYjRkZjJmOWIiCmRlcGVuZGVuY2llcyA9IFsKICJlbHJvbmQtd2FzbSIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZWxyb25kLXdhc20tb3V0cHV0Igp2ZXJzaW9uID0gIjAuMzYuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIzMmE4YzAyNTE1ZTQzZWY3ZmRhMGM3NGNjNGEwYTRkMzUzODQ2YWY5OTljYzgwMmMyMzA2YzM0ZmQ3MGNkYTExIgpkZXBlbmRlbmNpZXMgPSBbCiAiZWxyb25kLXdhc20tbm9kZSIsCiAid2VlX2FsbG9jIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbXB0eSIKdmVyc2lvbiA9ICI0LjUuNiIKZGVwZW5kZW5jaWVzID0gWwogImVscm9uZC13YXNtIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbXB0eS13YXNtIgp2ZXJzaW9uID0gIjQuNS42IgpkZXBlbmRlbmNpZXMgPSBbCiAiZWxyb25kLXdhc20tbm9kZSIsCiAiZWxyb25kLXdhc20tb3V0cHV0IiwKICJlbXB0eSIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZW5kaWFuLXR5cGUiCnZlcnNpb24gPSAiMC4xLjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYzM0ZjA0NjY2ZDgzNWZmNWQ2MmUwNThjMzk5NTE0N2MwNmY0MmZlODZmZjA1MzMzNzYzMmJjYTgzZTQyNzAyZCIKCltbcGFja2FnZV1dCm5hbWUgPSAiZ2V0cmFuZG9tIgp2ZXJzaW9uID0gIjAuMi4zIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjdmY2Q5OTk0NjM1MjRjNTI2NTk1MTdmZTJjZWE5ODQ5M2NmZTQ4NWQxMDU2NWU3YjBmYjA3ZGJiYTdhZDI3NTMiCmRlcGVuZGVuY2llcyA9IFsKICJjZmctaWYgMS4wLjAiLAogImxpYmMiLAogIndhc2kiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImdpdC12ZXJzaW9uIgp2ZXJzaW9uID0gIjAuMy41Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImY2YjBkZWNjMDJmNDYzNmI5Y2NhZDM5MGRjYmU3N2I3MjJhNzdlZmVkZmEzOTNjYWY4Mzc5YTUxZDVjNjE4OTkiCmRlcGVuZGVuY2llcyA9IFsKICJnaXQtdmVyc2lvbi1tYWNybyIsCiAicHJvYy1tYWNyby1oYWNrIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJnaXQtdmVyc2lvbi1tYWNybyIKdmVyc2lvbiA9ICIwLjMuNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJmZTY5ZjFjYmRiNmUyOGFmMmJhYzIxNGU5NDNiOTljZThhMGEwNmI0NDdkMTVkM2U2MTE2MWIwNDIzMTM5ZjNmIgpkZXBlbmRlbmNpZXMgPSBbCiAicHJvYy1tYWNyby1oYWNrIiwKICJwcm9jLW1hY3JvMiIsCiAicXVvdGUiLAogInN5biIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiaGFzaGJyb3duIgp2ZXJzaW9uID0gIjAuMTEuMiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJhYjVlZjBkNDkwOWVmMzcyNGNjOGNjZTZjY2M4NTcyYzVjODE3NTkyZTkyODVmNTQ2NGY4ZTg2ZjhiZDM3MjZlIgpkZXBlbmRlbmNpZXMgPSBbCiAiYWhhc2giLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImhleCIKdmVyc2lvbiA9ICIwLjQuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI3ZjI0MjU0YWE5YTU0YjVjODU4ZWFlZTJmNWJjY2RiNDZhYWYwZTQ4NmE1OTVlZDVmZDhmODZiYTU1MjMyYTcwIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJoZXgtbGl0ZXJhbCIKdmVyc2lvbiA9ICIwLjMuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1YWYxZjYzNWVmMWJjNTQ1ZDc4MzkyYjEzNmJmZTFjOTgwOWUwMjkwMjNjODRhMzYzOGE4NjRhMTBiODgxOWM4IgoKW1twYWNrYWdlXV0KbmFtZSA9ICJsaWJjIgp2ZXJzaW9uID0gIjAuMi44MSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIxNDgyODIxMzA2MTY5ZWM0ZDA3ZjZhY2EzOTJhNDY4MWY2NmM3NWM5OTE4YWE0OTY0MWEyNTk1ZGI2NDA1M2NiIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJtZW1vcnlfdW5pdHMiCnZlcnNpb24gPSAiMC40LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiODQ1MjEwNWJhMDQ3MDY4ZjQwZmY3MDkzZGQxZDlkYTkwODk4ZTYzZGQ2MTczNjQ2MmU5Y2RkYTZhOTBhZDNjMyIKCltbcGFja2FnZV1dCm5hbWUgPSAibmliYmxlX3ZlYyIKdmVyc2lvbiA9ICIwLjAuNCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJjOGQ3N2YzZGI0YmNlMDMzZjRkMDRkYjA4MDc5YjJlZjFjM2QwMmI0NGU4NmYyNWQwODg4NmZhZmE3NzU2ZmZhIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJudW0tdHJhaXRzIgp2ZXJzaW9uID0gIjAuMi4xNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1NzhlZGUzNGNmMDJmODkyNGFiOTQ0N2Y1MGMyODA3NWI0ZDNlNWIyNjk5NzIzNDVlN2UwMzcyYjM4YzZjZGNkIgpkZXBlbmRlbmNpZXMgPSBbCiAiYXV0b2NmZyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAib25jZV9jZWxsIgp2ZXJzaW9uID0gIjEuOC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjY5MmZjYjYzYjY0YjE3NTgwMjllMGE5NmVlNjNlMDQ5Y2U4YzU5NDg1ODdmMmY3MjA4ZGYwNDYyNWU1ZjZiNTYiCgpbW3BhY2thZ2VdXQpuYW1lID0gInByb2MtbWFjcm8taGFjayIKdmVyc2lvbiA9ICIwLjUuMTkiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZGJmMGM0OGJjMWQ5MTM3NWFlNWMzY2Q4MWUzNzIyZGZmMWFiY2Y4MWEzMDk2MDI0MDY0MGQyMjNmNTlmZTBlNSIKCltbcGFja2FnZV1dCm5hbWUgPSAicHJvYy1tYWNybzIiCnZlcnNpb24gPSAiMS4wLjI0Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjFlMDcwNGVlMWE3ZTAwZDdiYjQxN2QwNzcwZWEzMDNjMWJjY2JhYmYwZWYxNjY3ZGFlOTJiNTk2N2Y1ZjhhNzEiCmRlcGVuZGVuY2llcyA9IFsKICJ1bmljb2RlLXhpZCIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicXVvdGUiCnZlcnNpb24gPSAiMS4wLjgiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiOTkxNDMxYzM1MTlhM2YzNjg2MTg4MmRhOTM2MzBjZTY2YjUyOTE4ZGNmMWI4ZTJmZDY2YjM5N2ZjOTZmMjhkZiIKZGVwZW5kZW5jaWVzID0gWwogInByb2MtbWFjcm8yIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJyYWRpeF90cmllIgp2ZXJzaW9uID0gIjAuMS42Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjNkMzY4MWIyOGNkOTVhY2ZiMDU2MGVhOTQ0MWY4MmQ2YTQ1MDRmYTNiMTViOTdiZDdiNmU5NTIxMzE4MjBlOTUiCmRlcGVuZGVuY2llcyA9IFsKICJlbmRpYW4tdHlwZSIsCiAibmliYmxlX3ZlYyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAic3luIgp2ZXJzaW9uID0gIjEuMC42NyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI2NDk4YTllZmMzNDI4NzFmOTFjYzJkMGQ2OTRjNjc0MzY4YjRjZWI0MGY2MmI2NWE3YTA4YzM3OTI5MzVlNzAyIgpkZXBlbmRlbmNpZXMgPSBbCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJ1bmljb2RlLXhpZCIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAidW5pY29kZS14aWQiCnZlcnNpb24gPSAiMC4yLjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZjdmZTBiYjM0Nzk2NTE0MzljOTExMmY3MmI2YzUwNTAzODU3NGM5ZmJiNTc1ZWQxYmYzYjc5N2ZhMzlkZDU2NCIKCltbcGFja2FnZV1dCm5hbWUgPSAidmVyc2lvbl9jaGVjayIKdmVyc2lvbiA9ICIwLjkuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1ZmVjZGNhOWE1MjkxY2MyYjhkY2Y3ZGMwMjQ1M2ZlZTc5MWEyODBmMzc0M2NiMDkwNWY4ODIyYWU0NjNiM2ZlIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJ3YXNpIgp2ZXJzaW9uID0gIjAuMTAuMit3YXNpLXNuYXBzaG90LXByZXZpZXcxIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImZkNmZiZDlhNzk4MjlkZDFhZDBjYzIwNjI3YmYxZWQ2MDY3NTZhN2Y3N2VkZmY3YjY2YjcwNjRmOWNiMzI3YzYiCgpbW3BhY2thZ2VdXQpuYW1lID0gIndlZV9hbGxvYyIKdmVyc2lvbiA9ICIwLjQuNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJkYmIzYjVhNmIyYmIxN2NiNmFkNDRhMmU2OGE0M2U4ZDI3MjJjOTk3ZGExMGU5Mjg2NjVjNzJlYzZjMGEwYjhlIgpkZXBlbmRlbmNpZXMgPSBbCiAiY2ZnLWlmIDAuMS4xMCIsCiAibGliYyIsCiAibWVtb3J5X3VuaXRzIiwKICJ3aW5hcGkiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIndpbmFwaSIKdmVyc2lvbiA9ICIwLjMuOSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1YzgzOWE2NzRmY2Q3YTk4OTUyZTU5MzI0MmVhNDAwYWJlOTM5OTI3NDY3NjFlMzg2NDE0MDVkMjhiMDBmNDE5IgpkZXBlbmRlbmNpZXMgPSBbCiAid2luYXBpLWk2ODYtcGMtd2luZG93cy1nbnUiLAogIndpbmFwaS14ODZfNjQtcGMtd2luZG93cy1nbnUiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIndpbmFwaS1pNjg2LXBjLXdpbmRvd3MtZ251Igp2ZXJzaW9uID0gIjAuNC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImFjM2I4N2M2MzYyMDQyNmRkOWI5OTFlNWNlMDMyOWVmZjU0NWJjY2JiYjM0ZjNiZTA5ZmY2ZmI2YWI1MWI3YjYiCgpbW3BhY2thZ2VdXQpuYW1lID0gIndpbmFwaS14ODZfNjQtcGMtd2luZG93cy1nbnUiCnZlcnNpb24gPSAiMC40LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNzEyZTIyNzg0MWQwNTdjMWVlMWNkMmZiMjJmYTdlNWE1NDYxYWU4ZTQ4ZmEyY2E3OWVjNDJjZmMxOTMxMTgzZiIK" }, { - "path": "meta/Cargo.lock", - "content": "IyBUaGlzIGZpbGUgaXMgYXV0b21hdGljYWxseSBAZ2VuZXJhdGVkIGJ5IENhcmdvLgojIEl0IGlzIG5vdCBpbnRlbmRlZCBmb3IgbWFudWFsIGVkaXRpbmcuCnZlcnNpb24gPSAzCgpbW3BhY2thZ2VdXQpuYW1lID0gImFoYXNoIgp2ZXJzaW9uID0gIjAuNy42Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImZjYjUxYTA2OTVkOGY4MzhiMWVlMDA5YjNmYmY2NmJkYTA3OGNkNjQ1OTAyMDJhODY0YThmM2U4YzQzMTVjNDciCmRlcGVuZGVuY2llcyA9IFsKICJnZXRyYW5kb20gMC4yLjgiLAogIm9uY2VfY2VsbCIsCiAidmVyc2lvbl9jaGVjayIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiYXJyYXl2ZWMiCnZlcnNpb24gPSAiMC43LjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiOGRhNTJkNjZjNzA3MWUyZTNmYTJhMWU1YzZkMDg4ZmVjNDdiNTkzMDMyYjI1NGY1ZTk4MGRlOGVhNTQ0NTRkNiIKCltbcGFja2FnZV1dCm5hbWUgPSAiYXV0b2NmZyIKdmVyc2lvbiA9ICIxLjEuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJkNDY4ODAyYmFiMTdjYmMwY2M1NzVlOWIwNTNmNDFlNzJhYTM2YmZhNmI3ZjU1ZTM1MjlmZmE0MzE2MWI5N2ZhIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJiZWNoMzIiCnZlcnNpb24gPSAiMC45LjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZDg2YjkzZjk3MjUyYzQ3YjQxNjYzMzg4ZTZkMTU1NzE0YTlkMGMzOThiOTlmMTAwNWNiYzVmOTc4YjI5ZjQ0NSIKCltbcGFja2FnZV1dCm5hbWUgPSAiYml0ZmxhZ3MiCnZlcnNpb24gPSAiMS4zLjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYmVmMzhkNDUxNjNjMmYxZGRlMDk0YTdkZmQzM2NjZjU5NWM5MjkwNWM4ZjhmNGZkYzE4ZDA2ZmIxMDM3NzE4YSIKCltbcGFja2FnZV1dCm5hbWUgPSAiYmxvY2stYnVmZmVyIgp2ZXJzaW9uID0gIjAuOS4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjQxNTIxMTZmZDZlOWRhZGIyOTFhZTE4ZmMxZWMzNTc1ZWQ2ZDg0YzI5NjQyZDk3ODkwZjRiNGEzNDE3Mjk3ZTQiCmRlcGVuZGVuY2llcyA9IFsKICJibG9jay1wYWRkaW5nIiwKICJnZW5lcmljLWFycmF5IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJibG9jay1wYWRkaW5nIgp2ZXJzaW9uID0gIjAuMi4xIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjhkNjk2YzM3MGM3NTBjOTQ4YWRhNjFjNjlhMGVlMmNiYmI5YzUwYjEwMTlkZGI4NmQ5MzE3MTU3YTk5YzJjYWUiCgpbW3BhY2thZ2VdXQpuYW1lID0gImJ5dGVvcmRlciIKdmVyc2lvbiA9ICIxLjQuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIxNGMxODljNTNkMDk4OTQ1NDk5Y2RmYTdlY2M2MzU2N2NmMzg4NmIzMzMyYjMxMmE1YjQ1ODVkOGQzYTZhNjEwIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJjYXJnb190b21sIgp2ZXJzaW9uID0gIjAuMTAuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIzNjNjN2NmYWExNWYxMDE0MTVjNGFjOWU2ODcwNmNhNGEyMjc3NzczOTMyODI4YjMzZjk2ZTU5ZDI4YzY4ZTYyIgpkZXBlbmRlbmNpZXMgPSBbCiAic2VyZGUiLAogInNlcmRlX2Rlcml2ZSIsCiAidG9tbCIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiY2ZnLWlmIgp2ZXJzaW9uID0gIjAuMS4xMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI0Nzg1YmRkMWM5NmIyYTg0NmIyYmQ3Y2MwMmU4NmI2YjNkYmYxNGU3ZTUzNDQ2YzRmNTRjOTJhMzYxMDQwODIyIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJjZmctaWYiCnZlcnNpb24gPSAiMS4wLjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYmFmMWRlNDMzOTc2MTU4OGJjMDYxOWUzY2JjMDEyMGVlNTgyZWJiNzRiNTNiNGVmYmY3OTExN2JkMmRhNDBmZCIKCltbcGFja2FnZV1dCm5hbWUgPSAiY3B1ZmVhdHVyZXMiCnZlcnNpb24gPSAiMC4yLjUiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiMjhkOTk3YmQ1ZTI0YTU5MjhkZDQzZTQ2ZGM1Mjk4NjdlMjA3OTA3ZmUwYjIzOWMzNDc3ZDkyNGY3ZjJjYTMyMCIKZGVwZW5kZW5jaWVzID0gWwogImxpYmMiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImN1cnZlMjU1MTktZGFsZWsiCnZlcnNpb24gPSAiMy4yLjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiOTBmOWQwNTI5NjdmNTkwYTc2ZTYyZWIzODdiZDBiYmIxYjAwMDE4MmMzY2VmZTUzNjRkYjZiNzIxMTY1MWJjMCIKZGVwZW5kZW5jaWVzID0gWwogImJ5dGVvcmRlciIsCiAiZGlnZXN0IiwKICJyYW5kX2NvcmUgMC41LjEiLAogInN1YnRsZSIsCiAiemVyb2l6ZSIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZGlnZXN0Igp2ZXJzaW9uID0gIjAuOS4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImQzZGQ2MGQxMDgwYTU3YTA1YWIwMzIzNzcwNDllMDU5MTQxNWQyYjMxYWZkNzAyODM1NmRiZjNjYzZkY2IwNjYiCmRlcGVuZGVuY2llcyA9IFsKICJnZW5lcmljLWFycmF5IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlZDI1NTE5Igp2ZXJzaW9uID0gIjEuNS4yIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjFlOWMyODAzNjIwMzJlYTQyMDM2NTlmYzQ4OTgzMmQwMjA0ZWYwOWYyNDdhMDUwNmYxNzBkYWZjYWMwOGMzNjkiCmRlcGVuZGVuY2llcyA9IFsKICJzaWduYXR1cmUiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImVkMjU1MTktZGFsZWsiCnZlcnNpb24gPSAiMS4wLjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYzc2MmJhZTZkY2FmMjRjNGM4NDY2N2I4NTc5Nzg1NDMwOTA4NzIzZDVjODg5ZjQ2OWQ3NmE0MWQ1OWNjN2E5ZCIKZGVwZW5kZW5jaWVzID0gWwogImN1cnZlMjU1MTktZGFsZWsiLAogImVkMjU1MTkiLAogInJhbmQgMC43LjMiLAogInNlcmRlIiwKICJzaGEyIiwKICJ6ZXJvaXplIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlaXRoZXIiCnZlcnNpb24gPSAiMS44LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiOTBlNWMxYzgzNjg4MDMxMTNiZjBjOTU4NGZjNDk1YTU4Yjg2ZGM4YTI5ZWRiZjhmZTg3N2QyMWQ5NTA3ZTc5NyIKCltbcGFja2FnZV1dCm5hbWUgPSAiZWxyb25kLWNvZGVjIgp2ZXJzaW9uID0gIjAuMTQuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIyYzg1YzU5NTE4NjRkZDQ4MTZlMWRmMmNlYWNjYjBmMjJjNjRmZjExN2RkY2RlMWY1MzM1MWFjZTRkNzg1YzQ3IgpkZXBlbmRlbmNpZXMgPSBbCiAiYXJyYXl2ZWMiLAogImVscm9uZC1jb2RlYy1kZXJpdmUiLAogIm51bS1iaWdpbnQiLAogIndlZV9hbGxvYyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZWxyb25kLWNvZGVjLWRlcml2ZSIKdmVyc2lvbiA9ICIwLjE0LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiMmE4OTg3YTdmNTA2YWU1YjM1MmFkN2FjMjhmYjEzYjlmNjAwMzU1YzhiODhhNDQ0ODgxZjg2YmM1NjVjNzVjZiIKZGVwZW5kZW5jaWVzID0gWwogImhleCIsCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJzeW4iLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImVscm9uZC13YXNtIgp2ZXJzaW9uID0gIjAuMzYuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI5ZmY3ZGQxMGY0YTcxMzNhMmM2ZmViM2Y3OWUwNDk1M2Y5YTNjMWVkYTlmODQ0NGI0M2MxMzAwZjMwMmUwMmZkIgpkZXBlbmRlbmNpZXMgPSBbCiAiYml0ZmxhZ3MiLAogImVscm9uZC1jb2RlYyIsCiAiZWxyb25kLXdhc20tZGVyaXZlIiwKICJnaXQtdmVyc2lvbiIsCiAiaGFzaGJyb3duIiwKICJoZXgtbGl0ZXJhbCIsCiAibnVtLXRyYWl0cyIsCiAid2VlX2FsbG9jIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbHJvbmQtd2FzbS1kZWJ1ZyIKdmVyc2lvbiA9ICIwLjM2LjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiMGQ1ZWRmZTg2OTg1OTU2ZjJkZTNhNjQ5YmIxNjE5YzFmOGI3OTRiNTQwZTYyMDQ2MWJhMDhmMDUwODYzNTNmYyIKZGVwZW5kZW5jaWVzID0gWwogImJlY2gzMiIsCiAiY2FyZ29fdG9tbCIsCiAiZWQyNTUxOS1kYWxlayIsCiAiZWxyb25kLXdhc20iLAogImhleCIsCiAiaXRlcnRvb2xzIiwKICJtYW5kb3MiLAogIm51bS1iaWdpbnQiLAogIm51bS10cmFpdHMiLAogInBhdGhkaWZmIiwKICJyYW5kIDAuOC41IiwKICJyYW5kX3BjZyIsCiAicmFuZF9zZWVkZXIiLAogInJ1c3RjX3ZlcnNpb24iLAogInNlcmRlIiwKICJzZXJkZV9qc29uIiwKICJzaGEyIiwKICJzaGEzIiwKICJ0b21sIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbHJvbmQtd2FzbS1kZXJpdmUiCnZlcnNpb24gPSAiMC4zNi4xIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjYwMzU4OTg5MTYzYWUxYzI4Yjc5ZDdjNjg3ODY5ODc0Yzc2NTAwMWJiZGZhMTJhMzFkZmQ5MjAzNTBiYzdhMjIiCmRlcGVuZGVuY2llcyA9IFsKICJoZXgiLAogInByb2MtbWFjcm8yIiwKICJxdW90ZSIsCiAicmFkaXhfdHJpZSIsCiAic3luIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbXB0eSIKdmVyc2lvbiA9ICI0LjUuNiIKZGVwZW5kZW5jaWVzID0gWwogImVscm9uZC13YXNtIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbXB0eS1tZXRhIgp2ZXJzaW9uID0gIjAuMC4wIgpkZXBlbmRlbmNpZXMgPSBbCiAiZWxyb25kLXdhc20tZGVidWciLAogImVtcHR5IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJlbmRpYW4tdHlwZSIKdmVyc2lvbiA9ICIwLjEuMiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJjMzRmMDQ2NjZkODM1ZmY1ZDYyZTA1OGMzOTk1MTQ3YzA2ZjQyZmU4NmZmMDUzMzM3NjMyYmNhODNlNDI3MDJkIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJnZW5lcmljLWFycmF5Igp2ZXJzaW9uID0gIjAuMTQuNiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJiZmY0OWU5NDcyOTdmMzMxMjQ0N2FiZGNhNzlmNDVmNDczODA5N2NjODJiMDZlNzIwNTRkMjIyM2Y2MDFmMWI5IgpkZXBlbmRlbmNpZXMgPSBbCiAidHlwZW51bSIsCiAidmVyc2lvbl9jaGVjayIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZ2V0cmFuZG9tIgp2ZXJzaW9uID0gIjAuMS4xNiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI4ZmMzY2I0ZDkxZjUzYjUwMTU1YmRjZmQyM2Y2YTRjMzlhZTE5NjljMmFlODU5ODJiMTM1NzUwY2NjYWY1ZmNlIgpkZXBlbmRlbmNpZXMgPSBbCiAiY2ZnLWlmIDEuMC4wIiwKICJsaWJjIiwKICJ3YXNpIDAuOS4wK3dhc2ktc25hcHNob3QtcHJldmlldzEiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImdldHJhbmRvbSIKdmVyc2lvbiA9ICIwLjIuOCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJjMDVhZWI2YTIyYjhmNjI1NDBjMTk0YWFjOTgwZjIxMTVhZjA2N2JmZTE1YTA3MzRkNzI3N2E3NjhkMzk2YjMxIgpkZXBlbmRlbmNpZXMgPSBbCiAiY2ZnLWlmIDEuMC4wIiwKICJsaWJjIiwKICJ3YXNpIDAuMTEuMCt3YXNpLXNuYXBzaG90LXByZXZpZXcxIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJnaXQtdmVyc2lvbiIKdmVyc2lvbiA9ICIwLjMuNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJmNmIwZGVjYzAyZjQ2MzZiOWNjYWQzOTBkY2JlNzdiNzIyYTc3ZWZlZGZhMzkzY2FmODM3OWE1MWQ1YzYxODk5IgpkZXBlbmRlbmNpZXMgPSBbCiAiZ2l0LXZlcnNpb24tbWFjcm8iLAogInByb2MtbWFjcm8taGFjayIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAiZ2l0LXZlcnNpb24tbWFjcm8iCnZlcnNpb24gPSAiMC4zLjUiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZmU2OWYxY2JkYjZlMjhhZjJiYWMyMTRlOTQzYjk5Y2U4YTBhMDZiNDQ3ZDE1ZDNlNjExNjFiMDQyMzEzOWYzZiIKZGVwZW5kZW5jaWVzID0gWwogInByb2MtbWFjcm8taGFjayIsCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJzeW4iLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImhhc2hicm93biIKdmVyc2lvbiA9ICIwLjExLjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiYWI1ZWYwZDQ5MDllZjM3MjRjYzhjY2U2Y2NjODU3MmM1YzgxNzU5MmU5Mjg1ZjU0NjRmOGU4NmY4YmQzNzI2ZSIKZGVwZW5kZW5jaWVzID0gWwogImFoYXNoIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJoZXgiCnZlcnNpb24gPSAiMC40LjMiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiN2YyNDI1NGFhOWE1NGI1Yzg1OGVhZWUyZjViY2NkYjQ2YWFmMGU0ODZhNTk1ZWQ1ZmQ4Zjg2YmE1NTIzMmE3MCIKCltbcGFja2FnZV1dCm5hbWUgPSAiaGV4LWxpdGVyYWwiCnZlcnNpb24gPSAiMC4zLjQiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiN2ViZGIyOWQyZWE5ZWQwMDgzY2Q4Y2VjZTQ5YmJkOTY4MDIxYmQ5OWIwODQ5ZWRiNGE5YTdlZTBmZGY2YTRlMCIKCltbcGFja2FnZV1dCm5hbWUgPSAiaXRlcnRvb2xzIgp2ZXJzaW9uID0gIjAuMTAuNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJiMGZkMjI2MGU4MjliZGRmNGNiNmVhODAyMjg5ZGUyZjg2ZDZhN2E2OTAxOTJmYmU5MWIzZjQ2ZTBmMmM4NDczIgpkZXBlbmRlbmNpZXMgPSBbCiAiZWl0aGVyIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJpdG9hIgp2ZXJzaW9uID0gIjEuMC41Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImZhZDU4MmY0YjllODZiNmNhYTYyMWNhYmViMDk2MzMzMmQ5MmVlYTA0NzI5YWIxMjg5MmMyNTMzOTUxZTY0NDAiCgpbW3BhY2thZ2VdXQpuYW1lID0gImtlY2NhayIKdmVyc2lvbiA9ICIwLjEuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIzYWZlZjNiNmVmZjljZTlkOGZmOWIzNjAxMTI1ZWVjN2YwYzhjYmFjN2FiZDE0ZjM1NWQwNTNmYTU2Yzk4NzY4IgpkZXBlbmRlbmNpZXMgPSBbCiAiY3B1ZmVhdHVyZXMiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gImxpYmMiCnZlcnNpb24gPSAiMC4yLjEzOSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIyMDFkZTMyNzUyMGRmMDA3NzU3YzFmMGFkY2U2ZTgyN2ZlODU2MmZiYzI4YmZkOWMxNTU3MWM2NmNhMWY1Zjc5IgoKW1twYWNrYWdlXV0KbmFtZSA9ICJtYW5kb3MiCnZlcnNpb24gPSAiMC4xNy4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjE4NDJlNzRjZmRlODc4ZTg2YWYwODY0ODMzMmMzNTdlNjMxMzU3NjNmNTU0ZmZiZDZlODJmMTEwZGVmZGJlYWYiCmRlcGVuZGVuY2llcyA9IFsKICJiZWNoMzIiLAogImhleCIsCiAibnVtLWJpZ2ludCIsCiAibnVtLXRyYWl0cyIsCiAic2VyZGUiLAogInNlcmRlX2pzb24iLAogInNoYTMiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIm1lbW9yeV91bml0cyIKdmVyc2lvbiA9ICIwLjQuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI4NDUyMTA1YmEwNDcwNjhmNDBmZjcwOTNkZDFkOWRhOTA4OThlNjNkZDYxNzM2NDYyZTljZGRhNmE5MGFkM2MzIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJuaWJibGVfdmVjIgp2ZXJzaW9uID0gIjAuMC40Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImM4ZDc3ZjNkYjRiY2UwMzNmNGQwNGRiMDgwNzliMmVmMWMzZDAyYjQ0ZTg2ZjI1ZDA4ODg2ZmFmYTc3NTZmZmEiCgpbW3BhY2thZ2VdXQpuYW1lID0gIm51bS1iaWdpbnQiCnZlcnNpb24gPSAiMC40LjMiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZjkzYWI2Mjg5YzdiMzQ0YThhOWY2MGY4OGQ4MGFhMjAwMzIzMzZmZTc4ZGEzNDFhZmM5MWM4YTIzNDFmYzc1ZiIKZGVwZW5kZW5jaWVzID0gWwogImF1dG9jZmciLAogIm51bS1pbnRlZ2VyIiwKICJudW0tdHJhaXRzIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJudW0taW50ZWdlciIKdmVyc2lvbiA9ICIwLjEuNDUiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiMjI1ZDMzODlmYjM1MDlhMjRjOTNmNWMyOWViNmJkZTI1ODZiOThkOWYwMTY2MzZkZmY1OGQ3YzZmNzU2OWNkOSIKZGVwZW5kZW5jaWVzID0gWwogImF1dG9jZmciLAogIm51bS10cmFpdHMiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIm51bS10cmFpdHMiCnZlcnNpb24gPSAiMC4yLjE1Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjU3OGVkZTM0Y2YwMmY4OTI0YWI5NDQ3ZjUwYzI4MDc1YjRkM2U1YjI2OTk3MjM0NWU3ZTAzNzJiMzhjNmNkY2QiCmRlcGVuZGVuY2llcyA9IFsKICJhdXRvY2ZnIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJvbmNlX2NlbGwiCnZlcnNpb24gPSAiMS4xNy4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjZmNjFmYmExNzQxZWEyYjNkNmExZTMxNzg3MjE4MDRiYjcxNmE2OGE2YWViYTExNDliNWQ1MmUzZDQ2NGVhNjYiCgpbW3BhY2thZ2VdXQpuYW1lID0gIm9wYXF1ZS1kZWJ1ZyIKdmVyc2lvbiA9ICIwLjMuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI2MjRhODM0MGMzOGMxYjgwZmQ1NDkwODc4NjJkYTRiYTQzZTA4ODU4YWYwMjViMjM2ZTUwOWI2NjQ5ZmMxM2Q1IgoKW1twYWNrYWdlXV0KbmFtZSA9ICJwYXRoZGlmZiIKdmVyc2lvbiA9ICIwLjIuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI4ODM1MTE2YTVjMTc5MDg0YTgzMGVmYjNhZGMxMTdhYjAwNzUxMmI1MzViYzFhMjFjOTkxZDNiMzJhNmI0NGRkIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJwcHYtbGl0ZTg2Igp2ZXJzaW9uID0gIjAuMi4xNyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1YjQwYWY4MDViMzEyMWZlYWI4YTNjMjlmMDRkOGFkMjYyZmE4ZTA1NjE4ODNlNzY1M2UwMjRhZTQ0NzllNmRlIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJwcm9jLW1hY3JvLWhhY2siCnZlcnNpb24gPSAiMC41LjIwK2RlcHJlY2F0ZWQiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZGMzNzVlMTUyNzI0N2ZlMWE5N2Q4YjcxNTY2NzhkZmU3YzFhZjJmYzA3NWM5YTRkYjM2OTBlY2QyYTE0ODA2OCIKCltbcGFja2FnZV1dCm5hbWUgPSAicHJvYy1tYWNybzIiCnZlcnNpb24gPSAiMS4wLjQ5Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjU3YThlY2E5ZjljNGZmZGU0MTcxNDMzNGRlZTc3NzU5NjI2NGM3ODI1NDIwZjUyMWFiYzkyYjViNWRlYjYzYTUiCmRlcGVuZGVuY2llcyA9IFsKICJ1bmljb2RlLWlkZW50IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJxdW90ZSIKdmVyc2lvbiA9ICIxLjAuMjMiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiODg1NmQ4MzY0ZDI1MmExNGQ0NzQwMzZlYTEzNThkNjNjOWU2OTY1YzhlNWMxODg1YzE4ZjczZDcwYmZmOWM3YiIKZGVwZW5kZW5jaWVzID0gWwogInByb2MtbWFjcm8yIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJyYWRpeF90cmllIgp2ZXJzaW9uID0gIjAuMS42Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjNkMzY4MWIyOGNkOTVhY2ZiMDU2MGVhOTQ0MWY4MmQ2YTQ1MDRmYTNiMTViOTdiZDdiNmU5NTIxMzE4MjBlOTUiCmRlcGVuZGVuY2llcyA9IFsKICJlbmRpYW4tdHlwZSIsCiAibmliYmxlX3ZlYyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicmFuZCIKdmVyc2lvbiA9ICIwLjcuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI2YTZiMTY3OWQ0OWIyNGJiZmUwYzgwMzQyOWFhMTg3NDQ3MmY1MGQ5YjM2MzEzMWYwZTg5ZmMzNTZiNTQ0ZDAzIgpkZXBlbmRlbmNpZXMgPSBbCiAiZ2V0cmFuZG9tIDAuMS4xNiIsCiAibGliYyIsCiAicmFuZF9jaGFjaGEgMC4yLjIiLAogInJhbmRfY29yZSAwLjUuMSIsCiAicmFuZF9oYyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicmFuZCIKdmVyc2lvbiA9ICIwLjguNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIzNGFmOGQxYTBlMjU5MjRiYzViN2M0M2MwNzljOTQyMzM5ZDhmMGE4YjU3YzM5MDQ5YmVmNTgxYjQ2MzI3NDA0IgpkZXBlbmRlbmNpZXMgPSBbCiAibGliYyIsCiAicmFuZF9jaGFjaGEgMC4zLjEiLAogInJhbmRfY29yZSAwLjYuNCIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicmFuZF9jaGFjaGEiCnZlcnNpb24gPSAiMC4yLjIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZjRjOGVkODU2Mjc5Yzk3MzcyMDZiZjcyNWJmMzY5MzVkODY2NmVhZDdhYTY5YjUyYmU1NWFmMzY5ZDE5MzQwMiIKZGVwZW5kZW5jaWVzID0gWwogInBwdi1saXRlODYiLAogInJhbmRfY29yZSAwLjUuMSIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicmFuZF9jaGFjaGEiCnZlcnNpb24gPSAiMC4zLjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZTZjMTBhNjNhMGZhMzIyNTJiZTQ5ZDIxZTc3MDlkNGQ0YmFmOGQyMzFjMmRiY2UxZWFhODE0MWI5YjEyN2Q4OCIKZGVwZW5kZW5jaWVzID0gWwogInBwdi1saXRlODYiLAogInJhbmRfY29yZSAwLjYuNCIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicmFuZF9jb3JlIgp2ZXJzaW9uID0gIjAuNS4xIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjkwYmRlNTI5NmZjODkxYjBjZWYxMmE2ZDAzZGRjY2MxNjJjZTdiMmFmZjU0MTYwYWY5MzM4ZjhkNDBkZjZkMTkiCmRlcGVuZGVuY2llcyA9IFsKICJnZXRyYW5kb20gMC4xLjE2IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJyYW5kX2NvcmUiCnZlcnNpb24gPSAiMC42LjQiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZWMwYmU0Nzk1ZTJmNmEyODA2OWJlYzBiNWZmM2UyYWM5YmFmYzk5ZTZhOWE3ZGMzNTQ3OTk2YzVjODE2OTIyYyIKZGVwZW5kZW5jaWVzID0gWwogImdldHJhbmRvbSAwLjIuOCIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAicmFuZF9oYyIKdmVyc2lvbiA9ICIwLjIuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJjYTMxMjlhZjdiOTJhMTcxMTJkNTlhZDQ5OGM2ZjgxZWFmNDYzMjUzNzY2YjkwMzk2ZDM5ZWE3YTM5ZDY2MTNjIgpkZXBlbmRlbmNpZXMgPSBbCiAicmFuZF9jb3JlIDAuNS4xIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJyYW5kX3BjZyIKdmVyc2lvbiA9ICIwLjIuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIxNmFiZDBjMWI2MzllOWViNGQ3YzUwYzBiODEwMGIwZDBmODQ5YmUyMzQ5ODI5Yzc0MGZlOGU2ZWI0ODE2NDI5IgpkZXBlbmRlbmNpZXMgPSBbCiAicmFuZF9jb3JlIDAuNS4xIiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJyYW5kX3NlZWRlciIKdmVyc2lvbiA9ICIwLjIuMyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJjZjI4OTBhYWVmMGFhODI3MTlhNTBlODA4ZGUyNjRmOTQ4NGI3NGI0NDJlMWEzYTBlNWVlMzgyNDNhYzQwYmRiIgpkZXBlbmRlbmNpZXMgPSBbCiAicmFuZF9jb3JlIDAuNi40IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJydXN0Y192ZXJzaW9uIgp2ZXJzaW9uID0gIjAuNC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImJmYTBmNTg1MjI2ZDJlNjgwOTdkNGY5NWQxMTNiMTViODNhODJlODE5YWIyNTcxN2VjMDU5MGQ5NTg0ZWYzNjYiCmRlcGVuZGVuY2llcyA9IFsKICJzZW12ZXIiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInJ5dSIKdmVyc2lvbiA9ICIxLjAuMTIiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiN2I0Yjk3NDNlZDY4N2Q0YjRiY2VkZjlmZjVlYWE3Mzk4NDk1YWUxNGU2MWNiYTBhMjk1NzA0ZWRiYzdkZWNkZSIKCltbcGFja2FnZV1dCm5hbWUgPSAic2VtdmVyIgp2ZXJzaW9uID0gIjEuMC4xNiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1OGJjOTU2NzM3OGZjNzY5MGQ2YjJhZGRhZTRlNjBhYzJlZWVhMDdiZWNiMmM2NGI5ZjIxOGI1Mzg2NWNiYTJhIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJzZXJkZSIKdmVyc2lvbiA9ICIxLjAuMTUyIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImJiN2QxZjBkMzAyMWQzNDdhODNlNTU2ZmM0NjgzZGVhMmVhMDlkODdiY2NkZjg4ZmY1YzEyNTQ1ZDg5ZDVlZmIiCmRlcGVuZGVuY2llcyA9IFsKICJzZXJkZV9kZXJpdmUiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInNlcmRlX2Rlcml2ZSIKdmVyc2lvbiA9ICIxLjAuMTUyIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImFmNDg3ZDExOGVlY2QwOTQwMmQ3MGE1ZDcyNTUxODYwZTc4OGRmODdiNDY0YWYzMGU1ZWE2YTM4Yzc1YzU0MWUiCmRlcGVuZGVuY2llcyA9IFsKICJwcm9jLW1hY3JvMiIsCiAicXVvdGUiLAogInN5biIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAic2VyZGVfanNvbiIKdmVyc2lvbiA9ICIxLjAuOTEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiODc3YzIzNTUzMzcxNDkwN2E4YzI0NjQyMzZmNWM0YjJhMTcyNjJlZjFiZDcxZjM4ZjM1ZWE1OTJjOGRhNjg4MyIKZGVwZW5kZW5jaWVzID0gWwogIml0b2EiLAogInJ5dSIsCiAic2VyZGUiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInNoYTIiCnZlcnNpb24gPSAiMC45LjkiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNGQ1OGExZTFiZjM5NzQ5ODA3ZDg5Y2YyZDk4YWMyZGZhMGZmMWNiM2ZhYTM4ZmJiNjRkZDg4YWM4MDEzZDgwMCIKZGVwZW5kZW5jaWVzID0gWwogImJsb2NrLWJ1ZmZlciIsCiAiY2ZnLWlmIDEuMC4wIiwKICJjcHVmZWF0dXJlcyIsCiAiZGlnZXN0IiwKICJvcGFxdWUtZGVidWciLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInNoYTMiCnZlcnNpb24gPSAiMC45LjEiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiZjgxMTk5NDE3ZDRlNWRlM2YwNGIxZTg3MTAyM2FjZWE3Mzg5NjcyYzQxMzU5MThmMDVhYTljYmYyZjJmYTgwOSIKZGVwZW5kZW5jaWVzID0gWwogImJsb2NrLWJ1ZmZlciIsCiAiZGlnZXN0IiwKICJrZWNjYWsiLAogIm9wYXF1ZS1kZWJ1ZyIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAic2lnbmF0dXJlIgp2ZXJzaW9uID0gIjEuNi40Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjc0MjMzZDNiM2IyZjZkNGIwMDZkYzE5ZGVlNzQ1ZTczZTJhNmJmYjZmOTM2MDdjZDNiMDJiZDViMDA3OTdkN2MiCgpbW3BhY2thZ2VdXQpuYW1lID0gInN1YnRsZSIKdmVyc2lvbiA9ICIyLjQuMSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI2YmRlZjMyZTgxNTBjMmEwODExMTBiNDI3NzJmZmU3ZDdjOTAzMmI2MDZiYzIyNmM4MjYwZmQ5N2UwOTc2NjAxIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJzeW4iCnZlcnNpb24gPSAiMS4wLjEwNyIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICIxZjQwNjRiNWIxNmUwM2FlNTA5ODRhNWE4ZWQ1ZDRmODgwM2U2YmMxZmQxNzBhM2NkYTkxYTFiZTRiMThlM2Y1IgpkZXBlbmRlbmNpZXMgPSBbCiAicHJvYy1tYWNybzIiLAogInF1b3RlIiwKICJ1bmljb2RlLWlkZW50IiwKXQoKW1twYWNrYWdlXV0KbmFtZSA9ICJzeW5zdHJ1Y3R1cmUiCnZlcnNpb24gPSAiMC4xMi42Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImYzNmJkYWE2MGE4M2FjYTM5MjFiNTI1OWQ1NDAwY2JmNWU5MGZjNTE5MzEzNzZhOWJkNGEwZWI3OWFhNzIxMGYiCmRlcGVuZGVuY2llcyA9IFsKICJwcm9jLW1hY3JvMiIsCiAicXVvdGUiLAogInN5biIsCiAidW5pY29kZS14aWQiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInRvbWwiCnZlcnNpb24gPSAiMC41LjEwIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjEzMzNjNzY3NDhlODY4YTRkOWQxMDE3YjVhYjUzMTcxZGZkMDk1ZjcwYzcxMmZkYjQ2NTNhNDA2NTQ3ZjU5OGYiCmRlcGVuZGVuY2llcyA9IFsKICJzZXJkZSIsCl0KCltbcGFja2FnZV1dCm5hbWUgPSAidHlwZW51bSIKdmVyc2lvbiA9ICIxLjE2LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNDk3OTYxZWY5M2Q5NzRlMjNlYjZmNDMzZWI1ZmUxYjc5MzBiNjU5ZjA2ZDEyZGVjNmZjNDRhOGY1NTRjMGJiYSIKCltbcGFja2FnZV1dCm5hbWUgPSAidW5pY29kZS1pZGVudCIKdmVyc2lvbiA9ICIxLjAuNiIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI4NGEyMmI5ZjIxOGI0MDYxNGFkY2IzZjRmZjA4YjcwMzc3M2FkNDRmYTk0MjNlNGUwZDM0NmQ1ZGI4NmU0ZWJjIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJ1bmljb2RlLXhpZCIKdmVyc2lvbiA9ICIwLjIuNCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJmOTYyZGY3NGM4YzA1YTY2N2I1ZWU4YmNmMTYyOTkzMTM0YzEwNGU5NjQ0MGI2NjNjOGRhYTE3NmRjNzcyZDhjIgoKW1twYWNrYWdlXV0KbmFtZSA9ICJ2ZXJzaW9uX2NoZWNrIgp2ZXJzaW9uID0gIjAuOS40Igpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjQ5ODc0YjUxNjdiNjVkNzE5M2I4YWJhMTU2N2Y1YzdkOTNkMDAxY2FmYzM0NjAwY2VlMDAzZWRhNzg3ZTQ4M2YiCgpbW3BhY2thZ2VdXQpuYW1lID0gIndhc2kiCnZlcnNpb24gPSAiMC45LjArd2FzaS1zbmFwc2hvdC1wcmV2aWV3MSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJjY2NkZGYzMjU1NGZlY2M2YWNiNTg1ZjgyYTMyYTcyZTI4YjQ4ZjhjNGMxODgzZGRmZWVlYWE5NmY3ZDhlNTE5IgoKW1twYWNrYWdlXV0KbmFtZSA9ICJ3YXNpIgp2ZXJzaW9uID0gIjAuMTEuMCt3YXNpLXNuYXBzaG90LXByZXZpZXcxIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjljOGQ4N2U3MmI2NGEzYjRkYjI4ZDExY2UyOTIzN2MyNDYxODhmNGY1MTA1N2Q2NWE3ZWFiNjNiNzk4N2U0MjMiCgpbW3BhY2thZ2VdXQpuYW1lID0gIndlZV9hbGxvYyIKdmVyc2lvbiA9ICIwLjQuNSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICJkYmIzYjVhNmIyYmIxN2NiNmFkNDRhMmU2OGE0M2U4ZDI3MjJjOTk3ZGExMGU5Mjg2NjVjNzJlYzZjMGEwYjhlIgpkZXBlbmRlbmNpZXMgPSBbCiAiY2ZnLWlmIDAuMS4xMCIsCiAibGliYyIsCiAibWVtb3J5X3VuaXRzIiwKICJ3aW5hcGkiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIndpbmFwaSIKdmVyc2lvbiA9ICIwLjMuOSIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI1YzgzOWE2NzRmY2Q3YTk4OTUyZTU5MzI0MmVhNDAwYWJlOTM5OTI3NDY3NjFlMzg2NDE0MDVkMjhiMDBmNDE5IgpkZXBlbmRlbmNpZXMgPSBbCiAid2luYXBpLWk2ODYtcGMtd2luZG93cy1nbnUiLAogIndpbmFwaS14ODZfNjQtcGMtd2luZG93cy1nbnUiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gIndpbmFwaS1pNjg2LXBjLXdpbmRvd3MtZ251Igp2ZXJzaW9uID0gIjAuNC4wIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gImFjM2I4N2M2MzYyMDQyNmRkOWI5OTFlNWNlMDMyOWVmZjU0NWJjY2JiYjM0ZjNiZTA5ZmY2ZmI2YWI1MWI3YjYiCgpbW3BhY2thZ2VdXQpuYW1lID0gIndpbmFwaS14ODZfNjQtcGMtd2luZG93cy1nbnUiCnZlcnNpb24gPSAiMC40LjAiCnNvdXJjZSA9ICJyZWdpc3RyeStodHRwczovL2dpdGh1Yi5jb20vcnVzdC1sYW5nL2NyYXRlcy5pby1pbmRleCIKY2hlY2tzdW0gPSAiNzEyZTIyNzg0MWQwNTdjMWVlMWNkMmZiMjJmYTdlNWE1NDYxYWU4ZTQ4ZmEyY2E3OWVjNDJjZmMxOTMxMTgzZiIKCltbcGFja2FnZV1dCm5hbWUgPSAiemVyb2l6ZSIKdmVyc2lvbiA9ICIxLjMuMCIKc291cmNlID0gInJlZ2lzdHJ5K2h0dHBzOi8vZ2l0aHViLmNvbS9ydXN0LWxhbmcvY3JhdGVzLmlvLWluZGV4IgpjaGVja3N1bSA9ICI0NzU2ZjdkYjNmN2I1NTc0OTM4YzNlYjFjMTE3MDM4YjhlMDdmOTVlZTY3MThjMGVmYWQ0YWMyMTUwOGYxZWZkIgpkZXBlbmRlbmNpZXMgPSBbCiAiemVyb2l6ZV9kZXJpdmUiLApdCgpbW3BhY2thZ2VdXQpuYW1lID0gInplcm9pemVfZGVyaXZlIgp2ZXJzaW9uID0gIjEuMy4zIgpzb3VyY2UgPSAicmVnaXN0cnkraHR0cHM6Ly9naXRodWIuY29tL3J1c3QtbGFuZy9jcmF0ZXMuaW8taW5kZXgiCmNoZWNrc3VtID0gIjQ0YmYwN2NiM2U1MGVhMjAwMzM5NjY5NWQ1OGJmNDZiYzk4ODdhMWYzNjIyNjA0NDZmYWQ2YmM0ZTc5YmQzNmMiCmRlcGVuZGVuY2llcyA9IFsKICJwcm9jLW1hY3JvMiIsCiAicXVvdGUiLAogInN5biIsCiAic3luc3RydWN0dXJlIiwKXQo=" + "path": "wasm/Cargo.toml", + "content": "W3BhY2thZ2VdCm5hbWUgPSAiZW1wdHktd2FzbSIKdmVyc2lvbiA9ICI0LjUuNiIKZWRpdGlvbiA9ICIyMDE4IgpwdWJsaXNoID0gZmFsc2UKCltsaWJdCmNyYXRlLXR5cGUgPSBbImNkeWxpYiJdCgpbcHJvZmlsZS5yZWxlYXNlXQpjb2RlZ2VuLXVuaXRzID0gMQpvcHQtbGV2ZWwgPSAieiIKbHRvID0gdHJ1ZQpkZWJ1ZyA9IGZhbHNlCnBhbmljID0gImFib3J0IgoKW2RlcGVuZGVuY2llcy5lbXB0eV0KcGF0aCA9ICIuLiIKCltkZXBlbmRlbmNpZXMuZWxyb25kLXdhc20tbm9kZV0KdmVyc2lvbiA9ICIwLjM2LjEiCgpbZGVwZW5kZW5jaWVzLmVscm9uZC13YXNtLW91dHB1dF0KdmVyc2lvbiA9ICIwLjM2LjEiCmZlYXR1cmVzID0gWyJ3YXNtLW91dHB1dC1tb2RlIl0KClt3b3Jrc3BhY2VdCm1lbWJlcnMgPSBbIi4iXQo=" }, { - "path": "meta/src/main.rs", - "content": "Zm4gbWFpbigpIHsKICAgIGVscm9uZF93YXNtX2RlYnVnOjptZXRhOjpwZXJmb3JtOjo8ZW1wdHk6OkFiaVByb3ZpZGVyPigpOwp9Cg==" + "path": "wasm/src/lib.rs", + "content": "Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwovLy8vLy8vLy8vLy8vLy8vLy8gQVVUTy1HRU5FUkFURUQgLy8vLy8vLy8vLy8vLy8vLy8vCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCiMhW25vX3N0ZF0KCmVscm9uZF93YXNtX25vZGU6Ondhc21fZW5kcG9pbnRzISB7CiAgICBlbXB0eQogICAgKAogICAgKQp9CgplbHJvbmRfd2FzbV9ub2RlOjp3YXNtX2VtcHR5X2NhbGxiYWNrISB7fQo=" } ] }