From 8558c54de2bc05ca799fe9904940d70890cad04c Mon Sep 17 00:00:00 2001 From: Don Perignom <10616301+madlabman@users.noreply.github.com> Date: Thu, 20 Jun 2024 18:55:04 +0200 Subject: [PATCH] CSM performance oracle module (#440) * add label to FRAME_PREV_REPORT_REF_SLOT * add withdrawal exit epoch * add labels to CONTRACT_ON_PAUSE * linter fix * fix typo * fix negative block on forks * Fix typo in docs * Fix typo in test function name * Fix typo in test function name * feat: attestation and committees * fix: type * fix: return -> yield * fix: pylint in tests * fix: mypy issues * fix: test * chore: change typing for clients * refactor: strict way for streams `_get_without_fallbacks` * chore: remove non-mandatory pylint ignore * make dockerfile buildable * feat: add CSM performance oracle module * contracts create * temp changes * rename typings * fix get_latest_blockstamp * fix test consensus * tests fixes * run black * fix linters * add blockhash * fix tests * fix mypy * fix linter * feat: CSM contracts as a separate module * fix comments * pylint fixed * fix lru cache * test for cache * fix linter * fix linters * remove unused import * fix: off-by-one error on logs fetching * chore: op_id -> no_id * feat: lazy-loading of CSM module * fix: get ABIs for contracts * chore: update docs for env variables * docs: few more corrections to README * chore: fix timeout_decorator type stub * fix: remove lru_cache from CSFeeOracle * feat: collect data for report building * fix: processing * fix: review * fix: ignore * feat: CSM contracts as a separate module * fix: off-by-one error on logs fetching * chore: op_id -> no_id * feat: lazy-loading of CSM module * fix: get ABIs for contracts * chore: update docs for env variables * docs: few more corrections to README * chore: fix timeout_decorator type stub * fix: remove lru_cache from CSFeeOracle * fix: lint * unify get call function * back to HexBytes * feat: add dummy IPFS provider (#436) * feat: `get_module_validators_by_node_operators` (#438) * feat: build CSM oracle report (#437) * fix: calculated l_ref_slot and r_ref_slot (#441) * fix: calculated l_ref_slot and r_ref_slot * fix: calculated l_ref_slot and r_ref_slot * CSM oracle hot fixes (#442) * feat: handle thread exception in processing (#443) * feat: handle thread exception in processing * fix: remove unused things * fix: use `ValueError`, shutdown the executor * fix: linter * chore: add a comment * fix: rise `SystemExit` (#446) * fix: put a stone into a tree (#444) * feat: `epochs_to_process` (#445) * feat: `epochs_to_process` * feat: two sets * feat: advanced validation * fix: use `unprocessed_epochs` * fix: private state properties * revert: `_data` -> ``data` * feat: gw3.io provider and MultiIPFSProvider (#447) * Fix report (#448) * fix: checkpoint range assert (#449) * fix: use reference blockstamp as r_slot for stuck events search (#450) * feat: use attestations endpoint * feat: fetch stuck events for the given frame only (#452) * feat: configure workers count for CSM module * chore: remove DummyIPFSProvider from main * fix: tests import * fix: csm `module` property * fix: logging CID via repr * chore: remove stone when not needed * fix: submit_report_data accepts a tuple * chore: fix mypy * feat: implement dynamic versions * fix: black: two lines * replace wget to culr * fix: call get_contract_version with block hash * Close some TODOs (#456) * fix message * chore: move iterator to folder * chore: add timestamp to logs * feat: add tests to lido contracts * fix: test slot * fix pylint * black fix * update workflow * chore: add v2 iterator * fix tests * fix: review * chore: move iterator to folder * chore: add timestamp to logs * feat: add tests to lido contracts * fix: test slot * fix pylint * black fix * update workflow * fix: review * fix: pylint * feat: absolute performance leeway * fix integration tests * iterator update * fix tests * fix: iterator test * feat: Multi Third Phase * squash sr abi * chore: use TOTAL_BASIS_POINTS const * fix middleware test * fix test * feat: ao-multi-third-phase-partial * fix: review * fix tests * fix: cast to tuple issue * fix log * fix: first validator issue * fix pylint * fix all tests * feat: Multi Third Phase * feat: ao-multi-third-phase-partial * fix: review * fix tests * fix: cast to tuple issue * fix log * tweak ejector * feat: checkpoints refactoring + tests (#463) * feat: review fixes * fix: linters * fix: lru cache * fix: call from v2 old contract * fix: linters * fix: `CSFeeOracle` with no initial epoch * Update src/modules/csm/csm.py Co-authored-by: Don Perignom <10616301+madlabman@users.noreply.github.com> * fix: first report l_ref_slot (#466) * fix: error messages for `validate_for_report` (#467) * fix: error messages for `validate_for_report` * fix: use error message explicitly * fix: Add warning log * feat: Update python to 3.12 * fix: State network average calculation * fix: compute operators shares via assigned attestations * refactor: fix linters * refactor: calculate distribution * tests: fix missing assert * refactor: no cache for stuck_operators * fix tests and improve cache * chore: log is_deployed result Co-authored-by: Raman Siamionau <1590415904a@gmail.com> * chore: add CSM_MODULE_ADDRESS to .env.example * chore: add more catch statements for IPFS * chore: add missing variables to README * fix: check contracts via _load_contracts * refactor: CSFeeDistributor calls casts and logs * chore: debug -> info logs on calls in CSM contracts * refactor: add Contract suffix to CSM contracts * Fix: wf * refactor: InconsistentEvents * refactor: move TOTAL_BASIS_POINTS out of perf_leeway * chore: fix sequence assert * chore: update CSModule abi * fix linters * fix: use module address to get keys from keysapi * fix: remove `no_cache` method for committees * fix: merge `get` and `get stream` base methods * feat: check module address * refactor: extract get_events_in_range into utils * fix: rework `get_first_non_missed_slot` * chore: remove events inconsistency check from cs_module * refactor: use get_events_in_range across the codebase * fix: add `Final` for env vars * tests: fix test_calculate_distribution * fix after merge * fix: black * fix: tests * refactor: extract get_operators_with_stucks_in_range * refactor: block -> block_identifier * chore: alias for Shares * fix: get_stuck_operators_ids return * tests: rework events utils tests * fix test names * fix: calculate_distribution shares as a defaultdict * docs: CSM-only variables as CSM only in README * Update src/utils/slot.py * chore: fix logging for get_events_in_range * chore: StakingModuleAddress as ChecksumAddress * chore: update authors * chore: remove redundant cache * refactor: move State.load to __init__ * fix: consensus farFutureEpoch const * chore: add check for l_ref_slot * fix: `minimum checkpoint step is not reached` is not error (#472) * fix: review * fix: test * feat: modify cache * comment problematic integration test * feat: block roots from state, events (#474) * feat: block roots from state, events * fix: check events len * fix: LazyCSM -> CSM * fix: assert * feat: check providers for CSM frame * feat: add DepositContract * chore: fix linters --------- Co-authored-by: madlabman <10616301+madlabman@users.noreply.github.com> * fix: linters * fix: `get_attestation_committees` returns list now (#476) * fix: `get_attestation_committees` returns list now * fix: linter * fix: `_get_block_roots` * fix: test * fix: checkpoint slot and tests * fix: use condition from spec * chore: set default concurrency for CSM to "2" * fix: iterator conditions (#477) * fix: iterator conditions * fix: black * fix: use max_available_epoch_to_check * fix: _get_block_roots * fix: black * fix: _select_block_roots * fix: pylint * feat: `batched` * feat: get CSFeeOracle address via CSModule (#478) * feat: check IPFS provider for CSM (#481) * feat: check IPFS provider for CSM * feat: IPFS checker all providers * feat: IPFS checker mark skipped providers * fix: review (#480) * fix: review * fix: linter * fix: tests * fix: no faker for checker --------- Co-authored-by: F4ever <1590415904a@gmail.com> Co-authored-by: shuoer86 <129674997+shuoer86@users.noreply.github.com> Co-authored-by: vgorkavenko Co-authored-by: Vladimir Gorkavenko <32727352+vgorkavenko@users.noreply.github.com> Co-authored-by: F4ever --- .env.example | 5 +- .github/workflows/ci-dev-goerli.yml | 29 - .github/workflows/tests.yml | 14 +- .gitignore | 7 +- Dockerfile | 9 +- README.md | 113 +- assets/CSAccounting.json | 1 + assets/CSFeeDistributor.json | 1 + assets/CSFeeOracle.json | 1 + assets/CSModule.json | 1 + assets/DepositContract.json | 1 + assets/StakingRouterV2.json | 1 + fixtures/common/contracts.json | 2 +- ...stamp_for_report_slot_deadline_missed.json | 2 +- ...slot_member_is_not_in_fast_line_ready.json | 4 +- ...or_report_slot_member_ready_to_report.json | 4 +- ...et_third_non_missed_slot_backward.cl.json} | 0 ..._get_third_non_missed_slot_forward.cl.json | 4895 +++++++++++++++++ poetry.lock | 4060 ++++++-------- pyproject.toml | 39 +- src/constants.py | 4 + src/main.py | 46 +- src/metrics/healthcheck_server.py | 10 +- src/metrics/logging.py | 1 + src/metrics/prometheus/business.py | 2 + src/metrics/prometheus/duration_meter.py | 7 +- src/metrics/prometheus/ejector.py | 4 +- src/modules/accounting/accounting.py | 112 +- .../accounting/third_phase/__init__.py | 0 .../{ => third_phase}/extra_data.py | 63 +- .../accounting/third_phase/extra_data_v2.py | 138 + src/modules/accounting/third_phase/types.py | 30 + .../accounting/{typings.py => types.py} | 36 +- src/modules/checks/suites/common.py | 17 + src/modules/checks/suites/conftest.py | 85 +- src/modules/checks/suites/consensus_node.py | 31 +- src/modules/checks/suites/execution_node.py | 32 +- src/modules/checks/suites/ipfs.py | 55 + src/modules/csm/__init__.py | 0 src/modules/csm/checkpoint.py | 250 + src/modules/csm/csm.py | 304 + src/modules/csm/state.py | 167 + src/modules/csm/tree.py | 46 + src/modules/csm/types.py | 28 + src/modules/ejector/ejector.py | 261 +- src/modules/ejector/{typings.py => types.py} | 2 +- src/modules/submodules/consensus.py | 157 +- src/modules/submodules/exceptions.py | 2 +- src/modules/submodules/oracle_module.py | 24 +- .../submodules/{typings.py => types.py} | 8 +- src/providers/consensus/client.py | 90 +- .../consensus/{typings.py => types.py} | 52 +- src/providers/consistency.py | 4 +- src/providers/execution/__init__.py | 0 src/providers/execution/base_interface.py | 32 + .../execution/contracts/accounting_oracle.py | 47 + .../execution/contracts/base_oracle.py | 117 + src/providers/execution/contracts/burner.py | 30 + .../execution/contracts/cs_accounting.py | 26 + .../execution/contracts/cs_fee_distributor.py | 66 + .../execution/contracts/cs_fee_oracle.py | 37 + .../execution/contracts/cs_module.py | 95 + .../execution/contracts/deposit_contract.py | 22 + .../execution/contracts/exit_bus_oracle.py | 66 + .../execution/contracts/hash_consensus.py | 149 + src/providers/execution/contracts/lido.py | 101 + .../execution/contracts/lido_locator.py | 124 + .../contracts/oracle_daemon_config.py | 61 + .../contracts/oracle_report_sanity_checker.py | 30 + .../execution/contracts/staking_router.py | 88 + .../contracts/withdrawal_queue_nft.py | 150 + src/providers/execution/exceptions.py | 5 + src/providers/http_provider.py | 39 +- src/providers/ipfs/__init__.py | 7 + src/providers/ipfs/cid.py | 19 + src/providers/ipfs/dummy.py | 36 + src/providers/ipfs/gw3.py | 90 + src/providers/ipfs/multi.py | 92 + src/providers/ipfs/pinata.py | 59 + src/providers/ipfs/public.py | 36 + src/providers/ipfs/types.py | 56 + src/providers/keys/client.py | 16 +- src/providers/keys/{typings.py => types.py} | 0 src/services/bunker.py | 29 +- .../bunker_cases/abnormal_cl_rebase.py | 65 +- .../bunker_cases/midterm_slashing_penalty.py | 6 +- .../bunker_cases/{typings.py => types.py} | 0 src/services/exit_order/__init__.py | 0 .../iterator.py} | 19 +- .../iterator_state.py} | 22 +- src/services/exit_order_v2/__init__.py | 0 src/services/exit_order_v2/iterator.py | 290 + src/services/prediction.py | 26 +- src/services/safe_border.py | 73 +- src/services/validator_state.py | 106 +- src/services/withdrawal.py | 76 +- src/{typings.py => types.py} | 12 +- src/utils/abi.py | 6 +- src/utils/blockstamp.py | 21 +- src/utils/cache.py | 24 + src/utils/dataclass.py | 13 +- src/utils/events.py | 42 +- src/utils/range.py | 10 + src/utils/slot.py | 47 +- src/utils/validator_state.py | 20 +- src/utils/web3converter.py | 11 +- src/variables.py | 57 +- src/web3py/contract_tweak.py | 24 +- src/web3py/extensions/__init__.py | 1 + src/web3py/extensions/contracts.py | 162 +- src/web3py/extensions/csm.py | 141 + src/web3py/extensions/lido_validators.py | 110 +- src/web3py/extensions/tx_utils.py | 23 +- src/web3py/{typings.py => types.py} | 4 + stubs/lazy_object_proxy/__init__.pyi | 1 + stubs/lazy_object_proxy/lazy_object_proxy.pyi | 8 + stubs/timeout_decorator/timeout_decorator.pyi | 2 +- tests/README.md | 4 +- tests/conftest.py | 50 +- tests/factory/blockstamp.py | 2 +- tests/factory/configs.py | 36 +- tests/factory/contract_responses.py | 2 +- tests/factory/member_info.py | 2 +- tests/factory/no_registry.py | 7 +- tests/factory/web3_factory.py | 8 +- tests/integration/__init__.py | 0 tests/integration/conftest.py | 119 + tests/integration/contracts/__init__.py | 0 tests/integration/contracts/contract_utils.py | 37 + .../contracts/test_accounting_oracle.py | 18 + tests/integration/contracts/test_bunker.py | 15 + tests/integration/contracts/test_lido.py | 32 + .../contracts/test_lido_locator.py | 74 + .../contracts/test_oracle_daemon_config.py | 55 + .../test_oracle_report_sanity_checker.py | 15 + .../contracts/test_staking_router.py | 27 + .../test_validator_exit_bus_oracle.py | 21 + .../test_withdrawal_queue_nft_contract.py | 74 + tests/modules/accounting/bunker/conftest.py | 22 +- .../modules/accounting/bunker/test_bunker.py | 8 +- .../bunker/test_bunker_abnormal_cl_rebase.py | 35 +- .../bunker/test_bunker_medterm_penalty.py | 6 +- .../accounting/test_accounting_module.py | 130 +- tests/modules/accounting/test_extra_data.py | 19 +- .../modules/accounting/test_extra_data_v2.py | 129 + .../test_safe_border_integration.py | 31 +- .../accounting/test_safe_border_unit.py | 158 +- .../accounting/test_validator_state.py | 181 +- .../accounting/test_withdrawal_integration.py | 20 +- .../accounting/test_withdrawal_unit.py | 15 +- tests/modules/csm/test_checkpoint.py | 379 ++ tests/modules/csm/test_csm_module.py | 65 + tests/modules/csm/test_state.py | 126 + tests/modules/ejector/test_data_encode.py | 7 +- tests/modules/ejector/test_ejector.py | 127 +- .../ejector/test_exit_order_iterator.py | 25 +- .../ejector/test_exit_order_state_service.py | 12 +- tests/modules/ejector/test_iterator_v2.py | 349 ++ tests/modules/ejector/test_prediction.py | 16 +- .../modules/submodules/consensus/conftest.py | 6 +- .../submodules/consensus/test_consensus.py | 31 +- .../submodules/consensus/test_reports.py | 28 +- .../modules/submodules/test_oracle_module.py | 6 +- tests/providers.py | 12 +- .../test_consensus_client.py | 30 +- tests/providers_clients/test_http_provider.py | 4 +- tests/services/test_safe_border.py | 66 +- tests/utils/test_cache.py | 51 +- tests/utils/test_dataclass.py | 31 +- tests/utils/test_events.py | 91 +- tests/utils/test_range.py | 18 + tests/utils/test_slot.py | 40 +- tests/utils/test_validator_state_utils.py | 11 +- tests/utils/test_web3_converter.py | 4 +- tests/web3_extentions/test_lido_validators.py | 3 +- tests/web3_extentions/test_middleware.py | 12 +- tests/web3_extentions/test_tx_utils.py | 25 +- 177 files changed, 13423 insertions(+), 3908 deletions(-) delete mode 100644 .github/workflows/ci-dev-goerli.yml create mode 100644 assets/CSAccounting.json create mode 100644 assets/CSFeeDistributor.json create mode 100644 assets/CSFeeOracle.json create mode 100644 assets/CSModule.json create mode 100644 assets/DepositContract.json create mode 100644 assets/StakingRouterV2.json rename fixtures/tests/utils/test_slot.py/{test_get_third_non_missed_slot.cl.json => test_get_third_non_missed_slot_backward.cl.json} (100%) create mode 100644 fixtures/tests/utils/test_slot.py/test_get_third_non_missed_slot_forward.cl.json create mode 100644 src/modules/accounting/third_phase/__init__.py rename src/modules/accounting/{ => third_phase}/extra_data.py (71%) create mode 100644 src/modules/accounting/third_phase/extra_data_v2.py create mode 100644 src/modules/accounting/third_phase/types.py rename src/modules/accounting/{typings.py => types.py} (77%) create mode 100644 src/modules/checks/suites/ipfs.py create mode 100644 src/modules/csm/__init__.py create mode 100644 src/modules/csm/checkpoint.py create mode 100644 src/modules/csm/csm.py create mode 100644 src/modules/csm/state.py create mode 100644 src/modules/csm/tree.py create mode 100644 src/modules/csm/types.py rename src/modules/ejector/{typings.py => types.py} (94%) rename src/modules/submodules/{typings.py => types.py} (95%) rename src/providers/consensus/{typings.py => types.py} (71%) create mode 100644 src/providers/execution/__init__.py create mode 100644 src/providers/execution/base_interface.py create mode 100644 src/providers/execution/contracts/accounting_oracle.py create mode 100644 src/providers/execution/contracts/base_oracle.py create mode 100644 src/providers/execution/contracts/burner.py create mode 100644 src/providers/execution/contracts/cs_accounting.py create mode 100644 src/providers/execution/contracts/cs_fee_distributor.py create mode 100644 src/providers/execution/contracts/cs_fee_oracle.py create mode 100644 src/providers/execution/contracts/cs_module.py create mode 100644 src/providers/execution/contracts/deposit_contract.py create mode 100644 src/providers/execution/contracts/exit_bus_oracle.py create mode 100644 src/providers/execution/contracts/hash_consensus.py create mode 100644 src/providers/execution/contracts/lido.py create mode 100644 src/providers/execution/contracts/lido_locator.py create mode 100644 src/providers/execution/contracts/oracle_daemon_config.py create mode 100644 src/providers/execution/contracts/oracle_report_sanity_checker.py create mode 100644 src/providers/execution/contracts/staking_router.py create mode 100644 src/providers/execution/contracts/withdrawal_queue_nft.py create mode 100644 src/providers/execution/exceptions.py create mode 100644 src/providers/ipfs/__init__.py create mode 100644 src/providers/ipfs/cid.py create mode 100644 src/providers/ipfs/dummy.py create mode 100644 src/providers/ipfs/gw3.py create mode 100644 src/providers/ipfs/multi.py create mode 100644 src/providers/ipfs/pinata.py create mode 100644 src/providers/ipfs/public.py create mode 100644 src/providers/ipfs/types.py rename src/providers/keys/{typings.py => types.py} (100%) rename src/services/bunker_cases/{typings.py => types.py} (100%) create mode 100644 src/services/exit_order/__init__.py rename src/services/{exit_order_iterator.py => exit_order/iterator.py} (93%) rename src/services/{exit_order_iterator_state.py => exit_order/iterator_state.py} (90%) create mode 100644 src/services/exit_order_v2/__init__.py create mode 100644 src/services/exit_order_v2/iterator.py rename src/{typings.py => types.py} (69%) create mode 100644 src/utils/range.py create mode 100644 src/web3py/extensions/csm.py rename src/web3py/{typings.py => types.py} (81%) create mode 100644 stubs/lazy_object_proxy/__init__.pyi create mode 100644 stubs/lazy_object_proxy/lazy_object_proxy.pyi create mode 100644 tests/integration/__init__.py create mode 100644 tests/integration/conftest.py create mode 100644 tests/integration/contracts/__init__.py create mode 100644 tests/integration/contracts/contract_utils.py create mode 100644 tests/integration/contracts/test_accounting_oracle.py create mode 100644 tests/integration/contracts/test_bunker.py create mode 100644 tests/integration/contracts/test_lido.py create mode 100644 tests/integration/contracts/test_lido_locator.py create mode 100644 tests/integration/contracts/test_oracle_daemon_config.py create mode 100644 tests/integration/contracts/test_oracle_report_sanity_checker.py create mode 100644 tests/integration/contracts/test_staking_router.py create mode 100644 tests/integration/contracts/test_validator_exit_bus_oracle.py create mode 100644 tests/integration/contracts/test_withdrawal_queue_nft_contract.py create mode 100644 tests/modules/accounting/test_extra_data_v2.py create mode 100644 tests/modules/csm/test_checkpoint.py create mode 100644 tests/modules/csm/test_csm_module.py create mode 100644 tests/modules/csm/test_state.py create mode 100644 tests/modules/ejector/test_iterator_v2.py create mode 100644 tests/utils/test_range.py diff --git a/.env.example b/.env.example index 2655a0ad2..ecc6b5cc0 100644 --- a/.env.example +++ b/.env.example @@ -2,4 +2,7 @@ CONSENSUS_CLIENT_URI=http://... EXECUTION_CLIENT_URI=http://... KEYS_API_URI=https://... LIDO_LOCATOR_ADDRESS=0x1... -MEMBER_PRIV_KEY=aaa... \ No newline at end of file +CSM_ORACLE_ADDRESS=0x... +CSM_MODULE_ADDRESS=0x... +MEMBER_PRIV_KEY=aaa... + diff --git a/.github/workflows/ci-dev-goerli.yml b/.github/workflows/ci-dev-goerli.yml deleted file mode 100644 index 79182dc6e..000000000 --- a/.github/workflows/ci-dev-goerli.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: CI Dev Goerli - -on: - workflow_dispatch: - push: - branches: - - goerli - paths-ignore: - - ".github/**" - -permissions: {} - -jobs: - # test: - # ... - - deploy: - runs-on: ubuntu-latest - # needs: test - name: Build and deploy - steps: - - name: Testnet deploy - uses: lidofinance/dispatch-workflow@v1 - env: - APP_ID: ${{ secrets.APP_ID }} - APP_PRIVATE_KEY: ${{ secrets.APP_PRIVATE_KEY }} - TARGET_REPO: "lidofinance/infra-mainnet" - TARGET_WORKFLOW: "deploy_testnet_lido_oracle.yaml" - TARGET: "goerli" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6177a6a10..7d765b733 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,10 +13,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v4 with: - python-version: "3.11" + python-version: "3.12" - name: Setup poetry run: > @@ -31,7 +31,11 @@ jobs: poetry install --no-interaction --with=dev - name: Test with pytest - run: poetry run pytest -m "not integration and not e2e" --cov=src tests + run: poetry run pytest --cov=src tests + env: + EXECUTION_CLIENT_URI: ${{ secrets.EXECUTION_CLIENT_URI }} + CONSENSUS_CLIENT_URI: ${{ secrets.CONSENSUS_CLIENT_URI }} + KEYS_API_URI: ${{ secrets.KEYS_API_URI }} linters: runs-on: ubuntu-latest @@ -39,10 +43,10 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v4 with: - python-version: "3.11" + python-version: "3.12" - name: Setup poetry run: > diff --git a/.gitignore b/.gitignore index 02a5723a3..a12e4a1a0 100644 --- a/.gitignore +++ b/.gitignore @@ -126,6 +126,8 @@ venv.bak/ .dmypy.json dmypy.json +.ruff_cache/ + # Pyre type checker .pyre/ @@ -134,4 +136,7 @@ dmypy.json # vim *.swp -.direnv + +# Cache +*.pkl +*.buf diff --git a/Dockerfile b/Dockerfile index e9c181d1a..3c4ad62fc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,9 @@ -FROM python:3.11-slim as base +FROM python:3.12.4-slim as base RUN apt-get update && apt-get install -y --no-install-recommends -qq \ - gcc=4:10.2.1-1 \ - libffi-dev=3.3-6 \ - g++=4:10.2.1-1 \ - curl=7.74.0-1.3+deb11u7 \ + libffi-dev=3.4.4-1 \ + g++=4:12.2.0-3 \ + curl=7.88.1-10+deb12u5 \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/README.md b/README.md index 963979ef4..f43d55468 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,12 @@ There are two modules in the oracle: ### Accounting module Accounting module updates the protocol TVL, distributes node-operator rewards, updates information about the number of exited and stuck validators and processes user withdrawal requests. -Also Accounting module makes decision to turn on/off the bunker. +Also Accounting module makes decision to turn on/off the bunker. **Flow** The oracle work is delineated by time periods called frames. Oracles finalize a report in each frame. -The default Accounting Oracle frame length on mainnet is 225 epochs, which is 24 hours (it could be changed by DAO). +The default Accounting Oracle frame length on mainnet is 225 epochs, which is 24 hours (it could be changed by DAO). The frame includes these stages: - **Waiting** - oracle starts as daemon and wakes up every 12 seconds (by default) in order to find the last finalized slot (ref slot). @@ -66,23 +66,23 @@ To prepare the report, Oracle fetches up to 10 days old events, makes historical Oracle needs two weeks of archived data. | Client | Tested | Notes | -|-------------------------------------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Geth](https://geth.ethereum.org/) | | `--gcmode=archive`
`--syncmode=snap`

OR

`--gcmode=archive`
`--syncmode=full` | -| [Nethermind](https://nethermind.io/) | | Not tested yet | -| [Besu](https://besu.hyperledger.org/en/stable/) | | Use
`--rpc-max-logs-range=100000`
`--sync-mode=FULL`
`--data-storage-format="FOREST"`
`--pruning-enabled`
`--pruning-blocks-retained=100000`
params | -| [Erigon](https://github.com/ledgerwatch/erigon) | | Use
`--prune=htc`
`--prune.h.before=100000`
`--prune.t.before=100000`
`--prune.c.before=100000`
params | +|-------------------------------------------------|:------:|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [Geth](https://geth.ethereum.org/) | 🟢 | `--gcmode=archive`
`--syncmode=snap`

OR

`--gcmode=archive`
`--syncmode=full` | +| [Nethermind](https://nethermind.io/) | 🔴 | Not tested yet | +| [Besu](https://besu.hyperledger.org/en/stable/) | 🟢 | Use
`--rpc-max-logs-range=100000`
`--sync-mode=FULL`
`--data-storage-format="FOREST"`
`--pruning-enabled`
`--pruning-blocks-retained=100000`
params | +| [Erigon](https://github.com/ledgerwatch/erigon) | 🟢 | Use
`--prune=htc`
`--prune.h.before=100000`
`--prune.t.before=100000`
`--prune.c.before=100000`
params | ### Consensus Client Node Also, to calculate some metrics for bunker mode Oracle needs [archive](https://ethereum.org/en/developers/docs/nodes-and-clients/#archive-node) consensus node. | Client | Tested | Notes | -|---------------------------------------------------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------| -| [Lighthouse](https://lighthouse.sigmaprime.io/) | | Use `--reconstruct-historic-states` param | -| [Lodestar](https://nethermind.io/) | | Not tested yet | -| [Nimbus](https://besu.hyperledger.org/en/stable/) | | Not tested yet | -| [Prysm](https://github.com/ledgerwatch/erigon) | | Use
`--grpc-max-msg-size=104857600`
`--enable-historical-state-representation=true`
`--slots-per-archive-point=1024`
params | -| [Teku](https://docs.teku.consensys.net) | | Use
`--data-storage-mode=archive`
`--data-storage-archive-frequency=1024`
`--reconstruct-historic-states=true`
params | +|---------------------------------------------------|:------:|-------------------------------------------------------------------------------------------------------------------------------------------------| +| [Lighthouse](https://lighthouse.sigmaprime.io/) | 🟢 | Use `--reconstruct-historic-states` param | +| [Lodestar](https://lodestar.chainsafe.io) | 🔴 | Not tested yet | +| [Nimbus](https://nimbus.team) | 🔴 | Not tested yet | +| [Prysm](https://github.com/prysmaticlabs/prysm) | 🟢 | Use
`--grpc-max-msg-size=104857600`
`--enable-historical-state-representation=true`
`--slots-per-archive-point=1024`
params | +| [Teku](https://docs.teku.consensys.net) | 🟢 | Use
`--data-storage-mode=archive`
`--data-storage-archive-frequency=1024`
`--reconstruct-historic-states=true`
params | ### Keys API Service @@ -150,13 +150,13 @@ Full variables list could be found [here](https://github.com/lidofinance/lido-or Oracle could be executed once in "manual" mode. To do this setup `DAEMON` variable to 'False'. -**Note**: Use `-it` option to run manual mode in Docker container in interactive mode. +**Note**: Use `-it` option to run manual mode in Docker container in interactive mode. Example `docker run -ti --env-file .env --rm lidofinance/oracle:{tag} {type}` In this mode Oracle will build report as usual (if contracts are reportable) and before submitting transactions Oracle will ask for manual input to send transaction. -In manual mode all sleeps are disabled and `ALLOW_REPORTING_IN_BUNKER_MODE` is True. +In manual mode all sleeps are disabled and `ALLOW_REPORTING_IN_BUNKER_MODE` is True. ## Env variables @@ -166,13 +166,17 @@ In manual mode all sleeps are disabled and `ALLOW_REPORTING_IN_BUNKER_MODE` is T | `CONSENSUS_CLIENT_URI` | URI of the Consensus Layer client | True | `http://localhost:5052` | | `KEYS_API_URI` | URI of the Keys API | True | `http://localhost:8080` | | `LIDO_LOCATOR_ADDRESS` | Address of the Lido contract | True | `0x1...` | +| `CSM_MODULE_ADDRESS` | Address of the CSModule contract | CSM only | `0x1...` | | `MEMBER_PRIV_KEY` | Private key of the Oracle member account | False | `0x1...` | | `MEMBER_PRIV_KEY_FILE` | A path to the file contained the private key of the Oracle member account. It takes precedence over `MEMBER_PRIV_KEY` | False | `/app/private_key` | -| `FINALIZATION_BATCH_MAX_REQUEST_COUNT` | The size of the batch to be finalized per request (The larger the batch size, the more memory of the contract is used but the fewer requests are needed) | False | `1000` | -| `ALLOW_REPORTING_IN_BUNKER_MODE` | Allow the Oracle to do report if bunker mode is active | False | `True` | +| `GW3_ACCESS_KEY` | An access key to gw3.io IPFS provider | CSM only | | +| `GW3_SECRET_KEY` | A secret key to gw3.io IPFS provider | CSM only | | +| `PINATA_JWT` | JWT token to access pinata.cloud IPFS provider | CSM only | | +| `FINALIZATION_BATCH_MAX_REQUEST_COUNT` | The size of the batch to be finalized per request (The larger the batch size, the more memory of the contract is used but the fewer requests are needed) | False | `1000` | | `ALLOW_REPORTING_IN_BUNKER_MODE` | Allow the Oracle to do report if bunker mode is active | False | `True` | | `DAEMON` | If False Oracle runs one cycle and ask for manual input to send report. | False | `True` | | `TX_GAS_ADDITION` | Used to modify gas parameter that used in transaction. (gas = estimated_gas + TX_GAS_ADDITION) | False | `100000` | | `CYCLE_SLEEP_IN_SECONDS` | The time between cycles of the oracle's activity | False | `12` | +| `MAX_CYCLE_LIFETIME_IN_SECONDS` | The maximum time for a cycle to continue | False | `3000` | | `SUBMIT_DATA_DELAY_IN_SLOTS` | The difference in slots between submit data transactions from Oracles. It is used to prevent simultaneous sending of transactions and, as a result, transactions revert. | False | `6` | | `HTTP_REQUEST_TIMEOUT_EXECUTION` | Timeout for HTTP execution layer requests | False | `120` | | `HTTP_REQUEST_TIMEOUT_CONSENSUS` | Timeout for HTTP consensus layer requests | False | `300` | @@ -181,18 +185,18 @@ In manual mode all sleeps are disabled and `ALLOW_REPORTING_IN_BUNKER_MODE` is T | `HTTP_REQUEST_TIMEOUT_KEYS_API` | Timeout for HTTP keys api requests | False | `120` | | `HTTP_REQUEST_RETRY_COUNT_KEYS_API` | Total number of retries to fetch data from endpoint for keys api requests | False | `300` | | `HTTP_REQUEST_SLEEP_BEFORE_RETRY_IN_SECONDS_KEYS_API` | The delay http provider sleeps if API is stuck for keys api | False | `300` | +| `HTTP_REQUEST_TIMEOUT_IPFS` | Timeout for HTTP requests to an IPFS provider | False | `30` | +| `HTTP_REQUEST_RETRY_COUNT_IPFS` | Total number of retries to fetch data from an IPFS provider | False | `3` | +| `EVENTS_SEARCH_STEP` | Maximum length of a range for eth_getLogs method calls | False | `10000` | | `PRIORITY_FEE_PERCENTILE` | Priority fee percentile from prev block that would be used to send tx | False | `3` | | `MIN_PRIORITY_FEE` | Min priority fee that would be used to send tx | False | `50000000` | | `MAX_PRIORITY_FEE` | Max priority fee that would be used to send tx | False | `100000000000` | +| `CSM_ORACLE_MAX_CONCURRENCY` | Max count of dedicated workers for CSM module | False | `2` | ### Mainnet variables -> LIDO_LOCATOR_ADDRESS=0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb +> LIDO_LOCATOR_ADDRESS=0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb > ALLOW_REPORTING_IN_BUNKER_MODE=False -### Goerli variables -> LIDO_LOCATOR_ADDRESS=0x1eDf09b5023DC86737b59dE68a8130De878984f5 -> ALLOW_REPORTING_IN_BUNKER_MODE=True - ### Alerts A few basic alerts, which can be configured in the [Prometheus Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/). @@ -225,26 +229,26 @@ groups: The oracle exposes the following basic metrics: -| Metric name | Description | Labels | -|-----------------------------|-----------------------------------------------------------------|----------------------------------------------------------------------------------------------------| -| build_info | Build info | version, branch, commit | -| env_variables_info | Env variables for the app | ACCOUNT, LIDO_LOCATOR_ADDRESS, FINALIZATION_BATCH_MAX_REQUEST_COUNT, MAX_CYCLE_LIFETIME_IN_SECONDS | -| genesis_time | Fetched genesis time from node | | -| account_balance | Fetched account balance from EL | address | -| slot_number | Last fetched slot number from CL | state (`head` or `finalized`) | -| block_number | Last fetched block number from CL | state (`head` or `finalized`) | -| functions_duration | Histogram metric with duration of each main function in the app | name, status | -| el_requests_duration | Histogram metric with duration of each EL request | endpoint, call_method, call_to, code, domain | -| cl_requests_duration | Histogram metric with duration of each CL request | endpoint, code, domain | -| keys_api_requests_duration | Histogram metric with duration of each KeysAPI request | endpoint, code, domain | -| keys_api_latest_blocknumber | Latest block number from KeysAPI metadata | | -| transaction_count | Total count of transactions. Success or failure | status | -| member_info | Oracle member info | is_report_member, is_submit_member, is_fast_lane | -| member_last_report_ref_slot | Member last report ref slot | | -| frame_current_ref_slot | Current frame ref slot | | -| frame_deadline_slot | Current frame deadline slot | | -| frame_prev_report_ref_slot | Previous report ref slot | | -| contract_on_pause | Contract on pause | | +| Metric name | Description | Labels | +|-----------------------------|-----------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------| +| build_info | Build info | version, branch, commit | +| env_variables_info | Env variables for the app | ACCOUNT, LIDO_LOCATOR_ADDRESS, CSM_MODULE_ADDRESS, FINALIZATION_BATCH_MAX_REQUEST_COUNT, MAX_CYCLE_LIFETIME_IN_SECONDS | +| genesis_time | Fetched genesis time from node | | +| account_balance | Fetched account balance from EL | address | +| slot_number | Last fetched slot number from CL | state (`head` or `finalized`) | +| block_number | Last fetched block number from CL | state (`head` or `finalized`) | +| functions_duration | Histogram metric with duration of each main function in the app | name, status | +| el_requests_duration | Histogram metric with duration of each EL request | endpoint, call_method, call_to, code, domain | +| cl_requests_duration | Histogram metric with duration of each CL request | endpoint, code, domain | +| keys_api_requests_duration | Histogram metric with duration of each KeysAPI request | endpoint, code, domain | +| keys_api_latest_blocknumber | Latest block number from KeysAPI metadata | | +| transaction_count | Total count of transactions. Success or failure | status | +| member_info | Oracle member info | is_report_member, is_submit_member, is_fast_lane | +| member_last_report_ref_slot | Member last report ref slot | | +| frame_current_ref_slot | Current frame ref slot | | +| frame_deadline_slot | Current frame deadline slot | | +| frame_prev_report_ref_slot | Previous report ref slot | | +| contract_on_pause | Contract on pause | | Special metrics for accounting oracle: @@ -263,12 +267,18 @@ Special metrics for ejector oracle: | Metric name | Description | Labels | |-----------------------------------|---------------------------------------------|--------| | ejector_withdrawal_wei_amount | To withdraw amount | | -| ejector_max_exit_epoch | Max exit epoch between all validators in CL | | +| ejector_max_withdrawal_epoch | Max exit epoch between all validators in CL | | | ejector_validators_count_to_eject | Validators count to eject | | +Special metrics for CSM oracle: + +| Metric name | Description | Labels | +|-----------------------------------|---------------------------------------------|--------| +| TBD | TBD | | + # Development -Python version: 3.11 +Python version: 3.12 ## Setup @@ -281,13 +291,25 @@ poetry install ## Startup -Required variables +Required variables for accounting and ejector modules + +```bash +export EXECUTION_CLIENT_URI=... +export CONSENSUS_CLIENT_URI=... +export KEYS_API_URI=... +export LIDO_LOCATOR_ADDRESS=... +``` + +Required variables for CSM module ```bash export EXECUTION_CLIENT_URI=... export CONSENSUS_CLIENT_URI=... export KEYS_API_URI=... export LIDO_LOCATOR_ADDRESS=... +export CSM_ORACLE_ADDRESS=... +export CSM_MODULE_ADDRESS=... +export MAX_CYCLE_LIFETIME_IN_SECONDS=60000 # Reasonable high value to make sure the oracle has enough time to process the whole frame. ``` Run oracle module @@ -300,6 +322,7 @@ Where `{module}` is one of: - `accounting` - `ejector` +- `csm` - `check` ## Tests diff --git a/assets/CSAccounting.json b/assets/CSAccounting.json new file mode 100644 index 000000000..348937605 --- /dev/null +++ b/assets/CSAccounting.json @@ -0,0 +1 @@ +[{"type":"function","name":"chargeFee","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"chargeRecipient","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"claimRewardsStETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"stETHAmount","type":"uint256","internalType":"uint256"},{"name":"rewardAddress","type":"address","internalType":"address"},{"name":"cumulativeFeeShares","type":"uint256","internalType":"uint256"},{"name":"rewardsProof","type":"bytes32[]","internalType":"bytes32[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"claimRewardsUnstETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"stEthAmount","type":"uint256","internalType":"uint256"},{"name":"rewardAddress","type":"address","internalType":"address"},{"name":"cumulativeFeeShares","type":"uint256","internalType":"uint256"},{"name":"rewardsProof","type":"bytes32[]","internalType":"bytes32[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"claimRewardsWstETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"wstETHAmount","type":"uint256","internalType":"uint256"},{"name":"rewardAddress","type":"address","internalType":"address"},{"name":"cumulativeFeeShares","type":"uint256","internalType":"uint256"},{"name":"rewardsProof","type":"bytes32[]","internalType":"bytes32[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"compensateLockedBondETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"depositETH","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"depositStETH","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"stETHAmount","type":"uint256","internalType":"uint256"},{"name":"permit","type":"tuple","internalType":"struct ICSAccounting.PermitInput","components":[{"name":"value","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"v","type":"uint8","internalType":"uint8"},{"name":"r","type":"bytes32","internalType":"bytes32"},{"name":"s","type":"bytes32","internalType":"bytes32"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"depositWstETH","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"wstETHAmount","type":"uint256","internalType":"uint256"},{"name":"permit","type":"tuple","internalType":"struct ICSAccounting.PermitInput","components":[{"name":"value","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"v","type":"uint8","internalType":"uint8"},{"name":"r","type":"bytes32","internalType":"bytes32"},{"name":"s","type":"bytes32","internalType":"bytes32"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"feeDistributor","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract ICSFeeDistributor"}],"stateMutability":"view"},{"type":"function","name":"getActualLockedBond","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getBond","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getBondAmountByKeysCount","inputs":[{"name":"keys","type":"uint256","internalType":"uint256"},{"name":"curve","type":"tuple","internalType":"struct ICSBondCurve.BondCurve","components":[{"name":"points","type":"uint256[]","internalType":"uint256[]"},{"name":"trend","type":"uint256","internalType":"uint256"}]}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getBondAmountByKeysCount","inputs":[{"name":"keys","type":"uint256","internalType":"uint256"},{"name":"curveId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getBondAmountByKeysCountWstETH","inputs":[{"name":"keysCount","type":"uint256","internalType":"uint256"},{"name":"curveId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getBondAmountByKeysCountWstETH","inputs":[{"name":"keysCount","type":"uint256","internalType":"uint256"},{"name":"curve","type":"tuple","internalType":"struct ICSBondCurve.BondCurve","components":[{"name":"points","type":"uint256[]","internalType":"uint256[]"},{"name":"trend","type":"uint256","internalType":"uint256"}]}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getBondCurve","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"tuple","internalType":"struct ICSBondCurve.BondCurve","components":[{"name":"points","type":"uint256[]","internalType":"uint256[]"},{"name":"trend","type":"uint256","internalType":"uint256"}]}],"stateMutability":"view"},{"type":"function","name":"getBondCurveId","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getBondLockRetentionPeriod","inputs":[],"outputs":[{"name":"retention","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getBondShares","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getCurveInfo","inputs":[{"name":"curveId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"tuple","internalType":"struct ICSBondCurve.BondCurve","components":[{"name":"points","type":"uint256[]","internalType":"uint256[]"},{"name":"trend","type":"uint256","internalType":"uint256"}]}],"stateMutability":"view"},{"type":"function","name":"getKeysCountByBondAmount","inputs":[{"name":"amount","type":"uint256","internalType":"uint256"},{"name":"curve","type":"tuple","internalType":"struct ICSBondCurve.BondCurve","components":[{"name":"points","type":"uint256[]","internalType":"uint256[]"},{"name":"trend","type":"uint256","internalType":"uint256"}]}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getKeysCountByBondAmount","inputs":[{"name":"amount","type":"uint256","internalType":"uint256"},{"name":"curveId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getLockedBondInfo","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"tuple","internalType":"struct ICSBondLock.BondLock","components":[{"name":"amount","type":"uint128","internalType":"uint128"},{"name":"retentionUntil","type":"uint128","internalType":"uint128"}]}],"stateMutability":"view"},{"type":"function","name":"getRequiredBondForNextKeys","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"additionalKeys","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getRequiredBondForNextKeysWstETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"additionalKeys","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getUnbondedKeysCount","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getUnbondedKeysCountToEject","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"lockBondETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"penalize","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"releaseLockedBondETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"resetBondCurve","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setBondCurve","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"curveId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"settleLockedBondETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"totalBondShares","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"}] diff --git a/assets/CSFeeDistributor.json b/assets/CSFeeDistributor.json new file mode 100644 index 000000000..da1cfa3ed --- /dev/null +++ b/assets/CSFeeDistributor.json @@ -0,0 +1 @@ +[{"type":"constructor","inputs":[{"name":"stETH","type":"address","internalType":"address"},{"name":"accounting","type":"address","internalType":"address"},{"name":"oracle","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"ACCOUNTING","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"DEFAULT_ADMIN_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"ORACLE","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"RECOVERER_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"STETH","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IStETH"}],"stateMutability":"view"},{"type":"function","name":"distributeFees","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"shares","type":"uint256","internalType":"uint256"},{"name":"proof","type":"bytes32[]","internalType":"bytes32[]"}],"outputs":[{"name":"sharesToDistribute","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"distributedShares","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getFeesToDistribute","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"shares","type":"uint256","internalType":"uint256"},{"name":"proof","type":"bytes32[]","internalType":"bytes32[]"}],"outputs":[{"name":"sharesToDistribute","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getRoleAdmin","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"getRoleMember","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"index","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getRoleMemberCount","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"grantRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"hasRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"hashLeaf","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"shares","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"pure"},{"type":"function","name":"initialize","inputs":[{"name":"admin","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"pendingSharesToDistribute","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"processOracleReport","inputs":[{"name":"_treeRoot","type":"bytes32","internalType":"bytes32"},{"name":"_treeCid","type":"string","internalType":"string"},{"name":"distributed","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"recoverERC1155","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"recoverERC20","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"recoverERC721","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"recoverEther","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"renounceRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"callerConfirmation","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"revokeRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"totalClaimableShares","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"treeCid","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"treeRoot","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"event","name":"DistributionDataUpdated","inputs":[{"name":"totalClaimableShares","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"treeRoot","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"treeCid","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"type":"event","name":"FeeDistributed","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"shares","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint64","indexed":false,"internalType":"uint64"}],"anonymous":false},{"type":"event","name":"RoleAdminChanged","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"previousAdminRole","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"newAdminRole","type":"bytes32","indexed":true,"internalType":"bytes32"}],"anonymous":false},{"type":"event","name":"RoleGranted","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"sender","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"RoleRevoked","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"sender","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"error","name":"AccessControlBadConfirmation","inputs":[]},{"type":"error","name":"AccessControlUnauthorizedAccount","inputs":[{"name":"account","type":"address","internalType":"address"},{"name":"neededRole","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"FeeSharesDecrease","inputs":[]},{"type":"error","name":"InvalidInitialization","inputs":[]},{"type":"error","name":"InvalidProof","inputs":[]},{"type":"error","name":"InvalidShares","inputs":[]},{"type":"error","name":"InvalidTreeCID","inputs":[]},{"type":"error","name":"InvalidTreeRoot","inputs":[]},{"type":"error","name":"NotAccounting","inputs":[]},{"type":"error","name":"NotAllowedToRecover","inputs":[]},{"type":"error","name":"NotEnoughShares","inputs":[]},{"type":"error","name":"NotInitializing","inputs":[]},{"type":"error","name":"NotOracle","inputs":[]},{"type":"error","name":"ZeroAccountingAddress","inputs":[]},{"type":"error","name":"ZeroAdminAddress","inputs":[]},{"type":"error","name":"ZeroOracleAddress","inputs":[]},{"type":"error","name":"ZeroStEthAddress","inputs":[]}] diff --git a/assets/CSFeeOracle.json b/assets/CSFeeOracle.json new file mode 100644 index 000000000..85a6e10d3 --- /dev/null +++ b/assets/CSFeeOracle.json @@ -0,0 +1 @@ +[{"type":"constructor","inputs":[{"name":"secondsPerSlot","type":"uint256","internalType":"uint256"},{"name":"genesisTime","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"CONTRACT_MANAGER_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"DEFAULT_ADMIN_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"GENESIS_TIME","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"MANAGE_CONSENSUS_CONTRACT_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"MANAGE_CONSENSUS_VERSION_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"PAUSE_INFINITELY","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"PAUSE_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"RECOVERER_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"RESUME_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"SECONDS_PER_SLOT","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"SUBMIT_DATA_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"avgPerfLeewayBP","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"discardConsensusReport","inputs":[{"name":"refSlot","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"feeDistributor","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract ICSFeeDistributor"}],"stateMutability":"view"},{"type":"function","name":"getConsensusContract","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getConsensusReport","inputs":[],"outputs":[{"name":"hash","type":"bytes32","internalType":"bytes32"},{"name":"refSlot","type":"uint256","internalType":"uint256"},{"name":"processingDeadlineTime","type":"uint256","internalType":"uint256"},{"name":"processingStarted","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"getConsensusVersion","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getContractVersion","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getLastProcessingRefSlot","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getResumeSinceTimestamp","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getRoleAdmin","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"getRoleMember","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"index","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getRoleMemberCount","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"grantRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"hasRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"initialize","inputs":[{"name":"admin","type":"address","internalType":"address"},{"name":"feeDistributorContract","type":"address","internalType":"address"},{"name":"consensusContract","type":"address","internalType":"address"},{"name":"consensusVersion","type":"uint256","internalType":"uint256"},{"name":"_avgPerfLeewayBP","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"isPaused","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"pauseFor","inputs":[{"name":"duration","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"pauseUntil","inputs":[{"name":"pauseUntilInclusive","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"recoverERC1155","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"recoverERC20","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"recoverERC721","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"recoverEther","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"renounceRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"callerConfirmation","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"resume","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"revokeRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setConsensusContract","inputs":[{"name":"addr","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setConsensusVersion","inputs":[{"name":"version","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setFeeDistributorContract","inputs":[{"name":"feeDistributorContract","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setPerformanceLeeway","inputs":[{"name":"valueBP","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"submitConsensusReport","inputs":[{"name":"reportHash","type":"bytes32","internalType":"bytes32"},{"name":"refSlot","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"submitReportData","inputs":[{"name":"data","type":"tuple","internalType":"struct CSFeeOracle.ReportData","components":[{"name":"consensusVersion","type":"uint256","internalType":"uint256"},{"name":"refSlot","type":"uint256","internalType":"uint256"},{"name":"treeRoot","type":"bytes32","internalType":"bytes32"},{"name":"treeCid","type":"string","internalType":"string"},{"name":"distributed","type":"uint256","internalType":"uint256"}]},{"name":"contractVersion","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"event","name":"ConsensusHashContractSet","inputs":[{"name":"addr","type":"address","indexed":true,"internalType":"address"},{"name":"prevAddr","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"ConsensusVersionSet","inputs":[{"name":"version","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"prevVersion","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"ContractVersionSet","inputs":[{"name":"version","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"FeeDistributorContractSet","inputs":[{"name":"feeDistributorContract","type":"address","indexed":false,"internalType":"address"}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint64","indexed":false,"internalType":"uint64"}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"name":"duration","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"PerfLeewaySet","inputs":[{"name":"valueBP","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"ProcessingStarted","inputs":[{"name":"refSlot","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"hash","type":"bytes32","indexed":false,"internalType":"bytes32"}],"anonymous":false},{"type":"event","name":"ReportDiscarded","inputs":[{"name":"refSlot","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"hash","type":"bytes32","indexed":false,"internalType":"bytes32"}],"anonymous":false},{"type":"event","name":"ReportSettled","inputs":[{"name":"refSlot","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"distributed","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"newRoot","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"treeCid","type":"string","indexed":false,"internalType":"string"}],"anonymous":false},{"type":"event","name":"ReportSubmitted","inputs":[{"name":"refSlot","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"hash","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"processingDeadlineTime","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Resumed","inputs":[],"anonymous":false},{"type":"event","name":"RoleAdminChanged","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"previousAdminRole","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"newAdminRole","type":"bytes32","indexed":true,"internalType":"bytes32"}],"anonymous":false},{"type":"event","name":"RoleGranted","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"sender","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"RoleRevoked","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"sender","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"WarnProcessingMissed","inputs":[{"name":"refSlot","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"error","name":"AccessControlBadConfirmation","inputs":[]},{"type":"error","name":"AccessControlUnauthorizedAccount","inputs":[{"name":"account","type":"address","internalType":"address"},{"name":"neededRole","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"AddressCannotBeSame","inputs":[]},{"type":"error","name":"AddressCannotBeZero","inputs":[]},{"type":"error","name":"AdminCannotBeZero","inputs":[]},{"type":"error","name":"HashCannotBeZero","inputs":[]},{"type":"error","name":"InitialRefSlotCannotBeLessThanProcessingOne","inputs":[{"name":"initialRefSlot","type":"uint256","internalType":"uint256"},{"name":"processingRefSlot","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"InvalidContractVersionIncrement","inputs":[]},{"type":"error","name":"InvalidInitialization","inputs":[]},{"type":"error","name":"InvalidPerfLeeway","inputs":[]},{"type":"error","name":"NoConsensusReportToProcess","inputs":[]},{"type":"error","name":"NonZeroContractVersionOnInit","inputs":[]},{"type":"error","name":"NotAllowedToRecover","inputs":[]},{"type":"error","name":"NotInitializing","inputs":[]},{"type":"error","name":"PauseUntilMustBeInFuture","inputs":[]},{"type":"error","name":"PausedExpected","inputs":[]},{"type":"error","name":"ProcessingDeadlineMissed","inputs":[{"name":"deadline","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"RefSlotAlreadyProcessing","inputs":[]},{"type":"error","name":"RefSlotCannotDecrease","inputs":[{"name":"refSlot","type":"uint256","internalType":"uint256"},{"name":"prevRefSlot","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"RefSlotMustBeGreaterThanProcessingOne","inputs":[{"name":"refSlot","type":"uint256","internalType":"uint256"},{"name":"processingRefSlot","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"ResumedExpected","inputs":[]},{"type":"error","name":"SafeCastOverflowedUintDowncast","inputs":[{"name":"bits","type":"uint8","internalType":"uint8"},{"name":"value","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"SecondsPerSlotCannotBeZero","inputs":[]},{"type":"error","name":"SenderIsNotTheConsensusContract","inputs":[]},{"type":"error","name":"SenderNotAllowed","inputs":[]},{"type":"error","name":"UnexpectedChainConfig","inputs":[]},{"type":"error","name":"UnexpectedConsensusVersion","inputs":[{"name":"expectedVersion","type":"uint256","internalType":"uint256"},{"name":"receivedVersion","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"UnexpectedContractVersion","inputs":[{"name":"expected","type":"uint256","internalType":"uint256"},{"name":"received","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"UnexpectedDataHash","inputs":[{"name":"consensusHash","type":"bytes32","internalType":"bytes32"},{"name":"receivedHash","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"UnexpectedRefSlot","inputs":[{"name":"consensusRefSlot","type":"uint256","internalType":"uint256"},{"name":"dataRefSlot","type":"uint256","internalType":"uint256"}]},{"type":"error","name":"VersionCannotBeSame","inputs":[]},{"type":"error","name":"ZeroPauseDuration","inputs":[]}] diff --git a/assets/CSModule.json b/assets/CSModule.json new file mode 100644 index 000000000..02b75373e --- /dev/null +++ b/assets/CSModule.json @@ -0,0 +1 @@ +[{"type":"constructor","inputs":[{"name":"moduleType","type":"bytes32","internalType":"bytes32"},{"name":"minSlashingPenaltyQuotient","type":"uint256","internalType":"uint256"},{"name":"elRewardsStealingFine","type":"uint256","internalType":"uint256"},{"name":"maxKeysPerOperatorEA","type":"uint256","internalType":"uint256"},{"name":"lidoLocator","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"type":"function","name":"DEFAULT_ADMIN_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"EL_REWARDS_STEALING_FINE","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"INITIAL_SLASHING_PENALTY","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"LIDO_LOCATOR","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract ILidoLocator"}],"stateMutability":"view"},{"type":"function","name":"MAX_SIGNING_KEYS_PER_OPERATOR_BEFORE_PUBLIC_RELEASE","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"MODULE_MANAGER_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"PAUSE_INFINITELY","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"PAUSE_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"RECOVERER_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"REPORT_EL_REWARDS_STEALING_PENALTY_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"RESUME_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"SETTLE_EL_REWARDS_STEALING_PENALTY_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"STAKING_ROUTER_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"STETH","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IStETH"}],"stateMutability":"view"},{"type":"function","name":"VERIFIER_ROLE","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"accounting","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract ICSAccounting"}],"stateMutability":"view"},{"type":"function","name":"activatePublicRelease","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"addNodeOperatorETH","inputs":[{"name":"keysCount","type":"uint256","internalType":"uint256"},{"name":"publicKeys","type":"bytes","internalType":"bytes"},{"name":"signatures","type":"bytes","internalType":"bytes"},{"name":"managerAddress","type":"address","internalType":"address"},{"name":"rewardAddress","type":"address","internalType":"address"},{"name":"eaProof","type":"bytes32[]","internalType":"bytes32[]"},{"name":"referrer","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"addNodeOperatorStETH","inputs":[{"name":"keysCount","type":"uint256","internalType":"uint256"},{"name":"publicKeys","type":"bytes","internalType":"bytes"},{"name":"signatures","type":"bytes","internalType":"bytes"},{"name":"managerAddress","type":"address","internalType":"address"},{"name":"rewardAddress","type":"address","internalType":"address"},{"name":"permit","type":"tuple","internalType":"struct ICSAccounting.PermitInput","components":[{"name":"value","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"v","type":"uint8","internalType":"uint8"},{"name":"r","type":"bytes32","internalType":"bytes32"},{"name":"s","type":"bytes32","internalType":"bytes32"}]},{"name":"eaProof","type":"bytes32[]","internalType":"bytes32[]"},{"name":"referrer","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"addNodeOperatorWstETH","inputs":[{"name":"keysCount","type":"uint256","internalType":"uint256"},{"name":"publicKeys","type":"bytes","internalType":"bytes"},{"name":"signatures","type":"bytes","internalType":"bytes"},{"name":"managerAddress","type":"address","internalType":"address"},{"name":"rewardAddress","type":"address","internalType":"address"},{"name":"permit","type":"tuple","internalType":"struct ICSAccounting.PermitInput","components":[{"name":"value","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"v","type":"uint8","internalType":"uint8"},{"name":"r","type":"bytes32","internalType":"bytes32"},{"name":"s","type":"bytes32","internalType":"bytes32"}]},{"name":"eaProof","type":"bytes32[]","internalType":"bytes32[]"},{"name":"referrer","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"addValidatorKeysETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"keysCount","type":"uint256","internalType":"uint256"},{"name":"publicKeys","type":"bytes","internalType":"bytes"},{"name":"signatures","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"addValidatorKeysStETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"keysCount","type":"uint256","internalType":"uint256"},{"name":"publicKeys","type":"bytes","internalType":"bytes"},{"name":"signatures","type":"bytes","internalType":"bytes"},{"name":"permit","type":"tuple","internalType":"struct ICSAccounting.PermitInput","components":[{"name":"value","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"v","type":"uint8","internalType":"uint8"},{"name":"r","type":"bytes32","internalType":"bytes32"},{"name":"s","type":"bytes32","internalType":"bytes32"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"addValidatorKeysWstETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"keysCount","type":"uint256","internalType":"uint256"},{"name":"publicKeys","type":"bytes","internalType":"bytes"},{"name":"signatures","type":"bytes","internalType":"bytes"},{"name":"permit","type":"tuple","internalType":"struct ICSAccounting.PermitInput","components":[{"name":"value","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"v","type":"uint8","internalType":"uint8"},{"name":"r","type":"bytes32","internalType":"bytes32"},{"name":"s","type":"bytes32","internalType":"bytes32"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"cancelELRewardsStealingPenalty","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"claimRewardsStETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"stETHAmount","type":"uint256","internalType":"uint256"},{"name":"cumulativeFeeShares","type":"uint256","internalType":"uint256"},{"name":"rewardsProof","type":"bytes32[]","internalType":"bytes32[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"claimRewardsUnstETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"stEthAmount","type":"uint256","internalType":"uint256"},{"name":"cumulativeFeeShares","type":"uint256","internalType":"uint256"},{"name":"rewardsProof","type":"bytes32[]","internalType":"bytes32[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"claimRewardsWstETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"wstETHAmount","type":"uint256","internalType":"uint256"},{"name":"cumulativeFeeShares","type":"uint256","internalType":"uint256"},{"name":"rewardsProof","type":"bytes32[]","internalType":"bytes32[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"cleanDepositQueue","inputs":[{"name":"maxItems","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"nonpayable"},{"type":"function","name":"compensateELRewardsStealingPenalty","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"confirmNodeOperatorManagerAddressChange","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"confirmNodeOperatorRewardAddressChange","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"decreaseVettedSigningKeysCount","inputs":[{"name":"nodeOperatorIds","type":"bytes","internalType":"bytes"},{"name":"vettedSigningKeysCounts","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"depositETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"depositQueue","inputs":[],"outputs":[{"name":"head","type":"uint128","internalType":"uint128"},{"name":"length","type":"uint128","internalType":"uint128"}],"stateMutability":"view"},{"type":"function","name":"depositQueueItem","inputs":[{"name":"index","type":"uint128","internalType":"uint128"}],"outputs":[{"name":"","type":"uint256","internalType":"Batch"}],"stateMutability":"view"},{"type":"function","name":"depositStETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"stETHAmount","type":"uint256","internalType":"uint256"},{"name":"permit","type":"tuple","internalType":"struct ICSAccounting.PermitInput","components":[{"name":"value","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"v","type":"uint8","internalType":"uint8"},{"name":"r","type":"bytes32","internalType":"bytes32"},{"name":"s","type":"bytes32","internalType":"bytes32"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"depositWstETH","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"wstETHAmount","type":"uint256","internalType":"uint256"},{"name":"permit","type":"tuple","internalType":"struct ICSAccounting.PermitInput","components":[{"name":"value","type":"uint256","internalType":"uint256"},{"name":"deadline","type":"uint256","internalType":"uint256"},{"name":"v","type":"uint8","internalType":"uint8"},{"name":"r","type":"bytes32","internalType":"bytes32"},{"name":"s","type":"bytes32","internalType":"bytes32"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"earlyAdoption","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract ICSEarlyAdoption"}],"stateMutability":"view"},{"type":"function","name":"getActiveNodeOperatorsCount","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getNodeOperator","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"tuple","internalType":"struct NodeOperator","components":[{"name":"totalAddedKeys","type":"uint32","internalType":"uint32"},{"name":"totalWithdrawnKeys","type":"uint32","internalType":"uint32"},{"name":"totalDepositedKeys","type":"uint32","internalType":"uint32"},{"name":"totalVettedKeys","type":"uint32","internalType":"uint32"},{"name":"stuckValidatorsCount","type":"uint32","internalType":"uint32"},{"name":"depositableValidatorsCount","type":"uint32","internalType":"uint32"},{"name":"targetLimit","type":"uint32","internalType":"uint32"},{"name":"targetLimitMode","type":"uint8","internalType":"uint8"},{"name":"totalExitedKeys","type":"uint32","internalType":"uint32"},{"name":"enqueuedCount","type":"uint32","internalType":"uint32"},{"name":"managerAddress","type":"address","internalType":"address"},{"name":"proposedManagerAddress","type":"address","internalType":"address"},{"name":"rewardAddress","type":"address","internalType":"address"},{"name":"proposedRewardAddress","type":"address","internalType":"address"}]}],"stateMutability":"view"},{"type":"function","name":"getNodeOperatorIds","inputs":[{"name":"offset","type":"uint256","internalType":"uint256"},{"name":"limit","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"nodeOperatorIds","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"view"},{"type":"function","name":"getNodeOperatorIsActive","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"getNodeOperatorNonWithdrawnKeys","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getNodeOperatorSummary","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"targetLimitMode","type":"uint256","internalType":"uint256"},{"name":"targetValidatorsCount","type":"uint256","internalType":"uint256"},{"name":"stuckValidatorsCount","type":"uint256","internalType":"uint256"},{"name":"refundedValidatorsCount","type":"uint256","internalType":"uint256"},{"name":"stuckPenaltyEndTimestamp","type":"uint256","internalType":"uint256"},{"name":"totalExitedValidators","type":"uint256","internalType":"uint256"},{"name":"totalDepositedValidators","type":"uint256","internalType":"uint256"},{"name":"depositableValidatorsCount","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getNodeOperatorsCount","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getNonce","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getResumeSinceTimestamp","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getRoleAdmin","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"getRoleMember","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"index","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"getRoleMemberCount","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getSigningKeys","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"startIndex","type":"uint256","internalType":"uint256"},{"name":"keysCount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bytes","internalType":"bytes"}],"stateMutability":"view"},{"type":"function","name":"getSigningKeysWithSignatures","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"startIndex","type":"uint256","internalType":"uint256"},{"name":"keysCount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"keys","type":"bytes","internalType":"bytes"},{"name":"signatures","type":"bytes","internalType":"bytes"}],"stateMutability":"view"},{"type":"function","name":"getStakingModuleSummary","inputs":[],"outputs":[{"name":"totalExitedValidators","type":"uint256","internalType":"uint256"},{"name":"totalDepositedValidators","type":"uint256","internalType":"uint256"},{"name":"depositableValidatorsCount","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getType","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"grantRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"hasRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"initialize","inputs":[{"name":"_accounting","type":"address","internalType":"address"},{"name":"_earlyAdoption","type":"address","internalType":"address"},{"name":"_keyRemovalCharge","type":"uint256","internalType":"uint256"},{"name":"admin","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"isPaused","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"isValidatorSlashed","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"keyIndex","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"isValidatorWithdrawn","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"keyIndex","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"keyRemovalCharge","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"normalizeQueue","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"obtainDepositData","inputs":[{"name":"depositsCount","type":"uint256","internalType":"uint256"},{"name":"","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"publicKeys","type":"bytes","internalType":"bytes"},{"name":"signatures","type":"bytes","internalType":"bytes"}],"stateMutability":"nonpayable"},{"type":"function","name":"onExitedAndStuckValidatorsCountsUpdated","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"onRewardsMinted","inputs":[{"name":"totalShares","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"onWithdrawalCredentialsChanged","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"pauseFor","inputs":[{"name":"duration","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"proposeNodeOperatorManagerAddressChange","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"proposedAddress","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"proposeNodeOperatorRewardAddressChange","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"proposedAddress","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"publicRelease","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"recoverERC1155","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"recoverERC20","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"recoverERC721","inputs":[{"name":"token","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"recoverEther","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"recoverStETHShares","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"removeKeys","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"startIndex","type":"uint256","internalType":"uint256"},{"name":"keysCount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"renounceRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"callerConfirmation","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"reportELRewardsStealingPenalty","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"blockHash","type":"bytes32","internalType":"bytes32"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"resetNodeOperatorManagerAddress","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"resume","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"revokeRole","inputs":[{"name":"role","type":"bytes32","internalType":"bytes32"},{"name":"account","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setKeyRemovalCharge","inputs":[{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"settleELRewardsStealingPenalty","inputs":[{"name":"nodeOperatorIds","type":"uint256[]","internalType":"uint256[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"submitInitialSlashing","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"keyIndex","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"submitWithdrawal","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"keyIndex","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"unsafeUpdateValidatorsCount","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"exitedValidatorsKeysCount","type":"uint256","internalType":"uint256"},{"name":"stuckValidatorsKeysCount","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"updateExitedValidatorsCount","inputs":[{"name":"nodeOperatorIds","type":"bytes","internalType":"bytes"},{"name":"exitedValidatorsCounts","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"updateRefundedValidatorsCount","inputs":[{"name":"","type":"uint256","internalType":"uint256"},{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"updateStuckValidatorsCount","inputs":[{"name":"nodeOperatorIds","type":"bytes","internalType":"bytes"},{"name":"stuckValidatorsCounts","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"updateTargetValidatorsLimits","inputs":[{"name":"nodeOperatorId","type":"uint256","internalType":"uint256"},{"name":"targetLimitMode","type":"uint256","internalType":"uint256"},{"name":"targetLimit","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"DepositedSigningKeysCountChanged","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"depositedKeysCount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"ELRewardsStealingPenaltyCancelled","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"ELRewardsStealingPenaltyReported","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"proposedBlockHash","type":"bytes32","indexed":false,"internalType":"bytes32"},{"name":"stolenAmount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"ELRewardsStealingPenaltySettled","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"ExitedSigningKeysCountChanged","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"exitedKeysCount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"InitialSlashingSubmitted","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"keyIndex","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint64","indexed":false,"internalType":"uint64"}],"anonymous":false},{"type":"event","name":"KeyRemovalChargeApplied","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"KeyRemovalChargeSet","inputs":[{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"NodeOperatorAdded","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"managerAddress","type":"address","indexed":true,"internalType":"address"},{"name":"rewardAddress","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"NonceChanged","inputs":[{"name":"nonce","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"name":"duration","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"PublicRelease","inputs":[],"anonymous":false},{"type":"event","name":"ReferrerSet","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"referrer","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"Resumed","inputs":[],"anonymous":false},{"type":"event","name":"RoleAdminChanged","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"previousAdminRole","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"newAdminRole","type":"bytes32","indexed":true,"internalType":"bytes32"}],"anonymous":false},{"type":"event","name":"RoleGranted","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"sender","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"RoleRevoked","inputs":[{"name":"role","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"account","type":"address","indexed":true,"internalType":"address"},{"name":"sender","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"SigningKeyAdded","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"pubkey","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false},{"type":"event","name":"SigningKeyAdded","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"pubkey","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false},{"type":"event","name":"SigningKeyRemoved","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"pubkey","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false},{"type":"event","name":"SigningKeyRemoved","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"pubkey","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false},{"type":"event","name":"StuckSigningKeysCountChanged","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"stuckKeysCount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"TargetValidatorsCountChangedByRequest","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"targetLimitMode","type":"uint8","indexed":false,"internalType":"uint8"},{"name":"targetValidatorsCount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"TotalSigningKeysCountChanged","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"totalKeysCount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"VettedSigningKeysCountChanged","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"vettedKeysCount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"WithdrawalSubmitted","inputs":[{"name":"nodeOperatorId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"keyIndex","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"type":"error","name":"AccessControlBadConfirmation","inputs":[]},{"type":"error","name":"AccessControlUnauthorizedAccount","inputs":[{"name":"account","type":"address","internalType":"address"},{"name":"neededRole","type":"bytes32","internalType":"bytes32"}]},{"type":"error","name":"AlreadySet","inputs":[]},{"type":"error","name":"AlreadySubmitted","inputs":[]},{"type":"error","name":"AlreadyWithdrawn","inputs":[]},{"type":"error","name":"EmptyKey","inputs":[]},{"type":"error","name":"ExitedKeysDecrease","inputs":[]},{"type":"error","name":"ExitedKeysHigherThanTotalDeposited","inputs":[]},{"type":"error","name":"InvalidAmount","inputs":[]},{"type":"error","name":"InvalidInitialization","inputs":[]},{"type":"error","name":"InvalidKeysCount","inputs":[]},{"type":"error","name":"InvalidLength","inputs":[]},{"type":"error","name":"InvalidReportData","inputs":[]},{"type":"error","name":"InvalidVetKeysPointer","inputs":[]},{"type":"error","name":"MaxSigningKeysCountExceeded","inputs":[]},{"type":"error","name":"NodeOperatorDoesNotExist","inputs":[]},{"type":"error","name":"NotAllowedToJoinYet","inputs":[]},{"type":"error","name":"NotAllowedToRecover","inputs":[]},{"type":"error","name":"NotEnoughKeys","inputs":[]},{"type":"error","name":"NotInitializing","inputs":[]},{"type":"error","name":"NotSupported","inputs":[]},{"type":"error","name":"PauseUntilMustBeInFuture","inputs":[]},{"type":"error","name":"PausedExpected","inputs":[]},{"type":"error","name":"QueueIsEmpty","inputs":[]},{"type":"error","name":"ResumedExpected","inputs":[]},{"type":"error","name":"SenderIsNotEligible","inputs":[]},{"type":"error","name":"SigningKeysInvalidOffset","inputs":[]},{"type":"error","name":"StuckKeysHigherThanExited","inputs":[]},{"type":"error","name":"ZeroAccountingAddress","inputs":[]},{"type":"error","name":"ZeroAdminAddress","inputs":[]},{"type":"error","name":"ZeroLocatorAddress","inputs":[]},{"type":"error","name":"ZeroPauseDuration","inputs":[]}] diff --git a/assets/DepositContract.json b/assets/DepositContract.json new file mode 100644 index 000000000..be0e97fc7 --- /dev/null +++ b/assets/DepositContract.json @@ -0,0 +1 @@ +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"pubkey","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"withdrawal_credentials","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"amount","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"signature","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"index","type":"bytes"}],"name":"DepositEvent","type":"event"},{"inputs":[{"internalType":"bytes","name":"pubkey","type":"bytes"},{"internalType":"bytes","name":"withdrawal_credentials","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes32","name":"deposit_data_root","type":"bytes32"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"get_deposit_count","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"get_deposit_root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}] diff --git a/assets/StakingRouterV2.json b/assets/StakingRouterV2.json new file mode 100644 index 000000000..307ede98b --- /dev/null +++ b/assets/StakingRouterV2.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"_depositContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AppAuthLidoFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"firstArrayLength","type":"uint256"},{"internalType":"uint256","name":"secondArrayLength","type":"uint256"}],"name":"ArraysLengthMismatch","type":"error"},{"inputs":[],"name":"DepositContractZeroAddress","type":"error"},{"inputs":[],"name":"DirectETHTransfer","type":"error"},{"inputs":[],"name":"EmptyWithdrawalsCredentials","type":"error"},{"inputs":[],"name":"ExitedValidatorsCountCannotDecrease","type":"error"},{"inputs":[],"name":"InvalidContractVersionIncrement","type":"error"},{"inputs":[{"internalType":"uint256","name":"etherValue","type":"uint256"},{"internalType":"uint256","name":"depositsCount","type":"uint256"}],"name":"InvalidDepositsValue","type":"error"},{"inputs":[],"name":"InvalidMinDepositBlockDistance","type":"error"},{"inputs":[],"name":"InvalidPriorityExitShareThreshold","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"InvalidPublicKeysBatchLength","type":"error"},{"inputs":[{"internalType":"uint256","name":"code","type":"uint256"}],"name":"InvalidReportData","type":"error"},{"inputs":[{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"expected","type":"uint256"}],"name":"InvalidSignaturesBatchLength","type":"error"},{"inputs":[],"name":"NonZeroContractVersionOnInit","type":"error"},{"inputs":[{"internalType":"uint256","name":"reportedExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"depositedValidatorsCount","type":"uint256"}],"name":"ReportedExitedValidatorsExceedDeposited","type":"error"},{"inputs":[],"name":"StakingModuleAddressExists","type":"error"},{"inputs":[],"name":"StakingModuleNotActive","type":"error"},{"inputs":[],"name":"StakingModuleStatusTheSame","type":"error"},{"inputs":[],"name":"StakingModuleUnregistered","type":"error"},{"inputs":[],"name":"StakingModuleWrongName","type":"error"},{"inputs":[],"name":"StakingModulesLimitExceeded","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"UnexpectedContractVersion","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentModuleExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOpExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOpStuckValidatorsCount","type":"uint256"}],"name":"UnexpectedCurrentValidatorsCount","type":"error"},{"inputs":[],"name":"UnrecoverableModuleError","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ValueOver100Percent","type":"error"},{"inputs":[{"internalType":"string","name":"field","type":"string"}],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"}],"name":"ContractVersionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"lowLevelRevertData","type":"bytes"}],"name":"ExitedAndStuckValidatorsCountsUpdateFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"lowLevelRevertData","type":"bytes"}],"name":"RewardsMintedReportFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"address","name":"stakingModule","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"address","name":"createdBy","type":"address"}],"name":"StakingModuleAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unreportedExitedValidatorsCount","type":"uint256"}],"name":"StakingModuleExitedValidatorsIncompleteReporting","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakingModuleFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"treasuryFee","type":"uint256"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleFeesSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxDepositsPerBlock","type":"uint256"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleMaxDepositsPerBlockSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minDepositBlockDistance","type":"uint256"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleMinDepositBlockDistanceSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakeShareLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priorityExitShareThreshold","type":"uint256"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleShareLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"enum StakingRouter.StakingModuleStatus","name":"status","type":"uint8"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"StakingModuleStatusSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakingRouterETHDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"withdrawalCredentials","type":"bytes32"},{"indexed":false,"internalType":"address","name":"setBy","type":"address"}],"name":"WithdrawalCredentialsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"lowLevelRevertData","type":"bytes"}],"name":"WithdrawalsCredentialsChangeFailed","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEPOSIT_CONTRACT","outputs":[{"internalType":"contract IDepositContract","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_PRECISION_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGE_WITHDRAWAL_CREDENTIALS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_STAKING_MODULES_COUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_STAKING_MODULE_NAME_LENGTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REPORT_EXITED_VALIDATORS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REPORT_REWARDS_MINTED_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_MODULE_MANAGE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STAKING_MODULE_UNVETTING_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOTAL_BASIS_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNSAFE_SET_EXITED_VALIDATORS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"address","name":"_stakingModuleAddress","type":"address"},{"internalType":"uint256","name":"_stakeShareLimit","type":"uint256"},{"internalType":"uint256","name":"_priorityExitShareThreshold","type":"uint256"},{"internalType":"uint256","name":"_stakingModuleFee","type":"uint256"},{"internalType":"uint256","name":"_treasuryFee","type":"uint256"},{"internalType":"uint256","name":"_maxDepositsPerBlock","type":"uint256"},{"internalType":"uint256","name":"_minDepositBlockDistance","type":"uint256"}],"name":"addStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"_nodeOperatorIds","type":"bytes"},{"internalType":"bytes","name":"_vettedSigningKeysCounts","type":"bytes"}],"name":"decreaseStakingModuleVettedKeysCountByNodeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositsCount","type":"uint256"},{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"_depositCalldata","type":"bytes"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_priorityExitShareThresholds","type":"uint256[]"}],"name":"finalizeUpgrade_v2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getAllNodeOperatorDigests","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"components":[{"internalType":"uint256","name":"targetLimitMode","type":"uint256"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.NodeOperatorDigest[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllStakingModuleDigests","outputs":[{"components":[{"internalType":"uint256","name":"nodeOperatorsCount","type":"uint256"},{"internalType":"uint256","name":"activeNodeOperatorsCount","type":"uint256"},{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"stakeShareLimit","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"},{"internalType":"uint16","name":"priorityExitShareThreshold","type":"uint16"},{"internalType":"uint64","name":"maxDepositsPerBlock","type":"uint64"},{"internalType":"uint64","name":"minDepositBlockDistance","type":"uint64"}],"internalType":"struct StakingRouter.StakingModule","name":"state","type":"tuple"},{"components":[{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModuleSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.StakingModuleDigest[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContractVersion","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_depositsCount","type":"uint256"}],"name":"getDepositsAllocation","outputs":[{"internalType":"uint256","name":"allocated","type":"uint256"},{"internalType":"uint256[]","name":"allocations","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLido","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256[]","name":"_nodeOperatorIds","type":"uint256[]"}],"name":"getNodeOperatorDigests","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"components":[{"internalType":"uint256","name":"targetLimitMode","type":"uint256"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.NodeOperatorDigest[]","name":"digests","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getNodeOperatorDigests","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"},{"components":[{"internalType":"uint256","name":"targetLimitMode","type":"uint256"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.NodeOperatorDigest[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"}],"name":"getNodeOperatorSummary","outputs":[{"components":[{"internalType":"uint256","name":"targetLimitMode","type":"uint256"},{"internalType":"uint256","name":"targetValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"refundedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"stuckPenaltyEndTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.NodeOperatorSummary","name":"summary","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingFeeAggregateDistribution","outputs":[{"internalType":"uint96","name":"modulesFee","type":"uint96"},{"internalType":"uint96","name":"treasuryFee","type":"uint96"},{"internalType":"uint256","name":"basePrecision","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingFeeAggregateDistributionE4Precision","outputs":[{"internalType":"uint16","name":"modulesFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModule","outputs":[{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"stakeShareLimit","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"},{"internalType":"uint16","name":"priorityExitShareThreshold","type":"uint16"},{"internalType":"uint64","name":"maxDepositsPerBlock","type":"uint64"},{"internalType":"uint64","name":"minDepositBlockDistance","type":"uint64"}],"internalType":"struct StakingRouter.StakingModule","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleActiveValidatorsCount","outputs":[{"internalType":"uint256","name":"activeValidatorsCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_stakingModuleIds","type":"uint256[]"}],"name":"getStakingModuleDigests","outputs":[{"components":[{"internalType":"uint256","name":"nodeOperatorsCount","type":"uint256"},{"internalType":"uint256","name":"activeNodeOperatorsCount","type":"uint256"},{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"stakeShareLimit","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"},{"internalType":"uint16","name":"priorityExitShareThreshold","type":"uint16"},{"internalType":"uint64","name":"maxDepositsPerBlock","type":"uint64"},{"internalType":"uint64","name":"minDepositBlockDistance","type":"uint64"}],"internalType":"struct StakingRouter.StakingModule","name":"state","type":"tuple"},{"components":[{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModuleSummary","name":"summary","type":"tuple"}],"internalType":"struct StakingRouter.StakingModuleDigest[]","name":"digests","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingModuleIds","outputs":[{"internalType":"uint256[]","name":"stakingModuleIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleIsDepositsPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleIsStopped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleLastDepositBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_maxDepositsValue","type":"uint256"}],"name":"getStakingModuleMaxDepositsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleMaxDepositsPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleMinDepositBlockDistance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleStatus","outputs":[{"internalType":"enum StakingRouter.StakingModuleStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"getStakingModuleSummary","outputs":[{"components":[{"internalType":"uint256","name":"totalExitedValidators","type":"uint256"},{"internalType":"uint256","name":"totalDepositedValidators","type":"uint256"},{"internalType":"uint256","name":"depositableValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.StakingModuleSummary","name":"summary","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingModules","outputs":[{"components":[{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"address","name":"stakingModuleAddress","type":"address"},{"internalType":"uint16","name":"stakingModuleFee","type":"uint16"},{"internalType":"uint16","name":"treasuryFee","type":"uint16"},{"internalType":"uint16","name":"stakeShareLimit","type":"uint16"},{"internalType":"uint8","name":"status","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint64","name":"lastDepositAt","type":"uint64"},{"internalType":"uint256","name":"lastDepositBlock","type":"uint256"},{"internalType":"uint256","name":"exitedValidatorsCount","type":"uint256"},{"internalType":"uint16","name":"priorityExitShareThreshold","type":"uint16"},{"internalType":"uint64","name":"maxDepositsPerBlock","type":"uint64"},{"internalType":"uint64","name":"minDepositBlockDistance","type":"uint64"}],"internalType":"struct StakingRouter.StakingModule[]","name":"res","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingModulesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingRewardsDistribution","outputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"stakingModuleIds","type":"uint256[]"},{"internalType":"uint96[]","name":"stakingModuleFees","type":"uint96[]"},{"internalType":"uint96","name":"totalFee","type":"uint96"},{"internalType":"uint256","name":"precisionPoints","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalFeeE4Precision","outputs":[{"internalType":"uint16","name":"totalFee","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawalCredentials","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"}],"name":"hasStakingModule","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_lido","type":"address"},{"internalType":"bytes32","name":"_withdrawalCredentials","type":"bytes32"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"onValidatorsCountsByNodeOperatorReportingFinished","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_stakingModuleIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_totalShares","type":"uint256[]"}],"name":"reportRewardsMinted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"_nodeOperatorIds","type":"bytes"},{"internalType":"bytes","name":"_exitedValidatorsCounts","type":"bytes"}],"name":"reportStakingModuleExitedValidatorsCountByNodeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"bytes","name":"_nodeOperatorIds","type":"bytes"},{"internalType":"bytes","name":"_stuckValidatorsCounts","type":"bytes"}],"name":"reportStakingModuleStuckValidatorsCountByNodeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"enum StakingRouter.StakingModuleStatus","name":"_status","type":"uint8"}],"name":"setStakingModuleStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_withdrawalCredentials","type":"bytes32"}],"name":"setWithdrawalCredentials","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"},{"internalType":"bool","name":"_triggerUpdateFinish","type":"bool"},{"components":[{"internalType":"uint256","name":"currentModuleExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOperatorExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"currentNodeOperatorStuckValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"newModuleExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"newNodeOperatorExitedValidatorsCount","type":"uint256"},{"internalType":"uint256","name":"newNodeOperatorStuckValidatorsCount","type":"uint256"}],"internalType":"struct StakingRouter.ValidatorsCountsCorrection","name":"_correction","type":"tuple"}],"name":"unsafeSetExitedValidatorsCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_stakingModuleIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_exitedValidatorsCounts","type":"uint256[]"}],"name":"updateExitedValidatorsCountByStakingModule","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"},{"internalType":"uint256","name":"_refundedValidatorsCount","type":"uint256"}],"name":"updateRefundedValidatorsCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_stakeShareLimit","type":"uint256"},{"internalType":"uint256","name":"_priorityExitShareThreshold","type":"uint256"},{"internalType":"uint256","name":"_stakingModuleFee","type":"uint256"},{"internalType":"uint256","name":"_treasuryFee","type":"uint256"},{"internalType":"uint256","name":"_maxDepositsPerBlock","type":"uint256"},{"internalType":"uint256","name":"_minDepositBlockDistance","type":"uint256"}],"name":"updateStakingModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"_nodeOperatorId","type":"uint256"},{"internalType":"uint256","name":"_targetLimitMode","type":"uint256"},{"internalType":"uint256","name":"_targetLimit","type":"uint256"}],"name":"updateTargetValidatorsLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}] \ No newline at end of file diff --git a/fixtures/common/contracts.json b/fixtures/common/contracts.json index a6b251db4..cf009cf73 100644 --- a/fixtures/common/contracts.json +++ b/fixtures/common/contracts.json @@ -119,4 +119,4 @@ "result": "0x000000000000000000000000655617d5fb44649e979e41229cbae9e9b63c0a2a" } } -] \ No newline at end of file +] diff --git a/fixtures/tests/modules/submodules/consensus/test_consensus.py/test_get_blockstamp_for_report_slot_deadline_missed.json b/fixtures/tests/modules/submodules/consensus/test_consensus.py/test_get_blockstamp_for_report_slot_deadline_missed.json index e4105cf4a..1d0ca68f6 100644 --- a/fixtures/tests/modules/submodules/consensus/test_consensus.py/test_get_blockstamp_for_report_slot_deadline_missed.json +++ b/fixtures/tests/modules/submodules/consensus/test_consensus.py/test_get_blockstamp_for_report_slot_deadline_missed.json @@ -51,7 +51,7 @@ "to": "0x3FD30E8360e2E637be3428fB78A3d8D0ad157197", "data": "0x8aa10435" }, - "0xe8f747cf6290c329c0ea73a1ffcf3dff24423810b4e5513e8acf95a294647dfa" + "0x0d339fdfa3018561311a39bf00568ed08048055082448d17091d5a4dc2fa035b" ], "response": { "jsonrpc": "2.0", diff --git a/fixtures/tests/modules/submodules/consensus/test_consensus.py/test_get_blockstamp_for_report_slot_member_is_not_in_fast_line_ready.json b/fixtures/tests/modules/submodules/consensus/test_consensus.py/test_get_blockstamp_for_report_slot_member_is_not_in_fast_line_ready.json index 7edfe1292..84139e1c9 100644 --- a/fixtures/tests/modules/submodules/consensus/test_consensus.py/test_get_blockstamp_for_report_slot_member_is_not_in_fast_line_ready.json +++ b/fixtures/tests/modules/submodules/consensus/test_consensus.py/test_get_blockstamp_for_report_slot_member_is_not_in_fast_line_ready.json @@ -51,7 +51,7 @@ "to": "0x3FD30E8360e2E637be3428fB78A3d8D0ad157197", "data": "0x8aa10435" }, - "0xe8f747cf6290c329c0ea73a1ffcf3dff24423810b4e5513e8acf95a294647dfa" + "0x05d6cacd19b66244baee75e9262cf6716928a43cb9348c100845005cbe7e3785" ], "response": { "jsonrpc": "2.0", @@ -66,7 +66,7 @@ "to": "0x3FD30E8360e2E637be3428fB78A3d8D0ad157197", "data": "0x5be20425" }, - "0xe8f747cf6290c329c0ea73a1ffcf3dff24423810b4e5513e8acf95a294647dfa" + "0x05d6cacd19b66244baee75e9262cf6716928a43cb9348c100845005cbe7e3785" ], "response": { "jsonrpc": "2.0", diff --git a/fixtures/tests/modules/submodules/consensus/test_consensus.py/test_get_blockstamp_for_report_slot_member_ready_to_report.json b/fixtures/tests/modules/submodules/consensus/test_consensus.py/test_get_blockstamp_for_report_slot_member_ready_to_report.json index ee63cf166..1bc42b314 100644 --- a/fixtures/tests/modules/submodules/consensus/test_consensus.py/test_get_blockstamp_for_report_slot_member_ready_to_report.json +++ b/fixtures/tests/modules/submodules/consensus/test_consensus.py/test_get_blockstamp_for_report_slot_member_ready_to_report.json @@ -6,7 +6,7 @@ "to": "0x3FD30E8360e2E637be3428fB78A3d8D0ad157197", "data": "0x8aa10435" }, - "0xe8f747cf6290c329c0ea73a1ffcf3dff24423810b4e5513e8acf95a294647dfa" + "0x0d339fdfa3018561311a39bf00568ed08048055082448d17091d5a4dc2fa035b" ], "response": { "jsonrpc": "2.0", @@ -21,7 +21,7 @@ "to": "0x3FD30E8360e2E637be3428fB78A3d8D0ad157197", "data": "0x5be20425" }, - "0xe8f747cf6290c329c0ea73a1ffcf3dff24423810b4e5513e8acf95a294647dfa" + "0x0d339fdfa3018561311a39bf00568ed08048055082448d17091d5a4dc2fa035b" ], "response": { "jsonrpc": "2.0", diff --git a/fixtures/tests/utils/test_slot.py/test_get_third_non_missed_slot.cl.json b/fixtures/tests/utils/test_slot.py/test_get_third_non_missed_slot_backward.cl.json similarity index 100% rename from fixtures/tests/utils/test_slot.py/test_get_third_non_missed_slot.cl.json rename to fixtures/tests/utils/test_slot.py/test_get_third_non_missed_slot_backward.cl.json diff --git a/fixtures/tests/utils/test_slot.py/test_get_third_non_missed_slot_forward.cl.json b/fixtures/tests/utils/test_slot.py/test_get_third_non_missed_slot_forward.cl.json new file mode 100644 index 000000000..abb83092c --- /dev/null +++ b/fixtures/tests/utils/test_slot.py/test_get_third_non_missed_slot_forward.cl.json @@ -0,0 +1,4895 @@ +[ + { + "url": "eth/v1/beacon/blocks/finalized/root", + "params": null, + "response": [ + { + "root": "0x14fe282cb29766b4eca3e1d1a168223e86f3c78bac161f50fb57791d1278e63b" + }, + { + "execution_optimistic": false, + "finalized": true + } + ] + }, + { + "url": "eth/v2/beacon/blocks/0x14fe282cb29766b4eca3e1d1a168223e86f3c78bac161f50fb57791d1278e63b", + "params": null, + "response": [ + { + "message": { + "slot": "1541632", + "proposer_index": "1087016", + "parent_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "state_root": "0x6d29101bc16ed814b0cd249bdbc48519eff26f1231a7af848ef30115f32569b2", + "body": { + "randao_reveal": "0x93993270a061d672a505b40c81e0abb90d515a0611629226da481fccb3c12e21330a76840ebcac1ce5a931b1d454baac0fb2cd90e106a2bd214eaa71893cc65fa67c676cef5143ea660de081395fcd08633c07a7608a08718683d14cb3423536", + "eth1_data": { + "deposit_root": "0xe224c112700cfb2a9c9f5e3297a77fea6afa82e0fb831f79f0a04d8516274123", + "deposit_count": "258908", + "block_hash": "0x38dbdfdaed6826f0cbce3dd711a944fe8edf832a57221a5971a543e7def363d8" + }, + "graffiti": "0x6574682e7032702e6f7267000000000000000000000000000000000000000000", + "proposer_slashings": [], + "attester_slashings": [], + "attestations": [ + { + "aggregation_bits": "0xfffebdffffd7f7ffbbfffdffffffffbf7bbffef7bfd3fffffafffefffbff776bfff57fe7ffdfff7edffffdebfffefffffffffcfbffffedfff53fffefffffbfafff7d7ff7f9ffbff7fdd7fefbe6dfd7f7ffff7fbfebfd7efff5ffefffff7f7dfffffbff17", + "data": { + "slot": "1541631", + "index": "47", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa21ccbbda21b1b81fe702182814a0f55c843a15d6e0106513872352ae13054ca8f53f974b442a1115d338bff11c799e20d3c8ee8894b1c1128d76e1a1cdb2ced1b59d4ec8e27f94e0006843b6f5ed4a8bbfc77c5290cf5a161f565dfbb1430bc" + }, + { + "aggregation_bits": "0xfffffbfffff5fffefff7ffcfffbffffc7fbbbefffff7dffffeeffeefbfffef7ee3fefbfffdfdf6fffeffffddffeefffdf77ff6fdfffdeffff777ffffebdff7eff3fefdebffffbffdffdef7f3ff5bffff4dff7576bfbf7ffff7efeffedddffd9fffdfff1f", + "data": { + "slot": "1541631", + "index": "27", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa96f6014755d092b8cbc25e03b2b2fc187e5bc99fc3563d92d6a92dbcc2bf58df2c8a22e8d818e368ada3d3ef2b560340aa36b736aca8bf6ca425f202e2b18362e98f27fc96b332cbc4c9a873b81190e4a19d11e8f860bf5b5025fd1bb7cf0ac" + }, + { + "aggregation_bits": "0xfefff3ffffafebdfffffeffffdf7fffdbeb7ffdf7f3fffffefffeff3fffffffeb5ffeefdfffffb5ff77fddfff777efffffdfbf3ffff6dbf6fff1fddd5fdff76e7e7ffffff7ffffd73dfffeefdfffffffe5f7fffb6fffdffbffbf77ddfef3fffedeebf71d", + "data": { + "slot": "1541631", + "index": "21", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x9846992146154eb88d3b1c2ca1dd94f7c5ac2750f6dc657df2a3b1fba92740c13cb313ad38a71b71287bb4be823d3cc501445c76652399bce84f8130a2ba3d2aaa09da0d620135d3630c8e6f61ccd95fadb5a61a96266ab987427c0d59707216" + }, + { + "aggregation_bits": "0xf7fffefffbefffdf7ebdff77bdf3edbffbfefff7effedfb7fffffffffeffd97ff57fff7ffbd77efdeffffbffffddb9ffefbff3beddfaffdfaff7affb3eff777bdff7fffffffdeffdf6ffffe7dfff6f7e7bf7feffffdffffe7ffffffdffffe5def5ef5f19", + "data": { + "slot": "1541631", + "index": "0", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x879e73462a4c476f86f8fe531684f30122e8ca630eccaf4b27864bd4fdb42eb350c09939e250b645d4bf3923c0d11139092262143fb217b04b85e886267b7b51ad351ae057a6697adf0a825c4e81cbfc3f8ec63d53772f228f04618f7f73875a" + }, + { + "aggregation_bits": "0xdfa3cbefffffdffffbfbbf7ffffbef9ffffdd7fefbffffeffffdfcedf7fbdefff6dfbefdff7fffd7bbffff73efff6ff7bff7d7feffeffefdefffff6feff7dffffefcf6fb3f7bfffcfb4effffbffdfdfdef7dfb7ffcc3ffebfff7ffdfff7efff7fffdff17", + "data": { + "slot": "1541631", + "index": "4", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x93042a9348056338bd60ee1555bd224709ea7556e6009a6a5d5f521df15df40ed7d3edeb9b3f2bc5121e6ce9edc75acb13500ae39b38b8b318aa58cd2a8ed294c3dc38a88f607460bd3a9cb3d1069cb057215ef3f8fcbff17067acae67a2cecf" + }, + { + "aggregation_bits": "0xfffe75fd7b6fffbfffffdfdfffffff7fffffffbf7edfeff9ff8c7ddfffffff7fff7fed6ffffdfe77bfbbfe7f9fffffffff5febffffeeffb7ffd7f7dfbdffeb9fff6335fffeffdf5ffbfaffffffffbffd7f7fffd6fff9fbf3d3ffdfbfe9f5bf697fffff1b", + "data": { + "slot": "1541631", + "index": "17", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x869c40c468a2a6441d79f2c9917ca37b82aa55edefbb3b8362da9a4b5b0715cb63b8bc6ed35adecc339e72d185f7960108268aa586e71142c20dfdd66535182a4c5bed30ea2d4b0766a9823a57f6b367234aebd065767541b6e6e85bb973a1a7" + }, + { + "aggregation_bits": "0xfdf7dff9ffbeffbb7bd7ffbffbdffefffeddbff7ebffdf7ff9dbbafdf7fffbffef7beffdfff3bffb7ddbffefffffebe7fbbfff17ff7ff7ffbffffffffbfffceeaaefefffbfbfefffdfeef7fef6fdebefffffbfbdffdaffaffffaffffefffffef39fdff0b", + "data": { + "slot": "1541631", + "index": "52", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb8f87228d3a239bd9bc7fe3f05c73e6ea8d2c8767127cc125da492940e800c6849628f35d0b929d3d4144abc061d33cb02db1e569350c381021bf6afe9a310801cdcf88493e844714d222dfebfc1b2e6498a3e53d22ae0807e7dbd5d23f530d7" + }, + { + "aggregation_bits": "0xdff7dff7ffff2befbffffffff67fbbefff7b7ff67dfafffdf3dffffbeffffffbbfefffefb7fa7effebfff4ffafffffeefdfffebf5feff64fb37ff5bf7eeffd0ffdfeff7fefedffb7efead7fffbff7fff7ffffeff77f67befffffef3ff7efefdffffff70f", + "data": { + "slot": "1541631", + "index": "18", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa87261119e6a12555763f225767d84bb7c00f108aaeed9edfeb79a0d0fffe4f4b80bcc00bb57e5b6586b9062eb65d0250973c27828fed73bafb53d16163e8a9b11078b6bc15f7efe58583273798f52c5605d829f44c117c7fa751bbc19b65e60" + }, + { + "aggregation_bits": "0xdeffffffed7fdb7ff7ddb77fdbffdfffff7bffdfffbff7ebbfffbdf58ffffefffffdf7ffffeeffebf1ffefffffff7fff4ffdb3fbdd9fbffdf5ddfff7efe7337fffffffffcedfe7ff7cff0febf3fe7e7fffbffff7ff7bbbfffffbffffd76cfbffff3fff0d", + "data": { + "slot": "1541631", + "index": "10", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb7a123af3caebdc24f2fd8c32d04be0b4148ababb63030989d7e6dcb5033937c423822122dfd17db6f2282ca389201de02902623349c42befd750b6b021b6fbadb745d0368ca65a752dbe8b7c87bddfef0c7b0e6062ce9199d078219d09c38c3" + }, + { + "aggregation_bits": "0xfffff3fcfffeffbfff6fbfffff3f6ee7f5bf7bfff76fff5fbcffe2fbffbfffafffffffcfffbfdffefdff9d7f7cffbdff5bf7f7fdefefdf5fef7d7ef7feef6fffffffdfffff97bfdff7ffb7bfefffffeff7cfffffffe5efffff7efbdffb7257ff7eef6f17", + "data": { + "slot": "1541631", + "index": "31", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x936075157a2443098dc0c2e064a18fe3a0686ff18cbf0a1e3d0bc49a543d8ffd5ac7d7980e365dd410c67de3d44c0925004823144cda59f05cad289a04bc86d92d3325f48430ade5c9c2fe4f87203619dff0e6707cd4d88ba6bb22bfd641075d" + }, + { + "aggregation_bits": "0xfffcffffecf7ffeffff6deab7fdfff7bfdeffcf7feffedfddfeffff7e9db7dfdf7ffefb8fefbf7fffdfdbcf7dfbaffbdffbefffffdf3dfffeffddeffbadf78bfbf7fd7ffedbfeffffffbff7f7df6feeefffef6ffebfff7fefffff9fdffebfdbf7fffff1f", + "data": { + "slot": "1541631", + "index": "45", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xabc06e2edee7441b0c0d4532799c4349caada2691b06b55127d50dcec014e7343dd3739dbc93791bb442bfc51f931b970f03662f6eabc8b7e6028bd09d35c42bfa9ff580bb71ea82b722314c5c872e33325d4b29d287a698ff3339aa5e000d30" + }, + { + "aggregation_bits": "0x7effdffffe77ffffb6fffff5ac3ff7fdff5ffdf7ffffebbeffedfbffffbffeefed6fdbbfe3ffedf6ffeeeffebf7ffffffffbff7f7bffeffffbf77ffdff3e7fff7fddf7ff3f6fffcdff4f92f9ffffff7efff9ffbdffffff6ebdfeffb6fbfffdb3fffdde0f", + "data": { + "slot": "1541631", + "index": "46", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa1696b9a79708e4dbe0c2935efc56b75932c6a025dc7c3ee7ffbc4cbccc17a2ec8196d6734dc603e089afd1261a923d900e61677a4347658aebd8337db52128878ea17d0252f69e4763ae4d59906c58a4416bbb439499778eaf0425b6ede3fbc" + }, + { + "aggregation_bits": "0x2fffff77efff17fefffbffeffff7fefd7affe5ffedffecffbbfdeddfffffdf7ffeffbffbfff37f7dfffdcf1f97ffaffffff7fd7ffffdfff6a7f7fedbfcfdfdf9ebffc7fba7cf7fffffffdda7b6fffffd7ff7ffbfdeebefffdffff7dfb9fffffbdff7ff1f", + "data": { + "slot": "1541631", + "index": "49", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb76fe8427ec73bf923ebe948b2d2375d31ae7550dac189d4e25334fc8d1f20ca1964df07b54e67b4b6d8cfb85adbf03303e949470e302f02127a46fbd3c356a7a28ffbe8ff3745a150ba871ddda252490ff557553da21077a08c53931b6efa23" + }, + { + "aggregation_bits": "0xfbffffffdbffdffffffffdeefbeaffd7fbfdbfffeef7fffd7efeefd7ff66ffffffbfffff76fff77fffff7cffffebdbff7cffbbdf7bfff3a7ff8dffffffafdf5ffbdfefffffdffbffdfabd7fc37ffdfef3bff7d6fffebf7e7dcfff7fffe9b7ffef9d9ff17", + "data": { + "slot": "1541631", + "index": "2", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa1b0ae38a470fef7733e10011e5f28a2c451c1afea7654a96495482f17df419126f652a1be19c62b17edf6d163aaf8ba07727d8b0f856e98d4ffe48662836f0a774c5652f672fefcbaa40ea476315805f2cba9a7a6cdbd95d20a61caa665d8ad" + }, + { + "aggregation_bits": "0xffebaf9f377ff6f7f7ffbfdefef3ffbffffffafb77fc77fffefffafffcefffbfffebffff5ffffcdfb3fffe5ffbbbffffff7bbebf9f7eebfffef7fffbdddffaffb8bf6ffffbfbfd5fffdfbedef7efeffb77dfffefdfe7ff9fffbbfffffbfdffffffaeff0d", + "data": { + "slot": "1541631", + "index": "54", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb54594fdc67cb25066b0e1472cef611b563fd7b430e08e8ed02cb930af4b612d65428b23c7d19dd30b3dd4362d91fb950c9b7183de68ec6a75f7acfb75f84ce8fd71cfcc32c3b5d65ada887a854f2afad7199169a28975d427b40f0ad6102785" + }, + { + "aggregation_bits": "0xfdff3ff77fffbeffff77ffbfdffadffb5ef62faef5ff6f7ff9fbfee7ffbfddefff6befda7fbf7fffff7aff7b7ffbf7feffffdffaef67ffe7cffdfffff72ffbddd9fdffbfffefefbffffdfffbf7d5f7dcdfffff7effffdb7fbff7feff7ffffdf3ffffef0f", + "data": { + "slot": "1541631", + "index": "24", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa630d69c8637dc4b361b4cd308d0d478969898d3ff264cde83c25f5115a0cf66d1e93c290980fb2b486056ff388799aa16c24c402d8fa98606f744c4b82464bfe8e3ff4ef19907a46fd700781b0efd4aeb3fd8fa038326c1cb072ea0b521d1f3" + }, + { + "aggregation_bits": "0x7bf0dfdfbfbf7dbfbfd7dbffffffff7ecffffbdef7fffefff7ffffbeff7fffdfcfdbbfdfffeefffefffefbbfb6fbbffdfbffebedbafffffffff5fff7fdefbfefffcd7ffd7fffd7ffe37fffdcd9dffdfdf1f7b7dfd9fff2fff4f3f77d9efffffffedff71e", + "data": { + "slot": "1541631", + "index": "23", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa44bbdcb3b2233449a25650c350476323b9390b43e4e7ac3a848480ebb7fbc0d599e677a16e02a9bd03f2215075029a4065184292f032f6e1349f53af5bf9ad50ae0ab7ae248a7d197a4b3909d9f1d6a5f28c8a3fd45d5ed8a5dee3b03ac6dab" + }, + { + "aggregation_bits": "0xd7fff7d77fbf6ff77fbffef3fdaeefdedffbfe7efbbfffbffdffbfffffff7bfff7bffffe7dff9cfbdedfffff8edaffffffaefddeffbef7fffffd7f9cfffffffaffeffdefbfffffbfae3dfeff6fb7fdf7eb7fbbdafe7eeffbffdfdffdffdbb8ffdffffa0f", + "data": { + "slot": "1541631", + "index": "20", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8346da20961592875bab6b8afead8ca1d71c36f36c38bd244ce7ec63c6f5a9ccaeb75bf446880437d0c10d27f1da800a0f26fb530a51827074522860d5b5f1f80f39749e10aa59466068de715a8a7cf44e03ab3598166640dfb86fbd2dfe065e" + }, + { + "aggregation_bits": "0xdffffcdffff77ceff3fbffffffbffff5ddffc7ffeffdffdfab75fffff7efbe7ddbf3fbd79bdfcbfdf3ffefffefffffb7affaffadfdfdfffdff67fffd7ff7fbffffbdfebf3ffefffffff7ff96dcbfb7bf6fbffffe97fbfff5bfdff7efdbdfffbf9fbfdf1e", + "data": { + "slot": "1541631", + "index": "43", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x80f4a6aba2f8b041ec1881a0ebcf7aa6dbe76887ef24ee516417d651f0545d1a595a103344e9341be607746701930b3909c0bb79b50215def60ab1064d8705f1f53beaeb452afb1ad0c69b16f9a7a680d1649936ec9769c500a3f04716fe9904" + }, + { + "aggregation_bits": "0xaffe7d3f87fbbfbffb9fddff7f9ffbfffdbeffffefeff7fff7dbbffbeff4fffedfbfff1fbfffff36ffddbdfbffeffefdfbffef7ffcfcebffffbfffb3fbeeff6ff73fbffdfbfffd2bf2efbffe7dfffffeffff8bfd5dfdfbfbfffaff7fffbfb7fffdfdef13", + "data": { + "slot": "1541631", + "index": "11", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa21c2b2b65a8e83686cc1202f0911a9c8082817a2dbe33826d769d68cbc31352d6237851012cfbed9e2d735e9e36b8631831bbc8b25d2c151e9ec0f7a8fc9d0ebda0a5149a1a6577cdcabaf70e71a31bc5bd43f905629be293cac597fd5f0bdf" + }, + { + "aggregation_bits": "0xfffffbffbbefd7dbfffffdaff7ff7fba757fafffbffffcfbd7fe7bf3ffffd7dbdffbf79efb7fffffbffffdeeefef7ff9ffffdec7dfbffbfff7ffaf7f8f9ffffffffefefebf3c9fffffffe7df3efaedfffffebeefafdffffebffdaff77f7ddee5fdedff0c", + "data": { + "slot": "1541631", + "index": "42", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x88aee9398a98c8587c5f87ff8ee6a26ca25ba63381de0cec417cd31b70217cff77f5499eb10c6d3b3461de140a76f41b19603f746d83ef90ae93dd1a1cea4e0592dd6db4c930252040b8be29a5fd3db388fd0faa6a62ee4a4c00db8f1769359e" + }, + { + "aggregation_bits": "0xfffbf7ffff7ffffffbff77bfffeffefefdf4fffdefbfdffbcf7f97f7f5fcef7f3dfff5ff6fefbd7ffbbf5cfc7ffbdbdd55fbeefb2fe7dfdf7fbd7bffff7f3fff7ffffffffeff5f7fdff9ff7ffcfffbf77fafffdff8fbfff7ffef3ec7fff77feeb79d7f1f", + "data": { + "slot": "1541631", + "index": "25", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x932904ff2374375a5b6edcce7656ffb6814a7c2d49ae0b2cd2c101090ef047f8947c9bde512f33fb3022f892c9d1c6e419c94103aa739e0313058fa7f1c2b79f1c7d21c6c13b7e75e197349bf2bf7f7f89451824a1d4cc995fb30fad9be2945d" + }, + { + "aggregation_bits": "0x5ffffe7ebe7fffbdefdb95bffff3dfdff9fffbefffd5f90fbbfaff7fbf7fffefbdafffeff7ec7f3ffffff6f59fbffbf5ffffdbdfffff7bfffffff9feffebdbfdf6779bddfebfbffffd7ffecf7fb3ffbf7fbb7fff7fe9ffbfeeffffddfffffebfff7fe40f", + "data": { + "slot": "1541631", + "index": "48", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb3dd6d47e21aa79815e883469873c1d9f40aba0b4f9cc6ad670396e152d7b7653d411ef8b1ac5a9bc733024bee8b93f5043eacf34667a52bc4e73a121a16984d62418a20bab6737ebf27ab82cd5ff5d587151565aa0f88ec4d95b44aa4d2e8df" + }, + { + "aggregation_bits": "0xffffffff65fed7f3fcff7fbfffedffaeafdfefdfdff7dffffedcdfe77567fffdffefbdffffdabeeddf5ebfffffdfcffdbfb9ffffefffffafffaffff5dff8eff7fdebefff7ff7ffffefffbffbfed8fb6fbbbbd72fb5ffcafcff7fff7fbfffffe5ffeabf1f", + "data": { + "slot": "1541631", + "index": "53", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x97f28b8fd5a1bda048880b7c37e40c03d642cc653e031a31b0f178022f57e7660005d3b1a70426bf0d90fddd028a14ce1775b7b181c05eec9569e40c50c208595104f7855042a468323eef566dad1828d4a58b94d6fae661a438ca01e86c91f0" + }, + { + "aggregation_bits": "0xdff6fe777edfef7fafffffdff7fffd6fbdfefebc9fed7ff67ff5fafffefbfff6fefbffbffffeffefd3fffeeffddeff57fffdffef6f8bcfffcbbdff77fbf6df5ff7ffff777f6f7fefef7fdf9dfddfbe57b7eefdfffedff7ff7eebbff6fbffdfbdfffffe1f", + "data": { + "slot": "1541631", + "index": "63", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x820b97e76cdf79a744ef41fda442d8ecf2097646ba0d6584ff55ef2d543dc53355aa05f05b1b666d961e7fe28b68309d0be69ef6a1cdcb648e0c215fcb77b8980b30d6f2c98d0c74ca6f185e5a4bbf1af1508725518c995a1c913cece48d0358" + }, + { + "aggregation_bits": "0xffbfb7fbfff79e7be6ffe6bfff56f7ffff7fffffb79ffbeb43fbcdf7ffddfffeffbffe7fffe7e715fffbdfafffffffbdbfbdfd3ffbfffbfdf7ffbeddf9fffdfeff7dffffdfbbefdfffffdf7dfe7f5ef3ffffb3fc9fef3fffe9df7e7dfc7fde5fffe5ff1f", + "data": { + "slot": "1541631", + "index": "8", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x80011a5b3b209989a56e8d14984d0779f89e1c8d09895acdfa981684641ff77a69571fa6ff0a9daf82c62471dba05ae41467ac0eb66535437141e3d0fce9e0817dbc71871fa3e71d615aff3462cb59c65cde4956a13888c289edd99bbda45336" + }, + { + "aggregation_bits": "0xdbffebfff7dbdfff1bdfceffd7bfdff7fbfdefffffd9ff5fffeffffbffdff677ffdfafdfdafffffbff5f7bffffefeffff6ddffefb9dff6eaff3dff5fffffebf72fbddadfeffffbbf7dffd7ed2ffbb7f57bcfe7efff9ff6fbffafbdfda7fbeefefeffff0f", + "data": { + "slot": "1541631", + "index": "44", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb26c1f2898902ca850927e1ccc4366c32d48123a023bedd5b8600b1b61688005b329a926c0414edb9ec3fb567819a5d4078b94ee33acc1a769ed0365feb78d62f7bbfcc1cef62d3b4dd55d7600a32c2589ed47f83408e8fcb88f438c44e0180e" + }, + { + "aggregation_bits": "0xf3da7feffffffdfd7adfffffbbf7f76df6fdcafffffffe7ffffaffc77befeff9bfef7cef5fffffbdd7fffdfffffffdbeffff6fbffdffbfcb3fffeffcb1bfcff7fffb7bdcabbbfdffffffeedefffdbfbffeffb78bfe7d577bbf9fbdf7efddfffffffafc1d", + "data": { + "slot": "1541631", + "index": "15", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8bc3c73544240ebe15157ee6e0c0327c3d91c24514950082a0f9e809c4daddf5cdd8a7c7fa70212dd6cd2e1cc88f26280f208125e38b4eb184a6c1a4dff3d68a876e15013148477390166aaa9ad7ab3fc5730c451aa3e3fb4379e432cdf2619a" + }, + { + "aggregation_bits": "0xfeff2fbfbb93af6dd73ad3bdbddeffffe9fe9ffadffafffbfffbfdaffebfff4bffffff7ffeb4ebfffdcfffd9ffffba7df0ffffffdffaffff7ffffedfbf7ffc5f39ff9fdfffdfffeffef9feff7fae4f7fff7ffffb7fdae7b7effffffe5fffffffddffff0f", + "data": { + "slot": "1541631", + "index": "50", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8e1b7443aa3eed78123d7024396fe1c7b770ef48736692daa9a371fe93a82766127561c9e156a020990bb12f636aa1c419e993e1690a5327606b46cc50dfe3268f6c27665bb6298be4b65e9adeb611eb0e50f54b6d29d8f779e9b80c1bc32122" + }, + { + "aggregation_bits": "0xef4fffffbd77ffff7ffffffafa7fec51efdeefffbfbfe7d67c3ddfffbfddfb771ffd79ff5ffefffffdffdfffff5fffef6777fffdfff7fb7b5ffd7ffe5de7fbfd5bed9fefffdf3dfffd5dbf3ffbfcfffbffaff3fffafabffdfb7effffff7ddfdef7ff7f1f", + "data": { + "slot": "1541631", + "index": "39", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb5557c84074689d30d414225470a4e234de9efef7abab2f09d9395d3766122b529047dbb653cafc3846b0c9760b330381778ebb2987e0a7954daba4670130dac70e0791b873419182774d3d92b037e70fc1abe5b6be2313e209060b76336bf99" + }, + { + "aggregation_bits": "0xfcf7fdfecf7fdfff73ffff9f7fefff7f8f79f9eff7bbd7ffbe7faffeffdfddff7ff2eeffffffe47ffdfeffdfbcbf7fdbbf7e76fbfe5fefffe7cffff7fbfffe97fffeefbb7bfff6ffffaef4dfcfc3fffbffdfffdd9fdfef69ffeb76ffbff7ffbfffffda1b", + "data": { + "slot": "1541631", + "index": "37", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x80acee07e608a8969cd9602d32c3bec0a7df934ba75c699150261fcf72bd747fa99791c10ace53a1005ae0e46492ddfd01a280290be07db9ca99961daa4a43710b3f6c3c5cbc456f0d544819b9c6bdee8edcd2a64a3b0ed93fc1b2d36c2e040f" + }, + { + "aggregation_bits": "0x7fffe7faeffdfdef6dfbbfebdffeffeb8ffcfafeffbefffeffeffebfff93ddefdfdfbff7ddf57ffbf7fbefffefbbf5effffffffffff7ff7bf5fdeebfcadb5d7fa6fa5ef73fdf3e7d7fff3bbfafeffdffffffdfff7fd56fffbfffbeafecdfefefdfeffe1f", + "data": { + "slot": "1541631", + "index": "6", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb926805ac4f89d085e6a288ea443649b771b2ffe217eb629b67d9cf3858a2ea47ebd10764cef0aa679482400d414d82110b24d241b9b492f7097d4ba920b7c6e78b807e4f48b06f2d77ec30b24daf0c4a8b4f2517840203ec19e1043e5f3322d" + }, + { + "aggregation_bits": "0x7ffff7feedbdcfbffdfdbdfb7fffbf9f7adbff7ffffebfdfffedbffcffbf65fcd7ff6feffb8fdabfeffe7dc3efffefff9fedf7bfffedfffcfefffefffdebfdffb7f7df9b3ffedeffffdafff7feffaf779dffffeffff83f77b9fdfa79ebdfff7ffffbff0b", + "data": { + "slot": "1541631", + "index": "60", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xafe5b368c90c244edc69eee68aef139a7f91145989549bf614e49dc7da62006aa2046ca01f1de269d8a6c97711512edc064e877b0105e7c4898b8e26c1fb6995611e0a3a5cf58f1cdb675905224358d664ee9377fb1acdce92910262886cebca" + }, + { + "aggregation_bits": "0xd7ff7bbfdffdffff9ffffee77b7bffcfffebf7fdb9febfddeff7ebffffbf7fea3fffffbf7fefff79fbff35fffd7effedfdeefffff6ffdaff9b75ffdf7fabbeef9beeeefeffff6ffff77d73bf9febb7ef9fdfd9ffeffffedff3efffebb7bffffdf7dfa60f", + "data": { + "slot": "1541631", + "index": "32", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xaf1f6aec61caf39fa0174758becc00217a3f818d40d48d08e8e94a7c1dd7d58f806b8e1e026e1c69f8b00c097be388aa054b6b04f3c95f2513ba5c2201693b385ba79033a3b3c9a1cc41bd1a30659d2cbe6ec7633837ab1dfd0d193d56ae1757" + }, + { + "aggregation_bits": "0x1f5def67ff5fceb7ffdedfff3ffbffff7a3ffff5fafbfaffff7fb7fff2afffbff9fff5bfefdfb7bff7dfedfe74ffddfdf6fbfe6ff7f4efbfffbafffe6fbbfffdfff7ffd5dffffed7b7ffffffdf779fade2fbbffddffff97fbdffff7ffbdfffe5f7ffdf0f", + "data": { + "slot": "1541631", + "index": "62", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb1ac3b871a594217117ceadedd05fa03960f9fca00eb01543e53f3a31d535315d329a85a858cf00cf708849deba48c69199d7a4777e201042300cf1ec8ef4a6eecea1d5ebd13578767be5deac1932d36ad3e0350b44b28c6e726da3fa84707e5" + }, + { + "aggregation_bits": "0xfbaf7dfafeff7eefefbffff7a3f1b7fffebd7ffe7fbfdcffbfdf3dfc7efffffffdf6fb7aeafffffbdffdff7fbebbfb67f9ffafebe8a5fe73fff3fffbfdfff7b7ff5dfffbbffefff7f7f9dff7fdf9bfefff7fffa0e7f7f7fdffffeffbffdfbbebfff7bf1f", + "data": { + "slot": "1541631", + "index": "35", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8d570f02891e49e81e2d087cc5e4dea11b0e112b601fb3b83e7b01a1e88b12bafd5ab5271163ceb01f2a03757538efdf08214fb4e397d4218768b7fa1752efea07b07c95b3fa60cbad28399fc4d3ed7b80b306aea39edd7b88ae4941858d21fa" + }, + { + "aggregation_bits": "0xdefbf6dbf7fecdcf3f7efdfdfbffeed7f7efefe9cfffefefebffffb5bdfedf7cb7efdbdffef7bfffe3fbff6ffb7ffffbfff7f75fef7ffffff6fefb4fff7fe3567efffffdf7fffbfd6efff5edd7fffdff6ffeb7f9ffdd6ebf7ddbfbfff3fefffb5fffff0e", + "data": { + "slot": "1541631", + "index": "30", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb2768704397720046d4a7a4c366279c03ce95f1ed0ed0a0642c02b6efbfc4353386a3fa1fa4b39349108da1370e04251094af5fa7e7bea58972911b9bcf7a9ced4055a87ca87632fc7459132ecbe1530890c4aaa04043537049baf183f45af28" + }, + { + "aggregation_bits": "0x7d7ffbfb7afbffcdf67ef6b7fffffdfe3ffbfd76fbbfd6ffff7ffff7f9fffe3ffcdfd7bfd5f7f6febffbf9f6fffd65fb71ff6fffbb7f3e7afbf6ef7ffdff7fffd7fffff9dffdfcfbffffffdfdbfffffffde7b7e3fe97fffffbeff7fc97feedffff5f6f0f", + "data": { + "slot": "1541631", + "index": "5", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8aa0aa21d5e1078fc60807ea509f45fc36ce790a914c86058653f5beb0f40f4515b1f1da9c5d8a6bc2e6b34c9a8b19e008b1b24e1df3d794705b84a4f36e2c49642cf3b391d3a4c17b2156507717843b6017195c97a66959c08ae5616f0dd722" + }, + { + "aggregation_bits": "0xfffdeebefafd9fee7ffff6bdfbfbffeef7f7ffeffffffff79ee7ffeffcd7ffefffffaff6faffeddbfdff5efffdebff6feffde6cfae7edde7ffb9ffddffdfffdee2febfebfffcdbf7bff7ffbdfefbbf7fe3ebee7fffffeeefffbbebfc7fdfdbffffd6fb09", + "data": { + "slot": "1541631", + "index": "28", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8572a563356b2a730bffcf160f8489c73ce57d4f60f640dbc41b0255b0dcdf9d7cc2fcb8abc7c9a9f8a895d2fe502ea20916eea7c8d88911f199d6214e4a61b1c6d22a6fcd06664f6b09ab7f70b1571c466211f9e3ca8b2ba262df802dfad06d" + }, + { + "aggregation_bits": "0x7fffa8fdfe6f3ff7b3ff0de97ffbbbf3ffffbffbefff6f77fed7ffbfdf7faf76dfbfffeffe777fbac1fdffdffffbdfedfffbffefef737bffd7dfdffeffff3cffeff7fefe7f6ff67fddfffdbfeeffffeffb5fdfff77ffd3fcbff773f7df9f3f7f7feffe1f", + "data": { + "slot": "1541631", + "index": "57", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa6c157aa359711b587796131778de20d1b49ef1923efc63ea9e70b783ee0f7e8f46c455f92d91e8160537038d0becf77053cb4e428a63e0356b1ef884633062bbe6cbfde79ddfbf413e0ed9a5498b56fde911697dc38649ccb65be5ded8784b6" + }, + { + "aggregation_bits": "0xbeffbeaf6fbff7fffbffffdffffff7fffd37fbfefff7fcdeae7ff79fbefff8fe5dfaffdccefbffaffedaaebfffefff7bbebfebf6eedb56ffeffbddf7ed5fbfdff7fbffff73ffffff7eefffffff7e79fd7ffdfbb7ddffbfd7effdfd5dbdfff2f7df57fd0f", + "data": { + "slot": "1541631", + "index": "1", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa58131f634e6dbaf9493944a0e3a169c7e858d42c2d9818c007c34e0e4e49518dcf76062c51539c4342e0739f77759b60c2df737390ee4017f35b27cf65076c72c6ed38bbefdb22e35b899000f80222e91c57f59ca8caed982f7eb499dabe58e" + }, + { + "aggregation_bits": "0xfed7ffaccefdfffffdcf7ff7afe97f9beffefffdbb7fff5fbfff7edef7bbf77f7f9dff5b7b5feffbfbdffe7dfcbfff7f9ff7fcfffbff6dff7fef7fe79edbefbfefdefffdebfffd4fffffdbffb48fdfffffa3bbefffd77e7fbf6ffedffdbdffff5effff0f", + "data": { + "slot": "1541631", + "index": "26", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa9a0fe1751565d3f6f1c8cd6233c720103d5733b074396272c66666efdaed9261cda02851382d8a2d948444c9c84682d0bf3d681c3f7095229f18b14091334c30b7519cd9896eeea4c0627271fa2a8c97a5c15581366aead1f39a6f3ca8a4ac7" + }, + { + "aggregation_bits": "0xff7f9d7cf5f4fffffe7e79fdefffee7fefffefebfd3ffff7ffdff53edff3ffadedabdddfffbfbfdfdf7bbdffffdee7fdff9dffefeffd7ef7fefdf7fbdfdfcfbf7f7fffebfeefffffdede67fff739fff9ffffffddf7fbefdfafce9f9d5ff7ffdfecf4fd17", + "data": { + "slot": "1541631", + "index": "19", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x87247a41018ae9a2651e6c106f48bea963e54e802011f923edcb205274b92fe62e4f4c8cb8685bc371dd6e45dccf6ec70e365f6c51541e86f4a1e736eeb739fb127f582d8d6092858eb1867c23af66b7bef030ec0d7da45e6533269953e94400" + }, + { + "aggregation_bits": "0xefffedfffdef6f8f7ffeb3ffbf7ff7fd7feb7effefeffddffafdc63fdbf7ff77feffffffff7ff3fe3bd7fffdf7f23bff3cbd8fbbeffff7fafd39fffda7ffb7efbf7f7bfff6fffdffffffdff3cff3dbbdff5dfaf7ff7fff0febffefcdf7fbfff7f7d3ff0b", + "data": { + "slot": "1541631", + "index": "38", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8ab5e1c1b2bca62d31cf7066b1efef47ef65128717ecfa7f1d131d480e63031fb5fee785b613c4099c8aa89a13af90a40ea10ea0fd9f86bb4bfa903665ed6053af4bc7ebde8885993f1e393be806a8de95d6bd79d4dbbd887ce9c303a875ae7c" + }, + { + "aggregation_bits": "0xbfffffbfceff5fffffff90bfcbfeebff7fdfbfff517ff76f75ff5c7bbd7dfdff9b7bf3f57e7febcddbffcfffedddf2fff7bdfffffff55efbeffdfbffffebffafbf0eff7efffdff73fb9fffffffeff7ffffeffdff5eb7f5df9ff77bfbfebeff7bffdf7f0f", + "data": { + "slot": "1541631", + "index": "58", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x94693a96d0538758f09818ed16faf787c219644529073d5c485fb4855337423131b4c7572249d600580fcf6954fe7cde015324bef9e1c64c4fc3576157116887c27c9ec982da12c9c285f6affe3f699a679f095f334597a15d11806cd7d9999f" + }, + { + "aggregation_bits": "0xffff7ffefd6cffccfdf9f7edbf7fb3fffee35fffffffbf7ffd77e4feffedfefffffbdfefff33dfdefd5fefdeff7fde7ffffef76fafcf8fafffbfb92b7f7efebffa5effdb5fc7bf7ffffff7fffddfff7d7f7ffe6f9ffefebbfffbffafedfee767fdef7f1e", + "data": { + "slot": "1541631", + "index": "13", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x86658af443865a323c2c2a0cf876fef003316682bab17b644cf25d3aca32c6189963c498c93d183c5a483ffbe03515fd142c53d79515168af01af939944163f49fb2bf660491203269eb2e45a29951ca11d8a5361a3472c391bdd39e81ba3121" + }, + { + "aggregation_bits": "0xed5bf7ed7ff7b5ffffe9dffe3d7fbedf3dfffafff7e27ffeffffdf7fdffeffbbfddf776efefdeff7dff7cfafeffeaeffb7fbedffb6ffffe6faf3b7fdeffff77fbfffffd5fefd76faff63dfcffe66ddfcffeffff7ff6eefdfbfffcfffdef6ffff7edebf0f", + "data": { + "slot": "1541631", + "index": "40", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa16b454b5128fbc8c96ed443ff9ce0548675d9f08edd89c4ed94442168746c0ebde2e4d9e93a474d072f178ce5adaa6504b77b18704ad529f04fec6d905b2dd10bf41799016a148155f7e0178184a069eb43f86c83b83831d235cbaf020c3436" + }, + { + "aggregation_bits": "0xfe6d7fbbff3df3d7fea9fdf9fff5ff6fda5b5ffbeff7b3ffffefeff7dff3ef4f7ffff457fcffffdff7ffffbdf6feffeff4ffbb7deffffaffffdffbffffaef7df7eff7ffbfdff7ffeefb9ffef7f62b77dffbfbfff77f3b3fd7ffea7f9efe7f7bf7bfff90f", + "data": { + "slot": "1541631", + "index": "9", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb644ca8e5307a334c5baec72d5473fe78502af2456bdad8ba040a87ff2a1a27937586ea741ffec9aab05926b342a47de01e04fb7b3d8574126af4209c2255737843e1c2d6ff3ef13ecbfb0831c29f63d4913817c66b1237ad7affbb7785c27b5" + }, + { + "aggregation_bits": "0xeffd7fbfeffefffb7ddffebeeff7737db7fffff39ffeb7feebeffb7eff93f6ebbf76dfe7ccdcff9e4ffef6eb7ff6efffbfffedfbbfff67fdfdf7bbfffbff87fbf2fd7f7ffffdf7dfffbffffe7f5e7fff7b9effefffffdbfc99ffdfff5dffdffe6b7f7f1b", + "data": { + "slot": "1541631", + "index": "41", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x85f69223203cf32a3fc8ff0427febe28451dd51f9f6269017f0706571e6f1609501e0834d8c95fe6f7da9391d7ad34df1938de0926b66c28cc65237da595e823e6c32ea57e9103967cf1a4e1f9602b43d75eabca72c9a6d1d7a44b61737d6305" + }, + { + "aggregation_bits": "0x7ffedfeadfeffb7deefdfbfffd7efb63d37f7dfefffbacffbedffffc5df4fffbfeffbfecffdfff7f739d6ffcaf9fdfb7ffefeefff5bbfeefffb7ff7f6bffb5bedf6fbffffeb3bbbf7f77f5ffbfff77dffffffefbffff7dfffff7fbfc57ff77edfeabae0f", + "data": { + "slot": "1541631", + "index": "14", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb6b2bfa3fe5176f2b1194b842816689eb86c02c272e746305349a0bee16688a41eb03f8754cac276741e60653bfd252d1790a25008f11268f6f888d5f5acdaaf13f3cd330efe552738725265cdd1247cc7668dbd75464b7e2ae5d087bf29d8ca" + }, + { + "aggregation_bits": "0xfdf57ff8d3fddffef753f667ebf7feeffff7ffffff7a7bf77ffdfff7efbf4dbbdfbffffce9dffbef3bfdcffffdfdfed77f6ebfe7bffb7fbfef3bf5febfeff7ff39fffdf78df3f756ffffff7fffedfeebebfffffaffbefeff7fefbbff3fff46befffeef0f", + "data": { + "slot": "1541631", + "index": "56", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa5a474279c81071ffc2f0a80fbee19b6cb699378e254ced14ab8e4c3ee8d8927f10e87d4e6fcf13b01b710495b6c672201249e5a8d4e74c7a8dfe9a9435ded0b21e7273cd7d503cee7be4d76e6996d00fa550da055ac0499ebf601eb8861cc1b" + }, + { + "aggregation_bits": "0xbfed7d7ffdfbfebff977fbffff7bf97efbfeeffe3feffaf3eebfffff5ffbfbf5fffafefbffeeeffe3fff7f3fffb7ffdfdff9fcff7f77fc65fff75d3fdff9ffbfffebffeffd9deffbffbf9df78f7ddff9efb5f7fffbded7df39fecf9ffef4ff6fe7efd71f", + "data": { + "slot": "1541631", + "index": "59", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8defe832b188c46263b7d9f90cae31fd40bf4bea4e67099141901ad181b29af9473740db41c2719f9ec048dc0cfb83a80d3edf71ad73758372fe28c0417903232b97cfcba0dc3c75dc39a4fee94cea1157ca22109a1ef3c0254644002e55febd" + }, + { + "aggregation_bits": "0x7bbaffefefffee9ff7fbffffd75ffbefebfabfdf57eecdffed7f2fffbbf7fb3fffecf7ffaeebffbbffdff7fffafe7ffefbda7fff9dafff6edbafaef9dddff0c7fe7fdfbff73dff7ffffbfbff7efaffffef7edddf7fdfdfff77fffffb9bffadfaaff3ff1b", + "data": { + "slot": "1541631", + "index": "33", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x965db63621b0ae9c63fdb4b6e6c760532d850e6c10ed9257366ecb3ba5320a65002cfae7b1458b3543b79580d7fa6ea110af6a1812b9d7407dd0d87ea61701877b3241c50c3e5199aa796c875c64cf1d15111e1826871a1514706117d1eddd85" + }, + { + "aggregation_bits": "0xdbefceff3d34867fffe7ffed3ffded8fedfbfffeb8ffef3cdbfcffdf7ffffff7ff7fdf73df7ffffffcbfbfcb8fdf7fffffffdffffefef7fffef2cffbfff7ffe7ff6dfbdee7bea7ffdfbf7fdffeb7ffbffeedafecdf7f7f7fffdfbeff5f9fffff0f7fb50d", + "data": { + "slot": "1541631", + "index": "36", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb40ee51bc4284fb98d4d759229171ea21ac8eb0fdbf813d9135aa566bde2ec328351affbb3bb607bbe4a312caad9fdf50e5c487ee8ff7bcb26ebbdcc86369c094887a3edb17a8bf3ca873d410db210bec3ff1481de9232cd8eb084f2bbe00804" + }, + { + "aggregation_bits": "0xfed9b3f7bb63affffd5ffb7fff5fdfffff7fcfe67eff3b4f177fdffffe7ffffdafb37effd77bdefbff6fff6efdfb2dfffdffffffbbf5ff7df7ebfbfef77aff3fffcbfccffebffd7b9ffbfbfffdffd577f3ff7fddfffdedfe96fffaabbeffffefbdffff0a", + "data": { + "slot": "1541631", + "index": "3", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb9f3ba9eada7ced39f17766bf4df4fc9eb8350889cea171d1f13fe53c866b4f093d50b7d675ee689acc32199720da10d0672ad1de6b4291f8c8977e48bfe057d97877bd5ed159ea92f06b1222b6df0fc0d480c0bc1c9a324cd7be8f15a6837ce" + }, + { + "aggregation_bits": "0xddfeffbfd17fafefbee7effb1cf27ff7ffbffdeffffbfd7ff7fe7d7dbd74ff7fefecfefebfbb5dff7bfff65ffffadf7fffabfbfffffbfff3ba34fdfffdbdfefffddebf6fffdfe5ff1ff67fbfcffdefefde7fcddf7effbfee77eff7fd6faffefff7befb0d", + "data": { + "slot": "1541631", + "index": "7", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x95bc84f1623c594d8fd0686cd884c190459bd46c42ee5ee63d6cce08fbb94b52da5942ac3dab991ed5fe431b03a072fd07fd33c7a687e697e31cdab35effdbaba58a9b3d10c152820228707062e197ee522234fe64bfdd5168508c4e0dc0d5d9" + }, + { + "aggregation_bits": "0xefffefdefd7fffd78ff7ffebbedbf7fb77bcfde6ff7fcf7fe7eff57deffdfebfddfdf77fdbbfdfe5ebbb8f5e7bf7fedfffffff5dffbebeff9feffebfbffdebfeeff53ffdfff9fd6f6ffebcf7ead7ddf7f67ebf3dbfffd7ff5bffffd5f3fdfadcdfffff1f", + "data": { + "slot": "1541631", + "index": "51", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb9eae78f5259b59b9f0dc000d41d9fd8525503fbd20a291bd94e5cebbbb40522306419801daed3a5910c57e7fc653fd90c23255754f1371e1f6b9e61e7acf0a8654a8a1db92e7ebbb213fe7091f379a3c81ffa34a00afe054476bd38ddc1575d" + }, + { + "aggregation_bits": "0xddcf7fffffffdfffeff7fe753fbf773fb99dbaffb97fddf6fffffdffd3ffcffd7fefff3ffcffbfecedf7bffffffeafffbbfff37efc4fffb8ffbfff7fefb77fbeffbb3f77f7cf3ab6b79ffffffefffefeff7ffe2744ffdfffdbf77eeb5dffdf7eb77fba0e", + "data": { + "slot": "1541631", + "index": "22", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x913d0936b5d8e594139d229b8476753949a83dd4e8a132cf284dfad159dda88175a8845d33be4a58318ba5e74ec772dd14e0a6812566b3d9785c817aad63cacec70b24dc649a7a353b07aa7814be2e963cee0be26d5e944b04d1f6ea9f0fe8cb" + }, + { + "aggregation_bits": "0xcbeef16bf3f9dffddd3ffde5fb7d7fff3edea7ffb3cfffcfffeff7ff7ffbf7ffffefcbedf6ffaefe1ffffbbbf7ffbffdeffffeeffdafffe7b9fbf9bff99bfdf7ffffbfc7fbdf7eb5fbf9f3fdd4fffb3bfffdbbffcdbec26fdffbfeffaeeefd7fffdfff1d", + "data": { + "slot": "1541631", + "index": "55", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x99e2d99a89e7894066ead18443d36843a97fe5f21d3229eda76b7207316083a839f22182e58f9f5ee935191afed7fa791732e0352aa3ef6c3e4fa7a484758aeb7a0c94be30c581d179409e6e332f066053a6a2ad809e68288028dab793348b9e" + }, + { + "aggregation_bits": "0xdbfffffff67f3efefff4fdfffe72f7abffbdffffff3f7ffbd6eff9fefbe3dfffcd77bff5fa7dfadfef6f5fd735fff3edffff267c2ffe2effedffdbedbbffb7f5fecbffedaeffffef7f12ebffffffadfbdff8fedefffff7ffdef7de3fdbffff7d7fb5ff1f", + "data": { + "slot": "1541631", + "index": "61", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb11f049cca286c7d3e1b8b64c9dbb6ad96dd1a489ba50303e480d52ccfc3f9fd5e0cc65c97d05ef1fe326fe5a682f8eb03002b1fa20190d0864068cbeed888f90e221dd67e5c8227efe31c986ea1878d2e5f8fb46b5e434bd90241d9bbe2c2ab" + }, + { + "aggregation_bits": "0x9dff5e77f77ff7abbd7dbfff957f7ef7fbbd99d7fffff53ffdfef7dbffef9dacfffff7e7773f7fffffed7a9f9ffffdfffffbfd7fbfefbfe1ffffff1bde7ffbfbdffffff7eef8e3ab1defed7fbfbffffbf7faff6f7debbec7cfff6da7fdf7df9ffbfeed0f", + "data": { + "slot": "1541631", + "index": "16", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x883b202f2a40321f5a7c4722785be4cdb4dd74f741c791f5951be27b10b846bcbea86620247c9b95f8d912c022252e5d02285fa92af52b3b46fe8d4aad8f3b5218618c79543b422a3138c0b0dfe538d49d8589605bffd88cc1efdfd107798f65" + }, + { + "aggregation_bits": "0xa6fdfffe6ff77fedfdffbffbb76f7fbafffdf57ffdeffe7569cbbbedff76feffbfa2ef5fff9ffffafbffc385fdd9bfefefeffeaf7f4f97fbbfedf7f5bffdf7ffbf7fffefebff5aafff65efdefffdbbefe3ebbefbdebdfffbff9fdbd7dfffffdfcff7df1f", + "data": { + "slot": "1541631", + "index": "29", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x88b1d3f142ed2bb70fc1855f8b7d866427ec2c9e4ca0d31d7314b7d3cee77b499cdb82acca9d083c2fd3797014d32ba402025393a083306d49354f1a87af142d712baadf3dc14b66c48a62375b11ee17a26129eec3a56c782b2eda2adccd22ef" + }, + { + "aggregation_bits": "0x9c7fffffff7f78ff6f3ed7efdfcfffde6ff719a7dffdff77fd7ffefb7f2fdf5791fefff77fffbfdff7feaefebef6feb3ffff3ef9bfafdfeffe7bbcedffeadcff76efefafef5deb7ffff373fdff7f77fb5b7ff7db7ffaff9f7fffffdfef6fddecfffddf0f", + "data": { + "slot": "1541631", + "index": "34", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8e61da37986b50720aff2c5f3e85c190e555410642ad2e242057217f9498c9bf50e0f79f19cdc7b16c3fc8c7a2c7d9fc03a163f98e6739cada56e6c3d96d298d04ae1b8291e605c8f271c5af1792b4b666df8c429550bbcfa5392fe4a84dc5ca" + }, + { + "aggregation_bits": "0xfffdb7efffafedf9dbff7fdfbbbeffbfef3ffe19ffad7f9bfdfd7f567fdbfcfbfaf9f6ffdfeb37ff3dffbdff5bfefa4ffffff73ffdeff7bf9fffff7fdfc557dff7ff7be9dff7773f377bffb9fefdbfbdfff5a73affb7e77fdfffffaebffeffb1bee7fe0c", + "data": { + "slot": "1541631", + "index": "12", + "beacon_block_root": "0xe65752827d3cdd3731e4a7889da5b4c77aadd8603e5a4c73831696bf2b1a1e27", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa136d67322cc59074d6a6d9c1b412ca0590fb27564494a98aaa02f2a44927615225664fba754db710869311abc631a8f11f4aa9d2e10d9fea13f02fabf2a36f4a62acf0d63bba9ab10cc6d2c2a9594d0d73265e203b4c99c3ddaeab52556dd22" + }, + { + "aggregation_bits": "0xdaffeffefeffffdffbf7dffff77ffffff3ff7effeffff76fbdff7efffdffffcffdcffff5fff7bdfbfbbfffeff3ffffffffbfdeafffffdfffffffffffbf7ffffbfff77effbfffeffffffbff9fddfffdf7fffdefceffbffbf7fffff7fbebffde7fdf7ff70f", + "data": { + "slot": "1541627", + "index": "25", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8c540b5b68e4e8b2bcdfa3c02f7b0bd80edc1175872b4c87efbc042ff98fa81792cde289cde1075f4455963af2614fbc10ccd4a6bbd860d17cf15e40fe28fdad4960c00da24956a2be008bf2f1e26bf449a472bac7adb95d7f09e36487418641" + }, + { + "aggregation_bits": "0x7ffffbff1effffffbfbfefefffdfbfffdfff7bff7fffdfb9dfdff67ffffffff777bfffffffffffffffebf7fefdfffdffdfffffffffffebfff5eefffffdfd7fbff7fbfff7ffffffffffbfdffff9daefe7e7ff6f7ffffff9bb6fd73fffffffffbfff7a3f0f", + "data": { + "slot": "1541627", + "index": "21", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x991407640c3ab6698a6c5ccc7552ef981714221378dd5412e2cf1da7f328642fc131d38b76844587a8e3ece6c0232035068f0d0af9f5b35acfed5e2a479423fb54be921acea80b0bcda12a521d19cfbd9b39148a3f474c87dbf7d0d53bb18dfd" + }, + { + "aggregation_bits": "0xebfbf7ffffdfdff3ff5fffbffffbf73ff96bbebc6ffff7ffbd7efbf7ffff76efffffdd3ff7fffffffff3ff6f7fff75ffffffffdbfffff7ffff7ffffffffeffbefffffffff3f7ffffb7ffffedffff7fffdff7ff3fffdbf7f79fefffffeffbffbfffbfff1f", + "data": { + "slot": "1541628", + "index": "48", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa8c89cddf3de4c78e0f76e732ff9ba5065621b56386216695aeb8f0c25d5a4736a73a9e73bfce237621638dcf02fbe6a167f657de1e5de02682dfae2c4c35325d71c55155dad41ea3a6062e9901560084e7f90fb7aeab4724256506da9b96225" + }, + { + "aggregation_bits": "0xffefffffffefbf7fdfefffafff6fffbfffdffdffffffeffff7fdbeffe6cfff77fffeffdeffdfffedf6dfff7fe9fffffbfdbdffeeffffff7fff5ff9fcffffffbfffffbffdd7ffffd7ffdffff9dafdfdffffe7ffcefdfbfbf7f77ffffffffdbffffcffff1b", + "data": { + "slot": "1541627", + "index": "4", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa0bf75d81c8cc2eacf3013c99033997f5c3e2e6b065b5197a5c39fd3bc9bff9149adfa806b21ee6515c498a9c04c772614af82b0cbe759c08a3bf09ad2f63eb4098b66e2a887f64c0f5b91eb0de04645c87f27717f18280ebd78547810f6bd0f" + }, + { + "aggregation_bits": "0xffaffef7defffff9ff7ffffffffffffffffbfffefeff773fff3fff77eff5ffebffffeefdfffed7fffbfbdfbfffeffeeebfd7fefdffffffffff7ffbf7e7ff73b7ffffffefffbfff7ff9fbff77dbfb7ffffffbffbfffddcffeffffffad7ffffbefdbffff1d", + "data": { + "slot": "1541628", + "index": "58", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb24f5f005896deb2df341194a272065275baf25e6c6110d1f52770bd04bfaa3d87d4303e6310f9f1bb1e4631cece384e0c9d2debd971f8697eaa1a8b089151b19d3cd0ed735b186f56d03acea499e81e4ac0f0e525561e86e06c48bdf8b58e33" + }, + { + "aggregation_bits": "0xf6feffeffffdffff7bdf7f7f7f7fefff7fdfff7fffffffffffefdffffffff7effdfdffeddff6ffbffdfdfb3fbaffffffbf7f7fffffeffffff7ffefdffdf9ddff7fbdf7fffbf7bebf7dffff5eff6ffffbb7eff97ff7feffbefbfffffedffffb7fffffdb0f", + "data": { + "slot": "1541627", + "index": "43", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x94701c708e46816ffc64c62dac01398d57082f9b1517dc9f84253485f074933a47a207f3ade2fb0041033890f916329c0567c8774a1f9dea54df5ba95204fd289c68cdaa8c827a5c002cfe62e86be76438c94cbcdc392887d0b15383fa12f2eb" + }, + { + "aggregation_bits": "0xf9bffdffff7ff7f7ffbffbe9efefffbffeffff7fffffdffffffb7ff7f7ffffffff7ddff3dffffffffa3bfff5fff7f7defffdfefbfffffffff5fffbfdfdff7fffffffffffffff7fffffef6bdaffffeffef7fffffffb7fb927beffdfff59ffff7fddbbe70f", + "data": { + "slot": "1541627", + "index": "15", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x845126fdfb3f2c758da595da2c2553d04f6c176f745198a6891ebad8f52c3989b775f3c46028261cc71290f84361dd1503b8dc1221c602da85099d8163ed7fd2781bf977f0202bcc9e122eec8f1e4d35fc5cbc253e38dc1dbb9990d4f6ae375b" + }, + { + "aggregation_bits": "0xffffeffefdaf7fffbfffbffffffffffffef7fcfffff97ffbb77bf5fffd9ffc57feffefbffcffdaffff7ffff7bddfef5ffffdff7ffff7ffcffdbfdfb9ddffffff7ff9fddffff5ffffbfffffffddefbfffffffffa7ffdffffffecffdfffffedfffffbfff0f", + "data": { + "slot": "1541627", + "index": "62", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8b2ce524603637a75f14490aef93872e215d294d6f878a9fb694dbf5cfd609bc7f940f8a52da77879145b3ff2cc42ab90da906f5577e818bb4d06c938c8ba558e3fa7cecd93eed040bc8a082564324b6d33c7b9dba0e5a5cb6e06d5c9bac7a1a" + }, + { + "aggregation_bits": "0xf7ffdbff7fdffefefbfbbfbfffccffffffffeef2f7ffdfffff6efffffffdf9f7fe1ddffffff1fffffaffffefffffffefbfbffff5fff7ffffffef77dbffbef7bffffdeffffffb7ffffbfeaf7fefdffffffff7dbfff1ffffffdb5fffff7bcff7ffffffff1d", + "data": { + "slot": "1541628", + "index": "29", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa16e6e4ef83c818c749512b75608415ebb88fe128a664aa874cf784b5aa3fdeabe239d895537b2602155aa3d5dcbc8db09cafd3b698ded5b0d892f8cfb282b8ac69237fc1da6ee46b595871e1a012b83c49d82963c40d15deaf56da818be2a98" + }, + { + "aggregation_bits": "0xfff75ff7fffdff7fffffffadfdfefeafffffffffbffffffbffeff7f7ffffeffffffffd7fbfffffffffbff6efffbfb9ff6fffbffffffffe3dbdf17fffff6fff3fffffffdfbddfbfdf5fbffef7ffffff5ffdffffdffffffeffe6fd5bffbdbbff6ff7f7ee0e", + "data": { + "slot": "1541628", + "index": "12", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x97f8417ba810593df7cb7df4fc76797080805ec4f2820e12d72ea84cb9b6de818c678a61816bbcb5e50abc8c635588f30cd5a948abc23f6e1f62471712b3f09b6e594aa94816a9d4968253925a382fa36ce90c89ea0083f19a9874af9300b605" + }, + { + "aggregation_bits": "0xffffebffbffffefdd7fdbfff7ffaffeffffedfffdfdffff7ffdfffeeffdf77fffbffffdfbbffffeff7fefffffffeff67efbffdbdfdff7ffdff977effffbffdf3fff7fffb3dfffbdddfee7fbfffdfbfffeaff7fffffffefb7dff7ffbb7fbfebbfffffff0f", + "data": { + "slot": "1541627", + "index": "41", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa9cf65317c6148c5b528d40094366da1fa7f898ca2991a8580472a764ddabb700dc26fb34e3ba0a02e0c6d4c7d5219ab00c7e9e6749a3d6abb68450b61840394d1b803f68c658ee329883aa82c22650018049e8aab5090de4dd267187418fd06" + }, + { + "aggregation_bits": "0xbf7f7ffffffbdff7ddbbffff9ffdffffdbfffbf3dff5fffdffff7dffff7ffefffffdfbffffffffedfffffeffffff3edfdfefcff7ffedfaffffbefbf6dfffffff8feddafaff7bfffbffffeff3fffeff9affffdf6bff2fff3ffffffffffffbeffeffffff0f", + "data": { + "slot": "1541628", + "index": "45", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb46f12df58310c974e57fc70dfdfb5c4b0635d8312851f68fd60253679744747b8ac59b6ee94ce3a5c0bdb82074861a51673922db346e9499ec3e1d6f482df53c1d23670f51e1cbd46ead0318a476677603d9bb5c794ed3b96baace65526d5c8" + }, + { + "aggregation_bits": "0xfffdcffeffffdffffdfdd77ffffebbfeffe6effffdfeffe47ffefceffcff7fffffbeffffbbffeff7ebddfff3efb7fff7ffefbfdfde7ffbfffffffffeffbdbf7cffbfff77f7ffef7fbfffffffff7fffefffffedfffffeffeebfdffffefefffdfffff9ff0f", + "data": { + "slot": "1541627", + "index": "52", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb79b198b66df5aebcad467353761f2a3e977b2add5489ade522ebab30a5756f382709e9e3d5a21ec13e6bd32d5936ff917b9039f231bde546133116bd46511026ff61000611ec582a9a0fc1aac29488865ccb6aacfa860e359331414be591f3e" + }, + { + "aggregation_bits": "0xf7fff8ffaff9fffbdfffffdfbbfffffffeff9ff7ffffffa76ffdfff7bfffffffbffffffff7bff3ff7b6ffebffbefffff6fffdffffbfffffdffffb9ffdffeffffefffffffff7effffdd7fd7ffbedefbbffff77db7ffffedef7ffdedffdfed7f7df7fcbf0f", + "data": { + "slot": "1541628", + "index": "38", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x89d88c7715c6dd6824612f54fc4471f6532cf74b1e2491ffd88b9329c18c73589e448373062fe015a5ea99f96db0ef73009739adec1394db9e62932ff9185dcef8e7ec25c59026b488c876df3f0b0f29d56b75e4543613d44b126b0d3d734817" + }, + { + "aggregation_bits": "0xffffcaedfffffefefdfffbb9fdfdfffffbffff3ffffdfbffbfffffffdfffffe7bfff3fffff7fddf78e9f77f7bfffffdffef7fff6ffff9ffcfffff7f7ffffffafbbfeffffbffff7fff7af9befffffffffffdfe7fb7fcfeffff7efeff7b7ffff3f7ff7fe1f", + "data": { + "slot": "1541627", + "index": "18", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8590fd6b365e5105a608913cf6d02c14dcdd91622d54790aafa7a0fee8328f90bb0ae0e7b2b9036807f730424fdc5bd1165c1b7f491f9eb23535d8148da52844c49140fdda2e549517bcffdef0b8535471d351c96174c3571ea04bb471f02fb1" + }, + { + "aggregation_bits": "0xfffffffbebffffff757bfffbfeeebbfffdee37ffefbfceefdfff7ffeffffdfffcff7fffedfbffcfffeffffbbdfdbffffffdf97ddefffffffd6dfffffffffff7ffffffff7fe7cffff7bfdcebff7fefffffffffdebfe9ffffefffefdffebfffffdffcfff0e", + "data": { + "slot": "1541627", + "index": "47", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x86cea7e5d4b5859fe8999dc6ceeb53dbdef474a3659c3e09874c48e83303ddd3386802c848927212fee9630432d206ae08ce9393704157ec6a0d1eb76724b3232dc5fe25d4fada6aaea307299904425d5eef9e3b1c95301fc0a44242b2595f2e" + }, + { + "aggregation_bits": "0xfeff9ffbfeb9fbbedfedf7ffadeffff57f3ffffffff7ffefefffebbeffffffffffffff9fbfbff9f7dfffffdffd5fbff7fff9fffdfeffaff9ffeffffdffffff5ffdbef7bee777efdf71bfffff7dfffff7fffffffffffffffffffff9fbfbfffff9fefdf71f", + "data": { + "slot": "1541628", + "index": "33", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8d8db822dd6069d1b911ac5cf95c9bb6629fc71935b76699a67020fbcccacbcaa6d07767f7bbe950ea98a53b35ae360f0078ec351013427a4d9456b4cf0022c1d010b108c3ab7fc16aa58c9da1608b1f56b67b17d4b054a2ccd37a68a7f31e7a" + }, + { + "aggregation_bits": "0xeff7fffff9fdeb9fefffcff7f777ffff7fffbe7efb7fbbffbf79fffe7fbfffffdfbfffffffffeffefbbfefff7dbeff7f5fe7b6feedff7dfbfffffffff7ffff5ffffffffffffdf7fffffeffdfc9ffefffefebffe9ffbfffffffd7dfbfffffb9ffbf7fbf1f", + "data": { + "slot": "1541627", + "index": "14", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb8a5f22f2c9e19008c5851b021c60c66b09b061cba88b8b020fb0121b5274f1f11913d74945cb2f4064ca42066f8ea4b03b21b018b4c5e620304eb84bff5a031bbc1e075795e199d159a57377f5dc9cb07161ebf8e8b661d00abfbb17b0abdbc" + }, + { + "aggregation_bits": "0xfdeefffffffdfffffffebffdefff7ff6ffffffffbbf7fffbfffdfffbbfbefddf7fdfef9bfbffdfbf7fffff77ffffbbffffff7fffffffffdf8bffbdefaffbfffffff7feff7fbf7fffebefffff77ffefff7ffdf7dfdefdfdbfeefdfffff4f87fbdeffb7d0e", + "data": { + "slot": "1541627", + "index": "56", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x88978a78d27cf13ab1e3dab15a3af11d9236f4db6982fda6c5c3bed293c842ead20ec4eb1690ba9793d361cac70929c104e827bff58939df2747fd98c83381db574ea04c2b6dbfd2bac950de75b4e01c8d76bf2a7126953c7b639ea80b22905d" + }, + { + "aggregation_bits": "0xbff3fffffff77ffffdbfffffffffefffdf9ed767fffbdfffffffdfffffffbfffbadfffdffbfffbf7f5f6fffffff7fbffbeefffdfedfbffdfbfdfbff5afffffdfbfcfb7ff7ffff6efbfefffff7d7ffeff9efbef3f7ffff7fffffffffbdedffefefffeaf0d", + "data": { + "slot": "1541628", + "index": "2", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa5b84502cd82613a8a64eb0f30af39e9c16b573066c0267ed214557af70ebb926e5f0320a8eed72e1ba0d3379cf6c3960554a715c7cbc95fc3d8fb87d8d197c828da6e8b3bec17212aa3e7d3495d076a6f7e840d14c33c72441c13410fedc0ad" + }, + { + "aggregation_bits": "0xd7ffff7fffdffffffbfafbff6bfff7ffffdfffdf7ffeffffffb6fdbfc777d7f7fff7bff7ffbfffeff5ffffefd6fbfff7bf67fff6f77dbbfaf7feffbff7eff7ffffdf5fedfbfffbff7f7fffffff77fffbeffaffffffffefdfffffffff7dfffffebfb9ff17", + "data": { + "slot": "1541628", + "index": "5", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x88684f7aaee6430bcf9faad64eb1134c1c4868aec082fa8d37c035caa17604cd0ed76a8dd8e12ff3252cb1f7cacf57a1059ac3b4aea24c0c2f18c9a4a6e9abb8fadf2be2ff277be6335db2fd260bbfa4a684467bb79e1d82f14b434989aaf6f1" + }, + { + "aggregation_bits": "0xffff5ffbfbdfeefffdfffeddffffefffefffffffffdfeeffddffffdffffeae7fffffdfedfffeffddfdfffe7f7fbfbedfffffdffd1afffddffbfffffefafffaed5efdfffdffbfffdffdffebfb7ffb6ffffff7ffdffffefffd7fffffff3ffafafffdf6eb1f", + "data": { + "slot": "1541628", + "index": "60", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa36c22cfb816715dabd9dca7353f7eb5814f20bfd5c3f537d8d3b18114552c49bc098b56879de3d98efd398f6be3054518d6dea535e0daa26248662f114c5e56618c5df989d1608453f8886afc07f95dbd2fc862189c8d21963f61a425d51524" + }, + { + "aggregation_bits": "0xdffffb7deffefeefffbffdfbfffd7fffffefcdffffdfbffffffffbffff6fdffffffffaf97ffdff3ffbfff7fdfdffbbffffeebff3aeaffffffffbe7d4ffbfbfdbfddb7dbfbef75fffdefefffdf77ffdfffffffffefefffff7fefff9ffffffffdffd7fff0f", + "data": { + "slot": "1541628", + "index": "6", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb913bd8216b889d7977bc651a1cdfdf5780276109931e97c26bc86702471ab533dcecb1105557d91593619a7d6f2565a0e6a4a77603081df12d50af78ff3e355e3417b1bcb376ea738be453a6dce4da8d3b2c4b7e73817d754402c94e161c896" + }, + { + "aggregation_bits": "0x5ddff7ffbffffeffbfdfffffd7fdf27fffcfffffefdffdff7fcfefff7ffedf7ffedafffdfeffffbfbabbfffffedfffff7fdfffff7affffefffdfdfbefbfffffbff7ff7feffafffffecdffdfaff7fffff7fbffdff6fffefeff7fffbefbf9fffffeeff750f", + "data": { + "slot": "1541627", + "index": "13", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x991bc34f436f3ddf9658c5908abb4d7ecf3bea466da97ecdfe3364f1309753695136a01317d0e1b050a63f2823c2cd58077325a82007ad34ace7e134c0fbbc7affd8d3f5350e9e63b23443fb00982c4b237d17cc4e806b60b5c8065d733f7254" + }, + { + "aggregation_bits": "0xffbfffbffff7fffff3f7dfffffe67ffefbffffcffffe5fdcf77ffbfffffdff7ffdf7fb7ffffffffeff7f7ffffdfffddfffffffbfffffffbf7dffbffffffef7fbfffd7fdf9ffffeadfffffffefdefbfbff97ffb7fdddeffce7c2feff3fbeb5ffbfffff70f", + "data": { + "slot": "1541628", + "index": "41", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa1019b92a70e2318ee789d9401d131de8a739dfc88abbcb05864309cb3f85850b6da7395a368a3da9bae2223587d50b902133e70cdf969a985f9af38883e0b0c6fbf965236d4521fc8c7c93a69ecdf42b41a9fde847be93ff02891ebd08ad1fd" + }, + { + "aggregation_bits": "0xfafffdffffde2f7f7fffdfff5f7f7fffffff7ff7effffefffbbffcd7bf7fdb9fff7ffffffbfffdfbfdb25effeffffffffbff7ff7be7aff7bfffdffdf7ffffdfffffffb7de5fffffd3ffff67ffcfffbefbfdeffff7ffbfefdefffffddfff7ff7fffffef0f", + "data": { + "slot": "1541627", + "index": "33", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x99eafd02493bfb9535b23c64b7f8f63a49341ed6d9d39c8add625d3ea3d8ea144f470af2601316f93bf0933cf7a908860ec8a56d5810582292002a24a75f67d245695bc86673ab0af480511effc2012796f0cc1a6e56bb69e9b29b7b2337e16e" + }, + { + "aggregation_bits": "0xfefffef6efffdffbfdefffffd7f7bffffffcfdffffd9bfef7fdef7fbebfffdf7dffffeb6fe76efffffff6f7befeff7bfeffdf3feffbffffdffdfffff7fffbbbefbffff7fffebffe2ef3ffff7fffdbfffffffbf7fffbfeee7fffbfffdffffddfffbffef1f", + "data": { + "slot": "1541627", + "index": "57", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x9815d49935be2de1d8fce7ec5033df6ea9ac5ead582dd63f7a5f887e5cacfb3a31c7019a1ed31410ac51e1ad7dffd55a047232c05c733326af3e9c32ace673881bca9d2b8cd185aee214b88f5fa6533bacb1ca7d7fa2f8a980511123c8091e62" + }, + { + "aggregation_bits": "0x5ffbff7bff7ebfdffffffdefffefdf7fbffffffcffdfffffffffffdfe7fdbdadefffffeefffffffbdefefbff7fbbfffdfff77fffffdffda777f3ef7ffffeaffffbfbfffe6ff7ffff7feffffbfd7bffeff6ffbfdff3fffe6fbffeff7ffffebffeebcbdf1f", + "data": { + "slot": "1541628", + "index": "19", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x85ff1bfeb5435dea6405ed05876405f27fa5704e91c432ef771cbd6158d6190e423e5cf657f61886b5c6d7153851295605bbe1a665d7a7e19200cfa2e78ab361d11e536ea0d3108a3053b60ac0602824b326bbb256868ced6d5f972a83ea0d32" + }, + { + "aggregation_bits": "0xfddfffbffb7ffffffffffefffefffff7feff3effeff9e3ddff7fffbfbbffbffbdbfbfbdfff3e5ffdfdfd7faffbfffffbe6b7ffbffff7fffefbffdfee3efeebfbe7ffffff7efffff9dfffbff67bfffbffeffff7f7edfdffffefdefffffffff7ffdfffdf0f", + "data": { + "slot": "1541627", + "index": "9", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x81d513f83b19f87a8808eaedfae4f6d9eb514301266dd7b0de0d4a521a5c7f6d6812efc3c80c85a6673c32756cd31d5f16f15045faa32f6994861ff11edb45159eb68e5945404a8976b45b0cc152e949b36826301ebc983b561d31190460eb5f" + }, + { + "aggregation_bits": "0xfdf7dff7dfbef7efffffffd7fffff7fefff7f7ffefaffbdaff739fdbffffffffffffddfff7bffaffdffefffb757effff37f7efefeffffef77ffffdeff7fcfff7dd7fdffffffffabffbfffefff7fffbd6fdefffcffffff7fedfbdffffff9feffbffaf7f1f", + "data": { + "slot": "1541628", + "index": "23", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xacc7fb9af1fa9d4e47fd7954433cada420acd07df9c47ff27439a635b28e1a43537025e02b6f5fd7f5904cbf6c9c794e01964cc25b6214f3a0fe11b3c8ce4165423bd0e1c00cd27a1eb3f8d037c0e7f616dd69abf5f80ad82626d7bde7b95662" + }, + { + "aggregation_bits": "0xbfff7bfffffef7fffff7fefd7fde77ebf9feffdbfbfffbbfeffb7b7effefeff7effdffdfbdf7ffeffffffbaff7edbffbfeffff57bfffffffffff3ff3ffffff77bdfbfffedfcffefbfaf9fdfffffffdfeffbfff7fffffb3fdeff7fffffffdf7df3fffdf0f", + "data": { + "slot": "1541628", + "index": "16", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xae0af131f77edf36d08d9e5d019ace6975b1d41d59392d69d327e47b7f8773db3e318d7dcd1e4e97a7855b3d85d462811228f4e7b04dcd1b086c7380f38c64c12b7f6bd54f0ce4d2659f8e2ff4c01465c2f52156ac11ead7881406af56884e97" + }, + { + "aggregation_bits": "0xffbdfbffffffffdfffdfbfbfeffffeffbfcffffbfffef5ffff7ffefbefffefbf7bdffe1ecffffb7ffdfdfdfafd3fffffff7fbffffffdff7fffff67fffbfdfffdfdffdffffebf4fff7dfffdfdffff9ffff9effff7f7fffdff7eefff7f3fc7f787ff7eef0f", + "data": { + "slot": "1541627", + "index": "17", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x86fc8bc1529accb5b9624ea36963d8ab46a3396f5ace02edce91867b3514b0580406e5b05c46fbb9ad986e671f1987d80c1f6580b71683415cb41742055a034507698a6a096a26d7a0a0dc7b953b836a457bf1e3ada4831ea360add19cc64bef" + }, + { + "aggregation_bits": "0xfff7fbe7fffffebff77e7ffffffbf9affffffbbfdfffbfffbffebdffff7ffd3f6bdfffbf8fffdfcdfffefeefef73fffeefffffffff7fbbffff3fdff33ff77fff6fffdbbdff5ff77fffffeffffefabffbffeff37ffdfffdffffb7fbffffffffffffffef18", + "data": { + "slot": "1541628", + "index": "35", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8c4ce027c91f6524042fc85e069b80ea339086c3f15c0fb142aa08279bb5f58f0ac8000a4355cbef3c32e5f262601b350bf9e86585bcfef79ffaa8f9768046a2d1caba2251d22638ddd1d6c47f492438e5845aa7030046fd8872d1db94e8a7e9" + }, + { + "aggregation_bits": "0xfdf6fffffff9bf7ef7bef7ffffdffefff72fffbde767fbfffffeffeffdf7ffdffefffeefff7effebfffadfffbffff7fffdfefff7fbffeffff3f9f7fff7ffcffffffffffffd7d7feffd73f7ffff7f3fffbbfff3ffff7e7ffffebf7bfaffbffe7fd7d7ff0f", + "data": { + "slot": "1541627", + "index": "5", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb3c5e436ae6e8ae7993f5d399cfee441741a735b835893fbe2cf4c47f3ca4de29334d5df814a48feaf1f3e2fad7442e80d7585920987352395c006f955c3ecb7138ee829197eb9b19a45a84181b25eaf0c3d3e8530b3bf21d1710706971d5c49" + }, + { + "aggregation_bits": "0xbfffbdf76defbddb9ffe7ffbfffffbfbff7df7ffdffeffbffff6fffffffbffef5fffefbffdfff7f98effebbfffeafffff7fffffffb7effffffffffefffffffffffbaf6dfdfdbeffff7effffedffffdff73ffbfffedfebeff7be5f7f7ffff4fffff7f7b0f", + "data": { + "slot": "1541628", + "index": "40", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x81e84528c47080321d0b7cfae507eb6f86630eb37054f725786408123f40f3f2341071aacbe2db206b73dbb6a963645113590901c31c45cdcc07e8816e11b9eac51db113d15cb8d7b45f6d0e4c9b6a083ca4eb5e18b5e8a70a05ae5ecb9628cf" + }, + { + "aggregation_bits": "0xffbfbffbfdefbf3f6dffffefff5fff7f7b7bfbffffeffefffffffa7effffffffff7b9fb7ff77bdf7feffe5ffffffff7bffbffbeffffffdffefeffbffffdfbddffe7dfef9ffbeeeff7fb7fefffbf9f7ffbf7fbdffbf7ffffdfffffd79deffffff3ffff91b", + "data": { + "slot": "1541627", + "index": "44", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8707917e5100feaf0eee14363246c7cf0405c08f151d6528cfdb779b8b2d22d6529baa219cc9add5e917d1ff64ca226e05ade2b47c2113e088d48b4c7ab2024d1d01d7e0081aa5292c75557ff96b322c09e93342bf670e5696d5ec78b5d7d6be" + }, + { + "aggregation_bits": "0xbfdfbfbffbffadfffff7fffbb6ffffe7df7f7afffffe7ddfffbfefffffeffff7febfffebffffbd77fbbefdffffbfffffbfedfd6f7f7feafffff7ffffe77fff5f7ffbfffffe7eff7fff7bbeddffff5fefffc7bebefffffff9f7ffffefff7ffdfffeffde1e", + "data": { + "slot": "1541627", + "index": "24", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb9418c7de91c070ac8a6c76d1a3d98aca40d6370f2998bece90733291e4dbab0c5ea125b0ab530e843256638cbfcd84019418a53de27c62aa195f3e1fc881f16295707c3798cbd8fa36701d129707a73b19b3bdf1354f0f908730bcfdce37ce6" + }, + { + "aggregation_bits": "0xf4f7ff7ffefff7ffffffdbeffffff7dfd3fe3abffffffe7ebffffef7ffffefff7fbfb7777eedffffcfe7fffff8bdb5f6bffffdfffdffeff7f9bd7fbffff6f7ffff7ffffd5f7fffbffafffefff7effb8fdfffffffeffffdfbfffffdfffff7fff7ffdff70f", + "data": { + "slot": "1541627", + "index": "1", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb4deab225f71684f6df08b729641c40fe20f30dd2891a3051330365c1893b51979a9781cc7c6b42747de5ee1d17966b601933dffd1a7b0e13cbd0d566fb77e8413c8187d650c5b3441ff5d0364c4455a9fedb8c4dc1949359f4f5499312cdf3f" + }, + { + "aggregation_bits": "0x7efff7bffdffffefdfbfffffebf3fdeefe73f77fdd7e7ffff7dff67ff7fffeffffffff7fffdfffffffb7fffff1effceffcbfffff7dfffff9fff5ffdeffd7ffffff7e7dfffffcfdffffdbfffefffff3ff7f7fbfbfeff1ff7efd3efdfeffcfbfffff3eff1f", + "data": { + "slot": "1541628", + "index": "3", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x87c89b73650e74c2536c43705ebccc8a4f2b328fd0a2d4d05d4a047313f3086ae1df45ade2dc6422556c71bb0bec12370c2ac99957bf50e2e6dd0f14d44c3fcfc243fec4a40fd788b17931ab13a4eb64c5c4c2343ce0d90e47d09d10676e3f99" + }, + { + "aggregation_bits": "0xcfbf8fffe6fffd7ffdd2ffee7dffff3fbff7efdffe7ff3bfffffffffebefffffdf7fffffffbdfafbf7fbfffffff77ffbffffdef7fffefbffefffffabfffffdffbfeffdfefeffffffeffffdfffee7f37fbdffdfbfefff77fba7f6fdfbfb6ebbffdffbff1f", + "data": { + "slot": "1541628", + "index": "42", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x949ba19c119ceaedf9172868af0852b9dbcb8dd3001ba41ca4884d240ff80bbdf91428cdc8467542b93d29eda7893eba0ad6ba3705eb5e21be1e5512a1e59f6da17097a2e6a6e5bbc34e5450840d8e6eef466105ed106b6faf3cfde9dd3a127b" + }, + { + "aggregation_bits": "0x7dedbffffffebfffff7dbfdffffdfffcffffffffff7deffffcfffcf7fefeffdfeebefffbcfbdffdffddff9dffbebedffffefbfefffffefdfdfffffffff97fff7f7deeffddeffef9ffbfff7fbfffffffbbfffdfa9ffd3fefbffffffdfbffdbe5d7ddfff1d", + "data": { + "slot": "1541628", + "index": "25", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8ef1c5bf52b3f438f8e75286ab4a54649127cd9e2aed3cc03e3f6e8baaeba0415e490f324f33419bc276cfe19bab841f0fec31c628b1480a2d0f45a2071b90369a36348487b3b459a75846b5cd5089e2229b78ba105c1cc430df48eb1541a473" + }, + { + "aggregation_bits": "0xfffeffff7bdeffffdefbdfb7fffeffffffeff7dbd5fff7fdfeff7fffbfffffafdf7ff3bfffeff9bb7fef7fdf7fffffddffdfaffbdfdffdfffbffbeb3dfffffcf7ffbaf3d7bffffff1fd7bfff9ffffbfdffffefdefdcffffffffafffbffddffff7ffff70b", + "data": { + "slot": "1541627", + "index": "29", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x91272cd8fa5b058a9f69904252e56553b75c4dd517e649ae4b65c26594f316d87a88df4a5a1c8821b9b920f13881a3be11977bfac8f36d58451399756c2a56e0e260278030ca77b39f03e6fd63010b0802fd4c5e40eabd6486393356ff5ce6ad" + }, + { + "aggregation_bits": "0xbff7dbff7effefdfffbbf6fffdff77dff7ffdffd7effff7fe7ffffffffffddfeff6dff7ff7fefffbb7affffefdfbf7ff6cff4ff7ffffffefbef7febffdffff5cffdfb7dbf7bfffbbfeffffefffefddef7ff7fffff7ff7fffef77fd2ffffffffcfbfef71b", + "data": { + "slot": "1541627", + "index": "51", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x830f6becee1b0a739bec225d144ff05781229bf19fcbfb3bcc48426449e97b0ef5044440758c190540207dd870ee590408c229f892f6d3d37a07ee80de929069e60503e44d6701e642910445f69710c2347badac93a39fe7dda5c5474165d87c" + }, + { + "aggregation_bits": "0xdefffb4ffffffffbfebbbbbffffdfffffffdffeffffdfdff9fffffffb67dffffbbff7e2fffffffff7ffffff9fffffffdfeffaffdfffffdebffffbff2ffeffafbfffffd9be7fffdfdf7bf5f7ef7fdfffbfdfdfeff6ffff5cbff3f7fdf97f7debbdf76ef1f", + "data": { + "slot": "1541628", + "index": "27", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa3b86c88570580330decdf1b5605d45c8c7f486f0fd6a498634eed09581331cd71b84ba2408a44e24e1ef8bcb60cc188155355c9dc472ac9621a738f474f2a8a76ec1990bfcf9b0b1ad7308f5fdfa7c91c2d11eec2878f1c31d296414409bcf7" + }, + { + "aggregation_bits": "0xdf7ffd7ffeffbb7f5f7ffdffff73f95dffffeffeffdfefffdffeffffffffeffff5fbfbfffeefffedff7ffbeff7babfff736ffe7bfffff7fdf9ffcf7fb37df6fffeeffbefff7fbdfbfdffffef7f9fffefd7ffb5fffffbffffffdff77ffef6fddfbfffeb1f", + "data": { + "slot": "1541628", + "index": "50", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa94ef8c5d29d4c154cb74c4bde42e1e90980c58139b00598d410119273b16b457691ef1ef80e3385b6aee3e331e61ebb062c03dd78396d184a7765afe4781cd43a2d26f0d74a4974bc12320cb88042421f06119484b60f0891bcf54db1dc6dc8" + }, + { + "aggregation_bits": "0x7ff7fbfbf9ffffffffffffbffcdffffffb3bdffffdfff7ffaffdffdffff7eff7fffffdf3ff7ffdf7f39fdfdffddffffafefffffed3dfff5fffefadffeffff7ffffdfffffadfffffffef77f6ff677fef7e7ffbfe9d85fdffff5d77efbb7fff9ffffffdf0a", + "data": { + "slot": "1541627", + "index": "37", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa881ff482ef02f9bb03437911b86215cad16802b639613920199635cb47dbb22bbc068c752b94af10805ab0e3ecd61ba15feba7c6e0fd905e9115d390e227de5070f9f4c258d5032db306f4df88c78db0da15fdcf5851c8c8335e0a81943ebc9" + }, + { + "aggregation_bits": "0xffdbd7fffff7e76fdf75fff3fbfffbf7fdffffffffbf7f5ffebdfff7fffdeff7efff7e3fdeffffff7fdfbfbfff7fdfbff7f2ffd7bfffffffffebff5beffffdefffc7cfbdeffffbff5dffd7fffeff8fffffc7ffdf1fff7fffffffaeef7ef8ffffffbf6f1f", + "data": { + "slot": "1541628", + "index": "21", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa311b00593b7b2bd6b097ad3c4886a8484cfb394fbef785d4944ca7998844e4d511a11025c80f22dfaf24a40587f9f1a032efc34c8d3ee2aa8c081f4d947ef93a7d380dbbe16c0725032e5c775e98f7b1c6f3e19093bdb08bf0ed80e75c672f4" + }, + { + "aggregation_bits": "0xdffdf7dfbfafdfc7ffffffe7f77ffefdffffefffdbf7f7fffdaff3ffeff2ff7fdffe7bfff7ffdfedfffdffbfffff7eeffaf7fbffff77ff3dfb6f7b7fff5ffaef7ffffef7fd6f9fffffafffff7dfffda7fbbbfbdffffb7befffffefdfbffffffe47ffff1e", + "data": { + "slot": "1541627", + "index": "53", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x89f2f66a608c8ce3762a18b66635dd9b7c3b28fa2d73555dea63edaa0a728dd36c48d4ae54e0afb901f6d80de8bf8c4807f85fddec59857d771b1260943e4f45b6acee2214f41ee96d7e57d8c5856a3cf8a381dc3d304bba593378126fdc3c58" + }, + { + "aggregation_bits": "0xffdfbfeffe7ffff5d53ff7fe3ffffe65effe77ffdff7ffdffffffbffaff6effbfefef7ffee7e76ffbc7bfffeffefdffbdfffeffbfb37bf7effe7dffffffffdfff5fffffffffebfef7fff7ff9fbf7fcdffff77bffffff7bfdfffff3ffffff9ffffdbec70f", + "data": { + "slot": "1541628", + "index": "22", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x920425671a357b56455dcba190e6c11193eacc4c8cdcf028f714411cbcbeb1fb8780d0ed6088882321c05d470d641a8d07061ddb951a311b2348aeee6c87df8b6d9378d0488eebfc9107750d481e999079d5dcca52c9305d83c5f60ae9bde08a" + }, + { + "aggregation_bits": "0xfdf7ffffbbceedffeffbebef5fdffffdedffff7b57ebff5edffefbfffeffdffffffa6ffff9d9dfffffefeffbfbdefff7ffffff3ffffffffeffdfffbefffff6fffbfbfffefebbe7ffe7af7f7fefff477fd73fdfebcfdffffdfeddf7fff7ffdfcfe7dfff0f", + "data": { + "slot": "1541628", + "index": "26", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8a0f30682b51f3e289bdee5008583542d7719837be7dfcb9efda989c66b705386b031c59771f291224d04b786c3873f106ab600c0a9b9064eff4c08888ebd42efbcd17948003837ff4b051bfadb8719794b1312edc6070e2060fef6366a06656" + }, + { + "aggregation_bits": "0xffdeffbbdedfdfffffd97bffe9ffffff7fff8fffdffe5ffffdfdfffef4fbfeffffff7faffffffedbeefc7ffef7ef7ffef7fffd97ffffeff8fffffffffdff7ffffbbfcffedffffffaaf77e7fffefee79fbff7ffbbff7ff6ffd9fdeffefdfce5bff72ffd0f", + "data": { + "slot": "1541627", + "index": "3", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x817158fb71ab51911d7f93abc12c0f2a2814324fb2530a0a21cca2a3d1cb3dcf0c382dc288d5f0ed3e185bd5691ae84a0c8d22501cc13aa1d42830c599afb59664acae6967c635777d2b957cbb510b0889fe7b3c8ba5a6b60fe9638aae6cc2eb" + }, + { + "aggregation_bits": "0xffd6fdff7fefbfbd7fd6ffbffdfdfdf7feffbd6fef5dfffffffffff6fbf6dffbe7dff777ffafffff94bf77effff7f7feffbf6fffffbbffcfff7f7fffffffffff2ffff7ff7fffffefbfffcddff6efffdff9effddc7f5dd7ef961ffff6fffbff3cffffff17", + "data": { + "slot": "1541627", + "index": "6", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8d3644efc17cf5e58a649aa74abbbb9aae4761b769427118731de14d9aa2e83051d7006f318e3d7c5827abe6360cf1fd123d7206203febd44cea9a2a95dea83a5ae977e1b98af30d38d88829fb1b1247ffdd032da477876b6f3c2e212a6dcc4d" + }, + { + "aggregation_bits": "0xfbcffdd7fbfddf8ffd9ffff753fff9fdffffffbff7ffefd67efffff7fdffffff6eff57fff9defffef7bfefff3ffffbb6fbbbfffbffeffb7ffffebbfffffe7edfdd76fbd7fffff7fbfeffff9f6f7deffbfbfffffffd3bfffeeaffffff7ffbedeffa7bbf0d", + "data": { + "slot": "1541627", + "index": "23", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x854cac4099256de01512ae5a65da712f162982f12d4084641a2562275de3ad4b830f82b8a382f21b10dc6d98e9e48ac2186cfbd34cba6068dc16b905f200795c05eac137817c1073c215ce76b10b7e39737f85846c53125c6d83c03de0f4fbc3" + }, + { + "aggregation_bits": "0xfcbf7ffff5f7fdeefffffdbff7ffefad77ddff7fffebfeb7dfd3ff7fffffffd1dfbdbbf6fdf7eef78efbfffbffffeffdfff5fd3feddfbf7fbfffbed7fff9fdfbfffdefdff3ff9f7fff7fff7fff7ffffedfff7f7fffe7ff7fde77ff7fdfecdffff6fbfe0f", + "data": { + "slot": "1541628", + "index": "49", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb807556e09b988c16a753579f3a638e6d788e4f71aa18332f632ffed73ab9fab6a4aa5d7c84bbda5cb69cc0ca8bcbeaa17ba341c32c03ed3b09d36f4e5b95264373df23f4398bfacaaf62900eb5980db97095d7a48c7260ef9605624c94ddf4e" + }, + { + "aggregation_bits": "0xfdfaffff7fadfefdffff6e3fbd1fdbdff5fdbed7fffb7ff7fffcfb6fed3fffffbeffefbffdfdffbfffbde7f77d7fbeeeffd77d7fff7f9fffdfefbfbffd6fffffbfbffffffdff7befdfcfffffff9fddf5feefff7fffffef5febffffdf9fffb2fdbff7ff0f", + "data": { + "slot": "1541627", + "index": "50", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8328e9beb708dca950bcafb4c01c760292357021a79a3ef5fad5de4859ff0a86c2cdc46b85bcde269509cd390e1bc2891261ae4a8d01da6fbd855cf9e19fcabe1701355b918505cea485df6e30e26cb10df8023ca4b79dcea80cb79c7729c2e6" + }, + { + "aggregation_bits": "0xeff6fffd5bff7ffff3fffffffbfeffffbfffb1dfffffbfef5ffff6fffbf77bebfffbf7ed6f7fdffedfff377dafffffefeeffffd777b7f977eafbbffffffffff6efff5dff3ffbff87dffff3efeffefbfb7fffb3ff7d7fbffaeffecfffff7d59ffdfffbf09", + "data": { + "slot": "1541628", + "index": "18", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8e6e92d75b64f2439e48fce82b50d9af749535427cb994e78186c5221df428f533c2e2ae31254dfa2f97c90c24ce2afc060356cff599db7675290170d96f3dc1c4a469756bea75efb5d44626dbd44ce32b8c185fa5738c3cdd8201e89a610d19" + }, + { + "aggregation_bits": "0xc9b7bddcfeffff7ffdfef7efbebfefffff7dfffdfdfffdb7fffdbfffdffffbbfb7fefe75fffdfbffefffe77fffffbedbfeff7effef7fffeefffffeddffb62bfeff7f77fff6ff3d77ffeff7ff7eeaabfffefffffbf6fef5ffb7bb6faf7f7ffecdedffff17", + "data": { + "slot": "1541627", + "index": "48", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa70793e1876c1f77e04b3454e17556cb2a95b023a8e418a046e1597d251e877c3e56b04a8ddc1a2746df69d0c54d68900dc6846d9f54f5ab4b9b44e051feb15302c984aa6d4bc51d03c5cfd7b95f4bf11e6c870baaeef24d2537fc71ae256b08" + }, + { + "aggregation_bits": "0xf4fdffffbf3f7fff77ffefffbfffffdffff7faff7bba5ffbffff9f7cdfffffd6f7ffcffbdb7ff5f7f77facfefaff1fff7e9efff99dffbfdfbdf6ffdc7b7effdb7ffffffbefe5f9f7bff7efeffffefffdefffbff799fe0ff7f77bffdddd7feffcffef570f", + "data": { + "slot": "1541628", + "index": "55", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa1f9d529c7a7b0ab7429744e854a53279eedd532ac9bb676dc1605e96833d3065f6fa1461301e7a4837fcc92fc45d26d02876c13585f6c55105fc553c0073230d190890642d0ec6a2177999fe45c0006e249e8ffbf68bcfc846c20fa822ab74f" + }, + { + "aggregation_bits": "0xfeffffffdfbfeffffb9df9fbfffeffdfb7fdfdffdfbef766fdfffefeffcf4f9feffa7efaeabbeffff1ffed7fffffbbf5fd97fe6b4effddcfffbfeeed7bbbfcffdf777cbfdf7fefffff3bf3e63fbbcbafdff7ff65faffb7f77fffedfdb5fff915fffffe09", + "data": { + "slot": "1541628", + "index": "36", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xaa92d0db3f8dd84c8d934cbe207887683618e1bb6fb302fc8781b153e5c4c611a660c0e3715d56dd24978a06c9895edd0800ad8f59e242fe32c396925881310db97056512c27c6e634456112fb10f6a376fa71b3278426b9b1eb07f32821dff7" + }, + { + "aggregation_bits": "0xb3b7c9ef7d71d37997c92bbf375bf9eff7befd34dbf7fdf7fffa7bfbdfeb7d6f78e6fe8edaff3ffd9adf4fb70f7f7fed5eddff765bbf3f77f3beedf6e3bffedc0fdf73dffd1f3cfa66f753fefeb7aad5afbffeebbddffd564f7ef333cfbcbeffeb7d3e0f", + "data": { + "slot": "1541628", + "index": "14", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xad5a3cfe73aedda84e5c8265a9be7356ead904286200f2f20dcb4abc93c33b7062b051cdf4e1d3993dd18ce0ddea67910cc861bf6a27b8991baba1e3b67ffe10a6495edfc1eb0706561113f81b953979875bbbc65de8d2ecc293377413142383" + }, + { + "aggregation_bits": "0xf1dd73ffe8df317e75cdd18f36cfffe7e77eebff436957ddfae5aafef7eef7bfcef577df5738cb317b4fff769fdfef7ffe4dff6b9997effffbe7edf87fe6bed3dffaeff9df93cd67eb7f7bbdfafbf5fb5b67e95adb3dfcba7fabe7d77eeafbee7edabf0d", + "data": { + "slot": "1541627", + "index": "58", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa65db076347af36f97fd31c895700ff579cf876c66ada9535d37a8457646dc2c588ddb4c6bf10f7c92cc01bfbcc1d959073eecfbafdce1675bb05e408d07e297ad686321e18281f3656821daf2ca7759b6dd8b17b56253b6c68e7145626dfca7" + }, + { + "aggregation_bits": "0x3ee3e16be9d737bdb6baa8e9aff3e613edeae7f774a7edfcfefdcbbb7ef743395fe5fbf3fc6c29de73ffaf25cedc27e2f787b7d53ff69f35e0abf7d9a637d1ebefb5eb9b776f4ff523fdb7db77b6ee7ecd2f63337df7e695bef74762eb55fdfdff1f9a17", + "data": { + "slot": "1541629", + "index": "51", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x82800fd3d60ed668f1c3144265eac8cafc7bfa6a4af52b937b08befbb4eedac728fa115caa2da88e9a277e43599c113610f8190de815b1fccef583a1ae09d65d05e30008634c3f77bb0928724903565776909fa289f153794adb9248838fa0c1" + }, + { + "aggregation_bits": "0x3e2aa26408c1d481c7233feb97c1000a4a38915d00a0ca059cf4368eff76188f04faa6c1c2c08fe04b05d65100bd3271023495480b3b84234a3bc092b677fd2f6f203ad2707128a030941051cb8208a3a0278e23e7e39f4ec41448cc0e54761a6f2c090c", + "data": { + "slot": "1541628", + "index": "20", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x92ad03338fbd439fa44a3e1375c45086bcb5a5d2e1c343c0d659a5b8a387b8eba107330d525cc27387f5155fcf6e5cec01e508c85df6bd5e27fb1ce5362e8a64ca4256779bd70e764c98e46028aea9a367abe6364afa94e448574a899c766e0c" + }, + { + "aggregation_bits": "0x008402011422401800410a0042d80cba2ad01ac01a20528f0c901a0623209c084a280b0800821500cc400280a088408c033a10b04248480320061005140102108824242b8019006a12301820908a19000444021a49c1e8302860819c02132800618d4810", + "data": { + "slot": "1541629", + "index": "51", + "beacon_block_root": "0x434bf387a1b6df8d7ccc2eb040b0b2e7a5ac0ff41fcd985082669240be3958e2", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb610109f5623802e03e9e065f3732ea1532e7666bcddb81382712103fbd37b7ad93a0ad6c16f76d0e399c974741e521b19ec32d1b321bb47361868bfd99c10e045bee4a1863841fe06945909de701884c85aab3e3a391d4a9d76b37382b3fad6" + } + ], + "deposits": [], + "voluntary_exits": [], + "sync_aggregate": { + "sync_committee_bits": "0xdffffaff7dff2fceffffffdf6efffffdfffffe3ef6f7e5ffffffcf5ffbdfffdeffffffffdbefdabff7bffffffbffff2fff57f7ffffbffdbffefff7bfffff7ff7", + "sync_committee_signature": "0x886a35d5e48d75000af6b915cc08b76beb631c49a3cbc7b593e6f067be220ebe1f6cce195419e5d75e065e1aa808f2451187dcef68da952c8650ad319b12d11b969aee2855ad27d356131c6aa7d4ee7d70bcdd4ce363b8dd567e021b79fcf470" + }, + "execution_payload": { + "parent_hash": "0x50f9d0435a27c4b25edecd9b24b2e0db3a500aa424023a7ca3c5e79d14e37d31", + "fee_recipient": "0xc473d412dc52e349862209924c8981b2ee420768", + "state_root": "0x5fe751959eea205b6f61c4702b4aa57c1cd5bd1ab77c8f33ffdd443ffb991d46", + "receipts_root": "0xbc9166467fce0e32f7d0126f1c25b0be981286df87a9182b73e58740e3e48697", + "logs_bloom": "0x050028800804c000a90010282c0001064002000a0400005494f000110040c64008001100210000400804208002080481001804270262840000b4108015284800210003a24050c023000600090408408f1185468a093c0292420424d930a02001000409000a89802086d200060000090008240002000630ac04201410102614428186b04004216008a40000c10c40244a622230853004b1028a40400924640c09032c1a44002484007090007237862804a3030204008003461e10002e406448c55c1a020232500100110001bc01900551aa25000a0080004200a8180123026110041288022c00105a21100940c018a0200d00800242420384440100000a29a640", + "prev_randao": "0x9342c0a4a809e5c83426774bd1d3eb0242bd1e4de1aba5f780dddbc5e55fc6fc", + "block_number": "1443465", + "gas_limit": "30000000", + "gas_used": "19655111", + "timestamp": "1714401984", + "extra_data": "0x4e65746865726d696e64", + "base_fee_per_gas": "1159351329", + "block_hash": "0x1aa74d6ff92f4f4d11d905a974af2d0c22c17f107caf156aa1252b875b8d756e", + "transactions": [ + "0xf8ac02850bf6430db5839ef8e094ce658e386fac0646cedaf810070f0525af14d11d80b844095ea7b3000000000000000000000000329d0c4a58b3cefdb40c5513e155228f6cc7b6c500000000000000000000000000000000000000000000065a4da25d3016c000008284f4a0b126116d81254d65a298e6bcbd70911644341a48721dab0f4e441a8e2346bcfda046fc3124db1434320293bebe0fab8cf931ef30c1d1cf5303f87771a4b4a5429b", + "0xf88e8303a6c58502c32786808259d894152b2c564e0caf9422b4b12f2aee26789f04052a880de0b6b3a76400009d5472616e73616374696f6e206279205374616b656c79204661756365748284f4a01289a3e4e3930ff08a0434e80d7efc4447d7329f468362b0ea7aa5665b5a54dda0347b87225a40ef4dbee81a9d44f0114996ec332628ae655d849e3504530023f6", + "0xf902940485022fc98282830191bc94f458747c6d6db57970de80da6474c0a3dfe94bf1872386f2704a5440b9022433bcd0cc00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000418fa4fd2b4dbacc421d9f7c98170606f88385ca00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000418fa4fd2b4dbacc421d9f7c98170606f88385ca000000000000000000000000418fa4fd2b4dbacc421d9f7c98170606f88385ca000000000000000000000000418fa4fd2b4dbacc421d9f7c98170606f88385ca000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000089544000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008284f4a07eca7d7d2656d260699e636fea5b07526ea4e3531024876c9594da1de986c82da0523bb27a9c98cf1b76bf2dfa28addb1e1114d1aec1b861a46af8531e42202fce", + "0x02f879824268830f8c3585012a05f20085746a5288008252089466b129814eefc19dba45a9ce4bbd6fb1adead33788016f55c5eb745a0080c080a0bd3110f4af6cef102867c58cbc05ee28f7c8c2159ee1bec7cfb37751959986ada0438665d3cb1789f5b40782981677407b5c62135a6786cd3c2abb837eae4a4876", + "0x02f9021a82426806847735940084d7e6c28b8301895294a098b76a3dd499d3f6d58d8accafc8efbfd06807872e9ba936cef000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c3511000000000000000000000000cd27f6de1743b59269193997e283dae80295c9060000000000000000000000000000000000000000000000000000000000004268000000000000000000000000cd27f6de1743b59269193997e283dae80295c9060000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000cd27f6de1743b59269193997e283dae80295c906000000000000000000000000cd27f6de1743b59269193997e283dae80295c906000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a0298d799e7bd0424da3e576ef71257878136fbb9a188ce747d6ae6993a72c7b0da06bbf01eae8bd611e7ff5236b426b3166ec11e2ec5b343d44b912db3b53061caf", + "0x02f9021a82426805847735940084d1b1f68b8301895294a098b76a3dd499d3f6d58d8accafc8efbfd0680787caed6d88ecf000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c3511000000000000000000000000d6ae7d4805aba66c422e4a13a05f90809fcb30650000000000000000000000000000000000000000000000000000000000004268000000000000000000000000d6ae7d4805aba66c422e4a13a05f90809fcb30650000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000d6ae7d4805aba66c422e4a13a05f90809fcb3065000000000000000000000000d6ae7d4805aba66c422e4a13a05f90809fcb306500000000000000000000000000000000000000000000000000bfd8b6c1df000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a0b87efd59ff683b0d6a0c8f8ba07d77d387fcc871707f42db7c8518edbc746431a056060267de036bda872b7abc13dcadeedb51fd79b2ec4e083a713e37b9a9ea0f", + "0x02f8b18242680284b0c9e1a084b0c9e1a082b76794a960d72f83a8a163412520a778b437ac5211a50180b844095ea7b30000000000000000000000002259662ed5de0e09943abe701bc5f5a108eabbaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001a0c3d8a56f00e9de96fc35ec08c3e35630ebbca4679cc47e9cce482a6b09d9db0aa02b6fa29d9cf5c37767cc2b51f7929c6df63d852bed13968714b9b99db5c25183", + "0x02f8b18242680284a40f336a84a40f336a82b76794a960d72f83a8a163412520a778b437ac5211a50180b844095ea7b30000000000000000000000002259662ed5de0e09943abe701bc5f5a108eabbaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a0b0b343d25b1a8d8d1b755c3def0d74087bd1ef742d6b2b69deb3c9b40a05b296a06b31bba6345a5fff9de5535816b8766a3d3f6d7129bd32b4491ad641a1dca84e", + "0x02f9021c824268808459682f00850146d018d08301895e94a098b76a3dd499d3f6d58d8accafc8efbfd068078801274c4a4515f000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c3511000000000000000000000000c4c795e54d5c2ed7293c283cece48534f8fe02300000000000000000000000000000000000000000000000000000000000004268000000000000000000000000c4c795e54d5c2ed7293c283cece48534f8fe02300000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000c4c795e54d5c2ed7293c283cece48534f8fe0230000000000000000000000000c4c795e54d5c2ed7293c283cece48534f8fe0230000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c001a0caea975454b7bc91e21987011c8de76c58e0b20797949730503e7d7f87c32c63a072e9dcbda58bb361ed95f911d5f43e1c5a35d62b20706fb5491223274cb5b782", + "0x02f9021c824268808459682f00850146d018d08301895e94a098b76a3dd499d3f6d58d8accafc8efbfd068078801274c4a4515f000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c3511000000000000000000000000ed899fce77fe2019cd863afa6a78c1eb2b7e4b830000000000000000000000000000000000000000000000000000000000004268000000000000000000000000ed899fce77fe2019cd863afa6a78c1eb2b7e4b830000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000ed899fce77fe2019cd863afa6a78c1eb2b7e4b83000000000000000000000000ed899fce77fe2019cd863afa6a78c1eb2b7e4b83000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a0d67fd41e123df2eef497acb121f476b06a445311af8b599c7af4a4945a2c6048a00b99bd79dc459c9fec7dea816d08acc33957f40c2203458b58ba11d7c98ea8cb", + "0x02f9021c824268808459682f0085014072c1b58301895e94a098b76a3dd499d3f6d58d8accafc8efbfd068078801274c4a4515f000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c351100000000000000000000000088c4c9d1ab2ed5a614b74f4f7be43f46ebe74f2f000000000000000000000000000000000000000000000000000000000000426800000000000000000000000088c4c9d1ab2ed5a614b74f4f7be43f46ebe74f2f0000000000000000000000000000000000000000000000000000000000028c6100000000000000000000000088c4c9d1ab2ed5a614b74f4f7be43f46ebe74f2f00000000000000000000000088c4c9d1ab2ed5a614b74f4f7be43f46ebe74f2f000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a0128f75892ae424d1cfec7c5c2e92cc807a07274ce72ba5be690f9d3e76a5b501a032b8fb31b42444c17e8727be4e9f0111a46db51c2a48170f9d0d9f0772e37674", + "0x02f873824268825a5b8459682f0084f41d464683010ea8944a7c735c43640917c187012d92249dc7d75302478084cb748456c001a099bcbfda6dea42106e79ab409e5f4c93be0816eca3f1982cdae5948e3f191e40a01eaecd10006bf9c06a916c38bf5fb4d9c462a633fbd9b86868567b55829024b1", + "0x02f894824268830621078459682f0084f41d4646834c4b4094e39b59f94001c648ddb0ad770ab5a2d2e475f4b780a4c7d1ac38000000000000000000000000d082c78982156451f6e7aba8e481771ed53c4691c001a09e196bd3278540d09503c46aa50cffec9d7f0f3059a4ac3192056078dc3eb4d9a04c9d5d315655d851a578a88386e334386210198f4720731a42962ebc2d6565d2", + "0x02f908358242688255fe8459682f0084e7c97c7e8302485b94d019a78a19f8ae1dcb5cd188620bcbc8fd3c809080b907c410364211000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000001606870000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000003902ae7518017bd306e1e0fce39d3862fdae405000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000005a69000000000000000000000000000000000000000000000000000000000000229c000000000000000000000000000000000000000000000000000000000000002300000000000000000000000000000000000000000000000000000000662fb2ae000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000052000000000000000000000000033503f021b5f1c00ba842ced26b44ca2fab157bd0000000000000000000000000000000000000000000000000000000000005a6900000000000000000000000000000000000000000000000000000000000022f600000000000000000000000000000000000000000000000000000000662fb2ae00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000411201d630459a040af335c1369b0adf83e212c7349ca6d95ecf4509a7d01af5bb3da12754e31f3d292830ffe64ff31bbc411cc2441a0f920ea4e3df8c4f451a391c000000000000000000000000000000000000000000000000000000000000000000000000000000000000006c76a22052d5e8bbad9801bf1e413477843af6980000000000000000000000000000000000000000000000000000000000005a6900000000000000000000000000000000000000000000000000000000000022f600000000000000000000000000000000000000000000000000000000662fb2ae00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000041feb31458dd6e12dcd06eb9d3fbe89431d90813d3a21b0d4e5440876c4c64be2975347e02bf8aab673f358dc2efdfb83b2608e79754d39fa94e0e9a16c7335a841c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000073bf91bb1327415ec7b9d436bfced67c3ee843fa0000000000000000000000000000000000000000000000000000000000005a69000000000000000000000000000000000000000000000000000000000000228e00000000000000000000000000000000000000000000000000000000662fb2af00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000004144bd6053075f141675a5df0acc770222b4594a5ce5a25c70a71dea6971d7d3943b05c28b76b4e2a6821ec6307f51475abc01ae6c1e09edc9c61dbead126e73851c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000c421e1216f99c838b0a426b1cd10c8e40030ca5c0000000000000000000000000000000000000000000000000000000000005a69000000000000000000000000000000000000000000000000000000000000228e00000000000000000000000000000000000000000000000000000000662fb2ad00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000418b914f11ef385510a91e782bd2c4c66c67c7cc62daa2026fa4180bd2d1b2881414f8b8730f328270da2ed693635047038aaeb047c604a9771ad585510a75200e1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000e3b520f525b57be060f2c7b9ca0ea98a2dc4500b0000000000000000000000000000000000000000000000000000000000005a69000000000000000000000000000000000000000000000000000000000000228e00000000000000000000000000000000000000000000000000000000662fb2ae00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000041447e594666552d2b7391422968ec6ec82a4872ebc39d76281e55f69812e97bd77ccf9335290290b71c41c1d51f56e920a843b8104ca12610f1b4c7ceb47070dd1b00000000000000000000000000000000000000000000000000000000000000c080a05323078469da4067ccb495c7df930a0a5d3b31e9424ffa8ff36c2110d7f4ae4ba008f6ab4ef18c04318c683eff83714f42b9b1eb7be2633e969acc8b2487c63ef8", + "0x02f9021a8242680d8459682f0084b63b3cf683024e0d94a098b76a3dd499d3f6d58d8accafc8efbfd06807871cd82ffeee7000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c3511000000000000000000000000a4e570f158becac5777610f34c95aa651ceaa97a0000000000000000000000000000000000000000000000000000000000004268000000000000000000000000a4e570f158becac5777610f34c95aa651ceaa97a0000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000a4e570f158becac5777610f34c95aa651ceaa97a000000000000000000000000a4e570f158becac5777610f34c95aa651ceaa97a0000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c001a0f15a005da16c39c9625c3825fc9446fba3237dd4adbed494c406f91aaa96654ca07599b8af7c23793a38a32e3be72ee9c9b7def697c3d8558ef9d399bb4fecc0b7", + "0x02f9021a824268098459682f0084b045fe3e83024d9f94a098b76a3dd499d3f6d58d8accafc8efbfd0680787038d7ea4c68000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c35110000000000000000000000003024d42dcb84f0c3f629fb7e0ee97c979a75d1ee00000000000000000000000000000000000000000000000000000000000042680000000000000000000000003024d42dcb84f0c3f629fb7e0ee97c979a75d1ee0000000000000000000000000000000000000000000000000000000000028c610000000000000000000000003024d42dcb84f0c3f629fb7e0ee97c979a75d1ee0000000000000000000000003024d42dcb84f0c3f629fb7e0ee97c979a75d1ee00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c001a07055965bd84029fc6d512eb9c00180418205d28d1ec4f8a488a284a79ad7a84ea0156e95be7882a81b4c592886a7d8276cf1ebf32469ad68f6590701d47366111d", + "0x02f9021a824268098459682f0084b045fe3e83024d9f94a098b76a3dd499d3f6d58d8accafc8efbfd0680787038d7ea4c68000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c35110000000000000000000000002173e7b80283dbb48083aa3de9c5d5f6eaee732100000000000000000000000000000000000000000000000000000000000042680000000000000000000000002173e7b80283dbb48083aa3de9c5d5f6eaee73210000000000000000000000000000000000000000000000000000000000028c610000000000000000000000002173e7b80283dbb48083aa3de9c5d5f6eaee73210000000000000000000000002173e7b80283dbb48083aa3de9c5d5f6eaee732100000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a0a423b3b0bd4d522e1359b9d7cc6a93853b8795a88458199fba3f198ba0407c74a0529658c8d5034910147145b1f6715886b9b11fd5ff2e1fc12b6767f4d7a82cf6", + "0x02f9021a8242680f8459682f0084b045fe3e8301895e94a098b76a3dd499d3f6d58d8accafc8efbfd06807870ea2356bd47000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c3511000000000000000000000000ff26343c7a8fff2e8b1174ea2d14c1aceb84c0bd0000000000000000000000000000000000000000000000000000000000004268000000000000000000000000ff26343c7a8fff2e8b1174ea2d14c1aceb84c0bd0000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000ff26343c7a8fff2e8b1174ea2d14c1aceb84c0bd000000000000000000000000ff26343c7a8fff2e8b1174ea2d14c1aceb84c0bd00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c001a0c82c74baf49a31b07ae9b2ab00dd595c675ec5235b1e21935c2e6d7cccbef175a0114e062a0c50daa508307b58093349b558764523c38886e607ca6adcfae6d8fe", + "0x02f8b1824268088459682f0084b045fe3e82b63a94a960d72f83a8a163412520a778b437ac5211a50180b844095ea7b30000000000000000000000002259662ed5de0e09943abe701bc5f5a108eabbaa000000000000000000000000000000000000000000000002b5e3af16b1880000c080a0589d1426259a6a6d40119af243729220948135d51fef63b2feb32d8968c11978a034cf026d68e4fd9859a1c7e8e9fb7b299ba1979218c8d9958d109cc893d5f3ac", + "0x02f90219824268378459682f0084b045fe3e8301890994a098b76a3dd499d3f6d58d8accafc8efbfd068078609184e72a000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c3511000000000000000000000000ee9ac8910eb5624f3f90b0bb91cd34a9011fc5e80000000000000000000000000000000000000000000000000000000000004268000000000000000000000000ee9ac8910eb5624f3f90b0bb91cd34a9011fc5e80000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000ee9ac8910eb5624f3f90b0bb91cd34a9011fc5e8000000000000000000000000ee9ac8910eb5624f3f90b0bb91cd34a9011fc5e8000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c001a080c709c878b3c220447befa13a4ef4edbb6156786ddbb122fdbc52602e0cbdc6a030384965a2557ae3073bb87fa94c371e5d3940549b6aaccc6c3662eb506304d2", + "0x02f8b18242680d8459682f0084b045fe3e82b63a94a960d72f83a8a163412520a778b437ac5211a50180b844095ea7b30000000000000000000000002259662ed5de0e09943abe701bc5f5a108eabbaa000000000000000000000000000000000000000000000002b5e3af16b1880000c080a076b758a54da945c8d3a2ed426f26c7a12c54a124643582c6318ebd3771ef4bdba01ea3b7dfa007f8854f77251298fe45ef5356ed5ad0a009fd60dffaa1b090979d", + "0x02f9021a824268098459682f0084aed5c3e583024d9f94a098b76a3dd499d3f6d58d8accafc8efbfd0680787038d7ea4c68000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c3511000000000000000000000000fd3b80317d01228b9c78f6ca66b01fc92b59867f0000000000000000000000000000000000000000000000000000000000004268000000000000000000000000fd3b80317d01228b9c78f6ca66b01fc92b59867f0000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000fd3b80317d01228b9c78f6ca66b01fc92b59867f000000000000000000000000fd3b80317d01228b9c78f6ca66b01fc92b59867f00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c001a04cb740c04cdd9053e704df793fdd0f9584dba889c24ef1f0d572b584e8df4c34a07e9f8758e807a06efba3eb2a8948557d9952a206d40ef8660eacb3f71c32fdaa", + "0x02f891824268178459682f0084aed5c3e5830123a994a960d72f83a8a163412520a778b437ac5211a50180a46a627842000000000000000000000000d4ade2be31b5e21658dea582b38a3da5a3a1b12ac001a02b2788bc266045a3587963872b0c5864637eca857eeda0cced9ea691f13dfc25a06e56b8a2165d7e21d07ebbf674400afc280c41e131e81ea7f005a1b75e43d5e0", + "0x02f9021a824268158459682f0084aed5c3e583024dfb94a098b76a3dd499d3f6d58d8accafc8efbfd0680787194ab15a27f000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c351100000000000000000000000078954edc32c8978da2719ccac0033d1d2e0ec9a7000000000000000000000000000000000000000000000000000000000000426800000000000000000000000078954edc32c8978da2719ccac0033d1d2e0ec9a70000000000000000000000000000000000000000000000000000000000028c6100000000000000000000000078954edc32c8978da2719ccac0033d1d2e0ec9a700000000000000000000000078954edc32c8978da2719ccac0033d1d2e0ec9a7000000000000000000000000000000000000000000000000000e35fa931a000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c001a0866d85de4afbd23d5d927a2978804d4be9ca466fe4f3e71e817f6be6f74d20c4a07911cd07887f561c607361c0b09788f5fc62494176cff43143e8bd69f5e00a0a", + "0x02f90159824268088459682f0084aed5c3e58302f064942259662ed5de0e09943abe701bc5f5a108eabbaa870e7dd43209f000b8e4b84d9ffe0000000000000000000000000000000000000000000000000000000000028c610000000000000000000000008e560aeda745a2fd41bf951a3e614d5678453db70000000000000000000000008e560aeda745a2fd41bf951a3e614d5678453db7000000000000000000000000000000000000000000000000000e7dd43209f000000000000000000000000000a960d72f83a8a163412520a778b437ac5211a50100000000000000000000000000000000000000000000000000000000000f4270000000000000000000000000000000000000000000000002b5e3af16b1880000c001a0721a0a82cabf8e7a366920987f881a72d6ff0e2522c4e29cd61e6855d7c49cf1a033763b2c16e5ad53eab02f6a78081f888adfe54543c14f8a9e7da74fcda8667f", + "0x02f8b28242680184520799b584a40f336a8301115d94a960d72f83a8a163412520a778b437ac5211a50180b844095ea7b30000000000000000000000002259662ed5de0e09943abe701bc5f5a108eabbaa000000000000000000000000000000000000000000000002b5e3af16b1880000c001a048013487680d196d8ccc9ce43257331e594eddff412e52e9f8280c3b933652efa04e05d14fe8eff6a9d7dc5f8097d8bb14bebc067bfeb972e59ebf87dbeb79e78d", + "0x02f8b282426824848158fc2c848158fc2c83023e0f94329d0c4a58b3cefdb40c5513e155228f6cc7b6c580b84447e7ef240000000000000000000000001317106dd45ff0eb911e9f0af78d63fbf9076f6900000000000000000000000000000000000000000000010f0cf064dd59200000c080a090ad3351514b2e9a89e92c6f4ecad6e3df29eed83566144a9163b4efb2a338bca059a34e3c9fd14ce37062211d714f171a05720752bf216bbf2343495660e958f0", + "0x02f8948242688206c4843b9aca00856dc304d006830493e094deb630199fb3f645d3655f3152d48e76b012573380a4ef61c0d900000000000000000000000000000000000000000000000000000000000cd69fc080a0dc39d0d7e482e5d4fbc82d9203d153046945f75d3d0123a1a546e238012954dda04ed252103eed0c35e4b7f742407cc56c92a368409aca0564864165f374e9cbca", + "0x02f8f482426882fe0f843b9aca0084d64fe1468301737294715ea64da13f4d0831ece4ad3e8c1aa013167f3280b8849aaab648268d7383b988d015f7dfd7880aba4b2e3b0a97f13af874462269918d722ab48c00000000000000000000000000000000000000000000000000000000006de31890a75a39318db84fffa3357d14dda3bb3aa2b83b1d3633ac348b7309df9ec0e20000000000000000000000000000000000000000000000000000000000160686c080a0aaef5ff446bbb60a628728c95872841edd068e721e436d8730ebf5869bb18135a068c04be49d601a0ab1daed5a931e368d4aaba0b76afd7bc0def0efd16088cdae", + "0x02f902e78242688305b684843b9aca0084d64fe1468278fc94ff0000000000000000000000000000000004206980b90276001c2be6de824dd39d90c462bcbca9df3a00000000025e78dadae1cff0c367c1c6cf9a0bff763e77684a0aff28bda6505a9ff3f24543e56d6f764aa83f90597054b4598cad6ec136d18eef9e1e09a2c6877e2ab1c62758f86cfbf0dbb77f57bb6c54e1f5a37702cc5bd2f437e51c8018f82a24cff5d6c45c2ec5e07cde598b3e5f5ad0a05ea535cd55aee8e7cd949581138e126d601ed4c08a9e42e733b3fcac1798cc6434bdd7b74174c50e8b95e2699221255e8bd2fa8bb28936b0006a20ff3f43c3eb36c2bda7161895f7edd49afff8efd7d6b68dd71b5f7f94e9b929e9fe8e68038ba0061af15c8c5aac37fbdc91e62b737d5fe62b71333666f6751d6d5fd961ddd8af2f799d68034ba006ba26e44db932bd56e0ed4ff5101de388adad1fdcbb64eb1b56ad6eb5639850f622aa598cad7e815fa667969fc653b3276c6dc527fc7266ddd9c8eb23bfe9694bd4bb35afd59d17ac051958063570e5ab923db9ba274c58991a4a4d15f98e39252557b5312d603d59b3a23dcc49d19068032ba00632cc36baa8ada4e0c5f570fb3fb7bb47b9229fbef50fe2953ff4a579e9f5194bad1e116d6015cc8505f1cb19bc0d66ea796d08c879e8a2f969e2e99a07d68e7542b9fa965378bf06126d600dd4402bc58332cb77afb250fef4b1e3c367719d0455e7db89de47de4cf5f0d369eeda204bb481755003eb5927053e4e657e375bb599d16dd3cbdfec5f763149795cedd5e0e62d7d6cc4d542b4810d500315ffec6ae2adfaa1b9e2d492c0bcb52bffc44c325c645fff77e643df55139e59f21d6b16636b58b061d30536bebfa57bff0b9e3d79c626bc34cfa8e3f295d0926df3e50d543e5f7dfb1e6460d30140000000ffff512eceed01c001a0e7ba95ff7fbe5d983c7338c43229b915e7f45e53b2a4c64d8521e7139abe1f32a015703e2f377dc6984258690b29197541216f3f0012fb3caccc7dcea692f9aa4e", + "0x02f90426824268830129b7843b9aca0084d64fe146828cf894ff0000000000000000000000000000000004206980b903b500ad94a7fb69ec4dbcaff0e5d4f51a198300000000039d78dadae1cff0c367c1a9894e42b39c2c5f4dde7f5a217d43c4faed5adbeeadccd81fdb7669dd41a5a3abfd9bc5d8a416fc3bf49ce368d7add849ae6c1ea1ab440dce09d72e73ae53b27f26c5563a797a606b4b9afe9a43072006ba5c2e9af0d670dbfc4915c9336ea76ce28e33b8a1b76cd5f4bb22995522b3d58fad24dac02350038b277ce708a97d3f6bebcbb9a1f727857a8739cfd53c5e2c98f2a6fe9bb4a0bf5601d1061e831ad8fa72ee7d669bef2a0f662e9bd127f338e269e366560f2177c52d7182a13e2b9ffe20dac0135003c5ffceddfbf50dc34e912b57024c66a4459d2fde52c62af16755dae6e0beaf3bf3638936f014d4c0f9d58edb56bb4fbcf9ac61ed3151dfd73572364d0f56bfbbf1f04fa2d4dae4eeb24fcd626cd20b56bef290fa56d2a1b3e1f629b610f678b11be27e1b55be19ac58c03991effaa3fd0a2003cf400ddca5bf42c0a8e3cd864775ad57a58b9feddf7df1f2d937f5277f6a4c3be7f8e34c6534d1069e831a78a9ebc136e92b53b8232b23bb539657bd13508a3195b93dd1705662c1ec255fec548936f002d440f52ea55b45c766395d138d517cdbe37fedc295acd8fb09c9775f9c10e91171fa339b68032fc1c2f0bfd4a71f0d42c7c5ab44eabfd618c61417babf0c8b559a7c60ebff057ba4e4fa8936f00ad4409b67a513f3d96b16adbfc1b1d4617be50593091c45370fa42f093b34f1d887ddf2b78836f01ad4c028ef655ffd2ee8db94eeb29cb3648aa18c7fd8d2a41cb67516330e5a4416bafc6b6a1663935930918ffda9dba230c359dd3bb7aba69e3fedb237e6489116abd5a54e73bf859f3d8e810cbc0135d0d6efd462bb99fe1b2ec6fd7c3d45f9ffe1ff692d8f4ca777f8da59f99d579972b09268036fc1f2f283fd1e5333cf7d8879227548d94ff7f9aa8d0fa72f9f92af759031fcb8ec472525a20dbc0335d05af739d3bf05b767a7a4fc74105a91a92895fe33ab5e8f5d8841ed1587dd9ed9d6441b780f6a608f0647e9adefe7ed624be4188d77abcd7a795faf3ecaeb869cefcbde2b7c3c1dcb8936f001d440d1b5e15b0305ae777dcd2db33eaff26f5bd505c5ac7b592d1a13d95aef27646c3022dac047500357cefdccfed1b6cf76475af6771df91d3e67af3cd8fd25d2d88447f1985a8ac5f5a4663136d905c12fedc31e8a768a3a9ed9c2c0245a73bd9327cf4c6f0563c105d50fd75ff8d43d0719f8046a60cd8d4d1bf7ddd8bc2bf9d6128fc9b9ef0dae2d08610efad165b28643da49d262d96aa20d7c7600100000ffffd59ce00401c080a0c0fb7cabc3883467759d52ade03f1d55cc28856141a901e785bcba3efbcf589ca06706f2d1f3cf999162f1dd52a83e117cfd912bfa6c8e962ce15a53403b53c8f3", + "0x02f90424824268830d3979843b9aca0084d64fe146828cc094ff0000000000000000000000000000000004206980b903b300399a82e2c7d19df3577732b668802d7b00000000039b78dadae1cff0c367418c1e7fe19ab97b4f6ddf902db820395583f3a678d5ddd0c59b9fab6e7772f82e65d42cc6d6b8c07e2d97e0be9baf622ebcf9ac7689efb5cdd500eebf4e33553b8f0af2a6372a0ba5b7a4e96fea380031f0b1a8e5c7f753d26ff2beb1b1a8b87bc2eca5186b4cea45bb96f4021e96d8977bfd9bc5d89a16545ab1bd0d5028e3698bc992bffefb78dbbe0f5bbd8ee47594ae102fed98b3a0590b646017d4406f4ef6def4af7f3fa998ed7db26941a1887679285b7ad7cd4efb3fba59c677849f116d600fd440ded4e96e5aa6f58b45de6f973ab2c77b9291f0ade7f15fe5c2ae975d4cba1774bd936803fba006363df89330aba8e056b4e7713bc590dd8c2dcb048516995cbabb5cd8d1c72a5d6f01d1064e801ab8e1e045a50d4f97ae4dbd5425fe286edafdab7f6f08f3891d38d9e6aec43b658ec625a20d9c043550ac9f9fe942392fa3766dccebc0f62b13d7553f94f4310d97dcb9b7cddbd0e3781cd1064e811ab8634b4485ac7e8a41d414fbde8522e57f598d3e9d38f143a8e8edbe23f7eb0aaeb8136de034a881770a9ed96e367cb5eef2a475dc2b32eba76cf6eadf5f717d5e4d7dfd5236a55bae5789367006d4c02ef36385ad9f05575ebf17a2b95026bdd8bc6e85e175b65dabd3960a5f2bfeebf195680367410dfc6fdd9275f88ef2f1c4c5dfb74ab27c695611ae32b3fbf4fcd13673196f1f294345a20d9c033570ab574524739303cbdbd827d1bbafac92718a6f5e70e65c3b235fcb810ef337e9cb8936701ed4c08b6d99e536173afbb73c7ac2d976785dea891c6be98d47e4f28f6b45bc33ff31438c680317400d74500d64faa23ee3ff5f8bdbe2b55b1233dd0f85f62edb7eb7c6525a94ff55c9fa06a20d5c043570c19919e7bdf7059e583acb3ef03e0febf575fa278e4456b8ef59535aef3dc5e8c303a20d5c0235b05d4939e97fc279d97d298fff94372f370adffe8ce561a36bf59da5319702dd786588367019d4c0cfa19f4f785d8fbceef0594585a33264fb3d719e57deb79bd73c120dd4fd6ad8da47b4812b6079d96179d6eb753f9cd787cedc23fcdac63e45e4a7103bdf0987fb2b67b4d4dfb2ca24dac05550033be646bd4aaa56289b55a51f1a77462668496140d0ff74ffb27ad32fea1afeb192441bb8066a609a76a9edf1da94e9190fb76e5f272c92b64cdd9b33618a5affe60b455cebe66a1e22dac0755003afda9fea4c560edfd9a4f33ce95bf00eedaea9f5324de7b22499b35af54fc66cb123dac00d0700010000ffff7b98335a01c001a023dcbb266aaf524ad490cb8f16c02c9fb76783c0d34f1a2b884b40c0a08a5247a00ccbab382a7cdd9538b65c2695b66cb5c3d7eb9d2aa166f9b0787c00137578b4", + "0x02f904dd82426882108a843b9aca0084c9fc177e8297b894ff0000000000000000000000000000000004206980b9046d0079a41072fe53a7d51a92878759255f3100000000045578da8cccfb53d2070000702f0da614093bd0ba6a15612aaeda49163eb2c7cc955e0fa9642bc116129595426e96a810296af3c5c4473e269d4ec231a9a999d9a998d34091c813255f2082a9634cc5f0d9aedb77bf7fff814fc3293b5b6839b53753f6248e271fd0050dde14ee631c3599a36f1cd0fac51aa7343bf3044a2e1a422fc7590e7ee67111226bf23538acf5b2fe5653c81828e07ff978677d9f3a599167b94fdb2395b7fc075ecea45822d0dce80cb8e3dd2ab8ae1e1379bdb1ad66375be11b7f883cc429040d76016027d13b8d4eb354fd13c346166b862d2b0dfa848f98f5aa869ef4d94db0fd6da0412500421d0ea7bf59b41a95bd2c7f06e5c4179348494a10e51dee95b6e1c1b7c812246850f53f2827e577db0d21f984314718a95eea3617ff62ef79926b8bbac0a68de8618006d500b86688b62dadf14986c38bbbd34d7b0d2ec32f19b6806a0773f4f996aa09660e9c8b865c2daf18ac90a6e9473161729904e2eed97165bffdb90ac98e2418e1516d9e72a1f513d80b806af5c9ae75f722837dfaff3a57c3b58f09631585a472ce548bfcb61ce17f8e158206fb0030a7240bb372074adc5ded6c9fe776cd3783720cfda3801cc22c3d13a4bdb9f63bd0603f00eabebf719db05db22ad646beaf113b4972beb9f007ff9ad1f9f443ec2d633bb10534a805404591104ef4f147b51a329371215eaeb59947e68bd31fbd22b53b9ed64d0e1f060d0e0260c06b8fb7c754c442070d6e63e9c52dabaed4e775322b4f8ef2990a878b4c4ba0c161006c4a3c48aaa51a3a4af1ba4288dff93549d00782bd9cd02bb465daeae881e59fb868c8b5f2ec9ac7e76e4aa9ea5c93459f3d9682c0238b47c81f75f5ec1d7697fc7719a89fc0510054b9bb72835517383a9ab12c3ea80d314ac0b1b92e0fa1abbfd337894f85ff021ad403e0a170d453ef9ca03b7b1a8e2cdf2eaf1ae9763707331456743882f703ea993510346800c0af4315592aa63a7896ca63caf1b9e370a800aa9ab2b176b152294e750c7fd0a011005b3d992f27fa5bc7b6e6373b5e3285b13f0c3465303d27f9ad3ba39ed235b251d0e00400ee135db95ea2cfd4c6ae532c948e2fe5cea89dde779bbd2875bf2a0f7116c41ad0e02400b6076e712e33aed7604b65ac5d910497c6d3fba28af54c1aaa92e31342b4714083d30078c0d239d2b7f1b5fd0c79fb3022b1bbe35efd71517e717e73dca69fbb22604217d0a019009f8d85cf529784bd852b0c4f6f6ed67888e06f12de14dac39883492558ac0d346801c07751549b2002e781d7b02f675773038b0889a80d27f4ebf628ad6b534d0928d0e00c00dec627463e9fd83c7deb8c71eb595f1cfdb8288c1e2746bccded9cd8fce71b111c343807804518afec5b31d9cd373ce863663d7fb132619c72145a5946150ab68dcf3b9f040dce03605952b493b7d499e049e6f1585775cdee296ea1e9b0c0829e7c7454b238c00d346803c0ae0f23e4326c5bece29afb181b8f3da258efea224408cd7667a95f05f869378006175bfe0d0000ffffb9bd003901c001a04a35bf5d6b0d65646701429df4514b24f0433d17a38c8c9b475d76ed31b87ce7a0591e30e32a8b4b6e68598ac2add735db584ad68e450c0f4f9c1ba4ff2b412640", + "0x02f9041582426882fc47843b9aca0084c9fc177e832dc6c09479c9109b764609df928d16fc4a91e9081f7e87db80b903a410d008bd000000000000000000000000000000000000000000000000000000000000f72d00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000340b0b2d0060efd75bdff11cdc9cc3c57756e3288d3d45574b69f1f3024f3d5edefc1c13fb884a4d7bbc86253e6eaebd517ea93db48617b61e219a46f1ba8a13a3001e52ec79a090bff8bda257389fb2b165188fdfab2d60ef7b1a7305529998a8f302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd0000000000000000000000001670090000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000000f72d000000000000000000000000000000000000000000000000000000000e4e1c0000000000000000000000000000000000000000000000000000000000662fb248000000000000000000000000000000000000000000000000000000000016068000000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000001a8beefabd75207f434b15e2a77838f9e7f1c033ef22e5d7965ec436680b9cc82000000000000000000000000ed1ba0ba5661d648c7b3988dac473f60403aff1e25df3082a2cee717321f9e43a8fb16af103891a5299405865e2de1baf9d7d9728abde4090e2ab2ab80ff06444d0432127eb1683d3e3686852991282b2fddca47fcd43ab90d0baf56b4ea7d3880aacab94cb9f7599a7b91517868ce1fadf8646f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c080a01a2cb3e58fe603a7b1a5b6bfeca7a7350158dee7ceafc7ec444f8c0da2cb6cc8a03df4dce20317f0242541ee75750cab1fc6e67cebb528cf05f6f7d8e20eb80ead", + "0x02f8b2824268058474e46e3b847b0b668f8301154594a960d72f83a8a163412520a778b437ac5211a50180b844095ea7b30000000000000000000000002259662ed5de0e09943abe701bc5f5a108eabbaa000000000000000000000000000000000000000000000002b5e3af16b1880000c080a0b2272150118dd62a60862f0abf24459e33d2378522772e52a3367c57efcda067a033890295d3729a0c803f688e5d65d39be33d36de54bece3c1572cb80dfd713ec", + "0xf88a01846aa37b04830123a994a960d72f83a8a163412520a778b437ac5211a50180a46a6278420000000000000000000000009db36a60a58e6e6839efc947094aea13bbc8bb178284f3a0aa3a4bd875310606755f978932def7fc18ee0982b7d0f490355b75cabc30bf74a005d94e5529d3a1922395681edc8851e1fb5a6cd880f8a24130407e5ae5b67bed", + "0xf8ab3284641d7bda83035d5994329d0c4a58b3cefdb40c5513e155228f6cc7b6c580b84447e7ef240000000000000000000000001317106dd45ff0eb911e9f0af78d63fbf9076f69000000000000000000000000000000000000000000000006046f37e5945c00008284f3a0fee6045dd884c009b9f20e7ba1625621a95c79059d04e72b5baefb6900623737a059ee0783ad0e2784fb9f9df47ad4e4bfdf0b85e4823be8a1ad3e3a5027415f1f", + "0xf8ab338465f9db888303567894329d0c4a58b3cefdb40c5513e155228f6cc7b6c580b84447e7ef240000000000000000000000001317106dd45ff0eb911e9f0af78d63fbf9076f69000000000000000000000000000000000000000000000000a688906bd8b000008284f3a0b6f34b3422b4c7549b3e4b218ee8d9ff2279a53c0945a7465e3aa522315bd602a0786f01e9329980c41a3aa304eae71a751f02418cb73305805e4eb01d9e634e82", + "0xf8ab34846a12ba938303567894329d0c4a58b3cefdb40c5513e155228f6cc7b6c580b84447e7ef240000000000000000000000001317106dd45ff0eb911e9f0af78d63fbf9076f69000000000000000000000000000000000000000000000000b469471f801400008284f4a00803a0f33d2f8447b1f2f239fc4da254f94f5d15017946a6139ffdbf9954564ba04339f02ff6e667efd7c3321ae69bb8c00837a6da085167d89b9c40054a317a1d", + "0xf8ab0284626f854083010f20940469760d321d08ab4fce75e2e799902c9f55da5980b844095ea7b3000000000000000000000000095ddce4fd8818ad159d778e6a9898a2474933ca000000000000000000000000000000000000000000000002b5e3af16b18800008284f3a034b312abd3f09cfa8046e760371e7048933106e00e0023722eae86dfad96816aa074dcdd997ee285b1ae5805a70fb7d9fa552dea399abfacf14569a269c012e9d4", + "0xf8aa148460cb874b82c90b944ed034262f1eced0c1bee237bc336a1999f7278380b844095ea7b3000000000000000000000000095ddce4fd8818ad159d778e6a9898a2474933ca0000000000000000000000000000000000000000000000536009a353a6c800008284f4a0a4652db32dcefe2e75434d4b9851312302275376a8f59610a9781ca2b3bc24f2a03e4870172a703c44dbed694d233dfe326085fe7ab25dcbf24084c65f946dc292", + "0x02f8b182426819845ae0b5c4845ae0b5c482b647941317106dd45ff0eb911e9f0af78d63fbf9076f6980b844095ea7b3000000000000000000000000329d0c4a58b3cefdb40c5513e155228f6cc7b6c500000000000000000000000000000000000000000000043b518c57d1d5a20000c001a09efcb74c520e960d3f7ccf5c58418a09eb301fe571b0d8972f5020f7e57d8844a01e8449e70f996d4ea2a5909fcf8b56568c3021bdc253795c6e686f36fb33dad3", + "0x02f87182426821845a99dc10845a99dc108301abe294bd95c31c3035d93c53106cd00a727f7c4664f2c88084359cf2b7c080a0f74c66022d7bc1983f119e87940595e08ab61633aa81e6f57ce3a3c0131234cfa042c76aa38aba9c4443f2ad9ffe24ba0fc3fc2e9ed498ea2d493a2b6a1ef900ec", + "0xf88a02845864f0d0830123a994a960d72f83a8a163412520a778b437ac5211a50180a46a627842000000000000000000000000814f2712b80e9c9072ba21a26952754704db23338284f4a0691eb8bd01cc541cd838043c5e03a7a877b8bc8dc795bbd70e591fd6afcc7d53a05e38d0e100294620dd7d0e19e9ff4e1fe7fe264cc9a4b6b79a83c20ac6f7e770", + "0xf9015203845864f0d08302edc9942259662ed5de0e09943abe701bc5f5a108eabbaa870e7dd43209f000b8e4b84d9ffe0000000000000000000000000000000000000000000000000000000000028c610000000000000000000000006f2a59cdf74fa6a28587f768f7bf52f3ab8f8c080000000000000000000000006f2a59cdf74fa6a28587f768f7bf52f3ab8f8c08000000000000000000000000000000000000000000000000000e7dd43209f000000000000000000000000000a960d72f83a8a163412520a778b437ac5211a50100000000000000000000000000000000000000000000000000000000000f4270000000000000000000000000000000000000000000000001a055690d9db800008284f3a06b53b469e83f2d70c65fa103ede2dd572a28730601930cba093f8998007fb694a009bb7d3e32510eb2ab1e19fbb69b0dc6493be4b09faf8edadde911e0fee21b7d", + "0x02f8718242688084562aff8284562aff828301abe294bd95c31c3035d93c53106cd00a727f7c4664f2c88084359cf2b7c080a073dcc15fb409d7a326c8e54cb58c292039b0b5f94333aa30c3dcff8647e634e4a00e0bca57b3854ed3a7b4d4dae088124cc0ab9a11dc30cee8bc52d191314a3950", + "0x02f8718242680184562aff8284562aff828301a7ec941828eaa3cde0b2373bc869a19cf5b4804c21752c8084359cf2b7c080a04208a448faf0d6539612e148ab8be57d1ecbdc9f40dfd8e165814adab4cffb7ba02e8863ac913eae309ea008d346e608ea76ca74dc577547a01cd5f5e3ae011098", + "0x02f8718242680f8454fae19c8454fae19c8301a7ec94bd95c31c3035d93c53106cd00a727f7c4664f2c88084359cf2b7c080a02724118f0de56e49aec2f272152cdcd29bd7c7b2b8605bf29f8290c166c92983a02e0f3f5aade9746370e13b9e39690405ad734ffc023e0e91bc01d4aaf285f237", + "0xf8898084536de736830123a994a960d72f83a8a163412520a778b437ac5211a50180a46a62784200000000000000000000000057d474eaf7bf16add7582be4d7181302d43e5f948284f3a07dd0caa37f0758844f575549904c1b083841381c4bc38f786d8f80d22ea0cb4d9f99fbf9d7c9c309655cd130d3132d605cc7c8989aa87846f3b87c5ddf86acac", + "0xf88a8084536de736830123a994a960d72f83a8a163412520a778b437ac5211a50180a46a6278420000000000000000000000006c2ae75a5eb53fdf9649930b92168e3ad92eca868284f4a0316fd17cb21394a50c5311b8e32f73f5c748ff0852a5bd565f24e96bda3c3e68a07b24e4f263cbf2c6db2fc439f426f162a8e714e773fa65eeaa2d8ade66857999", + "0x02f8708242680484536de73684536de73682df8894bd95c31c3035d93c53106cd00a727f7c4664f2c88084359cf2b7c080a0d1059f82ef1f955f1d46fdbd421954597b6ba91dd6c8360dc013c7a348f9f74ea04bdc45ef11fba8897ffa2ffd74404659a8bc5916e8a9741eb0f21dd07ebd798e", + "0x02f9021a8242680184536de73684536de7368301b0b494a098b76a3dd499d3f6d58d8accafc8efbfd068078715bd32b5617000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c3511000000000000000000000000ccd658226c53c83450d7b4bf63ef86a106f471030000000000000000000000000000000000000000000000000000000000004268000000000000000000000000ccd658226c53c83450d7b4bf63ef86a106f471030000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000ccd658226c53c83450d7b4bf63ef86a106f47103000000000000000000000000ccd658226c53c83450d7b4bf63ef86a106f47103000000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a037379f8194ae9c5db57fad0ca450fcefcdaf7b6f10250b37560c27854a79ec02a02071e79ce665d7b3d071bb960a71be9d2d853e7448ef1f02f68fb3984f92e5ec", + "0x02f8708242680584536de73684536de73682e2b2941828eaa3cde0b2373bc869a19cf5b4804c21752c8084359cf2b7c001a0c256489c47b8169680ef33acc525655358327323ef85dd4771d6f804432f94b4a026bb33122fa191bdd597d4e34063b37220b77bb1bbb3a0c19be4475ebeb803f2", + "0x02f9057582426882d8e5840dccfe78849e94028a8305449b9454a03db2784e3d0acc08344d05385d0b62d4f43280b905047794965a0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000014072100814389cd57d00258544edcfdd7ce00d6cd21ce8e41f75aa082a8a6b3f11000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000001606390000000000000000000000000000000000000000000000000000000000000002000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026464000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001c0287af7752a836402cdb6661cfdbd6d9b22a5a6acebbf0173dc75567c9cdc8bf7079bb1538afea28828e22f53b669bde0725b3fa8e1e032f766ecb08ebc6e229829fee65d5c9d883769e5958bd8c0df17f9e77a0105bf24915e6b7a591f07361415c4dd046f28cc23408c0433896e2462c067e4c7e3caf39bdbff64f940095ae12d77b7f14bbba92146dd0d40e7eff66fd7d66d914debe9141cdcada7a8c73ec32bc00c632eda86b53bf6bf308c6582d0aec5d480bcd33da2ba9123e6f89c377e000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000002c0000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000206f8a70779657a4990c2ea64d42f0626b8ac94899708d95972b0e84372e436022313c9ac6c16ba3e4ce7c9dcff7ed2fdf4035f0c196a13427cc9070585a5460400c6bf3b51088d3729658ce0afb9dd5e5617b3e63e3f257fb05060d4e790328e207cac1efdd01c0c372c7ef2e80c943b04f3e8a8bfb92a9545ca54e311ed082c00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000019000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a04677bf8528777da8648e278003232df6d9321a566388ea505b03f15d6abac2f1a0123c08b94a9060b6a1bcaeac885c50e6450d8fd087254210fe61c4fc6b3ca35a", + "0xf902130584520799b58301895e94a098b76a3dd499d3f6d58d8accafc8efbfd06807871cd82ffeee7000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c3511000000000000000000000000ed96f36f9d9a85964f3f7f4de1fecf466ac3a5150000000000000000000000000000000000000000000000000000000000004268000000000000000000000000ed96f36f9d9a85964f3f7f4de1fecf466ac3a5150000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000ed96f36f9d9a85964f3f7f4de1fecf466ac3a515000000000000000000000000ed96f36f9d9a85964f3f7f4de1fecf466ac3a5150000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000008284f4a002f3d36f1206ca3bf7945e245707ec45ef4fb8b48906cc838f26bbace7cb1ba8a0415d493973ad24cfd65858311ddccb3cda236131d7f2bae7b3faac02bd15c5de", + "0xf902130484520799b58303655d94046b82d9010b534c716742be98ac3fef3f2ec99f871dd5efbed2e000b901a41f59a83000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000028c6100000000000000000000000090ae8a949b109de32de4ace6122aacdb428bd32900000000000000000000000090ae8a949b109de32de4ace6122aacdb428bd329000000000000000000000000000000000000000000000000001dd5efbed2e000000000000000000000000000ffde3c59415e0cae633eae131d2826f1ae5c8fb600000000000000000000000000000000000000000000000000000000001cfe120000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000008284f3a06d97220825af492deaad6a37409a10dc45d714024bf5eb6b80c5aef660ce7ba2a02ca61eff2b39babad0b1fcf635df28b2f41cbae7146d9842d7020b8d94865b23", + "0xf8708205c084520799b583018da3947c4eb9ee410659dee660b56bf1194f71e17d30ad88016345785d8a0000808284f4a027fa297e64274bc445c09e4138761cab780d2c60079d385d80529536faf5077aa068cd1095e096891300b6ca0e9c9cea694cf756a316e9f1aca6b9c76e36319579", + "0xf8cb0384520799b58301850f94347acd533bf6ad850ddfa911a3378ec3e34f66a280b864d0def5210000000000000000000000007662ec0846f214c075d68a27f4c0ab150760c98a000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008284f3a01ef5ebe72f7ad419a05647a5f91f3f1f549eb953e34cb3fb96913490375e40f2a0295e3d315b39601c3384bc5f0847e4fb053ca6bc5ac21434eebb2c3680d06bc0", + "0xf8aa0484520799b582c13094cea1147eef7cfa5aee48794f9e647d51845b1ed880b844095ea7b3000000000000000000000000046b82d9010b534c716742be98ac3fef3f2ec99f00000000000000000000000000000000000000000000000000000000000000008284f3a0b9a3efcb19406671dc578dbe978c0aa20b6200455a7f396ae79c89474c9238f1a0089175feb70dcc0e62cd4607fdd5c93d25ce7c7fe8b5769c55a26fddb80d3e08", + "0xf92d040184520799b583255fb58080b92cb0608060405234801561000f575f80fd5b50604051612bf0380380612bf0833981810160405281019061003191906102ec565b338282815f9081610042919061056f565b508060019081610052919061056f565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100c5575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016100bc919061067d565b60405180910390fd5b6100d4816100dc60201b60201c565b505050610696565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6101fe826101b8565b810181811067ffffffffffffffff8211171561021d5761021c6101c8565b5b80604052505050565b5f61022f61019f565b905061023b82826101f5565b919050565b5f67ffffffffffffffff82111561025a576102596101c8565b5b610263826101b8565b9050602081019050919050565b8281835e5f83830152505050565b5f61029061028b84610240565b610226565b9050828152602081018484840111156102ac576102ab6101b4565b5b6102b7848285610270565b509392505050565b5f82601f8301126102d3576102d26101b0565b5b81516102e384826020860161027e565b91505092915050565b5f8060408385031215610302576103016101a8565b5b5f83015167ffffffffffffffff81111561031f5761031e6101ac565b5b61032b858286016102bf565b925050602083015167ffffffffffffffff81111561034c5761034b6101ac565b5b610358858286016102bf565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806103b057607f821691505b6020821081036103c3576103c261036c565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026104257fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826103ea565b61042f86836103ea565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61047361046e61046984610447565b610450565b610447565b9050919050565b5f819050919050565b61048c83610459565b6104a06104988261047a565b8484546103f6565b825550505050565b5f90565b6104b46104a8565b6104bf818484610483565b505050565b5b818110156104e2576104d75f826104ac565b6001810190506104c5565b5050565b601f821115610527576104f8816103c9565b610501846103db565b81016020851015610510578190505b61052461051c856103db565b8301826104c4565b50505b505050565b5f82821c905092915050565b5f6105475f198460080261052c565b1980831691505092915050565b5f61055f8383610538565b9150826002028217905092915050565b61057882610362565b67ffffffffffffffff811115610591576105906101c8565b5b61059b8254610399565b6105a68282856104e6565b5f60209050601f8311600181146105d7575f84156105c5578287015190505b6105cf8582610554565b865550610636565b601f1984166105e5866103c9565b5f5b8281101561060c578489015182556001820191506020850194506020810190506105e7565b868310156106295784890151610625601f891682610538565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6106678261063e565b9050919050565b6106778161065d565b82525050565b5f6020820190506106905f83018461066e565b92915050565b61254d806106a35f395ff3fe608060405234801561000f575f80fd5b5060043610610109575f3560e01c8063715018a6116100a0578063b88d4fde1161006f578063b88d4fde146102a1578063c87b56dd146102bd578063d0def521146102ed578063e985e9c51461031d578063f2fde38b1461034d57610109565b8063715018a61461023f5780638da5cb5b1461024957806395d89b4114610267578063a22cb4651461028557610109565b806323b872dd116100dc57806323b872dd146101a757806342842e0e146101c35780636352211e146101df57806370a082311461020f57610109565b806301ffc9a71461010d57806306fdde031461013d578063081812fc1461015b578063095ea7b31461018b575b5f80fd5b61012760048036038101906101229190611a20565b610369565b6040516101349190611a65565b60405180910390f35b6101456103c9565b6040516101529190611aee565b60405180910390f35b61017560048036038101906101709190611b41565b610458565b6040516101829190611bab565b60405180910390f35b6101a560048036038101906101a09190611bee565b610473565b005b6101c160048036038101906101bc9190611c2c565b610489565b005b6101dd60048036038101906101d89190611c2c565b610588565b005b6101f960048036038101906101f49190611b41565b6105a7565b6040516102069190611bab565b60405180910390f35b61022960048036038101906102249190611c7c565b6105b8565b6040516102369190611cb6565b60405180910390f35b61024761066e565b005b610251610681565b60405161025e9190611bab565b60405180910390f35b61026f6106a9565b60405161027c9190611aee565b60405180910390f35b61029f600480360381019061029a9190611cf9565b610739565b005b6102bb60048036038101906102b69190611e63565b61074f565b005b6102d760048036038101906102d29190611b41565b61076c565b6040516102e49190611aee565b60405180910390f35b61030760048036038101906103029190611f81565b610877565b6040516103149190611cb6565b60405180910390f35b61033760048036038101906103329190611fdb565b6108b7565b6040516103449190611a65565b60405180910390f35b61036760048036038101906103629190611c7c565b610945565b005b5f634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103c257506103c1826109c9565b5b9050919050565b60605f80546103d790612046565b80601f016020809104026020016040519081016040528092919081815260200182805461040390612046565b801561044e5780601f106104255761010080835404028352916020019161044e565b820191905f5260205f20905b81548152906001019060200180831161043157829003601f168201915b5050505050905090565b5f61046282610aaa565b5061046c82610b30565b9050919050565b6104858282610480610b69565b610b70565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036104f9575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016104f09190611bab565b60405180910390fd5b5f61050c8383610507610b69565b610b82565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610582578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161057993929190612076565b60405180910390fd5b50505050565b6105a283838360405180602001604052805f81525061074f565b505050565b5f6105b182610aaa565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610629575f6040517f89c62b640000000000000000000000000000000000000000000000000000000081526004016106209190611bab565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610676610d8d565b61067f5f610e14565b565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546106b890612046565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612046565b801561072f5780601f106107065761010080835404028352916020019161072f565b820191905f5260205f20905b81548152906001019060200180831161071257829003601f168201915b5050505050905090565b61074b610744610b69565b8383610ed7565b5050565b61075a848484610489565b61076684848484611040565b50505050565b606061077782610aaa565b505f60065f8481526020019081526020015f20805461079590612046565b80601f01602080910402602001604051908101604052809291908181526020018280546107c190612046565b801561080c5780601f106107e35761010080835404028352916020019161080c565b820191905f5260205f20905b8154815290600101906020018083116107ef57829003601f168201915b505050505090505f61081c6111f2565b90505f815103610830578192505050610872565b5f8251111561086457808260405160200161084c9291906120e5565b60405160208183030381529060405292505050610872565b61086d84611208565b925050505b919050565b5f610880610d8d565b5f60085f81548092919061089390612135565b9190505590506108a3848261126e565b6108ad8184611361565b8091505092915050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b61094d610d8d565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109bd575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016109b49190611bab565b60405180910390fd5b6109c681610e14565b50565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a9357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610aa35750610aa2826113bb565b5b9050919050565b5f80610ab583611424565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b2757826040517f7e273289000000000000000000000000000000000000000000000000000000008152600401610b1e9190611cb6565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b610b7d838383600161145d565b505050565b5f80610b8d84611424565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610bce57610bcd81848661161c565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c5957610c0d5f855f8061145d565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610cd857600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b610d95610b69565b73ffffffffffffffffffffffffffffffffffffffff16610db3610681565b73ffffffffffffffffffffffffffffffffffffffff1614610e1257610dd6610b69565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610e099190611bab565b60405180910390fd5b565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f4757816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401610f3e9190611bab565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516110339190611a65565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b11156111ec578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02611083610b69565b8685856040518563ffffffff1660e01b81526004016110a594939291906121ce565b6020604051808303815f875af19250505080156110e057506040513d601f19601f820116820180604052508101906110dd919061222c565b60015b611161573d805f811461110e576040519150601f19603f3d011682016040523d82523d5f602084013e611113565b606091505b505f81510361115957836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016111509190611bab565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146111ea57836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016111e19190611bab565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b606061121382610aaa565b505f61121d6111f2565b90505f81511161123b5760405180602001604052805f815250611266565b80611245846116df565b6040516020016112569291906120e5565b6040516020818303038152906040525b915050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036112de575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016112d59190611bab565b60405180910390fd5b5f6112ea83835f610b82565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461135c575f6040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081526004016113539190611bab565b60405180910390fd5b505050565b8060065f8481526020019081526020015f20908161137f91906123f4565b507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7826040516113af9190611cb6565b60405180910390a15050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b808061149557505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156115c7575f6114a484610aaa565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561150e57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611521575061151f81846108b7565b155b1561156357826040517fa9fbf51f00000000000000000000000000000000000000000000000000000000815260040161155a9190611bab565b60405180910390fd5b81156115c557838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b6116278383836117a9565b6116da575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361169b57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016116929190611cb6565b60405180910390fd5b81816040517f177e802f0000000000000000000000000000000000000000000000000000000081526004016116d19291906124c3565b60405180910390fd5b505050565b60605f60016116ed84611869565b0190505f8167ffffffffffffffff81111561170b5761170a611d3f565b5b6040519080825280601f01601f19166020018201604052801561173d5781602001600182028036833780820191505090505b5090505f82602001820190505b60011561179e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611793576117926124ea565b5b0494505f850361174a575b819350505050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561186057508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611821575061182084846108b7565b5b8061185f57508273ffffffffffffffffffffffffffffffffffffffff1661184783610b30565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106118c5577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816118bb576118ba6124ea565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611902576d04ee2d6d415b85acef810000000083816118f8576118f76124ea565b5b0492506020810190505b662386f26fc10000831061193157662386f26fc100008381611927576119266124ea565b5b0492506010810190505b6305f5e100831061195a576305f5e10083816119505761194f6124ea565b5b0492506008810190505b612710831061197f576127108381611975576119746124ea565b5b0492506004810190505b606483106119a25760648381611998576119976124ea565b5b0492506002810190505b600a83106119b1576001810190505b80915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6119ff816119cb565b8114611a09575f80fd5b50565b5f81359050611a1a816119f6565b92915050565b5f60208284031215611a3557611a346119c3565b5b5f611a4284828501611a0c565b91505092915050565b5f8115159050919050565b611a5f81611a4b565b82525050565b5f602082019050611a785f830184611a56565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f611ac082611a7e565b611aca8185611a88565b9350611ada818560208601611a98565b611ae381611aa6565b840191505092915050565b5f6020820190508181035f830152611b068184611ab6565b905092915050565b5f819050919050565b611b2081611b0e565b8114611b2a575f80fd5b50565b5f81359050611b3b81611b17565b92915050565b5f60208284031215611b5657611b556119c3565b5b5f611b6384828501611b2d565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611b9582611b6c565b9050919050565b611ba581611b8b565b82525050565b5f602082019050611bbe5f830184611b9c565b92915050565b611bcd81611b8b565b8114611bd7575f80fd5b50565b5f81359050611be881611bc4565b92915050565b5f8060408385031215611c0457611c036119c3565b5b5f611c1185828601611bda565b9250506020611c2285828601611b2d565b9150509250929050565b5f805f60608486031215611c4357611c426119c3565b5b5f611c5086828701611bda565b9350506020611c6186828701611bda565b9250506040611c7286828701611b2d565b9150509250925092565b5f60208284031215611c9157611c906119c3565b5b5f611c9e84828501611bda565b91505092915050565b611cb081611b0e565b82525050565b5f602082019050611cc95f830184611ca7565b92915050565b611cd881611a4b565b8114611ce2575f80fd5b50565b5f81359050611cf381611ccf565b92915050565b5f8060408385031215611d0f57611d0e6119c3565b5b5f611d1c85828601611bda565b9250506020611d2d85828601611ce5565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611d7582611aa6565b810181811067ffffffffffffffff82111715611d9457611d93611d3f565b5b80604052505050565b5f611da66119ba565b9050611db28282611d6c565b919050565b5f67ffffffffffffffff821115611dd157611dd0611d3f565b5b611dda82611aa6565b9050602081019050919050565b828183375f83830152505050565b5f611e07611e0284611db7565b611d9d565b905082815260208101848484011115611e2357611e22611d3b565b5b611e2e848285611de7565b509392505050565b5f82601f830112611e4a57611e49611d37565b5b8135611e5a848260208601611df5565b91505092915050565b5f805f8060808587031215611e7b57611e7a6119c3565b5b5f611e8887828801611bda565b9450506020611e9987828801611bda565b9350506040611eaa87828801611b2d565b925050606085013567ffffffffffffffff811115611ecb57611eca6119c7565b5b611ed787828801611e36565b91505092959194509250565b5f67ffffffffffffffff821115611efd57611efc611d3f565b5b611f0682611aa6565b9050602081019050919050565b5f611f25611f2084611ee3565b611d9d565b905082815260208101848484011115611f4157611f40611d3b565b5b611f4c848285611de7565b509392505050565b5f82601f830112611f6857611f67611d37565b5b8135611f78848260208601611f13565b91505092915050565b5f8060408385031215611f9757611f966119c3565b5b5f611fa485828601611bda565b925050602083013567ffffffffffffffff811115611fc557611fc46119c7565b5b611fd185828601611f54565b9150509250929050565b5f8060408385031215611ff157611ff06119c3565b5b5f611ffe85828601611bda565b925050602061200f85828601611bda565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061205d57607f821691505b6020821081036120705761206f612019565b5b50919050565b5f6060820190506120895f830186611b9c565b6120966020830185611ca7565b6120a36040830184611b9c565b949350505050565b5f81905092915050565b5f6120bf82611a7e565b6120c981856120ab565b93506120d9818560208601611a98565b80840191505092915050565b5f6120f082856120b5565b91506120fc82846120b5565b91508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61213f82611b0e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361217157612170612108565b5b600182019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f6121a08261217c565b6121aa8185612186565b93506121ba818560208601611a98565b6121c381611aa6565b840191505092915050565b5f6080820190506121e15f830187611b9c565b6121ee6020830186611b9c565b6121fb6040830185611ca7565b818103606083015261220d8184612196565b905095945050505050565b5f81519050612226816119f6565b92915050565b5f60208284031215612241576122406119c3565b5b5f61224e84828501612218565b91505092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026122b37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612278565b6122bd8683612278565b95508019841693508086168417925050509392505050565b5f819050919050565b5f6122f86122f36122ee84611b0e565b6122d5565b611b0e565b9050919050565b5f819050919050565b612311836122de565b61232561231d826122ff565b848454612284565b825550505050565b5f90565b61233961232d565b612344818484612308565b505050565b5b818110156123675761235c5f82612331565b60018101905061234a565b5050565b601f8211156123ac5761237d81612257565b61238684612269565b81016020851015612395578190505b6123a96123a185612269565b830182612349565b50505b505050565b5f82821c905092915050565b5f6123cc5f19846008026123b1565b1980831691505092915050565b5f6123e483836123bd565b9150826002028217905092915050565b6123fd82611a7e565b67ffffffffffffffff81111561241657612415611d3f565b5b6124208254612046565b61242b82828561236b565b5f60209050601f83116001811461245c575f841561244a578287015190505b61245485826123d9565b8655506124bb565b601f19841661246a86612257565b5f5b828110156124915784890151825560018201915060208501945060208101905061246c565b868310156124ae57848901516124aa601f8916826123bd565b8355505b6001600288020188555050505b505050505050565b5f6040820190506124d65f830185611b9c565b6124e36020830184611ca7565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffdfea26469706673582212202540ee918e4df6d1e3653efd3abe64ef363173095adc5bd653b560c0f749995164736f6c6343000819003300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000644616e69656c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000644414e49454c00000000000000000000000000000000000000000000000000008284f4a058495b1a30acd17e0d70f6a32eef0d4cfda13ccbf8a31d05247ee550bcd1897ba010b5768763d8044167b7b5b0f54a88c5bce46020a14c5aaa9aaca6350bccb670", + "0xf8cb0284520799b58301850f94136fdc5ae085f4c4ac2b4359208f5c4b6260319280b864d0def5210000000000000000000000005209b1a98162be6dd5e060857f6c5eee29a7c8ac000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008284f3a0504b5f3f210874b9aedc559480c1158fa5c6aecada1429754fe8b1101079b266a0064e790b6669ddf2b779a068915be4e9325ba5074804fd3f2626ba75f54318e7", + "0xf8cb0384520799b58301850f9449bd7ec59a592682964b15a386920648a3eecf5d80b864d0def521000000000000000000000000ec185370c53a193bec4235e5e00f7fcdc4ef8cf2000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008284f3a09df7014ff2d7f2ee2ea11ffa5e335b6d4e405334e16ed9f14214afad766fbf76a053b2d457b81a6cff2e1e3904dfea1a3cc0be4b0d5940cb2f07574be29b454319", + "0xf92d040184520799b583255fd08080b92cb0608060405234801561000f575f80fd5b50604051612bf0380380612bf0833981810160405281019061003191906102ec565b338282815f9081610042919061056f565b508060019081610052919061056f565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100c5575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016100bc919061067d565b60405180910390fd5b6100d4816100dc60201b60201c565b505050610696565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6101fe826101b8565b810181811067ffffffffffffffff8211171561021d5761021c6101c8565b5b80604052505050565b5f61022f61019f565b905061023b82826101f5565b919050565b5f67ffffffffffffffff82111561025a576102596101c8565b5b610263826101b8565b9050602081019050919050565b8281835e5f83830152505050565b5f61029061028b84610240565b610226565b9050828152602081018484840111156102ac576102ab6101b4565b5b6102b7848285610270565b509392505050565b5f82601f8301126102d3576102d26101b0565b5b81516102e384826020860161027e565b91505092915050565b5f8060408385031215610302576103016101a8565b5b5f83015167ffffffffffffffff81111561031f5761031e6101ac565b5b61032b858286016102bf565b925050602083015167ffffffffffffffff81111561034c5761034b6101ac565b5b610358858286016102bf565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806103b057607f821691505b6020821081036103c3576103c261036c565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026104257fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826103ea565b61042f86836103ea565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61047361046e61046984610447565b610450565b610447565b9050919050565b5f819050919050565b61048c83610459565b6104a06104988261047a565b8484546103f6565b825550505050565b5f90565b6104b46104a8565b6104bf818484610483565b505050565b5b818110156104e2576104d75f826104ac565b6001810190506104c5565b5050565b601f821115610527576104f8816103c9565b610501846103db565b81016020851015610510578190505b61052461051c856103db565b8301826104c4565b50505b505050565b5f82821c905092915050565b5f6105475f198460080261052c565b1980831691505092915050565b5f61055f8383610538565b9150826002028217905092915050565b61057882610362565b67ffffffffffffffff811115610591576105906101c8565b5b61059b8254610399565b6105a68282856104e6565b5f60209050601f8311600181146105d7575f84156105c5578287015190505b6105cf8582610554565b865550610636565b601f1984166105e5866103c9565b5f5b8281101561060c578489015182556001820191506020850194506020810190506105e7565b868310156106295784890151610625601f891682610538565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6106678261063e565b9050919050565b6106778161065d565b82525050565b5f6020820190506106905f83018461066e565b92915050565b61254d806106a35f395ff3fe608060405234801561000f575f80fd5b5060043610610109575f3560e01c8063715018a6116100a0578063b88d4fde1161006f578063b88d4fde146102a1578063c87b56dd146102bd578063d0def521146102ed578063e985e9c51461031d578063f2fde38b1461034d57610109565b8063715018a61461023f5780638da5cb5b1461024957806395d89b4114610267578063a22cb4651461028557610109565b806323b872dd116100dc57806323b872dd146101a757806342842e0e146101c35780636352211e146101df57806370a082311461020f57610109565b806301ffc9a71461010d57806306fdde031461013d578063081812fc1461015b578063095ea7b31461018b575b5f80fd5b61012760048036038101906101229190611a20565b610369565b6040516101349190611a65565b60405180910390f35b6101456103c9565b6040516101529190611aee565b60405180910390f35b61017560048036038101906101709190611b41565b610458565b6040516101829190611bab565b60405180910390f35b6101a560048036038101906101a09190611bee565b610473565b005b6101c160048036038101906101bc9190611c2c565b610489565b005b6101dd60048036038101906101d89190611c2c565b610588565b005b6101f960048036038101906101f49190611b41565b6105a7565b6040516102069190611bab565b60405180910390f35b61022960048036038101906102249190611c7c565b6105b8565b6040516102369190611cb6565b60405180910390f35b61024761066e565b005b610251610681565b60405161025e9190611bab565b60405180910390f35b61026f6106a9565b60405161027c9190611aee565b60405180910390f35b61029f600480360381019061029a9190611cf9565b610739565b005b6102bb60048036038101906102b69190611e63565b61074f565b005b6102d760048036038101906102d29190611b41565b61076c565b6040516102e49190611aee565b60405180910390f35b61030760048036038101906103029190611f81565b610877565b6040516103149190611cb6565b60405180910390f35b61033760048036038101906103329190611fdb565b6108b7565b6040516103449190611a65565b60405180910390f35b61036760048036038101906103629190611c7c565b610945565b005b5f634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103c257506103c1826109c9565b5b9050919050565b60605f80546103d790612046565b80601f016020809104026020016040519081016040528092919081815260200182805461040390612046565b801561044e5780601f106104255761010080835404028352916020019161044e565b820191905f5260205f20905b81548152906001019060200180831161043157829003601f168201915b5050505050905090565b5f61046282610aaa565b5061046c82610b30565b9050919050565b6104858282610480610b69565b610b70565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036104f9575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016104f09190611bab565b60405180910390fd5b5f61050c8383610507610b69565b610b82565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610582578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161057993929190612076565b60405180910390fd5b50505050565b6105a283838360405180602001604052805f81525061074f565b505050565b5f6105b182610aaa565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610629575f6040517f89c62b640000000000000000000000000000000000000000000000000000000081526004016106209190611bab565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610676610d8d565b61067f5f610e14565b565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546106b890612046565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612046565b801561072f5780601f106107065761010080835404028352916020019161072f565b820191905f5260205f20905b81548152906001019060200180831161071257829003601f168201915b5050505050905090565b61074b610744610b69565b8383610ed7565b5050565b61075a848484610489565b61076684848484611040565b50505050565b606061077782610aaa565b505f60065f8481526020019081526020015f20805461079590612046565b80601f01602080910402602001604051908101604052809291908181526020018280546107c190612046565b801561080c5780601f106107e35761010080835404028352916020019161080c565b820191905f5260205f20905b8154815290600101906020018083116107ef57829003601f168201915b505050505090505f61081c6111f2565b90505f815103610830578192505050610872565b5f8251111561086457808260405160200161084c9291906120e5565b60405160208183030381529060405292505050610872565b61086d84611208565b925050505b919050565b5f610880610d8d565b5f60085f81548092919061089390612135565b9190505590506108a3848261126e565b6108ad8184611361565b8091505092915050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b61094d610d8d565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109bd575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016109b49190611bab565b60405180910390fd5b6109c681610e14565b50565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a9357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610aa35750610aa2826113bb565b5b9050919050565b5f80610ab583611424565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b2757826040517f7e273289000000000000000000000000000000000000000000000000000000008152600401610b1e9190611cb6565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b610b7d838383600161145d565b505050565b5f80610b8d84611424565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610bce57610bcd81848661161c565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c5957610c0d5f855f8061145d565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610cd857600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b610d95610b69565b73ffffffffffffffffffffffffffffffffffffffff16610db3610681565b73ffffffffffffffffffffffffffffffffffffffff1614610e1257610dd6610b69565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610e099190611bab565b60405180910390fd5b565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f4757816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401610f3e9190611bab565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516110339190611a65565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b11156111ec578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02611083610b69565b8685856040518563ffffffff1660e01b81526004016110a594939291906121ce565b6020604051808303815f875af19250505080156110e057506040513d601f19601f820116820180604052508101906110dd919061222c565b60015b611161573d805f811461110e576040519150601f19603f3d011682016040523d82523d5f602084013e611113565b606091505b505f81510361115957836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016111509190611bab565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146111ea57836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016111e19190611bab565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b606061121382610aaa565b505f61121d6111f2565b90505f81511161123b5760405180602001604052805f815250611266565b80611245846116df565b6040516020016112569291906120e5565b6040516020818303038152906040525b915050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036112de575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016112d59190611bab565b60405180910390fd5b5f6112ea83835f610b82565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461135c575f6040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081526004016113539190611bab565b60405180910390fd5b505050565b8060065f8481526020019081526020015f20908161137f91906123f4565b507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7826040516113af9190611cb6565b60405180910390a15050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b808061149557505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156115c7575f6114a484610aaa565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561150e57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611521575061151f81846108b7565b155b1561156357826040517fa9fbf51f00000000000000000000000000000000000000000000000000000000815260040161155a9190611bab565b60405180910390fd5b81156115c557838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b6116278383836117a9565b6116da575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361169b57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016116929190611cb6565b60405180910390fd5b81816040517f177e802f0000000000000000000000000000000000000000000000000000000081526004016116d19291906124c3565b60405180910390fd5b505050565b60605f60016116ed84611869565b0190505f8167ffffffffffffffff81111561170b5761170a611d3f565b5b6040519080825280601f01601f19166020018201604052801561173d5781602001600182028036833780820191505090505b5090505f82602001820190505b60011561179e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611793576117926124ea565b5b0494505f850361174a575b819350505050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561186057508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611821575061182084846108b7565b5b8061185f57508273ffffffffffffffffffffffffffffffffffffffff1661184783610b30565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106118c5577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816118bb576118ba6124ea565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611902576d04ee2d6d415b85acef810000000083816118f8576118f76124ea565b5b0492506020810190505b662386f26fc10000831061193157662386f26fc100008381611927576119266124ea565b5b0492506010810190505b6305f5e100831061195a576305f5e10083816119505761194f6124ea565b5b0492506008810190505b612710831061197f576127108381611975576119746124ea565b5b0492506004810190505b606483106119a25760648381611998576119976124ea565b5b0492506002810190505b600a83106119b1576001810190505b80915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6119ff816119cb565b8114611a09575f80fd5b50565b5f81359050611a1a816119f6565b92915050565b5f60208284031215611a3557611a346119c3565b5b5f611a4284828501611a0c565b91505092915050565b5f8115159050919050565b611a5f81611a4b565b82525050565b5f602082019050611a785f830184611a56565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f611ac082611a7e565b611aca8185611a88565b9350611ada818560208601611a98565b611ae381611aa6565b840191505092915050565b5f6020820190508181035f830152611b068184611ab6565b905092915050565b5f819050919050565b611b2081611b0e565b8114611b2a575f80fd5b50565b5f81359050611b3b81611b17565b92915050565b5f60208284031215611b5657611b556119c3565b5b5f611b6384828501611b2d565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611b9582611b6c565b9050919050565b611ba581611b8b565b82525050565b5f602082019050611bbe5f830184611b9c565b92915050565b611bcd81611b8b565b8114611bd7575f80fd5b50565b5f81359050611be881611bc4565b92915050565b5f8060408385031215611c0457611c036119c3565b5b5f611c1185828601611bda565b9250506020611c2285828601611b2d565b9150509250929050565b5f805f60608486031215611c4357611c426119c3565b5b5f611c5086828701611bda565b9350506020611c6186828701611bda565b9250506040611c7286828701611b2d565b9150509250925092565b5f60208284031215611c9157611c906119c3565b5b5f611c9e84828501611bda565b91505092915050565b611cb081611b0e565b82525050565b5f602082019050611cc95f830184611ca7565b92915050565b611cd881611a4b565b8114611ce2575f80fd5b50565b5f81359050611cf381611ccf565b92915050565b5f8060408385031215611d0f57611d0e6119c3565b5b5f611d1c85828601611bda565b9250506020611d2d85828601611ce5565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611d7582611aa6565b810181811067ffffffffffffffff82111715611d9457611d93611d3f565b5b80604052505050565b5f611da66119ba565b9050611db28282611d6c565b919050565b5f67ffffffffffffffff821115611dd157611dd0611d3f565b5b611dda82611aa6565b9050602081019050919050565b828183375f83830152505050565b5f611e07611e0284611db7565b611d9d565b905082815260208101848484011115611e2357611e22611d3b565b5b611e2e848285611de7565b509392505050565b5f82601f830112611e4a57611e49611d37565b5b8135611e5a848260208601611df5565b91505092915050565b5f805f8060808587031215611e7b57611e7a6119c3565b5b5f611e8887828801611bda565b9450506020611e9987828801611bda565b9350506040611eaa87828801611b2d565b925050606085013567ffffffffffffffff811115611ecb57611eca6119c7565b5b611ed787828801611e36565b91505092959194509250565b5f67ffffffffffffffff821115611efd57611efc611d3f565b5b611f0682611aa6565b9050602081019050919050565b5f611f25611f2084611ee3565b611d9d565b905082815260208101848484011115611f4157611f40611d3b565b5b611f4c848285611de7565b509392505050565b5f82601f830112611f6857611f67611d37565b5b8135611f78848260208601611f13565b91505092915050565b5f8060408385031215611f9757611f966119c3565b5b5f611fa485828601611bda565b925050602083013567ffffffffffffffff811115611fc557611fc46119c7565b5b611fd185828601611f54565b9150509250929050565b5f8060408385031215611ff157611ff06119c3565b5b5f611ffe85828601611bda565b925050602061200f85828601611bda565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061205d57607f821691505b6020821081036120705761206f612019565b5b50919050565b5f6060820190506120895f830186611b9c565b6120966020830185611ca7565b6120a36040830184611b9c565b949350505050565b5f81905092915050565b5f6120bf82611a7e565b6120c981856120ab565b93506120d9818560208601611a98565b80840191505092915050565b5f6120f082856120b5565b91506120fc82846120b5565b91508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61213f82611b0e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361217157612170612108565b5b600182019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f6121a08261217c565b6121aa8185612186565b93506121ba818560208601611a98565b6121c381611aa6565b840191505092915050565b5f6080820190506121e15f830187611b9c565b6121ee6020830186611b9c565b6121fb6040830185611ca7565b818103606083015261220d8184612196565b905095945050505050565b5f81519050612226816119f6565b92915050565b5f60208284031215612241576122406119c3565b5b5f61224e84828501612218565b91505092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026122b37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612278565b6122bd8683612278565b95508019841693508086168417925050509392505050565b5f819050919050565b5f6122f86122f36122ee84611b0e565b6122d5565b611b0e565b9050919050565b5f819050919050565b612311836122de565b61232561231d826122ff565b848454612284565b825550505050565b5f90565b61233961232d565b612344818484612308565b505050565b5b818110156123675761235c5f82612331565b60018101905061234a565b5050565b601f8211156123ac5761237d81612257565b61238684612269565b81016020851015612395578190505b6123a96123a185612269565b830182612349565b50505b505050565b5f82821c905092915050565b5f6123cc5f19846008026123b1565b1980831691505092915050565b5f6123e483836123bd565b9150826002028217905092915050565b6123fd82611a7e565b67ffffffffffffffff81111561241657612415611d3f565b5b6124208254612046565b61242b82828561236b565b5f60209050601f83116001811461245c575f841561244a578287015190505b61245485826123d9565b8655506124bb565b601f19841661246a86612257565b5f5b828110156124915784890151825560018201915060208501945060208101905061246c565b868310156124ae57848901516124aa601f8916826123bd565b8355505b6001600288020188555050505b505050505050565b5f6040820190506124d65f830185611b9c565b6124e36020830184611ca7565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffdfea26469706673582212202540ee918e4df6d1e3653efd3abe64ef363173095adc5bd653b560c0f749995164736f6c634300081900330000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000074e6174617368610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074e415441534841000000000000000000000000000000000000000000000000008284f4a03ec85443c6eb335753d25c13e15a033394bc1b4f4ba0ec632e16aa669afec22ca00f7154cef3cacff1b20a80602dffd7844dc44e7759eb78aa9f956aa7d7c6784d", + "0xf92d040184520799b583255f7f8080b92cb0608060405234801561000f575f80fd5b50604051612bf0380380612bf0833981810160405281019061003191906102ec565b338282815f9081610042919061056f565b508060019081610052919061056f565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100c5575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016100bc919061067d565b60405180910390fd5b6100d4816100dc60201b60201c565b505050610696565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6101fe826101b8565b810181811067ffffffffffffffff8211171561021d5761021c6101c8565b5b80604052505050565b5f61022f61019f565b905061023b82826101f5565b919050565b5f67ffffffffffffffff82111561025a576102596101c8565b5b610263826101b8565b9050602081019050919050565b8281835e5f83830152505050565b5f61029061028b84610240565b610226565b9050828152602081018484840111156102ac576102ab6101b4565b5b6102b7848285610270565b509392505050565b5f82601f8301126102d3576102d26101b0565b5b81516102e384826020860161027e565b91505092915050565b5f8060408385031215610302576103016101a8565b5b5f83015167ffffffffffffffff81111561031f5761031e6101ac565b5b61032b858286016102bf565b925050602083015167ffffffffffffffff81111561034c5761034b6101ac565b5b610358858286016102bf565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806103b057607f821691505b6020821081036103c3576103c261036c565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026104257fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826103ea565b61042f86836103ea565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61047361046e61046984610447565b610450565b610447565b9050919050565b5f819050919050565b61048c83610459565b6104a06104988261047a565b8484546103f6565b825550505050565b5f90565b6104b46104a8565b6104bf818484610483565b505050565b5b818110156104e2576104d75f826104ac565b6001810190506104c5565b5050565b601f821115610527576104f8816103c9565b610501846103db565b81016020851015610510578190505b61052461051c856103db565b8301826104c4565b50505b505050565b5f82821c905092915050565b5f6105475f198460080261052c565b1980831691505092915050565b5f61055f8383610538565b9150826002028217905092915050565b61057882610362565b67ffffffffffffffff811115610591576105906101c8565b5b61059b8254610399565b6105a68282856104e6565b5f60209050601f8311600181146105d7575f84156105c5578287015190505b6105cf8582610554565b865550610636565b601f1984166105e5866103c9565b5f5b8281101561060c578489015182556001820191506020850194506020810190506105e7565b868310156106295784890151610625601f891682610538565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6106678261063e565b9050919050565b6106778161065d565b82525050565b5f6020820190506106905f83018461066e565b92915050565b61254d806106a35f395ff3fe608060405234801561000f575f80fd5b5060043610610109575f3560e01c8063715018a6116100a0578063b88d4fde1161006f578063b88d4fde146102a1578063c87b56dd146102bd578063d0def521146102ed578063e985e9c51461031d578063f2fde38b1461034d57610109565b8063715018a61461023f5780638da5cb5b1461024957806395d89b4114610267578063a22cb4651461028557610109565b806323b872dd116100dc57806323b872dd146101a757806342842e0e146101c35780636352211e146101df57806370a082311461020f57610109565b806301ffc9a71461010d57806306fdde031461013d578063081812fc1461015b578063095ea7b31461018b575b5f80fd5b61012760048036038101906101229190611a20565b610369565b6040516101349190611a65565b60405180910390f35b6101456103c9565b6040516101529190611aee565b60405180910390f35b61017560048036038101906101709190611b41565b610458565b6040516101829190611bab565b60405180910390f35b6101a560048036038101906101a09190611bee565b610473565b005b6101c160048036038101906101bc9190611c2c565b610489565b005b6101dd60048036038101906101d89190611c2c565b610588565b005b6101f960048036038101906101f49190611b41565b6105a7565b6040516102069190611bab565b60405180910390f35b61022960048036038101906102249190611c7c565b6105b8565b6040516102369190611cb6565b60405180910390f35b61024761066e565b005b610251610681565b60405161025e9190611bab565b60405180910390f35b61026f6106a9565b60405161027c9190611aee565b60405180910390f35b61029f600480360381019061029a9190611cf9565b610739565b005b6102bb60048036038101906102b69190611e63565b61074f565b005b6102d760048036038101906102d29190611b41565b61076c565b6040516102e49190611aee565b60405180910390f35b61030760048036038101906103029190611f81565b610877565b6040516103149190611cb6565b60405180910390f35b61033760048036038101906103329190611fdb565b6108b7565b6040516103449190611a65565b60405180910390f35b61036760048036038101906103629190611c7c565b610945565b005b5f634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103c257506103c1826109c9565b5b9050919050565b60605f80546103d790612046565b80601f016020809104026020016040519081016040528092919081815260200182805461040390612046565b801561044e5780601f106104255761010080835404028352916020019161044e565b820191905f5260205f20905b81548152906001019060200180831161043157829003601f168201915b5050505050905090565b5f61046282610aaa565b5061046c82610b30565b9050919050565b6104858282610480610b69565b610b70565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036104f9575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016104f09190611bab565b60405180910390fd5b5f61050c8383610507610b69565b610b82565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610582578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161057993929190612076565b60405180910390fd5b50505050565b6105a283838360405180602001604052805f81525061074f565b505050565b5f6105b182610aaa565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610629575f6040517f89c62b640000000000000000000000000000000000000000000000000000000081526004016106209190611bab565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610676610d8d565b61067f5f610e14565b565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546106b890612046565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612046565b801561072f5780601f106107065761010080835404028352916020019161072f565b820191905f5260205f20905b81548152906001019060200180831161071257829003601f168201915b5050505050905090565b61074b610744610b69565b8383610ed7565b5050565b61075a848484610489565b61076684848484611040565b50505050565b606061077782610aaa565b505f60065f8481526020019081526020015f20805461079590612046565b80601f01602080910402602001604051908101604052809291908181526020018280546107c190612046565b801561080c5780601f106107e35761010080835404028352916020019161080c565b820191905f5260205f20905b8154815290600101906020018083116107ef57829003601f168201915b505050505090505f61081c6111f2565b90505f815103610830578192505050610872565b5f8251111561086457808260405160200161084c9291906120e5565b60405160208183030381529060405292505050610872565b61086d84611208565b925050505b919050565b5f610880610d8d565b5f60085f81548092919061089390612135565b9190505590506108a3848261126e565b6108ad8184611361565b8091505092915050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b61094d610d8d565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109bd575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016109b49190611bab565b60405180910390fd5b6109c681610e14565b50565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a9357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610aa35750610aa2826113bb565b5b9050919050565b5f80610ab583611424565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b2757826040517f7e273289000000000000000000000000000000000000000000000000000000008152600401610b1e9190611cb6565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b610b7d838383600161145d565b505050565b5f80610b8d84611424565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610bce57610bcd81848661161c565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c5957610c0d5f855f8061145d565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610cd857600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b610d95610b69565b73ffffffffffffffffffffffffffffffffffffffff16610db3610681565b73ffffffffffffffffffffffffffffffffffffffff1614610e1257610dd6610b69565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610e099190611bab565b60405180910390fd5b565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f4757816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401610f3e9190611bab565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516110339190611a65565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b11156111ec578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02611083610b69565b8685856040518563ffffffff1660e01b81526004016110a594939291906121ce565b6020604051808303815f875af19250505080156110e057506040513d601f19601f820116820180604052508101906110dd919061222c565b60015b611161573d805f811461110e576040519150601f19603f3d011682016040523d82523d5f602084013e611113565b606091505b505f81510361115957836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016111509190611bab565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146111ea57836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016111e19190611bab565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b606061121382610aaa565b505f61121d6111f2565b90505f81511161123b5760405180602001604052805f815250611266565b80611245846116df565b6040516020016112569291906120e5565b6040516020818303038152906040525b915050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036112de575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016112d59190611bab565b60405180910390fd5b5f6112ea83835f610b82565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461135c575f6040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081526004016113539190611bab565b60405180910390fd5b505050565b8060065f8481526020019081526020015f20908161137f91906123f4565b507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7826040516113af9190611cb6565b60405180910390a15050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b808061149557505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156115c7575f6114a484610aaa565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561150e57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611521575061151f81846108b7565b155b1561156357826040517fa9fbf51f00000000000000000000000000000000000000000000000000000000815260040161155a9190611bab565b60405180910390fd5b81156115c557838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b6116278383836117a9565b6116da575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361169b57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016116929190611cb6565b60405180910390fd5b81816040517f177e802f0000000000000000000000000000000000000000000000000000000081526004016116d19291906124c3565b60405180910390fd5b505050565b60605f60016116ed84611869565b0190505f8167ffffffffffffffff81111561170b5761170a611d3f565b5b6040519080825280601f01601f19166020018201604052801561173d5781602001600182028036833780820191505090505b5090505f82602001820190505b60011561179e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611793576117926124ea565b5b0494505f850361174a575b819350505050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561186057508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611821575061182084846108b7565b5b8061185f57508273ffffffffffffffffffffffffffffffffffffffff1661184783610b30565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106118c5577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816118bb576118ba6124ea565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611902576d04ee2d6d415b85acef810000000083816118f8576118f76124ea565b5b0492506020810190505b662386f26fc10000831061193157662386f26fc100008381611927576119266124ea565b5b0492506010810190505b6305f5e100831061195a576305f5e10083816119505761194f6124ea565b5b0492506008810190505b612710831061197f576127108381611975576119746124ea565b5b0492506004810190505b606483106119a25760648381611998576119976124ea565b5b0492506002810190505b600a83106119b1576001810190505b80915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6119ff816119cb565b8114611a09575f80fd5b50565b5f81359050611a1a816119f6565b92915050565b5f60208284031215611a3557611a346119c3565b5b5f611a4284828501611a0c565b91505092915050565b5f8115159050919050565b611a5f81611a4b565b82525050565b5f602082019050611a785f830184611a56565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f611ac082611a7e565b611aca8185611a88565b9350611ada818560208601611a98565b611ae381611aa6565b840191505092915050565b5f6020820190508181035f830152611b068184611ab6565b905092915050565b5f819050919050565b611b2081611b0e565b8114611b2a575f80fd5b50565b5f81359050611b3b81611b17565b92915050565b5f60208284031215611b5657611b556119c3565b5b5f611b6384828501611b2d565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611b9582611b6c565b9050919050565b611ba581611b8b565b82525050565b5f602082019050611bbe5f830184611b9c565b92915050565b611bcd81611b8b565b8114611bd7575f80fd5b50565b5f81359050611be881611bc4565b92915050565b5f8060408385031215611c0457611c036119c3565b5b5f611c1185828601611bda565b9250506020611c2285828601611b2d565b9150509250929050565b5f805f60608486031215611c4357611c426119c3565b5b5f611c5086828701611bda565b9350506020611c6186828701611bda565b9250506040611c7286828701611b2d565b9150509250925092565b5f60208284031215611c9157611c906119c3565b5b5f611c9e84828501611bda565b91505092915050565b611cb081611b0e565b82525050565b5f602082019050611cc95f830184611ca7565b92915050565b611cd881611a4b565b8114611ce2575f80fd5b50565b5f81359050611cf381611ccf565b92915050565b5f8060408385031215611d0f57611d0e6119c3565b5b5f611d1c85828601611bda565b9250506020611d2d85828601611ce5565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611d7582611aa6565b810181811067ffffffffffffffff82111715611d9457611d93611d3f565b5b80604052505050565b5f611da66119ba565b9050611db28282611d6c565b919050565b5f67ffffffffffffffff821115611dd157611dd0611d3f565b5b611dda82611aa6565b9050602081019050919050565b828183375f83830152505050565b5f611e07611e0284611db7565b611d9d565b905082815260208101848484011115611e2357611e22611d3b565b5b611e2e848285611de7565b509392505050565b5f82601f830112611e4a57611e49611d37565b5b8135611e5a848260208601611df5565b91505092915050565b5f805f8060808587031215611e7b57611e7a6119c3565b5b5f611e8887828801611bda565b9450506020611e9987828801611bda565b9350506040611eaa87828801611b2d565b925050606085013567ffffffffffffffff811115611ecb57611eca6119c7565b5b611ed787828801611e36565b91505092959194509250565b5f67ffffffffffffffff821115611efd57611efc611d3f565b5b611f0682611aa6565b9050602081019050919050565b5f611f25611f2084611ee3565b611d9d565b905082815260208101848484011115611f4157611f40611d3b565b5b611f4c848285611de7565b509392505050565b5f82601f830112611f6857611f67611d37565b5b8135611f78848260208601611f13565b91505092915050565b5f8060408385031215611f9757611f966119c3565b5b5f611fa485828601611bda565b925050602083013567ffffffffffffffff811115611fc557611fc46119c7565b5b611fd185828601611f54565b9150509250929050565b5f8060408385031215611ff157611ff06119c3565b5b5f611ffe85828601611bda565b925050602061200f85828601611bda565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061205d57607f821691505b6020821081036120705761206f612019565b5b50919050565b5f6060820190506120895f830186611b9c565b6120966020830185611ca7565b6120a36040830184611b9c565b949350505050565b5f81905092915050565b5f6120bf82611a7e565b6120c981856120ab565b93506120d9818560208601611a98565b80840191505092915050565b5f6120f082856120b5565b91506120fc82846120b5565b91508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61213f82611b0e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361217157612170612108565b5b600182019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f6121a08261217c565b6121aa8185612186565b93506121ba818560208601611a98565b6121c381611aa6565b840191505092915050565b5f6080820190506121e15f830187611b9c565b6121ee6020830186611b9c565b6121fb6040830185611ca7565b818103606083015261220d8184612196565b905095945050505050565b5f81519050612226816119f6565b92915050565b5f60208284031215612241576122406119c3565b5b5f61224e84828501612218565b91505092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026122b37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612278565b6122bd8683612278565b95508019841693508086168417925050509392505050565b5f819050919050565b5f6122f86122f36122ee84611b0e565b6122d5565b611b0e565b9050919050565b5f819050919050565b612311836122de565b61232561231d826122ff565b848454612284565b825550505050565b5f90565b61233961232d565b612344818484612308565b505050565b5b818110156123675761235c5f82612331565b60018101905061234a565b5050565b601f8211156123ac5761237d81612257565b61238684612269565b81016020851015612395578190505b6123a96123a185612269565b830182612349565b50505b505050565b5f82821c905092915050565b5f6123cc5f19846008026123b1565b1980831691505092915050565b5f6123e483836123bd565b9150826002028217905092915050565b6123fd82611a7e565b67ffffffffffffffff81111561241657612415611d3f565b5b6124208254612046565b61242b82828561236b565b5f60209050601f83116001811461245c575f841561244a578287015190505b61245485826123d9565b8655506124bb565b601f19841661246a86612257565b5f5b828110156124915784890151825560018201915060208501945060208101905061246c565b868310156124ae57848901516124aa601f8916826123bd565b8355505b6001600288020188555050505b505050505050565b5f6040820190506124d65f830185611b9c565b6124e36020830184611ca7565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffdfea26469706673582212202540ee918e4df6d1e3653efd3abe64ef363173095adc5bd653b560c0f749995164736f6c634300081900330000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000044a6f64690000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a4f4449000000000000000000000000000000000000000000000000000000008284f3a04c5c5e2cc950451f88fe884b241458cb6c6b85af9d8906eda9b2f40a9bbf6dc4a036a3ee2246a0f125e0b1810fc6fa5b46e39e31fdae672f2e6a4f0bc329b3532a", + "0xf8cb0384520799b58301850f94e0d979643fb000bcbd1697d75ff9680e35ec0ff380b864d0def521000000000000000000000000a52b199d8f75e8261656ec09421bca8908ddc8da000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008284f3a0979264f9c582d7b3c28dd66f35e32cc815a71d0b5848afc00cc0d5a58f98cdb8a03633e9a5e8c1778dc0e3efb9a3d45cafa927e382670806c6254cb4bba23e7717", + "0xf92d040184520799b583255fea8080b92cb0608060405234801561000f575f80fd5b50604051612bf0380380612bf0833981810160405281019061003191906102ec565b338282815f9081610042919061056f565b508060019081610052919061056f565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100c5575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016100bc919061067d565b60405180910390fd5b6100d4816100dc60201b60201c565b505050610696565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6101fe826101b8565b810181811067ffffffffffffffff8211171561021d5761021c6101c8565b5b80604052505050565b5f61022f61019f565b905061023b82826101f5565b919050565b5f67ffffffffffffffff82111561025a576102596101c8565b5b610263826101b8565b9050602081019050919050565b8281835e5f83830152505050565b5f61029061028b84610240565b610226565b9050828152602081018484840111156102ac576102ab6101b4565b5b6102b7848285610270565b509392505050565b5f82601f8301126102d3576102d26101b0565b5b81516102e384826020860161027e565b91505092915050565b5f8060408385031215610302576103016101a8565b5b5f83015167ffffffffffffffff81111561031f5761031e6101ac565b5b61032b858286016102bf565b925050602083015167ffffffffffffffff81111561034c5761034b6101ac565b5b610358858286016102bf565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806103b057607f821691505b6020821081036103c3576103c261036c565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026104257fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826103ea565b61042f86836103ea565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61047361046e61046984610447565b610450565b610447565b9050919050565b5f819050919050565b61048c83610459565b6104a06104988261047a565b8484546103f6565b825550505050565b5f90565b6104b46104a8565b6104bf818484610483565b505050565b5b818110156104e2576104d75f826104ac565b6001810190506104c5565b5050565b601f821115610527576104f8816103c9565b610501846103db565b81016020851015610510578190505b61052461051c856103db565b8301826104c4565b50505b505050565b5f82821c905092915050565b5f6105475f198460080261052c565b1980831691505092915050565b5f61055f8383610538565b9150826002028217905092915050565b61057882610362565b67ffffffffffffffff811115610591576105906101c8565b5b61059b8254610399565b6105a68282856104e6565b5f60209050601f8311600181146105d7575f84156105c5578287015190505b6105cf8582610554565b865550610636565b601f1984166105e5866103c9565b5f5b8281101561060c578489015182556001820191506020850194506020810190506105e7565b868310156106295784890151610625601f891682610538565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6106678261063e565b9050919050565b6106778161065d565b82525050565b5f6020820190506106905f83018461066e565b92915050565b61254d806106a35f395ff3fe608060405234801561000f575f80fd5b5060043610610109575f3560e01c8063715018a6116100a0578063b88d4fde1161006f578063b88d4fde146102a1578063c87b56dd146102bd578063d0def521146102ed578063e985e9c51461031d578063f2fde38b1461034d57610109565b8063715018a61461023f5780638da5cb5b1461024957806395d89b4114610267578063a22cb4651461028557610109565b806323b872dd116100dc57806323b872dd146101a757806342842e0e146101c35780636352211e146101df57806370a082311461020f57610109565b806301ffc9a71461010d57806306fdde031461013d578063081812fc1461015b578063095ea7b31461018b575b5f80fd5b61012760048036038101906101229190611a20565b610369565b6040516101349190611a65565b60405180910390f35b6101456103c9565b6040516101529190611aee565b60405180910390f35b61017560048036038101906101709190611b41565b610458565b6040516101829190611bab565b60405180910390f35b6101a560048036038101906101a09190611bee565b610473565b005b6101c160048036038101906101bc9190611c2c565b610489565b005b6101dd60048036038101906101d89190611c2c565b610588565b005b6101f960048036038101906101f49190611b41565b6105a7565b6040516102069190611bab565b60405180910390f35b61022960048036038101906102249190611c7c565b6105b8565b6040516102369190611cb6565b60405180910390f35b61024761066e565b005b610251610681565b60405161025e9190611bab565b60405180910390f35b61026f6106a9565b60405161027c9190611aee565b60405180910390f35b61029f600480360381019061029a9190611cf9565b610739565b005b6102bb60048036038101906102b69190611e63565b61074f565b005b6102d760048036038101906102d29190611b41565b61076c565b6040516102e49190611aee565b60405180910390f35b61030760048036038101906103029190611f81565b610877565b6040516103149190611cb6565b60405180910390f35b61033760048036038101906103329190611fdb565b6108b7565b6040516103449190611a65565b60405180910390f35b61036760048036038101906103629190611c7c565b610945565b005b5f634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103c257506103c1826109c9565b5b9050919050565b60605f80546103d790612046565b80601f016020809104026020016040519081016040528092919081815260200182805461040390612046565b801561044e5780601f106104255761010080835404028352916020019161044e565b820191905f5260205f20905b81548152906001019060200180831161043157829003601f168201915b5050505050905090565b5f61046282610aaa565b5061046c82610b30565b9050919050565b6104858282610480610b69565b610b70565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036104f9575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016104f09190611bab565b60405180910390fd5b5f61050c8383610507610b69565b610b82565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610582578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161057993929190612076565b60405180910390fd5b50505050565b6105a283838360405180602001604052805f81525061074f565b505050565b5f6105b182610aaa565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610629575f6040517f89c62b640000000000000000000000000000000000000000000000000000000081526004016106209190611bab565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610676610d8d565b61067f5f610e14565b565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546106b890612046565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612046565b801561072f5780601f106107065761010080835404028352916020019161072f565b820191905f5260205f20905b81548152906001019060200180831161071257829003601f168201915b5050505050905090565b61074b610744610b69565b8383610ed7565b5050565b61075a848484610489565b61076684848484611040565b50505050565b606061077782610aaa565b505f60065f8481526020019081526020015f20805461079590612046565b80601f01602080910402602001604051908101604052809291908181526020018280546107c190612046565b801561080c5780601f106107e35761010080835404028352916020019161080c565b820191905f5260205f20905b8154815290600101906020018083116107ef57829003601f168201915b505050505090505f61081c6111f2565b90505f815103610830578192505050610872565b5f8251111561086457808260405160200161084c9291906120e5565b60405160208183030381529060405292505050610872565b61086d84611208565b925050505b919050565b5f610880610d8d565b5f60085f81548092919061089390612135565b9190505590506108a3848261126e565b6108ad8184611361565b8091505092915050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b61094d610d8d565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109bd575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016109b49190611bab565b60405180910390fd5b6109c681610e14565b50565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a9357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610aa35750610aa2826113bb565b5b9050919050565b5f80610ab583611424565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b2757826040517f7e273289000000000000000000000000000000000000000000000000000000008152600401610b1e9190611cb6565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b610b7d838383600161145d565b505050565b5f80610b8d84611424565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610bce57610bcd81848661161c565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c5957610c0d5f855f8061145d565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610cd857600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b610d95610b69565b73ffffffffffffffffffffffffffffffffffffffff16610db3610681565b73ffffffffffffffffffffffffffffffffffffffff1614610e1257610dd6610b69565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610e099190611bab565b60405180910390fd5b565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f4757816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401610f3e9190611bab565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516110339190611a65565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b11156111ec578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02611083610b69565b8685856040518563ffffffff1660e01b81526004016110a594939291906121ce565b6020604051808303815f875af19250505080156110e057506040513d601f19601f820116820180604052508101906110dd919061222c565b60015b611161573d805f811461110e576040519150601f19603f3d011682016040523d82523d5f602084013e611113565b606091505b505f81510361115957836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016111509190611bab565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146111ea57836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016111e19190611bab565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b606061121382610aaa565b505f61121d6111f2565b90505f81511161123b5760405180602001604052805f815250611266565b80611245846116df565b6040516020016112569291906120e5565b6040516020818303038152906040525b915050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036112de575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016112d59190611bab565b60405180910390fd5b5f6112ea83835f610b82565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461135c575f6040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081526004016113539190611bab565b60405180910390fd5b505050565b8060065f8481526020019081526020015f20908161137f91906123f4565b507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7826040516113af9190611cb6565b60405180910390a15050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b808061149557505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156115c7575f6114a484610aaa565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561150e57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611521575061151f81846108b7565b155b1561156357826040517fa9fbf51f00000000000000000000000000000000000000000000000000000000815260040161155a9190611bab565b60405180910390fd5b81156115c557838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b6116278383836117a9565b6116da575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361169b57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016116929190611cb6565b60405180910390fd5b81816040517f177e802f0000000000000000000000000000000000000000000000000000000081526004016116d19291906124c3565b60405180910390fd5b505050565b60605f60016116ed84611869565b0190505f8167ffffffffffffffff81111561170b5761170a611d3f565b5b6040519080825280601f01601f19166020018201604052801561173d5781602001600182028036833780820191505090505b5090505f82602001820190505b60011561179e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611793576117926124ea565b5b0494505f850361174a575b819350505050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561186057508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611821575061182084846108b7565b5b8061185f57508273ffffffffffffffffffffffffffffffffffffffff1661184783610b30565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106118c5577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816118bb576118ba6124ea565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611902576d04ee2d6d415b85acef810000000083816118f8576118f76124ea565b5b0492506020810190505b662386f26fc10000831061193157662386f26fc100008381611927576119266124ea565b5b0492506010810190505b6305f5e100831061195a576305f5e10083816119505761194f6124ea565b5b0492506008810190505b612710831061197f576127108381611975576119746124ea565b5b0492506004810190505b606483106119a25760648381611998576119976124ea565b5b0492506002810190505b600a83106119b1576001810190505b80915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6119ff816119cb565b8114611a09575f80fd5b50565b5f81359050611a1a816119f6565b92915050565b5f60208284031215611a3557611a346119c3565b5b5f611a4284828501611a0c565b91505092915050565b5f8115159050919050565b611a5f81611a4b565b82525050565b5f602082019050611a785f830184611a56565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f611ac082611a7e565b611aca8185611a88565b9350611ada818560208601611a98565b611ae381611aa6565b840191505092915050565b5f6020820190508181035f830152611b068184611ab6565b905092915050565b5f819050919050565b611b2081611b0e565b8114611b2a575f80fd5b50565b5f81359050611b3b81611b17565b92915050565b5f60208284031215611b5657611b556119c3565b5b5f611b6384828501611b2d565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611b9582611b6c565b9050919050565b611ba581611b8b565b82525050565b5f602082019050611bbe5f830184611b9c565b92915050565b611bcd81611b8b565b8114611bd7575f80fd5b50565b5f81359050611be881611bc4565b92915050565b5f8060408385031215611c0457611c036119c3565b5b5f611c1185828601611bda565b9250506020611c2285828601611b2d565b9150509250929050565b5f805f60608486031215611c4357611c426119c3565b5b5f611c5086828701611bda565b9350506020611c6186828701611bda565b9250506040611c7286828701611b2d565b9150509250925092565b5f60208284031215611c9157611c906119c3565b5b5f611c9e84828501611bda565b91505092915050565b611cb081611b0e565b82525050565b5f602082019050611cc95f830184611ca7565b92915050565b611cd881611a4b565b8114611ce2575f80fd5b50565b5f81359050611cf381611ccf565b92915050565b5f8060408385031215611d0f57611d0e6119c3565b5b5f611d1c85828601611bda565b9250506020611d2d85828601611ce5565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611d7582611aa6565b810181811067ffffffffffffffff82111715611d9457611d93611d3f565b5b80604052505050565b5f611da66119ba565b9050611db28282611d6c565b919050565b5f67ffffffffffffffff821115611dd157611dd0611d3f565b5b611dda82611aa6565b9050602081019050919050565b828183375f83830152505050565b5f611e07611e0284611db7565b611d9d565b905082815260208101848484011115611e2357611e22611d3b565b5b611e2e848285611de7565b509392505050565b5f82601f830112611e4a57611e49611d37565b5b8135611e5a848260208601611df5565b91505092915050565b5f805f8060808587031215611e7b57611e7a6119c3565b5b5f611e8887828801611bda565b9450506020611e9987828801611bda565b9350506040611eaa87828801611b2d565b925050606085013567ffffffffffffffff811115611ecb57611eca6119c7565b5b611ed787828801611e36565b91505092959194509250565b5f67ffffffffffffffff821115611efd57611efc611d3f565b5b611f0682611aa6565b9050602081019050919050565b5f611f25611f2084611ee3565b611d9d565b905082815260208101848484011115611f4157611f40611d3b565b5b611f4c848285611de7565b509392505050565b5f82601f830112611f6857611f67611d37565b5b8135611f78848260208601611f13565b91505092915050565b5f8060408385031215611f9757611f966119c3565b5b5f611fa485828601611bda565b925050602083013567ffffffffffffffff811115611fc557611fc46119c7565b5b611fd185828601611f54565b9150509250929050565b5f8060408385031215611ff157611ff06119c3565b5b5f611ffe85828601611bda565b925050602061200f85828601611bda565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061205d57607f821691505b6020821081036120705761206f612019565b5b50919050565b5f6060820190506120895f830186611b9c565b6120966020830185611ca7565b6120a36040830184611b9c565b949350505050565b5f81905092915050565b5f6120bf82611a7e565b6120c981856120ab565b93506120d9818560208601611a98565b80840191505092915050565b5f6120f082856120b5565b91506120fc82846120b5565b91508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61213f82611b0e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361217157612170612108565b5b600182019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f6121a08261217c565b6121aa8185612186565b93506121ba818560208601611a98565b6121c381611aa6565b840191505092915050565b5f6080820190506121e15f830187611b9c565b6121ee6020830186611b9c565b6121fb6040830185611ca7565b818103606083015261220d8184612196565b905095945050505050565b5f81519050612226816119f6565b92915050565b5f60208284031215612241576122406119c3565b5b5f61224e84828501612218565b91505092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026122b37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612278565b6122bd8683612278565b95508019841693508086168417925050509392505050565b5f819050919050565b5f6122f86122f36122ee84611b0e565b6122d5565b611b0e565b9050919050565b5f819050919050565b612311836122de565b61232561231d826122ff565b848454612284565b825550505050565b5f90565b61233961232d565b612344818484612308565b505050565b5b818110156123675761235c5f82612331565b60018101905061234a565b5050565b601f8211156123ac5761237d81612257565b61238684612269565b81016020851015612395578190505b6123a96123a185612269565b830182612349565b50505b505050565b5f82821c905092915050565b5f6123cc5f19846008026123b1565b1980831691505092915050565b5f6123e483836123bd565b9150826002028217905092915050565b6123fd82611a7e565b67ffffffffffffffff81111561241657612415611d3f565b5b6124208254612046565b61242b82828561236b565b5f60209050601f83116001811461245c575f841561244a578287015190505b61245485826123d9565b8655506124bb565b601f19841661246a86612257565b5f5b828110156124915784890151825560018201915060208501945060208101905061246c565b868310156124ae57848901516124aa601f8916826123bd565b8355505b6001600288020188555050505b505050505050565b5f6040820190506124d65f830185611b9c565b6124e36020830184611ca7565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffdfea26469706673582212202540ee918e4df6d1e3653efd3abe64ef363173095adc5bd653b560c0f749995164736f6c634300081900330000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000084b696d6265726c7900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084b494d4245524c590000000000000000000000000000000000000000000000008284f4a0a7c0356219b93ab00638ad363cc520e2460367b56d3a36028d840b6676f19142a0225ee98a3147f95e86ec031afdab689e62419533eb2d79b125c8969c7ae70144", + "0x02f87882426805840c2508e4846bb2a00f83044144941cf3f95312ad9dbe95ed2eaf3cb352d14bf373d087470de4df82000084f6326fb3c001a0e16b7eedd2cc4d729e26d53e49f0bf8fac58d7cf4d8a5267192831ed95b8643ea02f681150316ee44c0cfa4a09e66457ffd68f485d7a22175e569d2db699999c97", + "0x02f8b58242688218ec840b0a652d85174876e800831e848094f57b0049b1d68fc6b2ec1b3381d6a989e4a8aaae80b8440c54143200000000000000000000000000000000000000000000000000000000000cd6a100000000000000000001b6a69d2332e9537850fef21a79681167b87efbe0e8fdc080a092465a9b4ed75ac8e129d67c4139ee7dd7e37a0eb4bc0fabc8bef21bfd3e0354a063d40f911d93e830ae53b1317aa3206b561cfecc6b2d73411e3617c7eca3507c", + "0x02f9013c824268820ba0840b0a652d851030767e8e8307a12094deb630199fb3f645d3655f3152d48e76b0125733877c585087238000b8c46c3174f100000000000000000000000000000000000000000000000000000000000cd6a400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000007000000000000000000000000cd501ee90c50b9e478776bb4bddc520012d160e700000000000000000000000000000000000000000000000000000000000000053032343638000000000000000000000000000000000000000000000000000000c001a09b764068f3a6eeebe92d2fde2cc5fd694674d194e5369df282f2b7485271bf2ca06f7589ad28979826af0af79d7b144054fbf5eb19f4cb56d2e30c700a57dbf6cb", + "0x02f8948242688208d9840b0a652d8502540be400830493e094deb630199fb3f645d3655f3152d48e76b012573380a4b93cc06300000000000000000000000000000000000000000000000000000000000cd6a1c001a0893ca879bdd811194a183998f54c10dd4b2d69c8f049e313e6bb64871744cbd8a07a3d316879f269d1605e9b52c2e4699a602118d3f2490309f7912ea7e7fdea42", + "0x02f87982426883012bda840b0a652d85014db79cd8830f424094694b9c8f67578dfb91eb36e6c46b92a68acfc731880de0b6b3a764000080c001a06e474baee962e5c928b83ace9545f1810c8bd12dc344429eb81bfeda589f2fc0a026b03ae4509ea82d147dedc0e144f78acb6318f158a670169e477acc6f4e3ee5", + "0x02f8768242688207dc840b0a652d84a5bf7c73825208945002ec478515eef7dedd1aa512d858af4f5709a5880de0b6b3a764000080c080a06db72c5c8a0a1da2ee71dc708a76a0be1067afcd0635222781c67461881a1bc5a01a81c36745f92b53f54081143a15019231ed83532e6d6333b94f8ef5f0148c2f", + "0x02f8f4824268825403840b0a652d84a5bf7c73830156ed942a4c79c0c3fbad96adf08d6213b86a086a8135a080b8849aaab648b42fcdd9b87012cba4d1bc408f2b3f889e116a2bedc097d666a8d19850ae432c00000000000000000000000000000000000000000000000000000000002761684e69496a4e28e536e4068673c84e6c9adcb10d4c1fb2e5845aeeaceb2743a0ad000000000000000000000000000000000000000000000000000000000016067fc080a0495ee1b69028ad065accf6e4598c7cc8e69ecd1aacac56e4fd8ccff2869b9d04a01f3fc2a37028e2b0b222c0f709bcc864ed152566fd346c1452ddf37463155d92", + "0x02f901b5824268827b08840b0a652d84996bb2ab830186a0945ff3cdc8cbd419405533b19332b1535caab65f9980b90144ad091f7600000000000000000000000000000000000000000000000000000000000000200000000000000000000000003c5e0e2a748d6577231bba856d50bc122a405fd70000000000000000000000005ff3cdc8cbd419405533b19332b1535caab65f995b34b9660000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6f6661632d706f6c696379000000000000000000000000000000000000000000c080a014de3b55f390b0126c319fd311eef6d50c055a3d338079e515e1403e67f910aaa01ce58c7532495730bd79e54b83ddc093c6ce4910ad3889b4127b504747439fa1", + "0x02f9083582426882490d840b0a652d8467dd73238305f8fc94329d0c4a58b3cefdb40c5513e155228f6cc7b6c580b907c45740b89d00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af8a00000000000000000000000000000000000000000000000000000000000172d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af8b00000000000000000000000000000000000000000000000000000000000172d1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af8c00000000000000000000000000000000000000000000000000000000000172d2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af8d00000000000000000000000000000000000000000000000000000000000172d3000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af8e00000000000000000000000000000000000000000000000000000000000172d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af8f00000000000000000000000000000000000000000000000000000000000172d5000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af9000000000000000000000000000000000000000000000000000000000000172d6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af9100000000000000000000000000000000000000000000000000000000000172d7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af9200000000000000000000000000000000000000000000000000000000000172d8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af9300000000000000000000000000000000000000000000000000000000000172d9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af9400000000000000000000000000000000000000000000000000000000000172da00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001c080a0a8cf3f6b4a8a76f8827fc0960b07b3699577fa8a92a550d291c1edb882b2cd76a00149c15da7412ae18880980db9a1ae3351eec2226eea510a8770ccae25180b6f", + "0x02f90113824268820d3c840ad6f2f6849938407482c93794a44151489861fe9e3055d95adc98fbd462b948e780b8a499be81c80000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004c68747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f63616e6479313236342f656967656e2f6d61696e2f6d657461646174612d6578616d706c652e6a736f6e0000000000000000000000000000000000000000c080a0c938cca3472ad85efe3391b1c1c4644bf06651a9f277450b4ab4aaaa9e9d4c10a0127cd3bfa1d7cfbeb55fbb35e78bb332a8a16d985b66edaea2ba746ac6daec65", + "0x02f902958242688237f7840ad6f2f6849938407483030d4094eac603ab68fb5a4a56d7a9fd54a669133fea725b80b90224dc549bf40000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000001606ea00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000bdb1d9bd64f29b292aa1e107fd631bfb70a9769b000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000041e0dab328d79c44ca06ea58ba03129d64b065719cd8a3a04eadd57b6581cbb31d32fe8d7471132ca068f2c04f1a6fb707fd76a27e87e98f4d9c08de4b98ee281e1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002463333535366265352d353861312d346261342d383939342d39653032373333316139383900000000000000000000000000000000000000000000000000000000c080a039e8df298fd910cc887bc567c63199ef0728deed59254ed49bd84ff02f3355aba032a560cd90babee613234880caf03d4971ca51e0dd2492712cd70f1779fa3677", + "0x02f90436824268830c47b6840ad6f2f6849938407483030d6e94b20bb9105e007bd3e0f73d63d4d3da2c8f736b7780b903c410d008bd00000000000000000000000000000000000000000000000000000000000f6f580000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000036090a75a39318db84fffa3357d14dda3bb3aa2b83b1d3633ac348b7309df9ec0e2c7e74cd0948b7ea7a67abc6cf03c6f5a27fd9726026e60f75424173e0138e525823d523534f5814fa4850f52d45ecd353cd9761974735b394cc19b85bd25a855302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd000000000000000000000000e1e210594771824dad216568b91c9cb4ceed361c00000000000000000000000000000000000000000000000000000000000f6f580000000000000000000000000000000000000000000000000000000000e4e1c000000000000000000000000000000000000000000000000000000000662fb2a8000000000000000000000000000000000000000000000000000000000016068600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010f2300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000c56fb0cd3a37e39ecf895c7d58d18068ae1be56c857f78f7419b7dc4f259e7e11f98434a8ea9ea9a90303a8642876c027a308e6b16e7bded021d2341505d3f569b545da57b54aeeb381db83da02bc9022a5c7757c417c0452f7b4a164e7601eef6db8fb06be8f7b54d4723c0e08f13498d77011695b2eceed8141603ad9af8ab00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c001a02d74c4de00fbaaf085012fce8d428617399715eb619cd50048125ef0cdac3d37a062428a5709defb76e4ed2eb4174434d70daaa4ce885d6c42b785f4f44ce00868", + "0x02f904368242688301feba840ad6f2f68499384074832dc6c094b20bb9105e007bd3e0f73d63d4d3da2c8f736b7780b903c410d008bd00000000000000000000000000000000000000000000000000000000000f6f590000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000036090a75a39318db84fffa3357d14dda3bb3aa2b83b1d3633ac348b7309df9ec0e2f240e5e2777aedab55329ea29061122318df7736fb61093e13ad1b405bb5e5a4104c57648bb0a53f2b55739c1397b67b96b3e5a81ee4fa4e34e492049a0fad5e302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd000000000000000000000000d55a15f388b2cf3d870b7fa6b4861da38020450200000000000000000000000000000000000000000000000000000000000f6f590000000000000000000000000000000000000000000000000000000000e4e1c000000000000000000000000000000000000000000000000000000000662fb2a8000000000000000000000000000000000000000000000000000000000016068600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012314000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000004dc058a7879e10f67333cfca985f82a0e72d7444bb18a4aa726d8d008dbc509d9b545da57b54aeeb381db83da02bc9022a5c7757c417c0452f7b4a164e7601eed19ffca09fa9740dbcc6f38e88a79f42103b6d6d04f7896302ed95267cfdc63c23084b4a1da39652036c41c8a6a4b8389478430016b6b49d1163baa7aea2799600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c080a007c6afa814be663a59bd1a2adb45d20e4ca9ad1619277e8fbbc04b7de304dd2fa01944fe77ec25a040590a35c9af4ccb8559de87202f030b668d7d3a291ee8a4b4", + "0x02f88f824268830c74fc840ad6f2f6849938407482540894ff0000000000000000000000000000000001700180a042df3b821942f7dc6fbeeff8a9f41f29b7a269e9d7f68e95c4cc4c1d3db039ccc080a02dedef0819c8ecd180793fc2d836dc6514ebb45d73b35bb25097b1e04bb85920a01dee5ae884537032553b0f7696f7d8803331f0b218b1a1ed559bb40b60e74698", + "0x02fa01baf9824268830d6ec8840ad6f2f68499384074832dc6c094b20bb9105e007bd3e0f73d63d4d3da2c8f736b77820466ba01ba84ef16e8450000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000004a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000006415bda9cebfbb54d81278e6b4c8a160c33bc55302e31382e302d646576000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000041e574f051bd887024b4dee2a7f684d6936c4488000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000662fb9bb0000000000000000000000000000000000000000000000000000000000160a870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000046600000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000004660000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041e96f36a2a795e064f1bdce5c234d71c13ae98abc953f368a6c7e8c2aaec48eb9396bb5801b0bf544c1aeae2eefbeea5745962298b5bc8aa9de34f54fb091b1e41b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b555fa01b551b89702f89483028c6019850165a0bc00850165a0bc00830267ac94edd0ddaedbc3fbf67ac4ff2ee14ace669821eac180a440d097c3000000000000000000000000c3181ec22cba566f5d04c14d21e81f1633ead7e0c080a0b2f2476c2b310fcf26ca7e738164ac5d52eae7c8dc3fd108964a6248ec178a03a07c938fb763dd07ab4d37416a4293f6a6ca64b4588e44e1d66909d343ac45ea74b8b802f8b583028c601a850165a0bc00850165a0bc008301ca9994edd0ddaedbc3fbf67ac4ff2ee14ace669821eac180b8447237855400000000000000000000000000000000000000000000000000000000000d3ccd0000000000000000000000001670080000000000000000000000000000000003c080a0eeca968d9c7d01fb9dd5f0bd8fd0ecc048a3d36b7d76f88db6e3577fb0130690a03fe1587db39aa696ce5c9e1ca5325d93b1cef8bb993f582400aa6142191e665eb9049a02f9049683028c601485012a05f20085012a05f2008303710094d2c3cbb943fed0cfc8389b14a3f6df518fd4634680b904243593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000662fb3b000000000000000000000000000000000000000000000000000000000000000030a000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000d69d3e64d71844bbdda51cd7f23ed3631e9fac49000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000066573d120000000000000000000000000000000000000000000000000000000000000001000000000000000000000000d2c3cbb943fed0cfc8389b14a3f6df518fd4634600000000000000000000000000000000000000000000000000000000662fb71a00000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000410f0f98837c6a8a2df7e4c412710c50b7f753ad7802f17ac811a3ee5267a6ce9f2e7a8dde2e1225ae5fb5dcbae2746788c6027abe9e792812d57b4d0a0f0e421e1c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000fe6bc2eee32429f09e0000000000000000000000000000000000000000000000000276c0bed5bc100200000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002bd69d3e64d71844bbdda51cd7f23ed3631e9fac490000640011e559da84dde3f841e22dc33f3adbf184d84a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000276c0bed5bc1002c080a07193141e263e0960dd888e33d68e62fa556ac7cb2d1149cdbe8420551eff3287a01bbbd39a9c582a8fe6130e208c7a00fab0c6629512224c3d26b80ae11d3f9f19b90f1302f90f0f83028c60830379c1090b8308c0ab94167008000000000000000000000000000000000180b90ea4013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c8c000000000000000000000000cfcbeb915fb0acb9edf26a1b1062c20fbd7aa8cc00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000cfcbeb915fb0acb9edf26a1b1062c20fbd7aa8cc000000000000000000000000cfcbeb915fb0acb9edf26a1b1062c20fbd7aa8cc000000000000000000000000cfcbeb915fb0acb9edf26a1b1062c20fbd7aa8cc000000000000000000000000000000000000000000000000004c6222d6abc0000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000b8df90b8ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a00ea7599086a524548ee2a638de6d1b52ccc3188782ade3b0fad03d0f332d5ffea0cd9691d86d7e34295657462b278c2d9e5719ebed807cc2904e13917adf985458a0785e5cec04b56c1b3f7cde086f0f145b59e03d6bf13cca0bd49417da6e3e493fa001dac040644be7d313330ab4f13f065c89014b39477d1b448f2e93b429240fd8a06e8b5b7bf2d33de94a4bc581c733362bbd9cc54063d4600845c50fa84fe989f7a022d5f1374e8575537e273ddf4b29d1f43e11d3b5d88433322a489f94cfcf2b7aa0ffaca60185d5788e1094068decde5cda96e5d3fbd0f4ee55509e5788c40ebfa0a09a257b4b401c68511b52b334739d0d48d28d60f4edf972f33af234bc81d3a79fa05b9ac0a6d36cd949d40978d739a3d6a335d2a6cd16bd4e439d4da9cd846ea1bea009a40d9c0fa70997ccd467192239b516fc68ad52b8814048abbc21e758c21a97a028100a8f9a52026bb3ddddb1fb33cf134625af387f98704bd5da57d3aee9727fa0c908b5a96966e855d3b2f86a6badfc28048c0b156fd56e7aa99213184393f6aea0cafd8337464d52b2788536e434bd4e6df0bf4222c087c4d4bd9a5147cb36a92fa0757a8e45c33d0ff69e87f850999fa4877ec0e78923053d089620e3675612b837a0e8d7bcacb8f8706dd7b0209331c1320024e4a69dc353b64e189c68821ecfb7d4a086b0dde605e175c6cf33c118b11c6de4719edaea09ba18eae150a6bd82aea90080b90214f90211a01c18d42993cad905d8a0e24fbdb6684e01ce2bb1480f5896c7733ee2367ede2ea0516b2e1c5f95817dbd7a145253537c2c76f535c9e4f5106ad594f120da24e4b9a0c834cde5fe2806306f33d1c597a850ae321898da529f2fc7d8aca2a403b86aeba03f8199810d3af51b99a6931c56846b25dcbd32dbfe04d2aff1a1535651aa795ea064f34c0a0e160c2b7a9acec88a23a9daa4f822cbdece368d649fd3b7f728716aa045d24b84526a4976a325eff5cd47a53b6450b80820607275c6ab4b01f6d0e0eba07b8889bbddd06405c15cb47c49a24ade9ac22cf32fef9aac911b12f04f2998bfa04030cf6c3fe1814521f20d89d06430af83c3ddc396ef7e6b538adbad7c3ca01aa0a1f1ae93b4f807e9a740e19e0992190c617b2830e7c9926d8cfef53d8f3b9260a059e10b5db0b210e1c9395ffceb52907f31a9a6628e6e8e69033d5b110573f5caa07aba05e0be65b0b6d04175a5bc23d7a89eea1c7dd1787b7aa48c46cbc00a8fd3a0f849bba13aef2b1994c127eb0b4046cae872bc4a2da6b9a84e779b96295c7f85a0bb422d034012f63b7e26caadf4231b13cef400515b34eaef2dbae926f31d8e72a0d855b0084f76f88a1161fde534c6c82861c3143d50b66966da12fd9039c25c81a03d07a6f6c8c2767963082f5026ca9ae2659e1352b9222415a4ffa09049c01bf0a0919423863a887d5f7ed8b39402e2e84ce6c2e745aa85118a1edbb290b6b0db4780b90214f90211a00b41d5afb16214af7b1ddfadb508e0f63a388246a105aef03229132558f483dea0af8af73aa85164d315ebd0c31cd50827458b4441a8a097cea9507206b25b9c26a053a91d571c96ed64793a0d59623c38822021f33a4e5acc1b941416a571473ff6a0fdec61509489f18c512e30c41a126882a4570fbbe44c79621e9a9ea660d827fba034f540fbb4ac1f0b24b1619a14635bf967e0b144be78d692146dcde97aae94f7a00a60a42d00e5ac9dbab2fce9fa8c78dc003890f00a5e6afbf6f26d65a479c36ca070c18b911d83e6f38e6eaa836da5fa522bcd90e8b68060add3720bf14024ab3ea0123df763066619f47ef51f3e3608fa44bd914a7fe6216465debdc2f0986013cda03d157151108823d105f53944687a2c39710d9b96e53fe310194487f5d1f9eb5da0cec5357d9fa43f7ca18d4cceafb3e0d92c6ac20cd703dae2025c32ae18478dd6a08f06c82367c80a13199cd2eddf23310aaf5b6081e336266fcdf9ed6354760bb5a042668160ae1ab6959e3f0a46f57ad7f00cf6657b57b5f0f41599cde0e0f389fda05f7eab4796a628e76eaa801e52df9fda818c0d81ad14b798078dfd555e4bfa6da0d61f0db3a17af1c71adb48669df81d25db65b00697f369e0813de10171f36895a0fb36d289fdee7baebbc3b5596fae9ae476a1b414e76c073935f48c7b8deea275a039ed6c119e80f3875ca871ffcd5636e6ce724fe589406a19621203df0cd4cb7380b90214f90211a08908d5e89b4640312cd64a4eb87248913fbe1f26e49382395987e3f6cea9d6b8a099a6f802a7ae93e5f0df1c7336bc3c8937356a145e092847d66ee3ac04576c54a06aecd1685f45bbca2fc5d3461f35f9f2445591bfa8e15d427ea191b5e9279042a0c25fa1eb423c0b7a37e27a041b4b94fac1f8555ac5c990c5960068faa6890f10a09e166c64fdf59312dc8e48703f50bd3692c015672ebac999411b2e24609702d2a0c801b19a8a14793b13dc965bee6974f76e19cbbcc9c284a5c18942024d72007ba0d942d4f3d0e6fbd8ab4e4023cc859930770b83612abaf882c800497bb9888f0ea0e8c55c1c9c40b91f43505583cae8a24433dc9feb761a1fdd2bf08da425795c40a01ca247acb1220ac21e3d1c7fc0e58fc712d8ca4b1bf92eec61ee54ae7b2768a1a0ca9fc225ab287b3c933ace8d7ec61fc6057ad3da9e376d11fec4a3b487ab834ca0c35b9a36a9d92203a7ff072180e42016c0a43fac76a8359fddb7d1acd3a82410a08d4825dc6384c985ac15351ca708360656048955b4edd4f78751f9c95c989615a07535b4ee7ea10d2363c8f35b8707cadf6ad4569a4f9b8a4b84c932b12a634302a0ead9036fe19f7a41ccb61fc3703f83b004d3d86a70a7d411372ebe8ef2ec7716a0d961b36b707a9e49005235da861a42ab9b9ef050a02d8f9f719a3e666a2c9533a0f68077409b4bf66edc984bc4e5f0aaae064c717c1a67078748aa0e2aa7d7949a80b8f3f8f1a058fe9546c8d95f2070ea20f2bc659c0c42bf4d7446cb7a293920c00908f5c60480a08f11bbc9906bb7fe2dd3c36c730d164f1d5e86b22f247996779be82e798a6ef580808080a044ae66b5b5e09b2618b4843dbed149c550bea6756b290c95e08705573119fb2c80808080a0ab3e7d7c62b2d9c7e53bec13fd852871db745e6997a9cc98fa66c00204ca4f46a07e326687c14d845ea749e139a3b8b785b3300f9c4ca504d8ec01224653ca4fc1a0bf387fd29a23bad4748efeb85db3b9d3a4b8377e6e08ed4ad511856461a3e3d7a03766aaaee720e7e7772d0bb9603a2eaf24396e0fe92d0a01df710583f7556e0a80a1e09e2016c6466979a354f27596aacf80919522b6bbcac5fec45f0a109b1e04d001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0384db79e3ce3706cd387bcd37fd835b5952cbfe8a2c4f4877808e679396c777fa07f5102578405b9d9b3f739b6ea11bbebfc7ed0f1a754d89e2fd171f20aeb16d9b90e5302f90e4f83028c608303764e090b8308b1ce94167008000000000000000000000000000000000180b90de4013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c4d00000000000000000000000068cce8ea83895b7b186750bb1f4925543b399c2a00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c6000000000000000000000000068cce8ea83895b7b186750bb1f4925543b399c2a00000000000000000000000068cce8ea83895b7b186750bb1f4925543b399c2a00000000000000000000000068cce8ea83895b7b186750bb1f4925543b399c2a00000000000000000000000000000000000000000000000000b8bdb9785200000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000acdf90acab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a00156302129b8b2128058bd57c4d20fde05eac8b14217362170e803fdc1bff321a0bc3f997544806fe9726bd5e8a1c556beb7ff50cfbd6956660be503a731638c4fa04d824b90a2c51dabda4863e724b45456b03e1bf124ccc5148d9b57b06c78c0c2a0f3b8673c0233a5837923bef328d5ad5b7073af27bdfbeb995d1f6706558a013ea04a2b351040e1b0b69899b816af4b34057619c1169f2897090964d8565555e2b7a01de6d617c0c37a8b4765baadb0ab2fe0773be074a020adf484b455d0450aa716a0d2f1f3d7a0ed0b1cc8c0945f342a131a5a165b45d7fe7878aa905dc120b9391ea0494a0598a97449321e6ff2a224b3ea54708de90bc91ccd7544e5c9967bd008faa07685abb4deca330b5fcff29a6b0d54cae4170c8a63fd17df0412aebcc944974ca0f63ab5119619637ae348c438736d542593643fd8978bd3f81619c0bcf5286139a0d410960c102d734c8e0225f7252782079af3bd366f1693e035bed2dcd07f4a65a004e94539df570223adfe1dc49076b8ce3fef2a61ca7af82049947d1058373342a0e4bdaa21944458dd7dbc063ce8f944782ffd95e9a8c581ab31ae3b9e28356013a0c061697fdbe9c8a88a87394571fb1be624584ef878985f90c2b0037df06a2f4ca0a17e876cea8ae4bffc5e36ae9434b4b437c4aec63fa932336ad23fd53965d06ca05b6db5e7b44eb456982482740ed51618ad6cffd608ea3063ee443663b698153380b90214f90211a067c031a064bfeeae9ce070070b1be87848f05c9a147273f40382d4911ea68dfba038eb52ac46eb4e08c5df11142cf6512002b4c978960bc27ba45901368c8f65e6a0ebb65703cd39c59d1635583ad447cd07e65c158dfa51f1a7ede650bbdb2e4c30a0741ef04d415e0c33cde428f53580d3d6dbe31906fed5808b5d427fe8a66560f0a0f5b299738d2cc990c02514ae2c157650df70e611c88e54c70add8e097530a26fa0b5cce402a10b454eeb4b917866962bc7aefa1417bca18c019ceee386a8fb23d6a0389c1d06a32f61f98d6fdbc12ce43bbc94bb4a819cb6779f189a8fd0537b1956a0a39db780f48db9f7129189ce9774412254f01bebea762da28d15bf156fc0796ba036f7023d32a5143932aa9e02622d05895cf2ad89032ba61d3375bc76b60a9143a06885e2a4b675e817d4415a9863cfc50398c5ff9a9470d4ffd4013737fd002fa4a09b62ee14e3660223941a9d8574f7c92fcb6ddbc154325a20697880df841cdabfa0e661fd0e47f64affd9da2de9af7be541a7bd5801361a3d481be52f7a5847c89ca0f591e1c2e1cd35d179b3cb41c48e0555e1068b192e96625802aa7681bfb183c1a093c8ae55e50439c11a06cf86f13a4186b1d2ac52e25d8bd45bd2cf783e48feb7a0b7766897081f63b04c2445fcd4a02d485c375be04a9e9ffe7c8d04bc09e7befda0207c546d13ee4358d6afc17d570f22b1f23e4355b72cbc64db095aff91830f7480b90214f90211a0ad2d55602df52e4c622d33cc8d809729dc04399b2b0d0d75b472dfb13fcb63d4a01e6429ae20fc27f32d2451106ad2f9296ac2e64d7f547b5893cc0ed33ccd471ba01cc8210f1f96a3db9138e3883525249e0afdc47f81f7184a2ddf5fef0cacb87ca0976c225ce9db5ab15dcda6fdcf560a17e62e3f8c9866b2a4b046908ef4bf748ea0a52dbbf34e665c793a522df4ba87980ca1fd0b3f598ed0039a12f2d75e5cc24fa0541842fc4c502c748b755c450d2150a11853605e43348a9d6d7eb5ff459d1c68a02aea4403966825e06e26367ded8a09433e53fd6437ecb6343180480890000368a08bfe94c00eedfd6ffafb623800953376645fba4a5b415bfcdd345bb13d3acf6aa0fe690bd1ebc994f1eb8c0f33b75db931b2cc3ae74b9e05e5c07f56deebfbae72a0a5022625e5babcdab77e96d6b102c1e937b7f094e779c686c33aa0fce30be465a095539fd60edca38b77e4ee9af10129d851c3a6cbbd3a9dfd2b8c61ef4d4d0d14a06ec59ce03e9a9d72685c00ed618738d7f3a031c94304e76b5d60a388c35dfac7a0a2a3838178c5635a5fbe84132ab168085ddc4a72e859fa1471336a64ac8b92fda02314f86812a06939c51a4a571b08e52d3b293324064d4f1d02a9c0329987e235a0feaf6ae06a564fec42716e6f8a90399524587aa939c5ba55cf250d18443aa4c0a0878b2026445a0b831be45b910ad8dfc0ad6aa898111f7abb2086e98a559e98b280b901b4f901b180a0a30783e5035c08ee27834f60d51cfd13ab919edee18032e9d0b74bb06132ffbda09ba8bfcf928c208d213a3a15b28ba963d5f9f83a978fe975290532c2a1b3f89ca0d6e4d2e9c878556af0fe3a662438c306d699cd3f1944fff19f03f09b296904fca0232154930a274dec485d9f48dbc1f637fe07973dd69089d5f7318f9afb5122e180a0e84b78aad39b045f949ec0641d2fa547cb19b22708122efbcc9a6c418e79981aa05d1e81253dd39614265f4c40ddb13392ae1a6d8d6b5dbaa87598f8451e02c478a0c4e6152b00962a6b753a0c3ab27571b2023507609aba6f08913a2dcc0a9c5112a0ff95419d48376526e78c1f9ea07f297bc5c73fe8b39409a9971e8e1f93ed8a37a0fca1cc171dac4b8628c7f94e37f41f4c31452d5ad19390348b296f1fd4b1a38ca002d5d4d31e8573431974c425e58cfa0d3f06b3e8961b51ba4ed289655ea932cfa057b5dc5ad7a43f166c21d270d16bad82d450227f20a1fd32b16fbfc53b188e6080a047e07ac896963ea12b2f75d5b7292541da4b5f98c21a9140da246fa1edca6151a050a4840fd85bb9a6296fd4939831db148bd14e2521332a19e1bf58393f2632fa80b893f8918080a0ff2940ecfb600d648440f196c0ae8f2f077fe894f6f3b5c627b23988033d9a93808080a00405a498ae7e6518f4760bdb7e8d53e3b3caf38f88e6e00e593971ad442275988080a04c6a464c133406a1f5220d54bd758aa3e781f0a73993417b9291c4eae626e6efa08b1f78c9cd9d4259390c6f2f092edb433ce7a42c6a8c5b6f7fa4d98034a8a7c9808080808080a1e09e201ae7bb82c704d119841df7acc20a111d20d34f73d28200e9e2d490bced01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0704168a97e3e721bb287fba11163158978b9c94d864b2b5be70036fc77dec455a018d9294ab80d67aaebd5de526dd7465875b56486f49a64049bd6b2a7c78649abb90f1302f90f0f83028c60830379c2090b830931b294167008000000000000000000000000000000000180b90ea4013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c7b0000000000000000000000006beffae75bce5b0490a0575e40ff0465dd5faa7500000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000006beffae75bce5b0490a0575e40ff0465dd5faa750000000000000000000000006beffae75bce5b0490a0575e40ff0465dd5faa750000000000000000000000006beffae75bce5b0490a0575e40ff0465dd5faa7500000000000000000000000000000000000000000000000000753d533d9680000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000b81f90b7eb90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0cd7efb2e1c779f5aec6f3429aa6ac5a2fc4470e67aa3297bbacdd366715c13e9a0726969581ad486eb7171717a9e12e3f274d17805c0d178e221a65f2ea9f67fb9a0b4cbe975d29a2881349fcaa7f45f9856c001f4f0880f449dc34ce985b6d0b4e0a01b9de20e1f77748d5075f6c3a4d997703d94a607d361e61ee13dceb440b82cd6a02b2b6ba29387b9cd9eeb727702da93a26657fff4eb328198e64fc09698452b5fa03e8436c2b4dc4f4d3d84abc958b66fbf328ff86fa76486f0c297b6e9972acfdea0aef69b93460621f8425440d5901dfeb9497bc8e113805ba3ee919644ac17d339a0c7e575bc91d7bd283498a43d4d0f5ea94ad434b30fc676ffa166499d094b8d44a078d19a09f67cf290c4eaa97bcc78ecb94b7354711dc675098c97c2ac05a573b8a0bc41c56bf50b02e0697206b88b1613661ff3d506f5e426e8d8a2be09617218cba05088b830c222a2b359cc173cea5dbc328a44b6321ada5acc7881e4d277c92ccda09bf9ecf20e5eb1789a7096c617f922e47836374b65311343ec995739de906942a050687457258fe081c4e40927b51218cb703b48349dd84465ddbdda971f7dfd57a080ffeb9190772039a3f5eef2b54cc2131e5da0f9ce39649d8025ca1d3fffc6a4a0e84025ba476e04d9f463a1a8644f01636cecc60033a35173dbb9a755695859eca0d61a3454029846824b1a17bfff62ccb968eace833c4bfbe3246c23f9f6a9d85580b90214f90211a032aae4c2a8aeca50af0ac967968587e8c4d2803022875c9ad232bd21e8214fbda0ae14cd74f5131da50e64208ffc5671c5a18a9f107093d8f8436ca5094686bd3aa0a4cf5e3c468b2dc30e709de771b0c274086c67b54837753e390182af8308c3fca0e30f79f3c2ca06bd0374dfd17849a447795c6ccb21b154e2fda00a83adfb63eba00593c5d0c384f50050753c1421d13bcb8617c29db585182b88338e32fcc9bbe3a05f078bcbf1430af57b6b36aff8b9dde2a5d986ef4c1fcaa9caf0ae1abfc97c49a02c0bfd61043a9bf4fa4c32c39094a4055da16b672f037e61debbfac5ee863ebca0ade63bcac150561311882bc6025df8c9a112c578f185611bc161f1b87b282ff3a051146a035db1f0ff17e9f978ebc033ccdc7ba405102e52af61a55c15c0d6cf2ca02b6868da2f0de68a2d424057448b712df5687083c777d964c12a8b5d39f715b0a0854bd5adbaaf1f6277051b5f260149dcf5a8b79bde9b69d18ae322fedc3d354fa0d3f9ab3556e63bf7825cb349093de050436c67f1708fc1950c0e795ecafc0e9da08fbe7a1be8ba030b5f69999a6a9ce44ebdf3c878285f75bc80ec13aee629f177a0a6cd1a5b68488ecd09c7c9228da048d9775783bdf031c5ec6dadf3cc8832eacba0a7be09ba9b3f9a35e6d565580a744ae8e86121e4b80f5e670a51ad3949e246cba000ad662c1805fbadce4660271ac773c35feee2007508edbbf2d244b082bb49a980b90214f90211a00b613a9b1d38668173ddef7ec0d714fe5747f6d9e2ef2d732bbaee4ab6bfcefca0d1f4c6892a277adda1ce287f5fe56e48fd67a7489760b85d36ad82607924cee4a07ccdc92b0890d93f6d5442578d73455b13cd4c7cd948175de6357f7496bc5062a0802cb96efd18fa40646bf958739e6d9515d27b0018b39bbb21fca87cdb3ea1faa02d06f1a328c028b3cebd6186fbda896f49c53ba3985ed33bbd0bfbed583125a8a0a85303ee62e6a4aa4c05988ad5b9685553a13d6bcd465b20c8b1e11abb7cc2aca099ab5e8eb8c24416c45da7dbec491578cb0be8325c8984e38ce6ecca82952b46a0f2a112eaeedc193e890a72039801e3ddc337cc344fe32d1b44473eb32f1811f6a038740234dd854829c62bc58ccb22cffa77dd8fc785ae900ac4fee16fdb573906a061ce52c75ccfda5f8d7313e20fbb20c39edc801734a00e0031ba73ec7afed174a075389e5f5ed4b0cfb92143ba693c9fc8e567a5313ce9a649a89f3f284b1b5a8aa09877890fcca9c72c6bbb6cf06c030419d137e6b04b5d231d5c2ce026f7c5a77fa0b152392e86a82e2277927031c98e6ce75331a124f3f58fc3a6b8879ecdc84dcda0eeac235108cab5ae1f362c9bc0295273560c977252876e350a9c67dc7e3866bda0e16d4ec97329c261a32476027bb0e0365cccd5ee6f8a4aa559e0ca48d873a9e3a030eb8e7ba17f3a104e9cf6990a492b0a1eed52b7fbfad17324ef49db027c4e9a80b901b4f901b1a0b48f98679c6f33e2c40e2f94a452296381f63a4538a22016c7e89dbbf0aebee1a007155bdda5b2658cc71b1cfe32fd08a8a9b12ebd32703702c79c817de09fa263a0adfb064371035c7b1d74dcb84346a4a945c01ca7f083f6308819facf78ee9743a0585852aa25e299f3ebdab8e170e24662480a902ac58993c478d2550064073498a0a45d5c2646fde8b84d897bb4ff4dfd9120a37fd23487565842d08d1c0726dd90a0f4cd78a3fd27d0ad415bf3d09b649ff1c0e558cdfb1618fd4a5253a07d456b1ba0f3940dae74bf85b8df27f936921a216490bcbecfb1b4fd6d6d58a5d74dca8fb9a0c7a1d40fe51860962f53c4c7362f676a3c3e93a0881a5791288cb6bfefd1cd5980a092275b37af02d2fc7f54ba6359234d4be7606d5f9717d8148fa1b64f29819ed880a09ae30078cd9df28a30c5f897ecaff22a8d733b3ac628e64d3f244f748b4ae47280a0297878b3fa098c5d20b97f9641bc248d0f0ed45b6c1b551d3943a1602dbcb38fa06ce19f9c4c659cb08cdad8a7da64ce5d3f76d0e6e1bc38b3fd71bbc6a08d51a1a003f79543f6abf18a741ca32135a73a5d7662b1a97c97b1904a9155cd51ff0e1780b8f3f8f1a0ad74c720acbf8ad6c39ef19623811b60f07a8d340660a92203e56daa6af95acea0503c129edaebeabe444375f9fee9cf635a14725af5a1ee0c4edb074de40e58dea0eab9c12dfab10034cd229b31d615e2c04a431496bd86c41332d79cde061f844aa0e321852c4cd007feb6d20a50a95785c340b9d0424374191f5115e9aa446dab1aa0dd744581895d09d6b8f20079679a990bef1221b4bee8eded67adcf6ca0f3e71c808080808080808080a024b9f14a46f4834432dd643d826e79ce9fda6587d88fdf6810c5f3c7064d5f0ea0c508a76cc7175075198476741c014f39dade3bbc7e711dc7dcc93c89e293f3fc80b853f85180808080a0d5180261f287584fcaeba14c33e8b648f74bb17c44a817814f95f9d17d44ee5f808080808080808080a0e1c1083891f14e944a75aef37d444026edc8aedc9a5c23d5c261337c8d6826048080a0df9d30dcd3f92d4d75abe6a685b96f7286a5193757b794fa441c38071f3e4d01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0e3dd61c03663f79710067655703e46fef8cdebdaf344c8f8b963cba2a6170158a017d823f4cf576763681cb7507063f458c6605da46a62e9179deaae1e327a949ab90ed302f90ecf83028c6083033829090b8308bba394167008000000000000000000000000000000000180b90e64013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c52000000000000000000000000b6d9aee1e255e496069ba195fe2b93be03a3137b00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000b6d9aee1e255e496069ba195fe2b93be03a3137b000000000000000000000000b6d9aee1e255e496069ba195fe2b93be03a3137b000000000000000000000000b6d9aee1e255e496069ba195fe2b93be03a3137b000000000000000000000000000000000000000000000000007cb343979dc0000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000b4df90b4ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0aa98cec5fabbebaf8cf36c4a6131dba73a3d7e70abe497f44ada7136cc89fcaba0a73a5ad7525521da700db0c93dad1f6bfc42c08507f0f9ab0275d45b7a47c134a05f78bb5941f675c0627068e84763b8ddb92aa924030b9a3b7daecdfd0c515db7a01437bca6e794d3792e0884ab3980ba45bc4a8ff053edd93f450326c0932352a0a015ba54506ba9287dd95e6c638901d4e65e31b143aefae47819130c0b65573c54a07c15b5009c87e335b6ebf5a5012d4542088ccc8e4e646f8d84e9191d9c144caca07e301d8e0adb7eaba07d9e403b5c48560afb1f9767a03ffba668d2e0dd834db7a0b479dadde5e73e8cfc1cc2984272da73bf25c959cac75f04b2fa48dbdbcd4f41a03e1fa45ab477d5a2d96eb0f7defb8540918cfe690a91c28fda42b7ba0a09c685a01c0feaa8252c4c569a30d89a09684ff1c25bdffe383631027ef41d031541fa59a091d5259c91ab6c5e1fc57eff3e269bf64d6358a851869377e00307ab3716ba47a03cc119feb7412854581e31796a1bff14744cdf3fb6fa31057461012f91fe8d9da042bb2b5ded56789365e7f50847403dddc040cd252e2d0265c2750248ebb449aaa0410f1ed125c772539fbf73a801205e4c48b4b08ac4c6cf4ab521bd10dc63c2faa0c20b046606b0fe10dfe094824ce95c58079a9bacc5fa15261fdcab610416a2d9a0a4010b0079fd746a9a67f720f6d4b1b28e685313f2046fe29b8f0b7475c7edc580b90214f90211a03c9dce09f13522dd50ada02e01953819f89f3320ef683d3551f7a71dcc09913aa04518f37692bccf81018f3b1d8ef4221d44afc6ee27a9b2e124f8b9cbe2164d67a07992225d9efefc7140be5be113b90e983e5325356ee8fb1a42d9f15fbc42e91ba08b9f9ac01238d95745d77950f081b61b6270eb7aafa44c4b907c71539a57cb67a035afdd7c0ef4b1d197dc060bec284454455f19086e5ba962e4628b12a2f7087ea05f280acba916463083a2cc1ca9dd3c37a0c04f3903810449991999ed3b79500da0e62b0c17e656107203d6cce694b0bbf63f24c73fe1a88366f6f0e262fc34ffeca0575e1ef82f560fec66caccf4bc37d1523a4a1ca614685bbdf50007922ef45e11a035e1185e3622179bca66df8627153ed8589cab3951d378ab2d15843c1eb2ef13a032a1b5c12ecceeaa5e2d988995b98e1a1049df2279309139afbe957f16c5309aa02cf40eac9de9fdb21828f067343dbe6e62c810350733ad55a72afeda14894324a03a5bd4fcd4f2d3c2387b6d61ba91974c11f70bb5395881c46a6de890f7a7f733a0ef91f0de3bd5b18db77ea8da13798887b85a0c563287ca2d9d5258216138a0d6a0bbc8c6918158e3f7d90a03f651f28831914577992fb68b7ec6563f6e20884473a0e3afca284197cb01ae681752849df6afde2a2b0d79dbb26eb28556be0f398b26a0a459fe79dd02f10712a0cb0830e546ba320623ec9036dcc34ca2c7a0e529954f80b90214f90211a0a1e5866427e272dc9c5e26d091e8eb10c57701d23f7c7705fb13ebb2fb472523a014242efb988faa2c0e816094adf56458c778c6b930010fe57f83db0f96e9541da0bd8c63cb12ee44d3de06d7242be5b538aaaed4bae2b8eec6db0b8fa6f7de1ea8a0a007f9c40ac2b3e8f3f6e5e84876d360e553a61293b19fcab8485e60d13886e9a0991351dceec08db96e7cc15ff88926ba10c194756137999c2aa274b9d162c014a0e5383e83b61c228b4b712edc4c35b0f61db0250c1c688bc98ea735aeb2388799a05233b026135399b04412c993e63c9326218497d3c8cd4d5c9d23c4f409768dc0a014972f552828a088d63722b4a276c3ddf3340d1fc943065ec0f6171e1dc7659ca076e484e083f3478698a4d55e691a0dee2bc42f45d1ea27f9738c5fe49f552239a0d6365e4bcab9ee5700242822917d119af5ab222af1a5d742a8b914a7260e8f43a0f79fb2254578f6c4375895dea183982c8708245d390faa13e4e68ff46c64e902a03e93dacfb1f9f0b537473eefaeb9e9be3a5c00acb4d3d72bbcefeb6f1e95f862a007b7c73f04441db3ffc04ddcededb92200fc709d075fa854007127a3e62dee55a0c465a97574b01a2afbdd2633d102e1a1a8f3c9a0abc81bce898cea9eab39a55aa009d7f3dff693109e5e7a19f11823b598af67915286d1347ed97d11a20100a6d5a051be650b4d845a5b96f8045688acb1407caf2c92b34b8352655646cd3d8b1c3480b901f4f901f1a0730ef6a2f0bdb197fa4cec4f0d86a4faaa2102320ef42afbadf32464ecc4b1dca0a7a6d6a1450fb494418198cd6354201eca547de768f6644914121a403e6d8fdaa00c13aae2b79a32e0c96240886666a0831fc6ef7c9695491c4062448743da6921a0dbd9b616dba49a75a84457b52e5b1a46c030a6ef3c0cc8b869e0acac55b7d6bba06f572b8d2f27cc15fb26c972f1c041965db8cf13637ebc30f538fbb44be9e531a0aa98aed63b08cc2cf2fe403671396c023f2009dfb75d79c1543967d69bac34aaa00b493c3da3d99e4042befe6ee2c630de0eae7453862a9bcd991a38a9293a2602a0e971d5bfbf5c1bf36331a78108c878297d17356809c7a7975b98ce668004203f80a0814e9faf20b0b6455dd9972962c58c0429d5643556c632413fe9b98ba336c1b9a0bdc159ca453987dcd3bfe0d8c752ee03a83cd5cc562d973d6d4c469b5d12416aa053147e7eb896b57f57ea800de6856a4945123d244aacce1b48f001927b5eb67da09c285696117beb052bc695926f47fc000bdf725195eb2a840125caac7c6c50ffa0f04efa77378e42c40ce6c76022dddd71790a2961853e92703058a74de5bf05eaa00a6592fa6f060f2ad4adbb864fb32f0c59824e4d07ac35adcf15f6bdfceec3e0a0b4c3e7cbff2963aa93041d0b35baf68aaf2dcaef892f4bd095a5e5f1333950dc80b8d3f8d18080a0cbe63132e5d1713c14b2217eb441b4d74e18131a6822c9b6b46a65826e10814e808080a02813318e26555eae0de7cb67132909bb7c1b8af92d464a566c489cac63c188b2a092a4b18d7bd02d9bdb965dde6d57ac1265b12cb5602ad2bcf56d1fb82f4352718080a09609fc4fce0a8210b6377fc9359d7d1164b90bf82b5bebd5892d72be6d2806f8a00a09285d9519647f08b3ba8a916a790834f6d38608e8b03ad80d67fec65580d9a0758abfd4c9c821a7faf4b1fc14f7cae67c175654fa73acc5b37798db0c17a35b80808080a1e09e206a74764b3d18b6f1607ed88be6840f2537fc0d3f1bfc99c13594426e2401000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a09b8260d46059fd0e70f91ddd452c58e473e70d4b730f4cb4d6f8489eee9a1b4ba055198bdced0d9abeb1edf8a59fc159dd18b231415c784b66016914fd9c785e8eb90ed302f90ecf83028c60830376f5090b8308bbc894167008000000000000000000000000000000000180b90e64013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c50000000000000000000000000cee9686eab1489f5385291aca94b7cc5468b83ac00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000cee9686eab1489f5385291aca94b7cc5468b83ac000000000000000000000000cee9686eab1489f5385291aca94b7cc5468b83ac000000000000000000000000cee9686eab1489f5385291aca94b7cc5468b83ac0000000000000000000000000000000000000000000000000066ac659a0240000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000b4df90b4ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a075a15dac85825db006746d8d89f89d1ee5a7ad77ae36fa3cebf7657d03f73bdca0bab252bfbcf9c800f50ba4e6bd8c3a5d49737ecc3791f12beb9c22f3091948bfa03e0ef6777ad6e9540778460020b008b43532260a1822d2e588c5952818ffa934a0e0685596d8f0b0265729b63f59c8b1fe9d0a9a07233319ffdb0cdcfca884f28ba0bb1313b7b1c0227e282d9e0b4c6c9aeab74cf3b63b7d6d37dd40fc309dfc5330a089f29221cc392487f90dca69a1fd0d133698e035214ce262e3321585b89fa145a0251c251705d4d4df77ec07b8c50dcc298384b607ed89c679bfe5d3e1abd0aa61a04c9daf84304d24c4702c9b628bbaf23757b00d99fbb344b419f3cf24d079f54da0ad82d13435c18c5cc3b903046cd7539818db9f0c93e33190178b7f2a30dad6dca0d534d45ee651c67f6af178fd59d0b3bcc08dcca0e81dbc27df1c57dcb828ad38a0fffe77bd96a94d4073f82e7c450be16257a5155f738e6553e9f2631eba32cacba0af06e1d03609a8bd3a4cc734c203bc263bde89de488fef23c50c53749ceaff5aa02cb562fd6bd691762de0477eeedaf283a8d8bfb831bf68509aba310fd3fa2bd3a09bd021e9c266e1013a07f2e69176eda41a425b8382b6bbffb2f7c3efb6bc8d09a012bb07e99a39555733c79d2338910d473d5b539cccb32f1335228c37a5fb05d0a052903fd8c05abb315645e2a78375db0257eeaafa1c398957c19130523a66858f80b90214f90211a02ba1899b2694a86322d3861f7c1cbb67250125de475a2de60fd164abe18041ffa0adba6ea113803c7b46b76b264ec0263d7aea06ddc822acac19c66693b33a5f0ba01573bd8457a0227f43010d22b9ef39113b30b12b3de58827c1a7c970f60bf7d0a02b443bc48370eac1d4b10e3de18a46960bfaf5051bfb961d6826bdc83a6d409da059d7cee3097b6dd2b65c99ac1e21387dc85f72f0e594860da145feb0cb4d5697a048a1e8326c0f59f0dec0e37afecfe506f99a67c2792d63e47f65e306d0e899b5a0d5e77c721d8ae0155cb5288e32ff679d28d5ea04fd7e3c556d061cc041cf957da0dea8389ccae61a6d335892e787d89021667330f6c1cc17a80cdeba441bd02125a0b8c360be803abe441fb94a0e9c3ab0766c7f62c7f666f394bcd9d2d1f3d009fba0aa7269a55aceead530844848864825899fdff3b882ec28da6e7808ded1a8cc40a037cb1d9bb635160c03685f8c2fafd1915c32927b2d409f31cb1bb926825b1e09a03e85c61c47bc2b16fc2367db03b3c359fc251236a79e74d36e85d3c9b3a318a3a04eb719ccb262de8a7cd7e8d67f7fce632b7e063341b32876215192ce7472e825a0d01df205e333cfe64d091cb140780babb7e9a9bf576af8a6de208e4db1969358a03de16129d4c0f71cc849faa964a7e4bea580c65edec9eb1faf30f87234373d97a094af24fa29d9172417073c428c087ec3596b70d6c6c3a00231a09bee751fea8280b90214f90211a0a2df03dfa32677c157a275ab21c9ada08b26a90f8905b7fbd5212bcc646f8aa4a0b2998b9afe5725e427d01f62e5f3c7f393fa25ad605b39a07a2f44345d232ef6a0d89df5d6048d3b09355b20ec63332f3ca6f11f44dcdbc2d136cff4deeefa9e38a0af443109d6a362d1ed25c173f4b1420ce2e9847d92a108f7cc431a1327d037a6a0abb0b016d3ab6aab971c398f9bf51333056453f37891a568e7b1911e19448154a0f355946caf6850d4c2515f32614e2ce2cd0268e8a3856269df49345f45428663a09c6693ac4371c5c0bcd2685cb40c201e0e2332bb96fdc818aad782ec7016f7b5a0760c5c08ba7284984a44cdedf2422f733df0a9da2b13eeeeb63e89c1555ea7bba09a74f1c8836fb6d101d59ad3d48889f507b311fc6efda26eec43af05518788f9a0afd7563ea3bd7074d33d9840004ac26671c3c182e106368a4ed81fc2366b3c5aa0ada106ed81536499319c0757634dabea03d42503dabcba402d8269acb7d2f6c1a06b8e6f19dc9c34b4d0dd71d97229b80ce1eb146bffaff28fa15604328e9c3992a04a1a28d2808c998bd049ece9dd25fbbbc08af10b8ee14a80796c2e09224b4d6fa02f3b49a740f498d839ff7e0ea83dacdff93d648566aa7d772bf8bcb071cdffa0a0968f71436c8f679b22d186734b9184998a4f9a5292bf64bc68af53c7960d522ea0f60b2061745c13e09ae447a7ea451d130fc236eb19be7f2da7ff4faaa03192f980b901f4f901f1a0e53515cdb7a7d15ff5c119bc51ce5f2a3998ca028a257788bedd0be7c727e290a0d1a4c0031813ed291e67a827c746522cb6f9fb4b71e1b81bf7b866f3c6771429a07a7c201e45f6d2da8eb0ac6ae35da929c68cb35aa28824b851186478d24410c5a0ff2b7aa0e2dc9c3c53f5df1af06c3fe53c9ba2a8c91dc4657f04b2df5a264000a0b40fc32c5e595d3070ba287588bb6e88ae264d472611b38ce79dccfa00f1d897a0ce29fb8044c263f1d18e87706bbae17f5dbf6451055ee443d83a9fe191eb14d8a04b9171715f33714f09e7ccfa9eef341ef4b3c3a8b74c5973d868aa1c2e10ab32a02c9eed13fe4d8ea71f1b2b355ababc946940c694bf17a0ccae3ec78d2a847d15a0a7b682bc4fdfd0751fa418c16e684af92e37016faba80625f3dcbd8bc1ed1261a0f77b5a613ea1c14363810b47cf41918fb54d827b6d9277a216a52c87f390ddb0a007743b9dc899643da48fd364fa60ec4a03b0965c4dda5d974da15a0c40796e88a0e8ed68c191388f13ea5f42052b0d28f77670fe0c7ca6e564ce67e4460148f90ba01dba784bdc3e89e3ea316621ba5e61ea265b2c8453b1b25b029648ae645ada45a0475af21bea9913fcd3749831a359ccd7a3b459bdf760d67827a5128dcf25872980a07c56ab7331eceed44c797b14bee99025256a7f7bfa6db6a87a3dbb0f7af9930680b8d3f8d1a0da6a2050a1c8e0fa18fbf0c433019520356add77b1ef184afef93032e0b4629d80808080a05c745acabdc09dadfd2be34be93f40aa391509e3428d7e10260fbf6b2fb3ea00a0d1e25168bb9801238b88a269624d83978c8c62054989a9415507e4717cf9208aa0ddb4090ed820dd24c46cf6152288986355161cefe22ae4a67dcd962fa8b9599aa0f9d2f0a760af978440b6bba8b84c3a467e2c4620358298406c1e552589aeb3c2a007638847a147744898aebb98ed6e015624f8de8b541860cb03e4876bd94b9ba680808080808080a1e09e209de365336a78bd1903bd836192692b918d8efce42c7f6d7d74370d1e7a01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0ce84cc99d39af84e6fbc3956b681987e668abbecd81f387d853b8036aa4d9278a038511a396c6d4c83b04adf3103c16bcdd9f757b12f03bce0089b6ec613d70901b90e7302f90e6f83028c608303779f090b8308b43e94167008000000000000000000000000000000000180b90e04013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c72000000000000000000000000f46cba6c5bc8091fb1ae0a2cb30c4972b740e33f00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000f46cba6c5bc8091fb1ae0a2cb30c4972b740e33f000000000000000000000000f46cba6c5bc8091fb1ae0a2cb30c4972b740e33f000000000000000000000000f46cba6c5bc8091fb1ae0a2cb30c4972b740e33f0000000000000000000000000000000000000000000000000080f6a85d58c0000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000aedf90aeab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a00156302129b8b2128058bd57c4d20fde05eac8b14217362170e803fdc1bff321a0bc3f997544806fe9726bd5e8a1c556beb7ff50cfbd6956660be503a731638c4fa04d824b90a2c51dabda4863e724b45456b03e1bf124ccc5148d9b57b06c78c0c2a0f3b8673c0233a5837923bef328d5ad5b7073af27bdfbeb995d1f6706558a013ea04a2b351040e1b0b69899b816af4b34057619c1169f2897090964d8565555e2b7a01de6d617c0c37a8b4765baadb0ab2fe0773be074a020adf484b455d0450aa716a0d2f1f3d7a0ed0b1cc8c0945f342a131a5a165b45d7fe7878aa905dc120b9391ea0494a0598a97449321e6ff2a224b3ea54708de90bc91ccd7544e5c9967bd008faa07685abb4deca330b5fcff29a6b0d54cae4170c8a63fd17df0412aebcc944974ca0f63ab5119619637ae348c438736d542593643fd8978bd3f81619c0bcf5286139a0d410960c102d734c8e0225f7252782079af3bd366f1693e035bed2dcd07f4a65a004e94539df570223adfe1dc49076b8ce3fef2a61ca7af82049947d1058373342a0e4bdaa21944458dd7dbc063ce8f944782ffd95e9a8c581ab31ae3b9e28356013a0c061697fdbe9c8a88a87394571fb1be624584ef878985f90c2b0037df06a2f4ca0a17e876cea8ae4bffc5e36ae9434b4b437c4aec63fa932336ad23fd53965d06ca05b6db5e7b44eb456982482740ed51618ad6cffd608ea3063ee443663b698153380b90214f90211a0224864f860bbca753b71e51a4144d1fd45d70d6d87bc04d65f82cbb315284fffa01f93c644d800ac573bb1106829e7584b9a763d80b47d01cf924f137866b1127ba05b11e9926b9b844a5be237ce828c67f0014c4b1d9127984face895d04cb4a395a041d54ca4c2274e5741e6c2e26e33c95a1d379a1e1d03ed2aee0a05c33bcb7e1aa08411c0acac23a476c8ea243f1fc2aa2cf3b29c2f38c19a3439bd7e2d16e00033a02c25fedf4912b5728fd67ff1e966029b669db361d1e2122597a7d40038d3fb66a01b2171e1b1ca4ec042a1533bcd3af8911e6d94f3f8344529212c8f1d7fe87274a09464ca49b3537b32d1aacb57f83e67aa1fd77b024e8766bbfc7f0138c50ffd00a0cc6b4ec83e52c57d1b5e3a00b870c5588e64693425511965271b4ea03d874bbda06591150a8e189a771002752582a43d86aefaaffa5aafe7b77d338eea08d0b114a04ea7e8abe3d2231800d3a6a7108deabc33f7a049f5bf0867f584a42056564a0aa0847a9eae1c43eed236ff661eb8ee6c46805ac5b5565e4c9faaeaac1bc98e5200a0f0ea0449bc703769a2ef27fbd8485f13eb9348251d6eee0e14a591afc1baf834a0174353aa4db57929b9b145551502373abd9ac34cc6de47a21b9f38511d8e94cea09801b883ad310c9ee1ee567263f54dc61745d19bdc5f38072bd5a138a00a3425a017785a551945081b9df7fdc67f003a73d9aba5782df9b7ee847c63d3efc01b3c80b90214f90211a0e4b4133e18a87e731dcdb259c3baba43e05d0962d61f3164d7cce4448182437ea0667e58f84986ec65d40f1db791d1f4c49cef42a92a018ca426446375188a632ea0f065e8f31580a596f32a7164bd218ef7aa7d49fb9551147215f562976ba399c2a011e63dda8ba69a6b717f4e9d1b4f6b73cc373956ec6c2482ef9ebfb46c81d71ca06ef6d23b1c6ae6f33e3681e9598390ab50cc23cbd11f3944863350052e78df7ca06b01a2c759cca2dafccb2dda9b0821596b3a60218c6ef85dec2e9b3b33a9d9e4a065af707c9bab80457191dba60bcc45436113c9035bf510b5e6a38822701fd06da0c07bc77241f3b7a7830465c91b82093256e56faf19c793fa366912d92a112426a0ea7465cde81ac1a3c749bb81f094b8e6c98bf61340959daf09488cb76c4b1263a07a210b4147d515cf2513e2f4312d26351f0aace473b604b947c968d03a77b362a04794cbbfdc5c7aff50eea1523ec0efe01357dc48bfd408c8291d2e8c9d194ddba052a74d28284310d306e7ce3965ec6893f7aa4f6229b5355991bff0ba807216aba022f90f98c67104a2b485145e0b23a784283659bc038d097192f2f7494acc4b52a0875c62d78727ddd248b3db8e50399c2b2ab45440b9b40fecebc16bd1c97b0ecca066e1977f9137a9be522a19a86a5fa570edc8e674496f255b364aae1b8fe0573ca05998263dd628dc4aabc4c54b202d4d2cb4e2e5310d9dd1c915a39875f683168580b901d4f901d1a0112458e9691662bfefaa0a82b4f53177980ef23fc351f57031873a776d312d83a0e9bbf2a4691a0e68c10ce41a86a4c2a2f1347bf7d773509daddb840386b285aaa0586127a6a56504b7310d47679d10afaaaa0918aea115aa907e32a902887eb6aba020b6be598e168aa3e0dc848a7ac16aaab9840ded7ba9a9c457bcb925293f1cfb80a0379afb4dc65afdb3ccc3ce5a689a129884da510fa980c9ca16430209ff0672dba0a4108c0390196531060fed4ea09e52da4c332be8f103ac8f6878f7bd48d1a70ca0e4101d14ebc19adfaf616f527274f7f54799e433377a7f31bd455e49cabab5d880a002643f938bb50cc85da0d1f478cfc8c9c142afcae720c63e9e3f84a56aea95bba099e6b7c64c2dae92d10973f0a633a4709ce0c0e2c698dad99997f92caf56b53fa00d21bab553d97cdd24116315309831109044d92284f026113fa79e70d7577cf4a0b8fa51a625af6d29a9b399068657c3a5c6cb64437a11c844edb7373246360927a0fda4e219df6962d78cc94dd07261815af9ad08637090a5244d73c5e9f789c3c2a0da9e98c0bdbdd5c47bea5573db14064f7c58bf6076368f4f7a425a9f787dcaa5a043f770b5950a122911bd428cb9ee96d7ee60a4c2e0fefa079c318f884473c5c480b893f8918080a03407c1d08142c0a87b5bc55c641f45a8d89a48097a98d7ac9356f2c952cdb41c80a0467d8caf6ddc42c6a37dea73178fee26d555d1360a5ddf153591c58be70ad2f5a08aafed8a67c168ca132467ed5db1d49226452a713341b3258547835f9adb409880808080a0dc8c42bd7dbadd2596614ee96fee964098419e1bdc2562e9f17b34e59779b081808080808080a1e09e20e471ab82fe8a41978d1a0bd2f86ae115ef63bbdf107cccf574e94b3a0801000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0e9acbb8a105e8f5c1304cee2d2a313e38d5572c210f73b19464248c5abb009aca01f86d2b46829befa7736d6f84457b13170a7af248a211fab9b8abacf8694ea91b90e7302f90e6f83028c6083033805090b8308b40e94167008000000000000000000000000000000000180b90e04013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c490000000000000000000000004b582685936576ff42418e42db348fba48df134b00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000004b582685936576ff42418e42db348fba48df134b0000000000000000000000004b582685936576ff42418e42db348fba48df134b0000000000000000000000004b582685936576ff42418e42db348fba48df134b00000000000000000000000000000000000000000000000000e6ed27d66680000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000aedf90aeab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a09591d235231196568d434755002a6d5947a58c34f77531a9c86ac3fc2b093b77a069368bbef45f706c2c14e5aa027146d788e6fac74f59b46bd407f0248bcd0d4fa068ef1adc0891f35bc2fae8495dc1c950c151c1ce108f66c0fc23b97f20c2da51a0daf7b9335c53a0deca87e98909726d8445cf30ee2c95e2181cbf77aae17de6c5a03c3b514e72a3414b9d17f87a7d268b2b838303ac2de439ae45d0619e7406d703a0e2429a5b6d7da0dbf2b99bfab3fa8355bf3a283a43a6571a99fa95f1e437cc6fa024eeed393b3dece2dd3f0356fcad84b9f9e8fce33388d4a7ba75f828dbed32b5a006ad72a9c5df7c3539f258997ddb6cf2c07902882ddc16f1b4bfd8d52025ea39a0305e5744210ff4e80529a039d3c91870e69568e232b27b3f259fdb2d005a0b64a05c92622b3d684e9bf0fa4d0ff90b02c6ea9ee44672efd63d5d2537eaf8fcf8cba0b22d9a89ad697c7436b6b13ca45f9c8548c6bae159fe7626c131cd0ddbb81a25a0a2b88ab0cd6572ed505973e66cc12cf5653c47e5b8d33118ff58a3d1e90c78fea0d1af0f2d79aa45f6a5f1667087ed0780ced415f5b31381ec705e28e5cc58d2eca01210e66bf57cebdcdc549dbabfaa3b99ea1ee57c14b9fe01ed5e8eb76c01d541a0dcb5547e96bb514cafd7fe53e31777553dd957628d7ef1bc267cdd6a532792a1a0bbc7f1181582829e3d8d3c4a7c9a1433c6ca19ead2a2cc720c0548cdcb9e726680b90214f90211a0681aa37dd84f16b3435dc2bac5767781f8f9b134f534e52ed247dadd49c65f01a00678b970600d15f3dbce07767005ba8e4679474b6193d7c0771a0f803162b89ba0cdd61147259cc5dde7a6abbf76b3aa65dd4e41f5f9ed96d42ad61b3e44008f2ba0382873d9854b69fdd6971b920fb7a053326b302742997eaec8e3c6d5046236f6a0112e0bed70b56e2786780986bc70ec0f1ad197be402990c8ddbcb3b2eec6274ba0183f59b690eecaf58a59962edb3743a03a7b00d5b5c562fa0968f58c0c6fadb0a0bbcb18819f4ff8ba0ea9a964a9d9c605662f3abc858a147a05c68a3a4b445328a06e4c0a9c9b53d1c4552568d6398325d84445b8fb9bea3a86b2875db3233b2972a08e068882c08db39636a66269ffb25116dc20e04bc333abc81206d12c95161b8ea09c38c34f7b8e0d56d3440d85b9f20ec505c4e3ba0d5681a4e252690dcc7369aea0b68d23fe6343c75af65ba11a2e32f722aa753a9f1029260d127e5490a1fcfa75a03807d10da6e24c8b6207b35ad0276bc2ba43a10ae80162df64dd6776ae24242aa05dfefc78a212bf43f85f7dd4861156e4aadb2d4be83549f0222ab46a44ed98e9a004466c64e16da2cf7d1b37f8940565131c989596bea2f7483d26da7e308f23efa058d7096abba5edf1fff1c395923a34821d0764891d55c3147029482fe240058ca00d481632d694dc2d848e33f01aa5bd64e412a53287a7b25f247091754802562c80b90214f90211a0f68c5e75e01bb86a276f18b719f7cb398fc1e4f5121c122635e7802a90d56571a000399b3bd20ad830fc1f1adc814f14aa1778bc72be78c3302c901f86b80ded7da0ebca265f791f2c9d686203ce81120c310cd9000a7ce7b95d94ed37f3a49d86ffa002668d45e97189dacf2b3ce33d751e441d6e57f190b45e31886c93c94e75afb9a0b0f476ec02bfb9cfdf64127fa08030a0d5a899a405959d40602dcb01ba51a4dba073a7149ebb6d9726849c1a2e3e5c3eed4738d9c5ac154d80a4c97bce29fced14a0e8f8b26df94097878e9a21afe3a7a1dcecfe43e1803d541a32315739ed3f3bc2a06b041c051109a6f6a455adc979cb8285903b4aa9e1207a9b99adc462ada50906a06812fa9e16f5449f2f8675458cc82d014b761a1a82284bd3c344c1f335b66525a07640aa203db1d7bfcb9809cc1ab7f00f3329a86394c6148f232ce8cfebae655da0e2e030c17c0556a2d801ff8f432c19186b2e337e6a8636465e45df2711009baaa08c56ce48c9cc7153313f03d3a43474236f52147df20a53a608983199e555b30ba0958b92eb536d2dcb9a5928aca8be58f82ea901f6267e691fb25fc67e32e33d6fa0fb88ff82d8cce71ee74d46850ff7042a862c2d77fca24adae338976db1fb14cba040d80cf12eb4ff642b5cd8f06fc05a43fe15fedc3363b0645bfb17215d9feccca05784517617924a5dea54abbdd26266e744b4158a9e10bee3c756ce997ea6e75d80b90214f90211a010a27f2ea774c221cd72eb18913b82b49d6c1fce5c458ae3a465ee4f8494274fa0d5df315fcffd0cdf521edf0b4012275bf4141ba038ca74681236ad683904082fa0ce9bf12f35ae4513f14ba0249ebbdd39da1e6ec50c320d5f309d2618d9957120a063276f44c740447f4bf70e8b0c374ebc585c7bd079f24da95a62b752df9467cda0011d84530050e4095f9b6ef275aa343d52bfa1d3f64e3f1c7d94fa1b05eb13f2a02576c567cc553145013b730740384f20fffa3728acc7c155068dbbb4ddcf1a98a015e5b7867326cb2a25a828a03b07a20f853617055e63651058e5ee40b8e3126da09d7c6a7ce99f1bc1d7fb72841ebc1d997b1c1cf97ea7ab4e9264c59b73a8ec7aa06e095a923b61e0a9a2ea0a4ebff6f126241a39499755fa9d03203f98614805f9a055ebfb6905bd920793c963d08b15e8683121fdf0054c45b6f4850ed89a62f772a0eb6b96efa19da3a8b35b86d8c4dc08cc906f1444614b4e3fe26055a9d341be4da0020449d40929546df70de8d86da5538b73fa269a7e2e739df484f988ed9b6cbda04fa0ee103ff5a86eacb31b200e308e4832309d018921ff3e268903642cdc24b1a03c7bf8bb30e50f5253d4106048b0fa58bc1dd5ecdbdeac42f5a6af8683095ba1a0e879621451697b8b8e7c8a62a55f4b3d0001d4f75f10976200cc1ee590bc6dcba04f83209fd75cacf2ef85aa1001b27ed74a4bb5bf520cb4a036ab1244d973e16880b853f85180808080808080808080808080a07699415741ba9692b92390ef8d1d9e862a3cb1579a346e2aa400a9c61c63acbb80a0548a0683ccb77c51a86582facbf800510ad283280f7f20735fba51cc6a0119c780a1e09e20526e70d7b9c8f6c41e88e9ce94927d786fc51a0a6d7fee846ea382ab4a01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a06e663f819ce1a5f00b4aeb95521922e246c6002c77bf448f0c58f52c59d9988da00fd9ad4dcaf08fa409162d7eb2c8d9e9f61a289ae43cc86c8f659565046f44c7b90e5302f90e4f83028c6083033515090b8308b19d94167008000000000000000000000000000000000180b90de4013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c66000000000000000000000000e11c4b5ada18b372e32753782ad228bbbb1f77b600000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000e11c4b5ada18b372e32753782ad228bbbb1f77b6000000000000000000000000e11c4b5ada18b372e32753782ad228bbbb1f77b6000000000000000000000000e11c4b5ada18b372e32753782ad228bbbb1f77b6000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000acdf90acab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a09591d235231196568d434755002a6d5947a58c34f77531a9c86ac3fc2b093b77a069368bbef45f706c2c14e5aa027146d788e6fac74f59b46bd407f0248bcd0d4fa068ef1adc0891f35bc2fae8495dc1c950c151c1ce108f66c0fc23b97f20c2da51a0daf7b9335c53a0deca87e98909726d8445cf30ee2c95e2181cbf77aae17de6c5a03c3b514e72a3414b9d17f87a7d268b2b838303ac2de439ae45d0619e7406d703a0e2429a5b6d7da0dbf2b99bfab3fa8355bf3a283a43a6571a99fa95f1e437cc6fa024eeed393b3dece2dd3f0356fcad84b9f9e8fce33388d4a7ba75f828dbed32b5a006ad72a9c5df7c3539f258997ddb6cf2c07902882ddc16f1b4bfd8d52025ea39a0305e5744210ff4e80529a039d3c91870e69568e232b27b3f259fdb2d005a0b64a05c92622b3d684e9bf0fa4d0ff90b02c6ea9ee44672efd63d5d2537eaf8fcf8cba0b22d9a89ad697c7436b6b13ca45f9c8548c6bae159fe7626c131cd0ddbb81a25a0a2b88ab0cd6572ed505973e66cc12cf5653c47e5b8d33118ff58a3d1e90c78fea0d1af0f2d79aa45f6a5f1667087ed0780ced415f5b31381ec705e28e5cc58d2eca01210e66bf57cebdcdc549dbabfaa3b99ea1ee57c14b9fe01ed5e8eb76c01d541a0dcb5547e96bb514cafd7fe53e31777553dd957628d7ef1bc267cdd6a532792a1a0bbc7f1181582829e3d8d3c4a7c9a1433c6ca19ead2a2cc720c0548cdcb9e726680b90214f90211a0134d1cf0c023961508f5f21b213240269275cf91a5bc675c811270434982fdc2a0a07eb58d904d93948b8b8c63958057c01a91820c8d61ebb97bf3986b9b48dfcaa069f075587047c26e58a570dbdccba6a1a3274097d35e9fa90dda4742656c47f8a08a97c1786039bbd51c380f330f9148dba53462632786d401124fac815213cbfea0e4ae6fbc379fa7d60a2a58b4cb3f00246732f63c13d64031b18869258d925323a05d12207a90c71c5f7639f6e3b814d86744de6ea39a20d3a4a099674107a4321ea0a39c365af32c9d2a14d603005a1c00135a29c85924e4991ab5e95be580476deca03c27c1981e39abd7454987b42004c4eaa8ffbad3e3fb17860e44375f03364bc6a0a94f535d4324b2b7b3d651cab2cab1c5ba0d8daa928519bc40bed118e1ca0c8fa0d18b603df47e14fa53b46e2707dd03104a03e1e6aa2f2ac6e2336cc66d138b8ba005e025d048bfdb0009ab43118c4d65526f9ec0f4c4f2617c85bcb9a4ac8f23eea0c7f1a9a494c1d710b1e959a39be0a50bf69a9d99cdbd8bb3a70123b33a39baada070b030b4953829bc059e8c085c9be6391703bb4a832c0e32a26cabfce806df78a0b47776228fc70910b2f51c331bbe0aee0775601586ee8af4caef5142da063fcaa05c8ec27b2c80026bfb5124ef4953bebed08da526e6a465a05cc3da500187e864a0c5f635c02aaf8fd5ff30854355b951e66795616393723af8c0b7dd944badbe0580b90214f90211a06fd82f15e957e4e411c09ee2ff390a85111585963745e464beafbac0a33b693ba0720c5f981b0816a7270e6dc72e1eeefd593a8214d7c576494e3a4c0ef7f9159da0794451563a905fc282fd33ceba611a30839de14fd5dc81d9ca8dbba3aa49130ba0bc2995a3db90c9ddc11e72ff6620200587dcd79ee982ea314806f1b0d4dbaa71a08a65775ad4d5988150f139436c3b958b02d794aceb213aec55603981af261adda00a197ddb8eaa2d80a9236a558b8e27ade5719fb7f99d8b51368f279da27c4881a08d98757b4207b32c9a0b7118688319b30a3173d093db46611f24a2f3d8585980a0233e470e44125bc2b21532b8614bd26eaf40c4f195b83b4878063517027ddce8a0947dd68ecba1c21439e3c3952eb8fd9e3411255b16cc04bf9a6a0e9032ecf401a0c17d98207e951e6f94b6aaa6a43a0f3a29e0342f8bd0ec823e1c96132c13fe3da0d83e3882d575394d22e6fb5399c030e3c9d30a4cc74217cc4be2a7f24fba4188a08bc76687c939b923a2f0f9396ac2a1e2d502e93286e923c02535f213b1181233a00289a7e94897ea26276a27d5ce58796d547ca36ceea0acb1e54c271c015196f6a01fa4ad2e4f5258bc6f7f9ca61e3c3bfac15270d006d063d275c7b72f837e0ad3a00d68f3a4dae6d943490000382af4d9d3d2d2f345ace9ad223a65387b6135eaf8a0eddeb2c9106861effed8d189e55bed73a88d6279ca9a10b1fe75d47a2da52bb180b901b4f901b1a0d540be57cd656a5202c01de565a68afc549b26c94d61c1310f22c2251d69aa61a03aa16d0bf40af50aea64ebe138b1f891204593b10b7cfd66efc0b9a4dad555e580a023c018d45dfbf13b45255e93b14c65dd3f89e893eebe55a4fea492aea7be794a80a044ee4ea105c5513447688eee02ba6012838008d833f67a294818848cd872424ba0719c8741ab7b0ca364d8ffcb9de09a5c996c67a6032b8b686c79d3bd78fef22aa09f622275e1a20d8d2d7d7d814908e6fa135ac48591fde6bdd8cc5b2bebda72f0a012aed913504afaec738de52bd605300f0113233f46549731a2766ad1949ed7dfa07d86904ae3c1fee7b330d7d186f083276e449387c9090b7405ab712beed788b0a07ca14ce67ab2c6dd802b335591f6e0275f9721dd4c55bc8efba9983a7767b1b3a0b7a2150fd39de6a630b6e2976a0f9ef6cb04d843b5035058f70bbfb80b019b8aa04f753d3bd4309498064d53fb4b8d9655f6995425c610e058f3a91529274d6769a059f8467898f8711b203b8c8e33cff51761e4367cb66b76217000e9667ab6cf0d80a064467095776fa160fe7eae1de1816880650044a1c7ea75a4d57d88816c5a3a5980b893f891808080808080a09aeb85a36cdc8d27adf09d62b6688642b4b9b92ae63e9310c561d3dfa20cebe480a0c346fea83e4039894c505ed8e5aab63c356b50c51cf97a1f719fc1e47223344a8080a08e115ee2507046ca84eaca2df257e827c1ac9e2cb3c0c24b4d3ff910996d951980a073b9de8062096035c66465f21aabebdfc54f35f38aea6aac2997ad80c8af43f5808080a1e09e207a7232bae46a4e5f4d88269e93c9e04c205624c633cefb42b0dc8ed7c701000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0da03cd9aec593bda9abfbfa584a1d197b64e5859a90fcf398acb735fced1cea1a0454960a3859e95b27f3d6b8787a49cfafaf56e9098253bb9b687fd1ee3997194b90e7302f90e6f83028c6083037727090b8308b44b94167008000000000000000000000000000000000180b90e04013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c8d0000000000000000000000008e1a93fc5beb33f4e4544b19a6ff6a653d2b847900000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000008e1a93fc5beb33f4e4544b19a6ff6a653d2b84790000000000000000000000008e1a93fc5beb33f4e4544b19a6ff6a653d2b84790000000000000000000000008e1a93fc5beb33f4e4544b19a6ff6a653d2b847900000000000000000000000000000000000000000000000000d529ae9e8600000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000aedf90aeab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0761ae4038e2742836158fea5c074e7edf78bd4cce5e0f66bd6dc721e5c85f775a01b2a5fde589960147cfc9ece3b84cb0fa6e056d4f426ded53d0bac2f385aa85fa0280afafd7bf9707084a5a537ad270fcc3fc92efa9a7bbe1e8cd22843266b6782a06f386076c231cf449587f885b121a1271c2a9f639ca147e1043941a61935251ca0fea2a607baa108b4d5b58960d24ef5b70402753b5bc5cd6025f25f6ee74da50aa04af82a814cb0b0e9755c95326dbf58a032405bf226a1da75692e0730caca0490a04db71e7674982c4ec882e380388e0cb490e0df0e52855c4a981aed9c909a6dbaa0024df9b65bc0b252e11a16de6aca6d1a47ba8863ce03f02c89e7ebae5eff39ada0d7fc15435db683f6202d3b6b72b559fcd9e61d7e26ca1eb4a6bccfcddc7ec24ba06719f335dae11422a6e135185b829e1babfb1b937e939411c31a12e9f8d35649a0bfb676dee4a0219797fd162ccdbfb63e33b3be8f0cfd1d579da754e47bb060aca008e06f2167c6b3e1dfb5ce3a10c2680d2905601bd1e392296ebc917196bc580ca07d97d76b748d8a5c54976206c62886d05a5b5423c768d0031b0d48c9009fff9da0d269a0fe461462d3504214ab4b4fd10396d85c2e6b293df7758de394e201d502a0f110b7ea826f72b02aaac97c0a299c3fab7c7852c070cee3d1d003dfb0df360ca0bbff1b235ea6d9e8bac8ece338063a25884e6eec6982be087dad7ffa772d587680b90214f90211a064bfdb3267ea70756f5df088e97694c81a7ccd9f23dd37b55d4c4896421bd30ea0417295c2340b21cede240b0149943fcfef22a786a7964d9fec6123b8dd330759a08625a1f33c5e2172f304855628710a93ed3a581f964e90a032760a92f56de0fda063fb630181151b87360f3393d1bef1e6b0677a7f46b99f52d3b6ab1f044aa6a7a072b675f938020c878644d96368f1b9870155634096e07eeb660fe625f954440ea073726308b069476f65dd86c8dc2ae653a80d4cdfb76584da869e5a20191924e1a0b4baa3e8788704102f045d330cbb98b07bd0e0fb34560356c9eeeebaef2fc6fea05baa276dda7855c08b473ff95da28ed3064516e3e4956cd8506aec4696c1e228a04d701cfd374e09effd6acaf53eba33e4efb1e3421079a9f1b7a1707bd881225aa0f263681ea82c76fd93fcf0a662b98bd2df729482a1730d8aa7ce4c16d138ba37a0708b0e28fefb8f3a94b185471201d447e075349655d876ccb7013757b740ba0aa05848b388ef21f90a656ae38d18dfeae048ca6248f9d90c61c5e571ad06f5c914a0e9d846c987ca65c3f3fc921b619866520c1f8649ab2e8c83b0423a7c35bc6061a06c9ddc7f95ee338e3739b8f7a84e576b1d4e2601a27646126271ae0ed4c18c77a0b4633b2264585582dc18a7e80d5d1440900c1d984a73653eff2fb4cb499069dfa0ee984db6b2aa91625962d5b83e10f5bd027d0289a10f2d79e7fe32ae35a5171f80b90214f90211a014545008223477a892895a63a4870fca6c9863355169420660de01fa1befe275a0907320319a1588d2b078e697252b62c260371d46c02801fcb020b56c8b300866a0208c552a120818b31dd1f70461fbf293fcbad4d03bfbebada232383b69229d4ba01cb093f9934d776a9e59e8ee4f8973e2d64b7a517c6da54e0eebe712a4df3e34a04a7001e2262eaaba1038846e63ba82cd558c12115e55a3c99bfb8eee34ec55caa028211c2b8d9bf27e1838db8a5b2702f52f0c7c095cdd662b1b5bec536e5296c1a0b774c93c3dc93eb426b10ee97c877632035b3074ea26df5e0f8ce3feccb5a122a0dbd9f78dd577f20baec26d65face2b9f5c155d79c437e71df9e5359d793dc75ca0b73b557f9155bc7d7162c5db2ada77f2e5e1a11645df26af9bdda5c0b13cdba4a0309f9ccadb2797c3630c707d36e61fb79c3c3e9f2b974c1e4e1e47cfc0a5951aa0eba7c34def00c2a559829ad1fb45584740317755031231ba4550976f2ff06b18a0ff04394692a130ef0eb8de7fad682e386b8009f4935137933278c13ca0399251a01a505e8e32ca01f5dfb07baf0d26b84ddb9587261aa453dd92c33c56e4cdf844a0c34fbb103a2b5c4bb0bccc3048b7e21c7565e7290f0c8382bd7a0985a2461edfa0b75546bf459f319a754544be77ab2b597966c86b2489bb2d3d699ae78f0bf9f8a0d0ca19fe9ac3770b414b5dfe21b4c6f5d4af2787747afba76a83446669cf431480b901f4f901f1a0361c55f22909d9317b9edd19837b4faba142af72965050356faaa7c4e75bd248a02c985b650adf57c2c76a0dac6a08e8f8d704b550c2e6062408df997039dea123a07e7c4d43999a6deebf7b3cb2d992ff00d41586c162bc962c4502d490a810059e80a0c4e9bf1c365a8fac0623cf3970e2163cbdda960be052a1b092283888a17fce2da03cbdd1294f7ff654d5a41781cb65db5c222b82bb60b5e5e1725e7d9440ab7041a0bc18a1b26bf9ce64dea09771269f6212b4188cce89456ed3c3a8ce29433219eca0617d5590ae45c60033400af8102fedc0ad53307b4b8b4f9ff77ab3614160cd63a04aaa9e77eb24e635adbede3c46fb615a11ca2f5fdac3ce767cfd260f8f434b0ea01597625c15a1350a26b8f4eaa775431189e3daf30082cfab6a5a8d6330e149aba06730ca9689f2f35c8ff86737552fedba14334a40fb2d9c2d61163b3a61418cd4a040edfd67766e1dd339ddaefd45a10a91b57deea7498bbfc0b8b607d6dcdd7aaea037250d76ea59ee2f91df098602024e5a66774b0c1b42b118a61ff87de81c3429a060498a24eaa142b4ef3a5a2111df5ed62ae2e11f73ac3b6f758151ee5eab02b9a0b9a88048815afc7204eaae81111a59251c1015b314e53900fbde282bcc2a4b75a07b359f60c2e07286541edeaa4153cfa02a679c1e466862d07fa015846c93e48680b873f8718080808080a0509333f50455bae94a3de6f7ca24d25e7803c1f26e842a7dfc55c31a1e8fc461a0307878a1371b180abf9842a4e05da3d7d05ae7812bd3befbf28ea53ec522b81980808080a05cb62c22cb09896a17eecfe962c7760b48ca34d6571a7174b07a79ea20e4923d8080808080a1e09e207e52217ff81e2a8054cea9610a9665471637d99ad1eb4487142798252f01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0e0935a9415de0e5ff489c055d2f65391a74b3e371ec9231a673ef21dccb4522ea02f6c695606d2a4bf0a24d0ae7d2517349e0b6340f0dfad8355445fae10e172b1b90eb302f90eaf83028c608303382a090b8308b92f94167008000000000000000000000000000000000180b90e44013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c770000000000000000000000006d905532dc8fd33e917e5c37ffbd83152cf281ca00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000006d905532dc8fd33e917e5c37ffbd83152cf281ca0000000000000000000000006d905532dc8fd33e917e5c37ffbd83152cf281ca0000000000000000000000006d905532dc8fd33e917e5c37ffbd83152cf281ca000000000000000000000000000000000000000000000000004c072fc63180000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000b2df90b2ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a07272c8925cb012e02ed54023927e8c2261ef5d3b1f437e5b2f92bc5b870ffbbaa0bbc5cb8dc10c33b047c6f279cb3b87167124cfc4de2b60eb1d1e36f089edde52a0527886f9386cb8fbc54db0c083dafde70d367bdf8a8f50b13c74548927962441a06989cb6073ca89e6737a04c7c834ab14bdeee51369ae3ba83e6876b5bfcbff73a0a416439377e5f75ff62f1547f1201e2a8ad804f042b54e8a348d5403a5b9661ea0d56ca8d817db357f387b648568bbe90d99d2b68ce6cea935c15f4aeb67bd5942a070ce7404232f041c62a63eb4090569f8677b67627813007ba6a8c94975502da9a0bbd3085ac80f731abb5681669571d83cbdb28edac273f69a8d0e0d7c9c2f2f41a089a87118f59724dd6e07d2e40ab79bc87547f4a22f81de8365ceca0ee94a9d86a084b5229f86aa55e2aa84c10370277a6cd6ad9659ff7556d9bdc7031e3e1873eda00db81e6c341ac3c8b5242269592b22fa35746e510fc02776b40c15193aed10fca0ad0bd4420a2ee3c7aef52f5772d6aed18cc0ba15fdd52dc7540bf8eefabdeb53a0564776deadbbd1d0f354aa93f2f827d8f4045fdb85efb8f0274755d3247487a4a0673c5b4903282addfd77c33ef304e4b77d8bcf12ab8119725e97e36e846d0166a01bb331c3dc2eb752de61d3eeababfa9ceb5633d18c592c16bbbe1b8958cd2adca0794a7e8c41354be687b640ae91f62046e5803176cd7718e97dc234df47a2f48f80b90214f90211a0a0fd1ddb738af15324e9004fc5847438a8591dde4fe3d8d742aead55d1eafc28a008fabb0651d2e48c52549a0dc1320e9a1e30e7be13480ddc1dc8827fa5208a33a0939795f28d7f11ddf81f56a7b0e62b13928220227919d4563bb3d7733da096a4a02782b98ccb0498f7a632af0e7bef64d3f6c1c595183746d95133f4c1140e66fda0a259e1ce451d9a852b41ed778bfdbb2ac269444fcb83ec76d3dcc3676b5092a0a0bc609e8cf1f3b92a3838843651dd982ab4cc157972c3577e22b4f357b71603e3a058b339e4b26904c78b5926d84d0d5a6567253ad55d0954f7213c63650c88ef77a0143e4126ff0d62ad066d916907cd7fb98fafb17a12d9b3db6b6b1a7de64f1e97a0aa5a9d22a14e42dfca0416e0bb2fa651503722753d59b0a27149dc71d9c0a9f4a0cd1071557e21f41a781f8b09c8cf00e1ef0ba145a8ace55d434bc09b2dcae540a058bfa2724c5bb17f591ea1190bfc173fb98fb4861c2d1f1e9f43fc2679cbe94ba0bbfa2fd2ee4eb8bcfb6ae1fb73d2bb37c787e47f3aa68967e2848da570209b58a0b0df472610408b7258aaaff03988729d586dfabbf46d6d9a6a132d0de600544ba095c1579aaa8b75918c3e64eca0461c76932191d3c913f2fad0ed5f820415b4daa09a50d83421014d3e1a79cced8cd534a73ca762259b83d25b040cfbb0ee9ae77aa054ed2486c931d9f785c8860fa20ab6b506b0c863313bd71bdf4d554a4b1c60d480b90214f90211a0716d71e2753262e825752e63e19947e706fc9c46e9aa55e1e3ab76eb78c4a4c7a05a2b4acdaa44d61bc556eba4bbd1d137df5aa09659ef08531b45274a3ee2265ca075d181d61259476c06e4ec78d5750faef9c2c0d519a56ae5a479ca87acd2bfb0a0373ce9c7e4774ea7b3c660060ff63b101b3a7f8329ebd9f60dded37ea5b1678ba0e3a203cda209fe3b4ec1d90e7e9d0ff3c2c6381ad5f112d5a87b27e1069da552a02cc52bcbd72875ecf987b38558047ddccc60a63be98a292b3d78f8d6b3c0bf23a01c697cdabe6461d99fc646e023e9457b0f090d6829270fce89a2447f54a445c3a05c427ef490a35c4c27c7ea297efd775886033b43864bcf7a0593443c632aed4ba0782f6e7db1569d8bb9ea2c216e292f889588137c387c13af58ac4cccdc67d3eba001944d78d6763c1926be947af7e12fbac66e0c75aa0f2887838853f399ca8a48a021565277b6dd513a05c34509a19d409585dac1fa97e6881842605b5e659533b4a08f129adba2512c917af500bcb8d8767cdb0f09d91a0501a9a3a24da2e7ff6e50a031b931cbaaeab4d2733bea788ccc8e1282e8879e0792e5ca048bd94d4eab70a1a06224c1a008f66e69d2448bad0b0e1be3e22c6d1918291d4c78090954cb253e6ba0c3ffa796cc94008b89ca56c6d9d774d1c079c2996f51e3ea7f1e47821858c160a01c94ea9914e4779036a54e1d744a7e70cd72c10945c8b3ad95dbb8e738fb085780b90214f90211a0a3175ad8460e19c4b235defb14178aa1538df9dc21c1164975b9a68c284dc70fa07f2e4ee0151fd01911bc3b64ee2f1789c17efe25db9cf34d53cc7354263a635ea00f1ae99e8b87e5f013e1d91aaec835771108b055652c0f91626c26627d056295a03ead10768874100e56d34f2197a0c8731078771e3b1d0828e99deb8715838926a0ac0934cd278083654f334cec8832eda8f9e4ac3b68cdb78bcd6f612e84563442a00f133568a3d498cb427e8e6901e3618ab91c62e6c1de34a848dd41270d3c915fa0661ada6fe682a0f100dd93befccb3f859b9603fd885b4294ca131f0b1874339da083837f6d70e9cde8f0d4ce4638d15b43cb7d42b38b29e3407d68b8faa7a2187ca0018973a84be1e1a96c1e7c1e9d6f00ab8f6f2be064ac7ce81e41e5b54d4bf568a04aa4a96926fcb6ab05898c86f563c36ca9bd4a97d3a093ef4c0e828d60e48524a0e5230585f9846a9f82839056f7facf88163a69b6d0f3a2697d09d0561c11d6e5a0ece2e80eeaddc4a8af306ca5acaa988b6726f742891d633b15020ecfa3bcec3ca09666651a5763f0b329f2dd1173f31f71d115554ee16f43109461759ce873cb92a01562114508befefc4ba3cdb6c7380c14353aa8eee730f3356c6d54a25a393ab2a00f151839460229530e9e670493947233316de443765a12867cbf4b3b73bdb3fca0eda005a02a3762d004127982401ee38aec2b74d22abb60422dc01c46a14eb83680b893f8918080a06d97315dcd37c0300539ba37f4288f7535a3622a7235c68ba62196fa87be3e6d80808080a0088c5905aa8bf2e5869216003ea71cdd715c3ca8e07a327395e3d991424d5742a00e1fc144fce0b615f5716df2a4a2a4608f87e3ea52c5afc2875087398aa11e5d8080a03e25983fe5c093b08622076cc7fba6952b773cd2759c149c1ac0974d714137778080808080a1e09e20afcf9683fbe1444b9fca3050815122f77933fbf690b42af6181e070a5801000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0b1d7916667dab9be344a294a5c68abce7fdda58dd9abbeb07a1c1c1166595d9fa07ea4a086306cd5ac2658b052ffedf59cf32ba690e5665aadb60ebe93b23cacc5b90e5302f90e4f83028c60830376f6090b8308b1da94167008000000000000000000000000000000000180b90de4013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c6400000000000000000000000094f073df05bac419dbd7a1259729a40fabcc8dad00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c6000000000000000000000000094f073df05bac419dbd7a1259729a40fabcc8dad00000000000000000000000094f073df05bac419dbd7a1259729a40fabcc8dad00000000000000000000000094f073df05bac419dbd7a1259729a40fabcc8dad0000000000000000000000000000000000000000000000000045a2189d9900000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bc000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000b800000000000000000000000000000000000000000000000000000000000000acdf90acab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a00ea7599086a524548ee2a638de6d1b52ccc3188782ade3b0fad03d0f332d5ffea0cd9691d86d7e34295657462b278c2d9e5719ebed807cc2904e13917adf985458a0785e5cec04b56c1b3f7cde086f0f145b59e03d6bf13cca0bd49417da6e3e493fa001dac040644be7d313330ab4f13f065c89014b39477d1b448f2e93b429240fd8a06e8b5b7bf2d33de94a4bc581c733362bbd9cc54063d4600845c50fa84fe989f7a022d5f1374e8575537e273ddf4b29d1f43e11d3b5d88433322a489f94cfcf2b7aa0ffaca60185d5788e1094068decde5cda96e5d3fbd0f4ee55509e5788c40ebfa0a09a257b4b401c68511b52b334739d0d48d28d60f4edf972f33af234bc81d3a79fa05b9ac0a6d36cd949d40978d739a3d6a335d2a6cd16bd4e439d4da9cd846ea1bea009a40d9c0fa70997ccd467192239b516fc68ad52b8814048abbc21e758c21a97a028100a8f9a52026bb3ddddb1fb33cf134625af387f98704bd5da57d3aee9727fa0c908b5a96966e855d3b2f86a6badfc28048c0b156fd56e7aa99213184393f6aea0cafd8337464d52b2788536e434bd4e6df0bf4222c087c4d4bd9a5147cb36a92fa0757a8e45c33d0ff69e87f850999fa4877ec0e78923053d089620e3675612b837a0e8d7bcacb8f8706dd7b0209331c1320024e4a69dc353b64e189c68821ecfb7d4a086b0dde605e175c6cf33c118b11c6de4719edaea09ba18eae150a6bd82aea90080b90214f90211a0a6711f31188d7e3b1a8c0fb11969a579b06bbbe07869afc5178723012620fb25a040cab30f37fd4818fbf2b272e0398621ca65c48533946692e91a282a40a0b4d6a03b37b8717163978c5680830a5f169a87e88b6b93c79c2e49e59d6503c0a5688ba0d740f37fc36c8cd8b6d2fe8db8dc68cccb6acff79e7ac40fd092ecf9797a48a2a059e873229a058ae26dcf9ff560a5fcbc045d487bda3733306350f674edfbcf9ba0ae2f70afeec1af525d63b441f115775ac660ffc62eb26de7d696bff689fb1596a04e1fdfafa2e83ff2f927b33a76142bbd9a3120bae4c1e28d45cd7ef21482871ea094b308c585c9eb51bd923086500f1725cc5ee53799729673439c3c4050eb1c41a0bb1f14d3adf397da422154d452c86e0ffa1c4ebd535486c07c5a6d2c637b4b6ea0a316e5ed56c2bd6ef63d3a834575249fb14449663ba38a816c468ddaeb4deac5a0e7933ce5f184882ccac75077423c109a4127be4cf3b2cd54d9d66a106480de41a05766d7b52d32cc0c714c4bfd47b4abe5101a965724b60dbe44b183554d4b8454a014a5d45b0d431701787e60834ce78801482503ab1fc281c25c637a52b307d17da08a7727e825721b56d0518ecbad788064eb2264e994e19f46029cf31b79b55ee9a06778685b5aab69e8d878a3455f824865f29d350191802380a7e0d3b9fe9f119da0921f38c8aa0a4e234fe2cd547a5275da38f2780eff89a95d1b879b9dfa864d1080b90214f90211a05ce67b4e0c5e8c40f30035bc2b46b96e281b12404ac4cce19357f02bea1d88a7a0fc4113d84c9eada67791022a6ab64d6ea03a3a3d4dd6bda52ad1421aeb5efe7ea0428fbcb7d44ba2c6220990cbaedb68ada7b25dbca654c80a236a4990d3faf160a0d75b0e9865762319b6067442fa227711a02ae814be98b0e02a4b0339f4b3f3c9a028837d9399147bdc35d1305f61e76d0f21b0eaa2f6ab475d57dadda5c263586ca0cfd7760a8610170d83f359be411d78917873bb521dec9d6d3b3f87fb24fd6e0ba097ab064aa7bf28cd4ca41bc5d47a4269b3f72bd6aca36e8e86bf2a3d96d293e5a0e25b1cc2166c32805d766ae19442d45d2153f6ebfe3fa5e02baa7a181230b937a059b509c0350ba4ddc36da2f6f5b5a2a877ebb35499f02f4630b09fb266e41076a008e804de409702b37b0eb91ca3411af4a504dd017b50980dae946144acbcbc7ea0caaee662ec120f24ec5db46e00dd76eebefa0da11aaffda808736daa1bbf382ba07ee82857b799fbf59c978be56c40edd93fa1e0cf8f8f6a51adcb32cfabf7aaa3a069b319d4a85401a71b90f2c07940f60c1e01b8a334a44a503cc8d4f6f31141d2a01c47430507a491b3ee7d0a597e57415c225e920195737b2ed4fe60ec89b890a3a072858758d128c45d928634249ccd193174e5e1b27b0a1a9dfcbeda537ca8fb47a0264f643aff0182cf5d1fa836819c238a38dc60848a2df266cd5b07750843034b80b901d4f901d1a0bd809b1a04756ff99533def1c28897c13db4e8956f478f09e8c9793b3ebf91b2a0947f997e800c1ebd50d5fc21e0a07dc9bc3ceacf2e74c93f6404879ab6bf1389a0dd2ee28efa5fe4acccec8fa32e8b1089d6dc52194abf2856826c458333915c1da0cf244ea58cbf98ac88cb3f19a58750ef096a270c5b9e58a92a213dacb791c46aa059753b134641250b812ccb9fc2079eaeca3be855a3606d9c300c5c89a978b9dfa01de86705bfeeeaf32c4e55a67bfb89d955166f469c37a524485aab77a40e46e5a07d0297d279db65d7e1ac912ac5d01026147785f78b1cbf4f62106c5f83e749dfa0ed066356bf34e19ddf001bdbfebaf446da5ef564167d360566e9f5ce2b1ebd9780a0e7ddcf8b745052baa1a6e1eb440bc47d1af29b5503ac770ef182e1438459499f80a095f073d5297770499136ca10cdf6361b7c53c39a8723363e3c5c0473c1d93ffaa00ed0868c0eda4a1a6bf6d176724e6f1693be70c19ca59ab8b7ee7f8f0169f8c3a0d83526351650ce641a9641891de06d8f825436b3c84962e29f4776a3e520bd88a009fbce84262f1dd063a7dab6be7a1d215efdc8d7659224c33e1b5782e7c36de2a0e03c5b985a0efae2e792e962413c3c2cf1743d0ed175bf23ac6a65c3f12ad00d80b873f871808080a033f80de52a0cd3adb5e2cc5cbd2b4e1fa3dfd456db58d7d6a30f7d3930e1a90c808080808080a0e642f540a3cabe5e703b1bf0268a58cecda4b7900a82db7eb79359afa4af649280808080a03999b9233ae090c0a1b8a66c0d89808434a88615aad2a7afc3bf9a33ecda1f4b80a1e09e20af1e490fe822959f217b528ccfb00e5e98c00e644172e35ef8091aecfb01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0e589d4da750bc2ef0fa09141a1d94ef00015203cd1917cf738ed4816e81cd953a06e73dd7c22f6f9687124ebebb612072b9374d46779398738e5640daa61a3b902b90ef302f90eef83028c608303764f090b83092ef694167008000000000000000000000000000000000180b90e84013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c700000000000000000000000004e137a375d98adf4d6aad4b6c979ba2090305c4500000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000004e137a375d98adf4d6aad4b6c979ba2090305c450000000000000000000000004e137a375d98adf4d6aad4b6c979ba2090305c450000000000000000000000004e137a375d98adf4d6aad4b6c979ba2090305c45000000000000000000000000000000000000000000000000004cbd15e72600000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c6000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000b61f90b5eb90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a05d654a33d10a6db08f8c99869b1a443490083187302f7f264e10320352612c6aa06fffc13a8d2912c192b1cd6f13332adaac05ad163bd18aeb440a5221941ce206a0abe9d510da30d67ce3cf6c0f5063ee29176a2f8c0f9eb2fb8b5df1773927a8b5a016b578962c6b258e98ae7e39fd0c627883c39714b6d72f35641cbbc911b2083fa0edc596d335991885ee282011a2068106bac4ceeefcf272097325bfd0f958293fa03b5f0f00263e5737cef321fa807667de630941b952f79a3ab2657153fc9b1f3aa06b06570ddb03c812a700c804e0f19b587419773287adfcfb49f24443c70174b4a00301ec645bff67a2513f28f2c6412333a2782ca81d87b0b1c89a0a888d4343b9a0448b3a2aba00f081a743a6e735b37d705acf12fc4c2c5d92a939906701ec1a7aa0d5e6da2a83333f2d0f531189d8840c14fde66827cbc9eb1b16d25c101726de94a0286ea8f2d6bec7df774383b3df20c0890f7171a55354f1e1c8adc6a895c1569da0cbf2ba9b6f63b2223bbb8941e6810ff0b1d9b8e71a2ad14fec190868a501122fa0102bec81944abd04dd1f77bbe128b60f817cbe35a602d701ae8a9cd3bb433199a0dc024fbbb0269f579ac73a0fa72e66361f7021cfbe30e053966be22bf85fea51a0dd60904c1ec97aada641c9a59d87d83cff3766ad5c708698365e2edb360d37b7a03617d6225b7d4d4bc2c42afedd488cedb20aecad12085ca02cc094eaa2da878780b90214f90211a0629fd7c6f791cdfd3b935ba4c1a4db1f1852d9e7e3e9c6c26e0f3851e1c4a114a0f978b61414bc90a8ed7769e7d7f7c83d544b05e9aba3f7111da9df4bfce28560a0ae37b0bc5c19ba6fb5d7b83554cf6e5c9b570813c404de4c104da67512301e83a0d8f939dbb046c260c24315c709482ae3d6b861f015e20161e9c704aded99a14ba0fb65f6c8ca63444aa393854278cfeecec506b674116f97423c3bb14a4df0cc5ca0b4d175d01c4ace4658f98e4b41a66d3f236507d6e19f3017bed73c91b58a5cd0a05a2d307636c0b282510be24db5fa508aff1edddb6b156dd8c97ee56f3990b3eca03a963332c43f23b42f6800ee4558ccde2430435c837208752e7ba7ccd04773eda077e0dfc6ac90e0762c3685a012eb1fc58d8483dea576cce2d9f949abdc2053bea0af58cb7ea0fce2a43a362fabe60832cf2a500387d66d7ed929ebb1a575dab1aca0ef1eea195a4fbd6994ff2f55284b3919f2752a22631c5d902fa30049d74f49a4a0979678f375735c4eafc984eb982d509961bc1f02bb99a9c891c34d88bc9c42efa0bb94e08b81a6ff697909cb792820599e95038481026b6b5fbe8b9afc1452085fa0c3baf1687a407989e1d30f6c00db6b4fe39385e069ae8e003c59944e1c73bb0ca0e89c2b0ced33416f248d55d2bd23033f4540b863b58ec884d5147b713c645cada04259550065df62101b785bc58c9bc324d19708fedb564be5fefb25beddaf5a2480b90214f90211a0902bf662cfc4ce0202c693bd1c998719e8fae7e3d229bef24ecb0d538c72c2ada0a725797412cfdb261e6644f7948e217ca2a705fbe5c8aa5c7c791a82ec946892a0d3af186617fa80e369419fc7a6b2847639fd25553e6345c1e086a2fee0bba3ffa0206161f56f2757995af398cf65debf6a7ac2507811acc8fa287d16671012d711a0c77ac22c4234c0d0b55859f5515581609bccf69289256b99134f2523f556e20ea09140c92171601086afe92841e894f83770e19da25273e0856b780ea0818f7814a058e9235861635fa4562590cc96eb4dbe13d937e48072782ecd607723c8cb37a5a02f2e5a516b87b6099977d83e5ebd3ed32942f2490ef0ed6b729ac775884a8503a0f85d6b521892cc7d69f22e632350b6d9e4f0e05d7a2b328cf9cf89ceb79ba9d4a0215a7c1dc99c3c8e48c10ddcb87261e1dc542252b34959ad52f2cda6f6cc8801a043bb6cf52a2afdad9cf373e8a1da802e79e36193a5842b19d39c2718e57ef23ca0c77faa48438906bd613d9d18291bacc42b2fefb4873d26e76f0957a7f411f688a0032659e1ac9d3acb2dd34ceb5360f0e566b96dcdd3a77be73fefc61517c648a1a0ff09af6301b47590225ed64ee22832f4cd5478e01bbf75090d1b6336072133dfa08fa2da7e8bdfa092b0cd38ad6cf22a7db530fa0091685b5036341f9ae5764c36a0659af82d91b296609e93b22b20de9fa2cc719766fbb44bcc6a7ff7350e3926d780b901f4f901f1a0edd0b82ca1f7d6d2b029fde8116cc82005464c38609befbd3fc1d5fd21879930a0a135d851252e361f2f49035f1ea226e843c267d95b92917da640469b5eda13f2a016c02a303bce7fce4ea4eb4d5c239f7cd0641125fbf0b1bffadc9f7089729557a070cbab85d94cdcba323156512c1f5eb825ecc6af9e1f546406e116ddc3cfb4d2a01d843fc0cd6de6afe8d591fdecd3bd5c490bf6eddd90c01a50a8c56d297e1c82a03402c7f2c14a01fd72b633ff321b90131b006787c039e1be450693e633a36f18a09ad898622b37f77530f9bfba001c0679c6dc37ceb0702601141e052dd33731b980a01e0b112b1ecce7567e2abb0eb305bd8ec05be5759398496d8d98a4c831d4dd7fa0a2e6f2306e42ea563d7508b7f7aedf1c1a6cbe35084794ce2824dc39eb22790da0e674b68314d31630e702621fc05b115977ecfcdf6b17016f5599a6bba0dc8b72a0a23d9446b3f3293fa55cbd25a5d378fbb4f768627889f5dcf49889008b42567ba0a55ddf9a23c250c53b6047801622429d666e202988c120c8eb2a00938da5b262a021ee8277f2f6e7ee78318dab8e1d523f601c3e5fe6d41d4cd1015e2fc87c62c6a0c2fbb2617a564e25d3809da3b5dbe47c7e7ada885582e83f901fb2f2c1a31f67a05210179eef841e1924a8cef278901f5c0c07fa05737e03708b436f12e00d427980b893f891808080a02befb99c9caa9e9aafd03323196a2a7d1b0b233f2ed1f5a5896148a3fd8be441808080a0970b97a5a6ada5f1908d63dd12aa21c71516907fce2de8b1b5152400848d71efa0683bc9607c630420bbf0b596e870b9f8b02518e5996c2b7f842fe52ac6bb05388080a04344bbab266b4a659a3c3a13709b299d7689a9029d1209117e183f8d30b02ae38080808080b853f8518080a097206741fd7785383e0c2eb2e8ba3f5a35e361619706de0aacd245e2cdf19085a0f0c29f84031e7abdf85831886c573ac7a8b0945115dce7097b77f483413a62e680808080808080808080808080a0df9d339c2f931130795607c633a644489a3e85899b85467e531d0a1b927c7201000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a068be396a2afd3efa768a3f12b76a18913b576c649a9f20c6acd349a30aaad14ea03c0f9312b048f6e3dd69633322ba7117d2536dfbc3bcc74937bdd23f65b9438bb90ed302f90ecf83028c6083033652090b83092ccc94167008000000000000000000000000000000000180b90e64013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c68000000000000000000000000930f8abf3118de240bae191f03a80b204cf80e7400000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000930f8abf3118de240bae191f03a80b204cf80e74000000000000000000000000930f8abf3118de240bae191f03a80b204cf80e74000000000000000000000000930f8abf3118de240bae191f03a80b204cf80e74000000000000000000000000000000000000000000000000008040c23c6440000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000b41f90b3eb90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0761ae4038e2742836158fea5c074e7edf78bd4cce5e0f66bd6dc721e5c85f775a01b2a5fde589960147cfc9ece3b84cb0fa6e056d4f426ded53d0bac2f385aa85fa0280afafd7bf9707084a5a537ad270fcc3fc92efa9a7bbe1e8cd22843266b6782a06f386076c231cf449587f885b121a1271c2a9f639ca147e1043941a61935251ca0fea2a607baa108b4d5b58960d24ef5b70402753b5bc5cd6025f25f6ee74da50aa04af82a814cb0b0e9755c95326dbf58a032405bf226a1da75692e0730caca0490a04db71e7674982c4ec882e380388e0cb490e0df0e52855c4a981aed9c909a6dbaa0024df9b65bc0b252e11a16de6aca6d1a47ba8863ce03f02c89e7ebae5eff39ada0d7fc15435db683f6202d3b6b72b559fcd9e61d7e26ca1eb4a6bccfcddc7ec24ba06719f335dae11422a6e135185b829e1babfb1b937e939411c31a12e9f8d35649a0bfb676dee4a0219797fd162ccdbfb63e33b3be8f0cfd1d579da754e47bb060aca008e06f2167c6b3e1dfb5ce3a10c2680d2905601bd1e392296ebc917196bc580ca07d97d76b748d8a5c54976206c62886d05a5b5423c768d0031b0d48c9009fff9da0d269a0fe461462d3504214ab4b4fd10396d85c2e6b293df7758de394e201d502a0f110b7ea826f72b02aaac97c0a299c3fab7c7852c070cee3d1d003dfb0df360ca0bbff1b235ea6d9e8bac8ece338063a25884e6eec6982be087dad7ffa772d587680b90214f90211a064bfdb3267ea70756f5df088e97694c81a7ccd9f23dd37b55d4c4896421bd30ea0417295c2340b21cede240b0149943fcfef22a786a7964d9fec6123b8dd330759a08625a1f33c5e2172f304855628710a93ed3a581f964e90a032760a92f56de0fda063fb630181151b87360f3393d1bef1e6b0677a7f46b99f52d3b6ab1f044aa6a7a072b675f938020c878644d96368f1b9870155634096e07eeb660fe625f954440ea073726308b069476f65dd86c8dc2ae653a80d4cdfb76584da869e5a20191924e1a0b4baa3e8788704102f045d330cbb98b07bd0e0fb34560356c9eeeebaef2fc6fea05baa276dda7855c08b473ff95da28ed3064516e3e4956cd8506aec4696c1e228a04d701cfd374e09effd6acaf53eba33e4efb1e3421079a9f1b7a1707bd881225aa0f263681ea82c76fd93fcf0a662b98bd2df729482a1730d8aa7ce4c16d138ba37a0708b0e28fefb8f3a94b185471201d447e075349655d876ccb7013757b740ba0aa05848b388ef21f90a656ae38d18dfeae048ca6248f9d90c61c5e571ad06f5c914a0e9d846c987ca65c3f3fc921b619866520c1f8649ab2e8c83b0423a7c35bc6061a06c9ddc7f95ee338e3739b8f7a84e576b1d4e2601a27646126271ae0ed4c18c77a0b4633b2264585582dc18a7e80d5d1440900c1d984a73653eff2fb4cb499069dfa0ee984db6b2aa91625962d5b83e10f5bd027d0289a10f2d79e7fe32ae35a5171f80b90214f90211a0d3c429c357f600db36cc6291df20a73eb9ccfbb7fcbe225e7bad3d4cd8dd1854a0ca491115d4e64f86b26c5b2191d1a1a4aa6a97b7e44a87ab83331902605e4009a09ec90a1d39a9f34ff3b377b781c4d534f4f56ca671bebe5e9ac098800af1711fa03abcc7be8f61d36e33f1ffffe17eed4bcd5ca1bc32b7ad9e46d4f540941ea403a02e30220e98429cbd5cdf7cf34cbc0a4e82caddb425cf30f4eeca375cb93d6ad2a0a63da4054f754a05de71f33e3d48617f5a2a06f4817f82b071e0856a6ca9e362a0a5d4485334f4eb3f474bc405eac3ae61d68721033717220abea6d7c0dbee620ca07440040fb046cb6f69fd37c094daf2e6a32df7a9a8772ad05dbbecc73bdd452da0c3f4e02deac51afa98bc2c70c333e7124fae19c3285a74834f0992b0290db2cea0c36d76e3df3c35a6f9553f722b6bf91afc10ba378483024e0a656027d11ae06fa0bfccda7a44c1544985722b871131cfcbdced4ec41bea54285ea35fb8a15ecc55a04c3b8339d513cecf8e4f0ce8e796e1a787a46d4dee0e0b66ee6d7f5d9ed71e98a00aa71ae87c8bca901d427f930bd9242256f7ed5899a6d8fec45e8172ef884673a044a03f5c528c10c302899e47b3dfa8f76cdba6192a486beeb3a9a3e4bf39ea66a08ecacf0dbf82048ec6dd1d3838fd74e165dddbf99c420c72ee2c99404cbdc9a3a0d284dc53841efd6b0a66c5fe7aff4beec24e598220669921aea3c4bf6c273d4180b901f4f901f1a0b9a6ddefdbb67ec2226cf42c6f4635f89e931eec83e4c2658766776867256ffaa0038b0b6403c9ea06f1b16553fce254d3c5c02543073076227d6ebf3caafffafda0e25b50e9d507dabfb000041f7cd86d39e6a107219f4ef0e7d0209f09518080eaa0ad7cdcd259fd120b069410d9ac3703fa7a796a548640ca74078a33670d1c47b1a0562044935645503f9dfc359e94443882af6e44bef4b2569b5699c8bc76a32ecca0072a4772da506ee9cbdd0ee74c193bae17a09faed082e7d3c2648f4ab91b03d6a098b7b0127ceb7d1e8f8ddffa96a174a2994ea80565070607ef59203647eba425a06cc6ad993772ec8c5113630e9c3619673f086377312e0ef6e6f4380a47e49a7a80a0f6ff3795a29774907aa841eb99b600daadcad3e99c1e4d74c5bd06ff04e26f6aa0d2ebfb4cbaac5683e2110033ea16235b620933541a43ce0e2440fe84266429b6a0e149f5907c392a2cbac0ef6d4b6e9704f4f43504b4305439b40ae6a6bc46cdf1a0af8e8cc03593a336c5835dbfa74bb7d0105445019ac658c46ebdfc1c7dfa88eba01cd2c8aaf860c1da6894f99d6ee8b731bb979f03243ef5228929f5e8016c5e6ca090599762285a8c60211ea64997a1f04e8e7626506c94f07b81015e5d5bb4dac5a0ad5c79ba820c2a85ad2c098ba39f466d6030002be761b5041f512c20543fc99480b873f871a0dc1fae0fe35257c1c49dfe70cbb6efc96bbb2ea7f377645f4a120a2a23419e3c8080808080a0f0f3374459888a1dc27cdc073a3bd7d3524d144e15d2074e69390f01f11c214d8080a0169ddf7615ef655b05bf80dd31c20d3f830e3aff91d50e92f8b55ec0bbdc9fcc80808080808080b853f851a054f646a947184d7f9007bfdd1ca9a1867bf4c047e1320e3df07422fef59bbe1080808080808080808080a004b91e00fed35677a86a9467aa778bd3a4ab52f1f07ec581cfb0e23c96f15e598080808080a0df9d331585313e36916baf87d6a482045c2ccd92194f44b12790cddacd6e3a01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0f584e88ee9e80aaf1fe9f5eec6587d7ae8e792930dea0048a692148ee85c102ba05ef88e26d84363434cb547e8969e5b388d7a2df2a48bc3e51e6c09ae8862348bb90e9302f90e8f83028c60830336dc090b8308b6be94167008000000000000000000000000000000000180b90e24013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c7a000000000000000000000000a16805b72ae97bf54e393ee9025170aa347677bd00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000a16805b72ae97bf54e393ee9025170aa347677bd000000000000000000000000a16805b72ae97bf54e393ee9025170aa347677bd000000000000000000000000a16805b72ae97bf54e393ee9025170aa347677bd0000000000000000000000000000000000000000000000000041b9a6e85840000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000b0df90b0ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0eb73706621c2757a66b8ed1535f0252a8008f15ef401004032a0236dd4149966a014cdc85462819c4f3c660cc2a732aee11a1b1b60011c96f35bc51838835c8601a0f48bd20f032e24fc9a1e6b080d44171fce0e9e8c9909a889883325b79dec9989a033245d23e9b76248cc3db418fd30fc058da1c5968dd5e811f77b27e271c32292a0958d10af1229549b7faff4bc5072a587f8d124591952327544b2bb0dadf38cb4a0782b61af439bd6f0f749d40424269bce896accca1ab5ae22e157543f4e803f2ba00c81d177183aecf97c55844b109e02a86b91fa09bf1df7274536e519e835842ba064d499f74397919979df3f3ce80c35cb13d616e8604aa4260b2d882991cbf016a06328b15923059d23ad0f2c6acca21e0520b958545acaa487edb573ac8ba2e8d7a0cc8796cb8f8c2283d5daf891a906d0de3858aba6414050975c0c926d1e5e74b3a0078f6cc580ca081aa2feb3f79865129e9b3cf0066b19e032fa373a3ff8712055a0a85b8ad92c7da1d62ef8bf7bfe79ccc2a6c36f7ce671772c6fb6806a212bc0d0a0f7d7c580ba4956bb1cba28cf621217e945b00daeb01722d56bef7ec8beb93ec4a0ed5f21c63e65d50032fce217db02976167dc6d17358e1e1180a342a499214459a0aaea5b81f3b9220d78f9a6673b023d7c7422e3fe65b3d0838cc5d560c5c83510a0c6ae66b11c85645ba5dc2a12e0769aff511c352ab7692b7203ed5da7033e1d5480b90214f90211a07a9bb8d053426f267d35722aa3e29553e80dd4c626b024ef5dea732560f5faa0a0a21d42f0a450d63dafa86e44afa3bbc79851d252e739be32e4625408bcc8c8cea057bdf787ccb36cb895cf06b666d81fd05a84fa9a1db3287f70561350a8e047b8a01663d9590e47b600d8b927d73db7da609524c77713139daac513645b6f071b7da075e1140c2cb7abc7da18f418a45f5659278ba91e3f686c51b2ceb9d7581e2102a074e133aa6534695c2777756fa366d6a37b1c73fbb149215799fbc0670c9b3b50a0fe940c84fe43ce4d6ca0f6b1e08d1c9d355cb11ce64dba2251059c35a269e474a037defa84b2b7d5291d02649bc8c16f09fd63cc3ca841b96b3afacf94ff5e6c55a0991f8b16d0acfeccd8194da72e3c8a04ff326fa6615aab04e02ab437151b8c68a00a2bed2167b54b50018be02398c3e4265ee90d758e933b946340ad1d09cc9bcea03907ab593fa690480d36350e2b0a499e715013fbc07ac820652bae88b8260f12a0dd309cb1ced2a54f0182e3fd1f81daf8383203b22ce56ac30c5da88ba858f241a052aa356eed5c1af09812a301c784007070850cc157388567185281e985b03fbda052e401d2b5b2c0672afccd21624b8798d412021950d9c4157873505aafd10796a01b7d2bc3c317c6babe612bc78bea2308150a495f28cbd1c61a59f824d00f176da02ec1dc863a7738fd07cddd27dc026aac9d73a444fd848463671b4d10dd1cacf280b90214f90211a0780e5e9beb1953d0f4acdaefe455a9dc6ef6d86894b14ea289814288fa37a38ea0b845c2128aa6f009d5c0d3a6702ec59d8a8751a061ee3d7d2ba87ce33b7e046fa077b0852232374949fa01c70efaadf18b64a2a43c9ffd7fa3de3569c3f45a3791a02b2f76c6505025511cb0fcf83c6cc56233e08c0f9030b99229cc300c94d84a2da08d5506508865accea2ea80e095fadda9caccbc1155889d04015b13a835863383a0d9d888429efa74a3c9f74e95ae6f0d6e53348389a27dc1f63da7417fc9152962a0d9274787c038f58690508b73df130af230f9a71d231a10d150f26453f5707653a00105c3459eda91d5764c711857521d01a3093fd84da79bf196c23e6fae76e9a5a0e8b10237d27a8d0c56d4efbc674b03862dc89ed06daa9d5b297ae3c29ddbb61aa0bbce1603aa04d801e44b7b59fe6a1ffdeeed4b8aa63dc509ae9eea931a24d914a0fd51121994825d5fa86d3bbb5c73ee89c2792c1f3fd4ee45c53db8b3df75029ba04ed512489c1d0064b77d5aee1a7b61231ec3e662733842d75c568b4458cb1a6ca049af10683cbae91620c91392ef943ed4408a9ee4b4cf87c00aad88edc9b94696a0a36cd1c9f10419755999593b554eaf7e08d7f4bd889a765144eed0c6f6d423d4a0aecfce94f632c0a9680e670718abf1d7cb63d427b2dc50d61c5b1a153cfc4085a0e4c333bc951e865d109992306431e1e6c6eb83cdafb3bbbcfe216a96b9e3e7ea80b901f4f901f1a08a4afd58e1ede0d1bfa91093384ffcbb3472707149e3a08476d84094f9a14e37a01e7155fa4f8858b834f9d092df92299ae530ccefd64d8f50eddf3a5aacffe141a0a0148cdd329b3d065aae59f8d48eab6b4efdf6de69c3da6cae4bf75be35934a3a03b89f50c3bf0751702ade4233eb1e61eb48f6ed7f19d40726485d76b6d00e417a08d597ffeda05096a344238491896bd272aafd8bd1dd172853ab0a73756221132a04c6648da30651084a95b07cef0d1f16a3a4fd7058dca533d1ae48523a7646f8fa0a7aca4b39f8ed98b3d01682d2f384a4fec5c424cefd765e3775718ad4429380ba033d76eceb7496805680a536da2e7740639a3c15d57950f0590b907139345c7b3a0f60b82b58a7332b5927b803fc323f7b8d5fdf404576dcb422983215892f7671ba079e31b194725f593639d2f84a94b08757d2fe1af9e5a93a6bfbae913c8db753ea0c1cbd80f8dac7347e3aec54d259abfdffc173a325f8e42ee72732940a0f428dfa0dec38164636fbedce57af6b6439b77739a9a6642ebbfcc7043d44dcd8eb1a99e80a09eb5ea9490bb548312de34b5aac21538afa63873c63b59bbdbec40c674fa3290a0a890e7bb2aabdaaf5911fcda22fcc2c40363c898dd87c8f342fe9f3cc894d796a0dad8f6ce8ce40c693e412bb9457aa5bc7afcb32ec01c23263399f073e7dc759980b893f891a07e3beadf2f5581daa6d928e0a43390bb9e4e75260296d00bb15b3a74400f8159a0fa960742e16f69caf287baf324d4f698b488d9c0d5715e77c740d9a83188dbd480808080808080a078eb54b969f06212b25bac8b49990d37b61772e2accd77b4d1ce95c55e7ea2bda0dc49cb1f059324c4a68e20cb53f8403fb3e71da6013ae5c09241dd76b6b8be68808080808080a1e09e20f514bf230dc63f8c004f88f38aebd8529c7c50203de1b956208ee28dec01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a081f8cb189e8970bc03d9dd54cee9480d2e215cc182ca5ef647ee533e8b70a859a039a2b25ff228cbddf063cefc837789335a50603f73c5f01dc90a487b73c765b7b90e7302f90e6f83028c6083033653090b8308b41a94167008000000000000000000000000000000000180b90e04013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c8600000000000000000000000056063b198f6afa35af1eb402b80209b3677a32e900000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c6000000000000000000000000056063b198f6afa35af1eb402b80209b3677a32e900000000000000000000000056063b198f6afa35af1eb402b80209b3677a32e900000000000000000000000056063b198f6afa35af1eb402b80209b3677a32e9000000000000000000000000000000000000000000000000005f36753ffb00000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000aedf90aeab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0402d30afb7972eedade42bbe54a4fe163fbcdf49c8cc2a3778a6909b890754a7a0d9995d1e7ea32abb11b1fb93abbb16160ed607d1a056b45237a014799bca4f4da00aa83456c142901fd3327929009eace9f652f4ca7eae3bf3e0401e322e32e367a07dcdb69d6ffe3c2f119adae076d7cd0296e8776bb6de4d3c8b194500b33e74fea03047cbdb11b0ebdeb1c7c9a368035df3a3c3a31cbdeb0fab007d7e375583657ea081b6709266f7efa2ab12014689fab794379e54a03926d71f2dd4fc4d5b78d2c2a0437b43ce6fcd63a27c5e06f932ef4a19153948faf983ecf73b96ac2969d3debea045093c3bca3ec4629dc8ebde10a426d679333a54a9c5b56e1d2e3314a5a343f6a0948bd73d3e8ead561da6505264822d5bc3ce0d47bc30b8037001952b30f06c6ba04d65154812e8d03947995de5b3ee358b423c7a5007e9b6aaaa60bf9c34d23f85a0da34ad5e3ccef7398bc112af8475fa52ac11acac41e0af52ae9d215d68e8a38da0509ba6aea3dc00e005042565af104984dfaafd7adc9e3a32b008b56aafb4a67ca07b8d860dc327a89668fcfb2091aff0db8a0567c1e16faadc04331c29370e1646a06bdf42e4a60c7f2209a34716146c0f02ed902cd85d2f1d70f084e669693dd711a09c6880346b317cd0922ce73022b4bd21b2e2e3c6d42625bed067110ad158f1aca09266f9dc7653175bd9190a516fc05d109bbd089c3397f604e5802d8313477a1b80b90214f90211a0e4f3e232621aa194aa3b72698ff756e3bfd60752a21b57d2387bba50ee7d4fdea0ce40ef4eaf960378f94577a0aa3bad7d0b7ddc7d0fc47c877aa73ac318a24198a063b94bacda1c4ea9f6b5793f09775873cf3a8953e7e0e2cdc28de8dc3f6f62d5a0f895df104a45171b9392ab1326f739afa871ceb1058f8904c1b1eba0c9d25568a0ee0d63e47370e8033a613fc51bada78dd963aaadbcc6a11cbc49f2c3ea743649a069a71ac3b09da17bf22617ca925f5074ef7a134c7cacea329dc6e64852a826a1a0efa155b582c8c9c0c6a9e628bf5de62098a282aecf940e8497b1890bb55fe824a0aad91573d91a99c99924d52b3e04da13899aa649888ee39300a7585257bdd42da090e35a784e6f61fbffffd0984155469e9d81906a8446d018e10ad5ab6e977188a044975b92a151a4897dba1544210e63a1ff8703b4956f48a2c8a208a51a9bec15a0a5417742a3486db9be79a4af95946b029e2c53559d130ce44fed2b88743b525ea067bd5f2e6ebbe8006bde1a6b30c590fd591eaca205196496e4992260c50babbaa0d6506bd3bd40f8100ffc863c53feed59c2b5ba14446ded881e3e0690111f7882a0cdb95bf26212d95020043f7454c1aa749dff01824659cb5e20099157f69e56e3a0a0ac442797a0cccac64723b22f91989c723381df345327d5f66c1aacad513105a0df301f40f264c506fd385651e986b57e181091885740df3a7e2fec8e37e66c0680b90214f90211a04caa4f0a5314ae90780fc5a6c0b82c10aa10c3479a241038338fd76c7bf806aba071f8c62bdc52689a7dd945ca78e1bdc384a685d4338cfd857929d7260a2d7460a0fc4bcb186d0a7f63b9c40641ff02ecdf85b7d9d0a0d9be6117022ef25b54c49aa0c2f0227b3b1ae63ec8d9d42f938101106e05d7266ecf93c3200e21a0f82d4b16a075b550710197f40f04e4d1ad1223cc9ba11d8174f9aa6dceb91e85b8e7cb68dba0d722fa5b5ba3db75d80a12b09d3af495d7517dba7c15d763a5dc8dd7e2777f3ba0a379958c097216dfc46b041cd7c5a33b6f8290069d756cde41fce1519dbf8521a06ad2e7b6578ff189ac19c9b06813518cec1dad99d781a3406a435f9d5e085569a0eb7dce90ad477cbab83d9b66215ea9353d94cf68830950aef4bd896b65de72ada080384e44f04b433f4c585e8e78b43e7d48194512d4284e7d764ff474e521c751a06878e80e34c6553ce09e6dd11601a9d9c9b0c58257da0db31458d07fa76c7536a00b53da028b610e2ba023e6629f333a7179816880f645343728f308d691e8127da0c1cd3106b8c0bf6864eb7e487556403d2d4f2409472b283ddcd440d1efe8101fa0b2e90c19f2001689bccedf0d0c367e12d72203362749bfa59e17db1d0338e8dea02ca73300d803ff80a294916ea1ff3cee359abc27f1a2413decd6147a60609465a0e938dab91b6b4891c6e0a3d8ca1147ab821be033dbef9c1bab009c6b5f2c4ddc80b901d4f901d1a0ed823d5c6d94a95229d3f30fddb6c82c7fc3861983e5923be7d51df19c46663b80a0b4ece6cfe5e14ecfb71498addbb9fee5b9f796b58d44c46b8d9873d483cb34a3a0cb2131fc63ffcb42db4268558590a03a64f485fad3e864120230db6d3c792fb7a0f7033b70bdf6e34b82d73b5ee00eaefcba6dd98ca082a245c9e6064d1d08262ca05b5327702290206efabd86da246094ded3ae564fa405c876b5a0a0e3c8b90021a06b471423424a9cf15fa6c597c621ca089ad6ea5e9a7f19023b0271806ed36c85a0bc0cf53804c44d5ffe9b52838ea508560a7bb214275033dede87c646f430758ca0556489ebc931d4beb94a7991afe2ab60f9d9a94f85f64da5ea9f52ce54ad52bda04c7f1b092e657a40445988571a5d36dbdd91cab5a19928bae5c9476b7558bde580a0fd9f1b5a3d9f2723b9b5eb6f1551c2185933ad2f07e4a9db24f76c92e291e7bfa0d6871453676e47123d5bf7e23cfe248ee6a8e6bfa87e13836bbbdb587ba18d6da0b68c3289a883fcdacf0f05176a74e32237abc01ed4487e0d18e144c99d37437fa0233494c09012341dd1522ff8869fe7f44c23542f70afe43d7ffb4e9d6b3ea72fa0cc4fcfda06aac386137cc5da6b6185a54ac06f7e76251010890c9227e52c509a80b893f891808080a04aca83f96e49638a6299d610b4e43107503ce80e192782b210e157cfab999af18080808080a0a2dec0f4723e01ca82cb8ec49c0319a653fad7934e1b87021a39b7b8d8682ed4a0f0cf1eb0b62b8325266024d90e2c68b9ed685f15188017fb679096e2604178a98080a099b5929e8f9d011954533ae6af5e838cd78c212e1a9eff19394099b14fbc93b3808080a1e09e20a53d5d09f1821c2629aa8b7641cf7c356c4e797e1fc8f61ae7548766bf01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a00e1c8d8ed97a4fe72828e8a8902b0caeef3a779dd66764832ee8699c804bd068a03b819e27d127c2c4586223ca9c9ee6f2470709e106f4538da99737d0a2c994f1b90e9302f90e8f83028c60830376f7090b8308b6a694167008000000000000000000000000000000000180b90e24013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c940000000000000000000000009c57d892f953ef40071ef16e63f69de1c2cf1fa500000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000009c57d892f953ef40071ef16e63f69de1c2cf1fa50000000000000000000000009c57d892f953ef40071ef16e63f69de1c2cf1fa50000000000000000000000009c57d892f953ef40071ef16e63f69de1c2cf1fa5000000000000000000000000000000000000000000000000005f36753ffb00000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000b0df90b0ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a026f93469575e7ca18b6ed52f5616781748719739d433f28fbc96846f89f19e4ea061d85a1b32424a58ed85ad9585a2c02309a3ff7469c0e57077744bf2e9f86beea0822c856d94b9b099d59415ce5f15c8fc94266cea4d21f85858ef24157dc00b69a0b8c3f28586b8da9e0986fce31aa800437a9aefd1946ff50daa6ca0b69292d7e7a0e4118df3b34b9aa2c443dbd2ab2dbb14f1dbc03963d8a3c300dc90c080f92b46a0ff2c3bdff946facfaf438d478683a47464ad75683a16c3b449b097e446da7af8a086ead228abcd15b2da34aee018017d62d1e293e0f189d18e938097cf04ac557ea0f3cb42cef2211c8542ea5beb17c7b952e38754971a504873d0a82f97fb997997a0b5770246f4e383270775a8140ada94f4292fa57f93203a39170658f6d3045e92a0f8167f8aa111a4230fb4ecbbb283b6b6595d5b100dfeda73aec2bc055c7c22b9a0aa8887275aa18c7d6551c63dba53a8d8ee5068fe54cd9883471449536695ff70a0b667193da4e2b5050722a251172515267df4b45c8b53bc5248b28501bcc49e90a05582fe73f4bc23bd817b5e347b056a80334fade8b0884fd78b23ab2c9172929da0bc01ddadd5bdd1bc7c862451fc00545ce9f6bf91ce2b5c80c801a2dc85567030a05c6c0ba2944aac42c0bf4698b8e5f7100a13db4d52d5ce5e764076da945d4601a08227d6e164048d39ad888bb317c7d4cdae8bc1c233b16294b3c4a3fedcc98e8d80b90214f90211a08ab59d83e469060ee5a570d89f22bb49dbab1e9defa91ab7e34263beb9aa90b1a0d07edae38a947707889dd055e963559e66fbbe00cc9aeb5098d0d399ae071760a06e51096391720f919aa5d4148a18ea2846fd158cec27a9eea73636fe8a0c4dc8a0f3f7cfc5f00a2993ab05f4a928aeee9767e8a1836c2c613df7e6d7bfd69fef9ba0956264873a39e947a303a7477b71be24d159e9c5c3184c0c94662e7efb06dc94a02eee36e96312005f36544649ea68ff739db626804dd11ccc44001e3a99337f17a0e412d0d3354d2650972e4f72721bae064daa853c28829c2f48906b57041d80baa0fb062df87a8eddaea89ba9aee4f5c0fbd0f03804ab6dc69c456d55b1becf9b3ba045d8d7e7bc15db0ae08b104b89c870368e29bb26a43adc9ac8f001aa72e70ebaa024a0d7db96d45925f03603b862f2b907faaca59e971b371f509eb26863d429c5a01871d8860d5cc0d6e7315b4ffdc3df3989961b4406c31fbad5b785d7ec22cc1fa0e0ddef1c96ac0c76bb7e15e8d3f749971870ec012be34b2945b9a6aeffa7b7fba0b682fcd05d064561258d673ceb55804a025e0c22036e896894ecd6771fe8cbc0a07fd582bdf75377631f92a8836965f6c417302f2879302ced6e2960042c01c28da0fd49c42dbaab3de7949c7627fd6bb9cce17ec07affa44a0eaba57f0c84277b61a005479bfc8aa0e4822f6af1d8ddbb5cfc4314bc3dff8caeaaa1394154a7048be580b90214f90211a07fda690ab814675276e6e90779cccea95944144089d59f74807681d2f92dd206a0f292a27cf64763bf454203c2258e75441792ab63626101c9882db934a4e59736a0718884f77ed667872c71a8c2041bda833880238bb5ddd49cf3b344b16e27b2eda00093070c793cca94c751d08cfbca6e0840f5c8ee5045321dff849b211c180970a0ffb45adf46d9acf90add5b94947d30d5fd35cec0603b365334ec1d1a79397c18a0eb9d96d33348c47591c64f072bd0223e73012c3f5de52cf50f293f52b528e183a07ba407998f84203af61a04c9874e7cd366368fcc5449299154b9a320dcf05201a0d7ca0bae5cbb60779b83434dd93e2febd7c4d11adecd8f8f6fe2bdd0910e661ba001076532fa564a7ee3a4564cb54b6af274dd29b9eb3a85f8b5fa67314591f4a2a0837b704242467b7a39e2054c591a05f2c1de93390c8f1a0e8b890451088bd86da06fbc1136720eaca23d206be5bce66197520d8586bb3a36bcc52bfc88c9e52fb8a07a18a61d55a8f2243eaa80aa11c90cb0192f5462699b69db61b695dd5dceae80a0a789e75180fcf172ecf0f32ac9ba614b2eeaab5c767f46e9557c5460e6392a89a0e6ca172c90326b177478d484bddd8f4f1ff4df9baadbf274225f0ed0069799b1a026d0270848b1baae4bcd18efd2b25c44a077ec21ad8e9782e76432a47c841ab0a075c35d60ea62ae93f539661491455034927d29cac4a2fa430e4cdd5790da60ac80b90214f90211a0a71695e6a38f1d2075d472f542111212a87f25c08967fb17299d4ed6b373846ea0ab0762b7f272282b2df3ac30941b2ad306bc3a5d2acbec24642bf362e494b16fa0a17757d8882e67cfe9768bfb391cafa4bfd33f0b6b2038fba8862ceb25843aeca09e79b1d49698d1d58249ca7960bc6458036c71bf6ec95d73e983c70a4b9da4eba05723922f84a151a8c416eff526f7a394b2924641be3b7d875f77554814a5f0bea0e428ccb44257118666cf43d7b19fb9fd85448a8718a5be744eff0371da5acde0a0a815cff6a9471628ce9ba38e27829637a15d64733fc6fbc25170f328ee909568a07d1b02be791201cbca3fe735c36a95d6c150bdc7d9c752ae7cd4f85fc8bcf428a07b5a3f4f431f2589d5746f854f9ab6556b7a8d3758940a71520c9f6454133c07a0f9512a8c8db5a4fe207437724e019b4a10d0322d488e09123d2e2c7c2aac9f25a0f2a7232c9a1d30a381044eab49548e89465c6d73f97d9b778c3444362c24e0b2a087dd85d6ad06b7b4d1f6fec479bab7e93ac79c47015fbc3c46fca34390c57ea2a0d1d86f54b10fb7f6d97403fe35f080fb9f66a6dea4cb89ebead0d833ec3069a4a0586622cf6613278fff632ca8bc6d79a4699439786301c92e0759275d88e57e6da05997914e0e264ac5bdbf6e4869764e6af661d6d891dad85d9bb30208c4b463b7a0132fd2a5aeeb9a9aba409646429da4f3805dc5462c94b0c28689e2200f844adf80b873f871808080808080808080808080a057f5ab4b6c00ebf37e8ab367e537489293670be5f945390d34c0daf78ad7826ea05ef4f4d9ac50a7e84bd22072f347b61faab5ead051a57224d6011a3b94ebf18180a0ffabc92296375a7c8fb2cfd7ce79d762b2cfc7de8778ec1757a98a4e94e4dfff80a1e09e20a736f9682cf5fa19cb0c03063ff35a3b55c77a4a4f8a6e01d470acba7a01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0b965726880cbcf644ab36c899838dd6cc4c00f5a462d2d5f192104493ab355d2a07307f2c9a9a2edca082f6849da1fe0f4d33f4642562643aa2017e7957dc36b32b90e7302f90e6f83028c6083037728090b8308b43294167008000000000000000000000000000000000180b90e04013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c750000000000000000000000001d6eb1fd5a06090fd02933d1dbe379820c6bd54900000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000001d6eb1fd5a06090fd02933d1dbe379820c6bd5490000000000000000000000001d6eb1fd5a06090fd02933d1dbe379820c6bd5490000000000000000000000001d6eb1fd5a06090fd02933d1dbe379820c6bd54900000000000000000000000000000000000000000000000000354a6ba7a180000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000aedf90aeab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0eb73706621c2757a66b8ed1535f0252a8008f15ef401004032a0236dd4149966a014cdc85462819c4f3c660cc2a732aee11a1b1b60011c96f35bc51838835c8601a0f48bd20f032e24fc9a1e6b080d44171fce0e9e8c9909a889883325b79dec9989a033245d23e9b76248cc3db418fd30fc058da1c5968dd5e811f77b27e271c32292a0958d10af1229549b7faff4bc5072a587f8d124591952327544b2bb0dadf38cb4a0782b61af439bd6f0f749d40424269bce896accca1ab5ae22e157543f4e803f2ba00c81d177183aecf97c55844b109e02a86b91fa09bf1df7274536e519e835842ba064d499f74397919979df3f3ce80c35cb13d616e8604aa4260b2d882991cbf016a06328b15923059d23ad0f2c6acca21e0520b958545acaa487edb573ac8ba2e8d7a0cc8796cb8f8c2283d5daf891a906d0de3858aba6414050975c0c926d1e5e74b3a0078f6cc580ca081aa2feb3f79865129e9b3cf0066b19e032fa373a3ff8712055a0a85b8ad92c7da1d62ef8bf7bfe79ccc2a6c36f7ce671772c6fb6806a212bc0d0a0f7d7c580ba4956bb1cba28cf621217e945b00daeb01722d56bef7ec8beb93ec4a0ed5f21c63e65d50032fce217db02976167dc6d17358e1e1180a342a499214459a0aaea5b81f3b9220d78f9a6673b023d7c7422e3fe65b3d0838cc5d560c5c83510a0c6ae66b11c85645ba5dc2a12e0769aff511c352ab7692b7203ed5da7033e1d5480b90214f90211a0c6bf8c8cf99d1fdf04d3dbdf4be61c10d26888f933a501cc258cd146bde4cdfda0bb0aefbcc3231fa59d1d21b5f82655f83d42a152f209692c158ac303f5069f94a0db73a020d5318c7852be86b5787aff01c0bf4585b90aca2a3f5311090778f14fa058c7c6d9158ae7e61c775ebb0f4f25ef61f43f8bf8795805b05d60820b6ef6fba000e375f9edd48eb00eedd14d56a30d39b096ebf7e4b347b441676972e0b2cfaca08d351d6c458dc629cf247756eeb0cc2eb6940f24a4ced0f93d2d08f4b9a1ce35a0508d93b30360ac95374e456359c19bd7756b0c5258cde494c87dbb38baa3ea8da070b43d84fbf7ebb402a8d84ac69141d853796b18f211371b10f502fefe15a8eaa0071bdeaedb5385f079fcd5ff02327411843160d3a50c24627d9b8e80b8fc2ea7a0ffb95e587447c9278cded63a1297e430e6c93e55cb28503b9c7f0cdd3ee53888a0963d9315614389e8354ab3a54d38af695f202019a5963f21982194eca0927797a0a7a2d9b573ce09b979b3d10c4135580efae957856857cd08368322d1ed4f2d82a0099d447cda58b7bcb876e683407edfbe1e3bb9af4118044db8a96addf3fa1172a0300984aa0203b49f01b94f2bc2facaec5876fbb048d958ecdfde5306cc605051a0c60d90eff26c403dc5c5c8c4214a3ac6fe7a28bfd95c64d52754ed4ae0577d72a0b81ac1f17f06e25d4b062b5cb039452a988ce45b2339e5b0caf5e4ce1169025e80b90214f90211a07a702363d4f98362c96491b3adfe2837f33acc296475db3bd37ae3549c691c37a038563ddf95368a7eaaa5b219e2d546e6663686b7887e82b4ce27248b54492389a0a94217cd93052aeec4d522879302b91cf11097aed5e4f7b6e12aa6e2a13e3561a0b64705e9e28f57ae08d9ff0c66971a7db66ba11782463c5791a598ec608f830fa00bd016874ce0a69ef3fa00f3d8741cff873f6b19f2145493217d1c8bdc8eadc0a0ee6eeeb1cbc1e8c7df989efa7e9f8b9e1e1e55f0decf68f4a4590bd9442c7574a020e0a0592b4da2cb7d977423faf5ba3192d6b9013f67029ffe31c38407233670a0a11a773e63596b754d6db450ada0c5505ce9bc219742a1f29208bc5dcfd28ab3a022941c9c29f1595c9a9be8a902715d16b9015a8645fa60769bbacb1888377d7aa08f3b4e2b7c8c9e143b97907db9b61129211b4b9a523ea347f0a0dfe01c33e55fa01f599a7fbbf67e7e12342f5bf186ebc57570f09fcda960c95dc7d93115f87130a0b4a9d444c43651af92c07221b98d323da9a8305d8ffa34cd5105303c1b9a7f73a08833cd5235f6c3ce00b542d5ccfab600fdc1a1606e396290d2e64ecfe97006f5a0c7d84258020e375247864c16c4538c994367c11caf0af4136541b2cd7db535e6a0cc4b376d170779face6f2632e9f887a8f72d8fff1d655d7d591ea10b8ff3820ea0abc7f1ac8e2108681e40a6d6ec0faf429b0ed833ad82a98da4d6513b4cec7f6d80b90214f90211a05efc2a94fe41f209e9357108614a1e66b7c3c1116a0b5a0cec5b46313769e3eaa07415d1c5e850f3ea7658b7fca5ff78d219005c7219bf98cf1d14be27935a6120a0d28f322abe824534cf71ed397ffefa794754a7b2bc4246a68467dd6143a10b1ba0b0e733f14fc11d43a4cb683787f92c2f6048088191bd281a0a2b48a84bdbd3aba0f728ecc8471ea22dbcc5fc6ef7b6c3b9e4f3013662fc98a49d8dced83d21b70da0bfb1de4d676d895d628fb8e36169327dede8a6744c2a6bf404c136e25f590340a0a470cf1f5758c764371e1d40d3020ff48ccb45d9e01613b3ef8c3eea35b4c19ea00f3d56d1d934586ebe6305dc879815d5b30d03f7eb6cd3bcb93cec997919d5f7a0a1c10cb79e835e5dae2b43d9e7c70db569ddfb98e6ff82b9a6b2a960c5d52f24a0c7c58188bddd6e2059105d07da3b3bd9cc8d7a77ee4c20ad083a744dfe64e940a092f352972aa6d3937abf5212c2e8fd0e2866bcb01ab894ee2ed150693092d449a05e093005cff06a7ce3444954a979695e621a87c3a6c3e5d9d9aa545aa66a289da0e0b4e77bd67f4bd5b72b8b9b8f5dd280a003fc2877ae051061ca12defb5cbc27a04d510569700bdf639e69a18cd38bbdf9a8a2d8e10f3c51ef2e3c68c045bc83eda00fb887dfd2d02e53d6b60aa5db35ff748533c21876ca44cd184a421333ffd3c1a094e6ac4cbb7e15d5c8bd97a7125af849af733ddd4a26ebef001051b7a15e18a980b853f85180808080a08c049e794e8b0f955f9269cff8f4f2e0b24030dcb72e31517a6c36620b7e836f808080808080a053ce10135089b5b82b431a495c68c9410043f5964da40e1a3fdfa0be2ac24eb38080808080a1e09e20d9163349c1fa75f2b4bdedc296842b6ec2728a7b9556130f8bfc99daa801000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0a27d023330c53f66286cfe3e80920f5d6e23aa8fd6fba858a74e2cc65d5c2f22a033f789cd11654406546196385da40ccd08dc26e3003bf54f5bec0cc3ccdd032fb90dd302f90dcf83028c608303382b090b830833ec94167008000000000000000000000000000000000180b90d64013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c670000000000000000000000007c23f6f5345008a0cb1cd915d4d31907f24b8b2f00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000007c23f6f5345008a0cb1cd915d4d31907f24b8b2f0000000000000000000000007c23f6f5345008a0cb1cd915d4d31907f24b8b2f0000000000000000000000007c23f6f5345008a0cb1cd915d4d31907f24b8b2f0000000000000000000000000000000000000000000000000089227ed85480000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b4000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000a58f90a55b90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0aa98cec5fabbebaf8cf36c4a6131dba73a3d7e70abe497f44ada7136cc89fcaba0a73a5ad7525521da700db0c93dad1f6bfc42c08507f0f9ab0275d45b7a47c134a05f78bb5941f675c0627068e84763b8ddb92aa924030b9a3b7daecdfd0c515db7a01437bca6e794d3792e0884ab3980ba45bc4a8ff053edd93f450326c0932352a0a015ba54506ba9287dd95e6c638901d4e65e31b143aefae47819130c0b65573c54a07c15b5009c87e335b6ebf5a5012d4542088ccc8e4e646f8d84e9191d9c144caca07e301d8e0adb7eaba07d9e403b5c48560afb1f9767a03ffba668d2e0dd834db7a0b479dadde5e73e8cfc1cc2984272da73bf25c959cac75f04b2fa48dbdbcd4f41a03e1fa45ab477d5a2d96eb0f7defb8540918cfe690a91c28fda42b7ba0a09c685a01c0feaa8252c4c569a30d89a09684ff1c25bdffe383631027ef41d031541fa59a091d5259c91ab6c5e1fc57eff3e269bf64d6358a851869377e00307ab3716ba47a03cc119feb7412854581e31796a1bff14744cdf3fb6fa31057461012f91fe8d9da042bb2b5ded56789365e7f50847403dddc040cd252e2d0265c2750248ebb449aaa0410f1ed125c772539fbf73a801205e4c48b4b08ac4c6cf4ab521bd10dc63c2faa0c20b046606b0fe10dfe094824ce95c58079a9bacc5fa15261fdcab610416a2d9a0a4010b0079fd746a9a67f720f6d4b1b28e685313f2046fe29b8f0b7475c7edc580b90214f90211a0b3b55caf3c966e19f5d5a6fde5e25347f161583a6e568722b8cf8552841b1439a0821bd6d9e539a7e0a2febbd50218160fccd43238ad00a01eed737a39916fb0f3a0d772b569537b18a5434c298877d76b43db0ab9601fd9c3cdb2c2115501d695f3a0ffbb530eaa1fb7b594d176972cd22653b50643b92fbdc2d2396e8af83b583cb5a0956c7e628349f0b703c0fe11ae1c51766a98da1bb5235b9b9191f64996212c9da09844d59b56ed346a146bfdac6790ce9c8d490389e7bcaba9bb61f692bd47dd8ca0b6d5b6b6cad0cc61b54aef8632bed9a81479e24ce65d9e79d76f1e6afbf0daa4a0285c265be140c37fcb4d722b33be9d8b59c7f45cf7d86e34477e59508ef3e3aaa02a51e788a5f59d4fbba42903b16bf0361030feb95df9b05d9aa10a078a7bebd7a0c5da69d85f9cd37699e3dfdee41c9b5a7cda401812eaa434b7e05d17cef70eada083c0a1cabef9c0fed02e945ca3e9796e5b46b6448d7305b384e3138bc0ab9bf2a03e7b8746c779d4c2ce5fb637dc82e57ea12a3a12ca9becd6871f39b24c550d25a00e5672c112c6706db3837065665f42e186f560b05d859dae659eeedb4ef8b736a087bf3f4273711515706630d1ae5baa314369c4412a1f37d015bcfdceba7c50eea098a9435e81e48836a05809ec907f875d88dead61b61d06a8be80f202ddaaedc4a08fe4220591f98367d685d0ca4269e823935f9d5a8deca14c19f7699a295e620980b90214f90211a00fb69eefbad0443ee8c03429d416632af9e4090b1a74db9e8b318a94e16d1411a02b39a83ec499864a7af7b37f13a16dbe9ea77e7ca4606dc981b2d67550f10c71a09bf9a3a92c25288f9757bf4fe651a1577d856eab9372f41a808ce2296395227ea07a6a31b4af03669644b3693dca9a9de91e4d6797c56a9c3f46e3931be38c8698a0a7df52dffd4e6c483e9bfb9fb933b452e6e7fd9d6e008ef00c8eb42459c70d3ca0a7689ce8cfd7aa1e37330c9945c22cb5b2f93053c83714eca7b5978299548000a0b2aea4626bd45791ee5e6100a2cc6b6fbc1a7efe29e650a9df955bbad383bc69a030ab17728cdc20001ec9d139575e44e23ba9da744e8ea4d3ea07306b547bbda6a01e1b4f7c31e98a223fa4a868fe053ab1ce8de80cd8fe44a284fd97923de58d18a0fedb0cb638ed7f13fd4d573cea0922701df7de17959219cf51eb5d0e5a76d208a0c9baa87f3bc9da3495cc54b0206da532056f65205e980501d7eb6b95b2a808b3a064a3fd026719a91e26cc626973260bb490a03a7b2dd17b4250957f9a4e515684a05e70ef17e54c222846a0af744acdf35fdd36dd20b866a243b40e506d49b02e53a08c8a5aa307b8ad5f13920a7e5d65ac15f9ecbb63e31b3efaff393042d199748ba043612b4d009d4fd9aca02212d54dca62a7d1a8c5f0a71fe1cfa2cf537b9c3641a07b622efc0eb8eedb70ddcec93e189c666b0113ad34d9aeb4fbace1622f0c941380b901d4f901d1a028680a62962efcbf82d5521bcf10c3ce4d5b04e7723644d95ee202a696b22367a026702b8c9101838e0b9162800be5e1ce136da5a2dc1d8df1de6273147bd0628b80a05ad81064e50fa11d8242130de7198aaba548d02e33617b5857f9bb64b45b3ea2a08aebedf45322d44fd48708cf44c0fa62486b9d2c74c06cf25dd676af34b495c7a035b57ad3b69b66ab784bbb6c7d9a561fac2821da269b42441233479ec98e2194a088054c5aaf86c71074769f66a943dd2f84ae7229e4748782c1430b122502961da0b828b7bd88f1b6595cacc8368761b3c7e430345a2013ea0e21f350390b9b843780a09dba24161a74be17cf114e5406a2edb09a44e9da35f648f85249a51c171aa643a0d9da3188abdd7a11754b1a5fdca2149ffdfc1bc9b2f793e2bdc7da7149ccfd94a0c5b0601000166c6637acd9d986c02cd005beeb34a6d31e4286f925c8a3fe7463a0e0f89e35b54cfb1e57345fe4595123df93a92a3a3997199a92aa6895f8ad8d96a0eb790f37d5d13cec1e8278cfa694f5d83c1556fdd6472255b803080ba9d4e2ada0dfcc9dd189cacc02cc19d3945cbe67dc762d8b89b3e0c7ca22b792715aabf472a0e4d35e3131a13b058697af240d3763a990b0d8616ed3883b5cf7512f09aaba8a80a1e09e3f4936b963e33a916c86d127ed1b784ce558c3b6c82fdcbc26f9670a91260100000000000000000000000000000000000000000000000000000000000000000000000000000000c080a051f6ca352b9b3aa673c036fd16cc364b7cadb2d7a56d962d5bf4f2050b02163aa07a0f5a89a0a61c15d5b4ece0b6b9c277f4bec4b76f707db722b07ef36ed2853db90e7302f90e6f83028c60830379c3090b8308b43294167008000000000000000000000000000000000180b90e04013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c63000000000000000000000000641d335157e51a3a8eed5b19515d052a4e35ba0e00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000641d335157e51a3a8eed5b19515d052a4e35ba0e000000000000000000000000641d335157e51a3a8eed5b19515d052a4e35ba0e000000000000000000000000641d335157e51a3a8eed5b19515d052a4e35ba0e000000000000000000000000000000000000000000000000003c6568f12e80000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000aedf90aeab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0cd7efb2e1c779f5aec6f3429aa6ac5a2fc4470e67aa3297bbacdd366715c13e9a0726969581ad486eb7171717a9e12e3f274d17805c0d178e221a65f2ea9f67fb9a0b4cbe975d29a2881349fcaa7f45f9856c001f4f0880f449dc34ce985b6d0b4e0a01b9de20e1f77748d5075f6c3a4d997703d94a607d361e61ee13dceb440b82cd6a02b2b6ba29387b9cd9eeb727702da93a26657fff4eb328198e64fc09698452b5fa03e8436c2b4dc4f4d3d84abc958b66fbf328ff86fa76486f0c297b6e9972acfdea0aef69b93460621f8425440d5901dfeb9497bc8e113805ba3ee919644ac17d339a0c7e575bc91d7bd283498a43d4d0f5ea94ad434b30fc676ffa166499d094b8d44a078d19a09f67cf290c4eaa97bcc78ecb94b7354711dc675098c97c2ac05a573b8a0bc41c56bf50b02e0697206b88b1613661ff3d506f5e426e8d8a2be09617218cba05088b830c222a2b359cc173cea5dbc328a44b6321ada5acc7881e4d277c92ccda09bf9ecf20e5eb1789a7096c617f922e47836374b65311343ec995739de906942a050687457258fe081c4e40927b51218cb703b48349dd84465ddbdda971f7dfd57a080ffeb9190772039a3f5eef2b54cc2131e5da0f9ce39649d8025ca1d3fffc6a4a0e84025ba476e04d9f463a1a8644f01636cecc60033a35173dbb9a755695859eca0d61a3454029846824b1a17bfff62ccb968eace833c4bfbe3246c23f9f6a9d85580b90214f90211a045492c1532cfd482ac72516c107c1c5ce6c63d0a088c156c8a066a8a77582353a0f7c54eee09ce06bff4da06f87e3018389aabd9efd578ab1b7fe9ff716ba4c3b2a0b580f1a84d6fe2fe91a20a75cf4a4680b5820131735ce4f72472ca73683ff0a5a06125797f14c32c78844eb055cf3d7c44b49b3b32122b8fbbc75f77559e901e7ca06c91b19bac295acbabd869e066141745c190e64f0e6a36a134baa8ade2e8a634a0739e1b724a062e4af782d16c3bace4f8cd348f00d024d45ad0a0e844a685340ba0bb46d1c16ba6553a76b3f0c9b62dec8bc1dfac1932294735d091049274b0033da06ddc296c01cb1efaf2983fe3db59cf47c72481dcc8d240edf9ea72b50ecc6675a02e0bda53a708f6659722dccfd714cb3d8f14d9309035dc7199b4f13eb82676cfa0c13622cb326319b17f97e94c344401121ef4d9255fe44e857f20ab8fbd5c783ba01762fde2f776d7cfb7b1c743619d995e3f698348f47e958eff963292d515bf6ba0b0347cad4e4d811cee678720f7666fdae93e272cd69c8345e33baad23418a7e7a05847cd0c4eed5907f6bfaec450043e1479f60280558b7c7dce2c7f8c1ebf44a3a01ca5a35c2af54ed0cb8a666c02c4c6e9fe517edf308b39d4a10fb1aff408b192a097e499637cca3e3472f4c87fbf2ff89e5e545309078740fb0a9b88aab169c022a0d3d0a98b505160099b38020f2f9686aa8888b7bc10643aaa37445a6c4d28dab280b90214f90211a0806d394d881a8d2538f9425af1236990b8a4655d7195a31ae5f0282c4c83790aa0daecbb792185e5c42bc5c762f1f2cafd28b65b9e29d402567c0e63c19b063cfda08879421f63a6b61d42de95083b8b2773fc8b836b5a4508633e1fcdd889eb2428a0a66ea9137647c7808fef48f9e3d6e35ca5840d801b0a325b71e3afe67e7ddb1da09f740508bf17001534a1832364673053187dbec9537b95759b8782ef8a58995ea082afe71f64928c679878a5e6c731c7ea3bd769c4a4815518c774a21881ec8012a02f84bcff8d016bbba68ff4fb340c1119c9025e2d934e6a69099a324e406ffe8da0108ff18b154e91fb9f92ddabc18bcf17ede4f19bd341c9863e7f31ef3bbc82e3a024775ae764a2cc70acadf5d378bff3a331171d25f7b62edb5c73f3884e2663aea05a6d4ae46ae17e1c6a9d2309c8257aefe92db3b34642817dc08a921c34b3fbf7a0af58a48d95bd6954778b931c8fe12ec93769d25114611db8b1723d83426371dfa0ddc7309c80755ea0a04c45f9388e3fec15ece15b5983bc146aef83290096a7f2a0c5b72f196728dc037b09d23be3241b4c97e86231dd7a6b80ddd77965362b2289a0bac19351849a3c2749d8aa920c1ed313f0116f0df63c5b08805a19f33ddc9f61a02bdc0d0ac9aa95236732a419e7a32562fa778a92b0e6ed970805dc5ef29abb91a01e51a3b967a1644ee4e368b46b73656c081399d96483b726f78cbe7d993b65ce80b901d4f901d1a088c7c2484d5ebcf73940b31ea98a94389e68370bba8738e5c643ab69b890fbc7a0feec8a10d4fe27933cc323c8f800fed3a8ec6b31c7ad46ed47ef17ab04f24e48a029a9f4e484a41ee438ca867be84748691d426224d88e2a0d300f3cdc40b267408080a04bdce534c5de1eaa40bc642d58a15d43d2f4e59092de2bb89ab3abbffab3511ca08fb65118824c3692ffc86c101a278fb41bf4f9acea14bd4a0d524d44a68d07bda043f761ffbd37f21159a3530bba57539f597490d2c1a58cd1cae2999e7e91daf7a0322e129277d04a4e8d81612d1ac9610e6c9b2606286d8f5cb2aacdc07afe0040a069e69df06dde5755d6c2fa5de9b639315bb40e1d89c74ec09dafa6f64775e9b8a08518999299c9faf4702960c352dca92536b29b07200ca96b3a374200ef21ab63a0df38e7a87014cafbabc77410fcac5439cafefb3c3813093c79cdd1e58bb4337da05b2e50b4ae45fd750cc425f0b53e6cbd145b2d6d26d788028d2b8a634bd2c400a0d68fd720ea22e7a771a31654804e8b1f494bdc2d38e4cad2e16cbbecdff5943aa0a595fd9242b707b91d365b214f401a0a7aa368922f638ee708076db7f80bf823a05bec1a333f060a88ef1cde524fa2790c2d7b46a7ff42295160b1cbce24fa231680b893f8918080a0ffc005850f27e8add67edc5a7f8112eacef390dcdf5e19f773b9c5e97338675ca0e481a4f056f342b8b017c2fe5950207d68382f3ebb6500999f8fe24ae2eb1be580a048360b91cd50a587a2237633055389b2e394118a5a6f74dfbd0d737e937e385180a06c2da65a2872f3e281b404681734b1f653656cacbd8bac51181be2dfadf11966808080808080808080a1e09e20d958b99ecc69c1fb2e1d385f148b5752ef81b2159642519b5dac1f511901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a004a909c959249862257a436b914b23b2546fc4dd3df98bfcd2c5534d6e833942a07311ce3e0690baf6bc4685694a83c1d1ff0085743710d6b358fd052eb78e1b8eb90eb302f90eaf83028c6083033806090b8308b95494167008000000000000000000000000000000000180b90e44013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c5b000000000000000000000000ce54654f1e47705a8b4f7d3446e118817ab0d2d100000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000ce54654f1e47705a8b4f7d3446e118817ab0d2d1000000000000000000000000ce54654f1e47705a8b4f7d3446e118817ab0d2d1000000000000000000000000ce54654f1e47705a8b4f7d3446e118817ab0d2d100000000000000000000000000000000000000000000000000626900d44740000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000b2df90b2ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a075a15dac85825db006746d8d89f89d1ee5a7ad77ae36fa3cebf7657d03f73bdca0bab252bfbcf9c800f50ba4e6bd8c3a5d49737ecc3791f12beb9c22f3091948bfa03e0ef6777ad6e9540778460020b008b43532260a1822d2e588c5952818ffa934a0e0685596d8f0b0265729b63f59c8b1fe9d0a9a07233319ffdb0cdcfca884f28ba0bb1313b7b1c0227e282d9e0b4c6c9aeab74cf3b63b7d6d37dd40fc309dfc5330a089f29221cc392487f90dca69a1fd0d133698e035214ce262e3321585b89fa145a0251c251705d4d4df77ec07b8c50dcc298384b607ed89c679bfe5d3e1abd0aa61a04c9daf84304d24c4702c9b628bbaf23757b00d99fbb344b419f3cf24d079f54da0ad82d13435c18c5cc3b903046cd7539818db9f0c93e33190178b7f2a30dad6dca0d534d45ee651c67f6af178fd59d0b3bcc08dcca0e81dbc27df1c57dcb828ad38a0fffe77bd96a94d4073f82e7c450be16257a5155f738e6553e9f2631eba32cacba0af06e1d03609a8bd3a4cc734c203bc263bde89de488fef23c50c53749ceaff5aa02cb562fd6bd691762de0477eeedaf283a8d8bfb831bf68509aba310fd3fa2bd3a09bd021e9c266e1013a07f2e69176eda41a425b8382b6bbffb2f7c3efb6bc8d09a012bb07e99a39555733c79d2338910d473d5b539cccb32f1335228c37a5fb05d0a052903fd8c05abb315645e2a78375db0257eeaafa1c398957c19130523a66858f80b90214f90211a0b18d40a003d8e8a9322975f1797eb19c0a4264b421d29a5597304a76f9441953a0a470fef1506d17b1e7a28302b4eea8c21e17b0896dfc73cdb51e406f59782c51a0046353dbb7c4ea2d9c5342f9ff963dfc2306db87c5a5b78e4d45f178f7a6a1dea01ecfee7e32ff49b1c93279c898cf551e334fa24910b8efcab6eba1f7187efb1ca0eeadf78908c7bc338d6fcf9b7d733d832bcb2e86e9427688b912ca944515383ca055ec329f680ce7bfe5dc3dddf861630a7376027d0aabb7f1911a40a94eed6e4fa036a067e3397af98683a03a53a0c79914043d8e4bfbf7e8bac2d404bee7c17128a0bb66d7ca99fa4d1d36d951449f2f929b828ffdd3edd42d71f49e342783b5d89aa0c43dd0b1c95f704cb7649d862c313cc2789b1972838317524f45009bc5d26381a002bda2ab58967deca9746e2745e95092fead541a47a8e8d9ad8da296f760ba0fa001c75509a524e6f0b1d5e2fd34e28676d123880c5f124bab870a3fc18cce4e71a045cda7c66c312aeca6768508c140ae215e63998d735c5820559815df762b86b2a0af4476b57b0893b19640fb49f612f23b44adf89473a3868a31ba6f95394ab9aba01c19e17628f16b90bbf2d399cf90f561f382a83761414a44e8b94b0c24bd34c6a0b0f99c6d300224fb26be03c861f601f28fb1826fa684f7e46ae8449af5abc96fa0e3758c734664d3c01db6c7dd47b8b67ea64712aefe3a658c45ffbb49ab10349a80b90214f90211a0217b7c827a010eb5a94a3ca5e576ab09033479d1320a03f3ce649f1d78b4ab15a0dec60f8176d3981a9ae4417fcb3b984d948bf42fa5845eb250ee27abf140cc06a0292b53aba6b33f6b935dca39e623da64d5edc29a7c40e146d12c9e50a24e68a3a08759e38a0268804563331f89df3efb5ebaf362dd7a87bc7d4e5e9f6e4e98f9c5a06c48ea31f7af8c67110207748bc36cd7be4fe6b84fc2a5c1082ad7f8a61056d5a05d584aa096a567db589c628892d47f00bc9997ffb6787d244c85923ac102b0d1a001201b013913101461e3d9b62638b41865fc7217cbf02696dc06810eb241d849a00e42ac27c6030333121ba057441d60950575f5b0cbc7fc44f6664472d304fd20a0ac3f09e20a61553185d55be50f4c682993d344b2c6d01e6422d12bf2a8b29e84a0baa1964259a845b557ff9306e710822e50d60aa05f08d73f5640868a638c5c86a00fb8e56b44dbd48c1f8c0be8dde5c2c767934306b1519182519c609ec1424783a08e8980ac4d1809f1c0dbe946ecff06ea3750c8937cec77383011d6eabef9d1efa08349ce47db9f9e5589f2f3d1a909e2ceb1108d040fe7c7eb027bb9db2eddf37ea0f7c5179352022f63dc7ec5ca1c8813131197a45b50648f85c29a4d119223a92ca0703d8e4391e7d8352b4822652bac93e4229fa08082554c3760ba5e8a8838f5daa01123d92814084f98c642ee5562e59fe470167bd0cc0e2582c8b10a22dcd064a680b90214f90211a024afc593556a1d5ab9a3774ee126e3a4e5dff5914c5179e41aaa2fc28b9e0751a0e8656c313b351ee2b7ccd3a3a8a3e57d6350f16c7c315a51441bae96e59249cda0d2df5f145f7badb6c09c60bd8d0031eaa953cfa90c3020fa4dc0aaf04e07aab2a0431ce27a120b7936c5db1d8210670741374156027dab61da8e58a01a2dccadcea0a7f6cf411aaf35dea18b2a8bf18bcf348e77279ea63c26ebe0bbe7914f8d98aca05d9221d7c2d3e507c3b5cb7b7366e24c598f82a16937bdb3518fe7f22a3385fda04dfa4b4504c076e244f06bed0a3ef0d8f6fe9441417397d388da3cfba4660a10a019e393f27d5e8965f7dbc2fcf02ca7c39ea45392ae9d0ff50cc67f33c4a307e2a0275f0de68f0a3a290d4f3ce48e8bd45ba79fa6413b7cb105253aa386febae2c1a0a53b1df3df585431d5afe1b42971a9763af62f79fe077db9f357e2e1bbd274b7a0c7bffc40c663300288c6687f67bca8bb01652dbf6681924cf0581f23a1749be8a0fc2e6bb864f548fc520c4a4e840aa72422a8ab126aec88afcf9c4f0e01095038a06207599de87380d4084b0cc6d135da06bddeac4536fb747222b8ecbb948c1805a0c313108cc5965c9e088fa14b9fff36136f3f36fdf9227b53334f4548a24c0e0fa087de89f629653a6d75a7fe626376f8ed8c58af5dec8dfff4f293b2b6f4e36303a0606a5dfedb38e1713759dec4bd8ab489cae5bd6c627bead077942dfc6298ddfa80b893f891a08ce4bbda1312fcceb9e51ee254f402e97c5623e09595b75dd0cf67c155e11b6880808080a0a2a46ae271ba8a97bd7c9b64dce7b2d9e06c9bffed2e701501d871a688972c478080808080a042c11351010b0aecfd4a84c413986f933170af32447c25a498bf2d4c8578818a808080a0fc649863e9bdc63547d224fa75d69268c1d3f3d21b8e23a745ffbfe24ff1519c80a1e09e202b624a7243657a0966553d836ead3e2c6ab71fbc1f48af122a733f454b01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a03a6e61f835b32a128666116a87363030d1aa3c26aff62a1364ed958b54ca534ea05b4a0e9affa98c7369e2247c567ec47e42d8534b49752d3ed3b9b416b2841600b90f1302f90f0f83028c60830336dd090b830931cb94167008000000000000000000000000000000000180b90ea4013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c650000000000000000000000003eeefd431b794660acc28df0cd845dcd6fa880a600000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000003eeefd431b794660acc28df0cd845dcd6fa880a60000000000000000000000003eeefd431b794660acc28df0cd845dcd6fa880a60000000000000000000000003eeefd431b794660acc28df0cd845dcd6fa880a60000000000000000000000000000000000000000000000000057c084e5f3c0000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000b81f90b7eb90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a09591d235231196568d434755002a6d5947a58c34f77531a9c86ac3fc2b093b77a069368bbef45f706c2c14e5aa027146d788e6fac74f59b46bd407f0248bcd0d4fa068ef1adc0891f35bc2fae8495dc1c950c151c1ce108f66c0fc23b97f20c2da51a0daf7b9335c53a0deca87e98909726d8445cf30ee2c95e2181cbf77aae17de6c5a03c3b514e72a3414b9d17f87a7d268b2b838303ac2de439ae45d0619e7406d703a0e2429a5b6d7da0dbf2b99bfab3fa8355bf3a283a43a6571a99fa95f1e437cc6fa024eeed393b3dece2dd3f0356fcad84b9f9e8fce33388d4a7ba75f828dbed32b5a006ad72a9c5df7c3539f258997ddb6cf2c07902882ddc16f1b4bfd8d52025ea39a0305e5744210ff4e80529a039d3c91870e69568e232b27b3f259fdb2d005a0b64a05c92622b3d684e9bf0fa4d0ff90b02c6ea9ee44672efd63d5d2537eaf8fcf8cba0b22d9a89ad697c7436b6b13ca45f9c8548c6bae159fe7626c131cd0ddbb81a25a0a2b88ab0cd6572ed505973e66cc12cf5653c47e5b8d33118ff58a3d1e90c78fea0d1af0f2d79aa45f6a5f1667087ed0780ced415f5b31381ec705e28e5cc58d2eca01210e66bf57cebdcdc549dbabfaa3b99ea1ee57c14b9fe01ed5e8eb76c01d541a0dcb5547e96bb514cafd7fe53e31777553dd957628d7ef1bc267cdd6a532792a1a0bbc7f1181582829e3d8d3c4a7c9a1433c6ca19ead2a2cc720c0548cdcb9e726680b90214f90211a0c20d65a70e3ca05e390ebfb7685090678b9c99af1094575d902c453527903cffa059623556debbeb220a8e7e944cea26af3dfd6d9e080f2e4d34cc218ca2a1b818a055e5a87b792e718a5f9552ed9430f8868dc4c631c58266348863edd34d2e80eea0e4942ba91584e692950553eaaf6b47dd7bdfce30c29411d6e7161fbeb2e28678a01a92aac7176cb5b91751111c07273022ba335fd0fc0da3bd34bf4087394b157da02f3711bcaa0cdb2ecb7659537916c4967ec2f35a66f9b79f3a9bc009af3f55aca0f3af0e77ad796d3fcc4a213459ebc6bc6e844d538e95a0d34daeb4733f32f3a0a0f8bf224f6524ddbc8b52ad4f151342f0e019a646421d01695463e6d2ae17be82a0f8dbdb6626d129f2c34d5c4e3337bd6ea7d88c4d0aa33d543a41dcb06fa216faa0129179dd4d49cb77927bbaaa2c8caae9a45ffd4ad484ac78dc7db51123d5ccaca0e05d1c8cb91704b5936ceb5bc5fdb79ba3e4f81e73d22906d1e69c4083250f2ba062d0b3743d9774eaeae01b0f5b89894411e8d4f65c070dc3b1ffd48db266ffc8a0221cfffdb5e7576e713c8cbe4f33903855ebbb00649c02e92c3c82ee9ce3c9dea04988534aa82d925b659a0e15848407c9039e65c639b5a908d46464a0bd84c889a0832ea4d778a0fc7f340a7ca40add7444efadebb5555f11a9d4dd826ed8029814a0a381c541f9820fa2dbca797c4876a2ca395157126339ea512150ea0c2707085f80b90214f90211a082167f61cb25331be6c99b3679c56348acd32637268d6edcd2400dfebf5a916aa0e900aa66e158fe3933bb0ae9c9fefbe8b4967fb62f6952cc6af7889ce8dd036ba021ad69d0ea4dd84f00cf678c806508d4e3164449226dca10cfe9a638fac32fc7a09a9c128ea15d8aa9a527bf009bd24611355753cc816ad7554695e1c6cdd814e5a04c62b9e02b62a313e26e303a4fc4c0c003fd201970fa0ea199d7d705daf60b22a043eb8ccb032382289dd2c94cf5d4faf7d4fa06d7d39e9a68dcca7dc066cc9dd4a06d96eb7ce1f3e3a9d2b54e3c6196d4b82237568c970e22ee1179369287b919eda03724bdfe9d59c2ce7fc0f52eba576ba23f7f855301131875c7cd6a4b411d7f4da04e54ef81f650010a1c4ebbdff7d757107adb16ba735dcc81211f6c27c3fc3109a0a3d7a78c6438ef7e64e2ca6a0fb41467999bf49eac4fcc065e5cf66810612850a088a4f7f437a762bf573b09f382e5f8a2f3d7e117bac06e86bb89b0f489121b59a0e724cd98d2a42d4df197dad196a0d3541102d073f2812c4dd01f89e4ecb05a2fa09d6ca420ecd6328f7c3b133a927c566d273987a1d9d39c769ac86b1d0e36611da0d99f87f8a9597878919693f5ad1f297e0a662c3a48b2466f999c283eba022c8ca05a7b685ac75e3ab948492ae69a9bc52bab27acb09a8f0a1e4dde068c93ab99f1a0c264c3a14e47bbcb6d7ccabb6fd7c0e54c8b460a038cbd77f6030315d8c197af80b90214f90211a0166b373f6cc9513d5aacb9fe67c03c7008b9d6ea763386cf7a981bbd7a692e28a0992c4ce701a4b230c0715260abebb8a144aec8334f4d45567396c20bd3a0f5d0a054a9cdf7b130c2ca7470b5cd2bb8da27e1ae9af325e62fccf81516f9325c2910a0422a340ca5fac5362d7b165247fed31eb0edd6a8d3a4e022f191a9ab35c7a0bda0f8854574e5deb1067085621fd595f1cd1a6887037b1ab504c608ea3c71c0bd74a09720102d2703e92c91ade6c7524cd7822fdf31989fdb02fbd3d933178aa9688ca0c09bd6c1141b39c67f405990be1f39583583ce9e0d026db54eeb587ed3a877a4a092ae2d1e99d5e75e56d9b8c30f1d861270c3ed43a21538534ed79ec2f281ed78a0b9228e885e0b13f54daae22f289cd8a4a0896622caacba751725e0f79cb5ead6a095b1e8e1183eac399890c82886744588463718796d2217e78e6af47d01b463e5a0380098f05e8861da888661cbe3c8187785790f3467d6b7bc26d08cb9bdf5d158a0518dafa82da8b0c2493d971c0e846264c5fb29fbfada6c92b1596cf0eac8d1c7a0f49b56676d69ab8d00b0d0b019fa5eec57aa23a668bb6e9a6f789ba98206689ea0af99e060accece100bf108357e787381b064ada5a1da2ebb82d0949435e4eb8ba081a32b796aea7b907fc4dc79e77f94e1342da9a9dd847305d5e3ddc7959936b9a05756e246cc49daee30dd16fdbc406c93e2a39a93e9b74e192e64b37907f214ae80b893f891a0c6fe976cbf2f71d09fd47531dd5b588052919df25ce56aba27023258cf8815888080808080a0a5af61eb117b0d7d2c29415df4147dd3857301eecbc2b0ca8bf24a38c326efb3808080808080a0836a6932c07736df68b3380e8e052f837c5ec3af1d9ac07b724994ede761aaed80a0ab40022b626b16a574d21aff91f0768e8b9483d4c0a92e7c436f068e757b95aa80b853f85180808080808080808080a0f3a827179669fed76bc02ecbb8c11b68b96137a10cc7d70c97e5ac3be42c1fef8080a0435117754b12bc25b5949b914d6c2af41ba8976ce61aef1c790cf62a602f6f85808080a0df9d3042f054b4414005fd62dd5d181b763978bf5a239ae5b6982bec0d227101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a06753d3d2e16fd1aa4c1dcb180a848a9457d114709167004f3ad8136c7ee3041fa06fc59d80fe5a6900c905a65fd6bfc1745c030746622b2474812c22fd2946f0e7b90ed302f90ecf83028c60830336de090b8308bba394167008000000000000000000000000000000000180b90e64013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6cab0000000000000000000000006d557188c2c4068c043a2fc3b840de9f21e45f0b00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000006d557188c2c4068c043a2fc3b840de9f21e45f0b0000000000000000000000006d557188c2c4068c043a2fc3b840de9f21e45f0b0000000000000000000000006d557188c2c4068c043a2fc3b840de9f21e45f0b000000000000000000000000000000000000000000000000002e2f6e5e1480000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c4000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000b4df90b4ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a00156302129b8b2128058bd57c4d20fde05eac8b14217362170e803fdc1bff321a0bc3f997544806fe9726bd5e8a1c556beb7ff50cfbd6956660be503a731638c4fa04d824b90a2c51dabda4863e724b45456b03e1bf124ccc5148d9b57b06c78c0c2a0f3b8673c0233a5837923bef328d5ad5b7073af27bdfbeb995d1f6706558a013ea04a2b351040e1b0b69899b816af4b34057619c1169f2897090964d8565555e2b7a01de6d617c0c37a8b4765baadb0ab2fe0773be074a020adf484b455d0450aa716a0d2f1f3d7a0ed0b1cc8c0945f342a131a5a165b45d7fe7878aa905dc120b9391ea0494a0598a97449321e6ff2a224b3ea54708de90bc91ccd7544e5c9967bd008faa07685abb4deca330b5fcff29a6b0d54cae4170c8a63fd17df0412aebcc944974ca0f63ab5119619637ae348c438736d542593643fd8978bd3f81619c0bcf5286139a0d410960c102d734c8e0225f7252782079af3bd366f1693e035bed2dcd07f4a65a004e94539df570223adfe1dc49076b8ce3fef2a61ca7af82049947d1058373342a0e4bdaa21944458dd7dbc063ce8f944782ffd95e9a8c581ab31ae3b9e28356013a0c061697fdbe9c8a88a87394571fb1be624584ef878985f90c2b0037df06a2f4ca0a17e876cea8ae4bffc5e36ae9434b4b437c4aec63fa932336ad23fd53965d06ca05b6db5e7b44eb456982482740ed51618ad6cffd608ea3063ee443663b698153380b90214f90211a0186a15eee86c5f09134ca747011f6810da1a87e10aae34a757537eabb543d8aea0b7f97c2691b1406319b79e465ac01ded2e9e110a9130c97a7d8fd7c09adee3bca07a48f38b789fda9c7315e55e0650659095d912c1579b0f322964c4e036ca0e4aa07a991f75ca4dbac2c91c1f003b3f4a568c7c0d0f427f1a6ba0f0027e722cb5aaa0b81cfb00b79c41749583adbf8b425f4b9af11ff69d701a5f63f3bc27b1bd156aa0903722ec896c0fd738f9035d221ff3a2121e729f0d3896b510b58b50bb029638a0aa41303676f9c2334dbb9d835583a0d90fb3900f914eeede7704a679f6f15974a005e5db11cf936044284173c4af88f9a2ed72b8a990f4396257e736020dbe180aa07bf0bfea6f6a72fff67596ce0e262cf6de2f6d456b16c04dca563e57740e394aa0e9024f585af858cca2b446f66939abbf0031348233c3abf3eed539a32a92af24a013181e488fa6852933d79971fc72c21f9aea560096620a92e9e1c4ec088cdc6ea03f52c52aa0e600de9aad6d373fa1df8939d7b7147d0c34d6e1268e523cc2948ca0b5304e60b4994f8323ebf8298fecafc9693aefdf0c8ae3ae71a8ef4cfe2ab674a0a36454540afa8cd1564573b0907050fc633e4b4cd234e47398e057dd02031da6a0ed260cd3df3939c42208fdec6484c1c7aec16a8504135b2f6123b32e8cad7046a032fed0c65d329baa099c6091158a7ab653a92f52c41d35adf4a809ed2158a2f680b90214f90211a09d82fe31339f3f85fceb48c2a6a44ce8b043dfcc2fb8132418c64d46e3d12cf5a0c1c7432bbb5ef6f08b7358c9c0cd82d62c7d6efd34a7ad24530aee3cc303c5dea032d2edc746bd9c3828548a2f0ae25323f93b2a3bd052ef4c88c07c6fe4a47deea0c4de7feb99176996a060049e8efb70c65c13a554315019115988428778faf6aca0e1935c9404b15eea506b320c7bb075b2b70ea209251ca80b1ea31e677e559e5da0d72c64922d4eebf1b6185ff8103f718dae44f0f8390fbd9505697f0fa338a2cfa07e14fbc8a766577817291e32dbbabb6a2a5a8ee33f6c6a1d00daaf3c8aa51f60a09d605eb56c92c794cdbcdf8fd9192c6ad643f8a725671e5c618cd1ffcfff3e42a0189ddbb3bf4e87655bb9373817741ae0c73db50b1f6c60b335f9de87861de598a0fc318fdec2ba92d131b90e14fd9d76279bda87ff06826580a4f6126763dfeb78a03894bdb506e4f0d37339691ed58d3869cf7c9102b4218b51fae5d8a0f2a31997a01ac723a28ae3f93b3cfccf03360f1e0e7318689d88d43eb92a6487baf68c59c1a0d4b1aa00d02133d51d4223d58eb159a791359eda8ede665f09d0429609da0e27a0d28fb52c82a90c9682c6ed8f091427cab24f3b4b28fe073f054c2b6ea47423f7a0ae2e74eae14b3a646a536290034cc9ce72a0c7674678dc21340c2c9e15815ccfa035c46dc337975c7cd0cac6638c6e06bca7f62311fda374962291f56f799396ec80b90214f90211a0e1535c401fc56ba6660b2f08e7fb37232a708c11ef8b55d89a33bfd3e8319921a0a5e34916c841624d53df62098568e6d1e713138bde4b3919a5a156c1018ce2cfa0524ec51b5558247cd06fd3b0e68f7e94465430f5dec20313f9f0df173e028396a03c89974cffb91eff28d4e5690d9bf504c2946f0c74a35306da3a0963cacf9daaa0bfb36b0e0e341bb406becdf80db518f6514439d07cbf4876ecb3331d1ec42b12a0de41f7fdfe7fccae128ce1718406f3afc6f35d0489ce27e0fee9fec9b231db19a05ab2cfac8c3210e5bfda630eb00e8da1c3ff602741b2742ae7ee68dcc1abf640a0f1109303dae9e404681f00f1af33649eacf848913887d489b502dbf9d8f27c02a0ba011e422fafe4292e14ab9476e6c45a899ef7c6a2c99536a9354fe81ab17686a0d8b05de922a2c494c8d7ddae2afe71d48c1dc2f89ecee8b21fd429dc83b2cccda0b431755e2497d247a043af533cbf4ee28bcf5fa24c5a7db0f482373387865719a0a0d6e9d4068c0ab71efca950b6f4297dc7cefd5da4151b78eb2779b9eab3c13da0c0a8d67b168c3429548fee1b01bbaced22c75a3bfcd512360bfb0b8d22e85a2aa0f910be5a1a7d6cbde8181e2dbc301c439ee91925ead604b763acfec2f52e194fa0a74ecad0df2e961ef6ba3f24b1ecd524639f5089b4b78a4f7d0399e6b85fc400a0d926fd79c377a8c8d3137f5a79da02b26a4990b52d3d3daa184c1e923704f2f380b8b3f8b180a090b28f1292afa0aca81687a34027d8d3e987778f9798ca0a351ea9f8117bdb278080a03fe3963b44e01e5e9ddcb279fc6c7ba4f14cc4fbdb7c79c408e926a398618ef4a0fd1e7dec02b693ad3ee239951ddd5a0b672e59ffa2718c689cc3821532f82c33808080a0fc09925cbd1e6ce23719c11bd117add6c771d36b6ce27c577f665a8b8438221780808080a080cbced6068b300b06583bce288841ca3c270ec031434c9b9679c9451090fbfd8080a1e09e2065174d7a01a80515d1c28874c8bb1381b3cb0ce19e129ecd289a7144de01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a061a8fa526e4d80c98aab1516aa213c61afca5af783f94e280763983586ee1ff8a04d49f2ebee36f7af4c5c45afc3fce85282e3a5fbac6b6534960f9f73c675cb5cb90e9302f90e8f83028c6083037650090b8308b68e94167008000000000000000000000000000000000180b90e24013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c6e0000000000000000000000001256b8dcdcbcab2c9de38899f56ba87bfddf18e700000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000001256b8dcdcbcab2c9de38899f56ba87bfddf18e70000000000000000000000001256b8dcdcbcab2c9de38899f56ba87bfddf18e70000000000000000000000001256b8dcdcbcab2c9de38899f56ba87bfddf18e7000000000000000000000000000000000000000000000000003ff2e795f500000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000b0df90b0ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0d73071ad6eeaeb699f09541c05ccca2f67d7cff5673a80c5b2e0635d5ea1e0a1a0ce687fee57c5a08b0a1cf0d1ca1027a90b0aaceb84dc718165344c0d6c640e3ba0c0345e4eaf958ce121991b7c4d68b43b665d5a22be671aa40e9bd8f8b4d0b111a01af823ffb490274ca93b60583b2e587e3c931c52fd95aad9709949e834d4bb47a01762cca6ba670e2e27fd83eae7316cb71492325baa004316b59e13667e47bdfca0b4cfb28a4302982d893ba9330ee7bf286dd05b19ae8567bf30fc118e8685d4b8a0f14ee14f99df68513f138c78f1ce44a933f4fe787524ec5338fa7e7ea65485cea0ec1a58c3601d66680ad0e31083cc1d69b3a7d3bd11c5fb3e802db5eb164f1204a0bd21a7a3c834530cd9b22751583cfb9eac02d00b3d0c650b7b2673cc6139c1b9a06e9c7e877bd1172f58a1d69eab6dfcd750c756180742d3cc4aafdf529cdbe6f7a0c97f62e9c3d9daec29a9cbe955e013babc8ee90cf13929dc08fe663c8bcd1872a0ccf588fe44ec3145f16203c58fa92161669767dc43bf8aba3d54b8133ad43f3da09dce183c2a7692ffaaf0d902aec4904bb64325470ff2fd1f9a6cb5fd844f9265a074ff1b6b21f6b2c75fbaef559f67e68c6dbfab546ac09faac10ce340b725b108a052cfa4ac6ebddb78d35d368267c0a6858e5c1536da2b08aef223aa1c85f7ad8ca01e6f62ed56090c8b8c450694f04f3dc6343f42d0cb7cd5d90a9c7a21837f414d80b90214f90211a0209f25a7b5ecd7d4ffbadf36aaad7f115c5cab2467fc27aab81e0c327a2d341aa03cc543d58fbebff15e5d39319964179514e6697df8cbb231b4278b8d91e6365da0f2393b2bfb00cea8962c1ab1236d266938ce7be1506edc6da9a284c33cecae73a07994b6322779193e95d8ad38679c030dec2ff6848bfed19caf55750a985e13d9a0a0a924e83db5dbfb7f80c49cd5b0019e85a44498216241403d8dbd93c7a3b063a058781857bdb9c3323f159f236fe5032f90e6b5a2ccadb2e9a264afbf4174c144a0cb0f2be1c92c98770f9db3638a6a314ba70075079855bd34bed6f60605781a4ea060e78a849cfdfa8430783ec9e5a3baa9f25abc21dd16b7a18c9422b8b5989894a08381d4ef42b4ac85c6eb1899aef42708594d98bde5570cb54e934ff30776b720a04444abd8e65a1826993510d892e9a7c12a0d04637f6eeb929b2bff319578b186a05d39f165ff9149987f4a5d3e5ba286a8ed9dbfbefbd3aca171d8458bf107d419a01d9deb60ee50e47339e376006fa1657e4810167ee3d0ac59fa35668e90118be5a04302d2f31ba5509ff8149aacbecf7f6cb2e86d12afe27734be8c4ed11cc1974ba04fdc65a1f13e3e1833189be3ed77e457fd8a036803bdc6791f41ec290eaa8d22a0c129c01ccc5882fe656bfd08f777da5b509e2a325d950f57fabac4ff9d360d40a04c2158c3e060bf4001df2fb0a35564b3c19b3dcaf26455b481fe921c3190771180b90214f90211a041749824e6c0bacecd5d7728bbef6f760f234ab56519aaebcbbf557697806eeea0bbf75b3b92c41d4eed53ebcc2ad38c110ad7be2177f66553316e3fe928057381a04f5c2d40373045f5f9eca7d29f5949f6aa473aa54a2ff8f00dcc3e71c6a1d40da09321c600b2630b23c10044d5cd34f43daec5a039361a477dceb4d80975f16bfaa068b945809f566dfd17a41f3fd49d5a41875f3ab7da08ecc3d7021225cdf64f65a003c69164eb319cbf008779b20157ef0da11fb1925d9c22110e2bc6a8fe804b6da0a638d4374f255c719cd320c5cd825e83356cf20fb58388458e6d55dff72a2de2a0fa40f074fd2b43d98f667834283c95263144fefd188bcda1c807475f4a54e205a03859b62113e1ed881dc748941f0420ed8e185c073c50afe6837d98a9b4d35f26a07c96a64577f941745477c31184b9be3e596ea6340a67730b34c8eeea1718d8bba0cda167302beb3164003596e87ee3cb2fc1f4008d4b232c46a0dde7285dcea933a0bd82c799a5cdd69133916fe401e0790ece65ae5ce5e7c3c428e4f07631b7b020a04d5209bc14e1778a8fde2108b1c412351daf220efc2878b8d09b5f402c6c6613a0edc69473a91863c662a3708fda2749647d12666bb90acabdcfe6aeca69799454a0326de3afd846711221c2bd4b7626a497b0fb657cc81225f69fd7d0d297e8e37aa0dd1fd96f97fefcc410b95dc42005efaa9ce6a29f17af4e415d9edc10467f518680b901d4f901d1a0ffe5a929cb39b1158deccfcdb06272c946b2525fa38fdf1ade01af82458af221a00466bdd6d408eb4b481e3ee2a30e954aa2b26fef957a16150ba12abecb53b68ea007363bbb4e594f7fc58f72c86014c6bddbbf8612bc459be40c59bee087c4eb84a0ecb04cbf3a1f88cd06ce7069de4b31ee0f2b1fab4d202286d87b283354e67dbf80a08e6664d5d0b6ebc577e869c8f12e53f0f376c5e7855d08d1cead13f6693baba7a0219ba215770a1b7c641ebd5cb1ba94c90f56ba873db2dad79fb3301affcf27e3a0d27ea67c4d6053878525ec27851be32612e9be479472b7270b0e8d7764131732a0db1a7d1a58f41d343a6d5a8dfade93d381e3f37cbed0e725f75d836535213711a0289f5e470d97e98421c448220d399bbce8c3f4777af1e079a0e10a48cd1d3f53a01ad09286e6c4465cd6b15c0bde83241b75b20d2dd3912ddcba729fe1f19739bca0f109606e5fe61fa92b3f6398761f45c98a2df5d19df06df9554c87f7967cfa1aa039fb1e19223a608189b8c39b23a75508fc6efcd6469973dd12ebb3a137881e0080a0d008a17be2e58516ab182b8d52319cd441d32b13492171e4423d77df5f8f9909a00dde5113b8cfc10c3434eb0d3d739330a54997e9b64439a69a5ea5de3684b50180b8b3f8b1a0c3a4d4ba6557fe025cb7d4cd60440f4f172a30f210d97db5e11a53a25222321a808080a065a24505ba7432d58452d8460c077fcb9e1f4eb8f355b9a0226037bff8f07336a076090959c44195f07149dcfc5cb24943263db58dd59d765ea46f314f01b867af8080808080a0931b5afd995b9fb26966e219e04e535d6ff59fe03e4f4ac656f1bfa942585446808080a03ab28c5f0bc72729b4cc8e7f583e5cbccd718fb775546d9978a0b9482ee48fff80a1e09e209290f4b325f53048b27a54e7479320048f70a1d4c82f89a3886290c93d01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0382e397cb81d0e83b149d11f106b2f5f2f1ff77a4af8416de1f8f820a9e4c4d0a0367482c2da3fc301d7360ee7b37e4725726b0373af8a1be77e080823b2e07e90b90e3302f90e2f83028c60830376f8090b8308e9be94167008000000000000000000000000000000000180b90dc4013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c7900000000000000000000000018d8ef3cb0bc897e6d7ea0582efd54d4a573571600000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c6000000000000000000000000018d8ef3cb0bc897e6d7ea0582efd54d4a573571600000000000000000000000018d8ef3cb0bc897e6d7ea0582efd54d4a573571600000000000000000000000018d8ef3cb0bc897e6d7ea0582efd54d4a57357160000000000000000000000000000000000000000000000000051007aace100000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000ab0f90aadb90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a09591d235231196568d434755002a6d5947a58c34f77531a9c86ac3fc2b093b77a069368bbef45f706c2c14e5aa027146d788e6fac74f59b46bd407f0248bcd0d4fa068ef1adc0891f35bc2fae8495dc1c950c151c1ce108f66c0fc23b97f20c2da51a0daf7b9335c53a0deca87e98909726d8445cf30ee2c95e2181cbf77aae17de6c5a03c3b514e72a3414b9d17f87a7d268b2b838303ac2de439ae45d0619e7406d703a0e2429a5b6d7da0dbf2b99bfab3fa8355bf3a283a43a6571a99fa95f1e437cc6fa024eeed393b3dece2dd3f0356fcad84b9f9e8fce33388d4a7ba75f828dbed32b5a006ad72a9c5df7c3539f258997ddb6cf2c07902882ddc16f1b4bfd8d52025ea39a0305e5744210ff4e80529a039d3c91870e69568e232b27b3f259fdb2d005a0b64a05c92622b3d684e9bf0fa4d0ff90b02c6ea9ee44672efd63d5d2537eaf8fcf8cba0b22d9a89ad697c7436b6b13ca45f9c8548c6bae159fe7626c131cd0ddbb81a25a0a2b88ab0cd6572ed505973e66cc12cf5653c47e5b8d33118ff58a3d1e90c78fea0d1af0f2d79aa45f6a5f1667087ed0780ced415f5b31381ec705e28e5cc58d2eca01210e66bf57cebdcdc549dbabfaa3b99ea1ee57c14b9fe01ed5e8eb76c01d541a0dcb5547e96bb514cafd7fe53e31777553dd957628d7ef1bc267cdd6a532792a1a0bbc7f1181582829e3d8d3c4a7c9a1433c6ca19ead2a2cc720c0548cdcb9e726680b90214f90211a0718c50ccfd1234868afb26cd584ed77fa3b9bda44ad5586cfa90ef5fd996750da0d77ccaf15517144f7b5168b5c4e04521d3bf7e3ac2ac6f676e7165a190d4187ea0196015a57df5f74b8091c9e2e7028be180a7b29a48db20149bd0bd94bbb00cf1a0482d1924a6d194cb56de4c1e899eef6aff80fe4ce7605efcc39af19c2ac0f503a0ebb44f9ecdffc442eae9aca11c6f7b6851fd57c224db3ea729cdb267b5574a93a025d98086dfba621d1b1f49a6e4f5a6ee39b3fa06aee098198b0da4e43f6a50afa074bd2bae6f12788b944cdc168f1d47eeb6da84b60c665d537a4b9970f5965694a0ace31ac496d9f9aa78a210c2ec64e12bc4234a305d1304e51a8d47b2f02a54eda0c7d1e2089cf70aeac8daaf839d667ff080561aade3e35628db213cf2c0ca5768a015f2c810f250fbe4a179835032934d1dd749fec2728119732e49d6f909d44274a0a44d971eed30975ac59b1339d4b50f26c76dff01abb27e98ce6de99000007c92a08a5882e634ee4ea7d7d11e891cc8bf020eddf35f9f48b5a991eca7f45dccbeb3a034442076324ed70e102782a5beae90792416e105ed7350aca981af6214443a6aa0fae5de1e6d749d7a1bda5f0f05ec931d08c8454c5f463778c76bf7e563c3a718a0daca395d6437911e0681c4341b7b7ec0e912b2c38ea01692c8f576380cd7f766a055be5f31c334ff217c9b891ae85ceeb3c894149c2aae4fbaeb943f052725839680b90214f90211a0c548c0a3f440f34c79a5ce88493f88f53c93b5e5a5a9ccdaf3a422a827b6f46aa01d0d6f1d51587ee1763f9269d7353dcd71ae0169dd84148351953fa8f86a840da0914087015b3e838c54ab9dcbf081aefa185f230bede468b4e383e67bd7ca5525a08aed68f0a5d9ef093ef614a74df24130c3041f2e0538d792d2a68b4aab28a24da0d5e2173b8ca4fd79863b008cc95ce7324f8faed856fd1e95610a8f47f08635f5a0f0dbdf93da7a03defad64f32c6e35792277b1b0f6eb71060face922c31f4fa27a0335230a33a72c7ae83c18f31634a3fed6deab819e16f47d90126765498217a5ba050853a34c8ed31bc1c62cce453128dbc2b93a29fdac59c832b612ebdd9761841a0d47acf1a0ed30b3c882f2097d4baddad2bd2a9c147d1323b9533cdb8b0a0fc80a017f09382d5cefe2c6e42621200943125fdf9ab2418ccc26f84418909ad3715aea08cb73a8a903a023ae2be4d2e292ea2cef204d8acd196b21877c94b0de0f261e3a05832a3de4807a4dedaa85a700c09ba8ee6afe2aabbe641cd6343671bd7dd5777a0f315fc0fecbbb196872186693dfa75c45ec09c805fd611c635a86425c786b538a06720e403483cf357895b4c210e9d3d9a0236f5a22c275e393f237f2cde912dd2a0a906552fe578f5ecaba55c0cacdf26574ba3ba996e788439403311ebc1d452dca0f33993bae0f11919dae3922e8ec0e2299c4dfee34dcfe9b45eaa6fac02634b6280b901b4f901b1a04334ddfaefdb6ac53ce0515ac3968d96ce298d4becf58c095d7c266a75c54a37a02dccc91d28a4bae93c807ed71b54caa2a49dcd1eafe8a383df4e5f3a22b9e75ca06914975fa3a349b7bbb9863ddb10b864876d3893f5358c6a4621fec78bf2f736a0ca8111c45ecebd4f26addf97cbe651eaf32369354c76b51fc3fbdc948e9f461380a05ff013c8879e2b9e3a6c5235c1b8ada187a6762e8d687f2274f39dfae0e88859a017a7c3078c2ead0e937fcc9680132c26920809ede0b45e8cda6fb44bd5c58944a06260e6385bfc99c6667065dc6289739847c64450c57510fb9881a3a3e4e3c2f8a0bc52b204c6d4e61508b2a1ac24afcb8ec47a13e4c5809f4e8704793e1bca3343a005be64d56f3403aff965baea7fa2d6f0f3ca935cc9e360db7f6f6f78a03bdba4a08a4794bf8f1893a115e4ae245f35551489f99d9e9f50943b1bd9544c513a38ae8080a05a38a568359f4df9a9a451e44d29743873e5a2f2c9c6e5b257b9d798d5c7e934a0daa4b21605675c00743139f6ee85e1c250533ad2d507ad2218de1bdb4269d239a039f25ad743ed3110826a8e0c8e14f3e181e9afe208d966fb9928cdc4d12643ad80a3e21ea09599566ccf975d73f07b11b6ed86fda8213bb2646ed4b833333e7af82e99e921b853f8518080808080a064eeef0c680e25d1b9f00c8ef401df38a9cbd1a8dbae06b7d5477a3be900b9b58080808080a03c50112678bf53ceea68abe934e8cef8168740e021184d59176f9aaaa44f6a798080808080a0df9d3c45731ddb5c968cd362098a79194c5d47fb46710a1eff2c0f0e5f974801000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a07eb6ff1a8febdb9e939df7faf93b69de8e63a442aa39c54e69fa4e0e3d9360eea0290746d9eab1df895a239a66942b1dfc274fa11a43865fe24cc26f2c9065252db90e9302f90e8f83028c6083033516090b8308b67594167008000000000000000000000000000000000180b90e24013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c570000000000000000000000000ed4e2ce5dee72b741a6e43602629c589cc5f98500000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000000ed4e2ce5dee72b741a6e43602629c589cc5f9850000000000000000000000000ed4e2ce5dee72b741a6e43602629c589cc5f9850000000000000000000000000ed4e2ce5dee72b741a6e43602629c589cc5f985000000000000000000000000000000000000000000000000005e808f1f0680000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000b0df90b0ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0b7253b218e38640343cde06204cab029a5b5679a4b58a80c68e7a71a0467d9d4a0a49a43b78d77212ab2bcce49035171cebb9099ec99721ae06194f394ee3800dea0e7b4994d9672530e31eef3a5400ba2bee8af01ded6b65c01ab7b2e4b62c4b923a008af6c895761231b2bca4142ef163bfc63d555f676f0b90a930087815beb4f1aa058cd3e6a07d54b1503b43672db448e43d0be04c0319a963a645ec59bcd4c5de6a0bcdb5526bdbdd86c85f11f48922328377aeb8a91a3f2d5f4bd26b894053d9be7a0bad0bc3eedcac3316b657a150dba35a0c216ea7587f9f658b97d2d5220db8f56a062994164f2464af91c1af3ccaeae7df28b1683eab795cc47bc929c20222cf117a03d6b92ef3136602b816888670bac079ae019c90204721baf5238147c4177a84aa075df0606e0ec4e3084a04fb37e27765e7940a3f94289f75a9df8b2da9cb8efafa0f65b95772d0961496c8f7e6779ae624310422d8b6471151c8235b96b5201a8b7a05971301703358e8b7e15499a21f067019bbaac5aa4d1cddc61334cca41317c6ca077d74d6e13f2e5833ddc400d81cd4286e65b0b2fb9f5071b6cc2c590f713a3cca0e09c8b4ab674a64aea3fc06408a736d2fd40d7416082ba9a8d2312a1002d4781a0f66c49e2be644ea72f8b4b2ad4fc0f27b1acaa3fef145ca98ad9fbc4b2e8127ea0fc25ce629e605e2a2b7dc284303ba0fff6181b879b3a8743719c027b1a12622b80b90214f90211a0034d0996a86a5738776babe4a0e8d56d0092746c768cfa339a4ba87b8d5b144aa0c30241fd9d640d45eb70436cc0b4b88690435eb0d8294952c70e1fb4c4aa1a96a0dd798f990a336062a7ed21972b333f71b5066e2263a4dc92fb3877a0ae6edb47a0a1e885a253475b1dfb3fbc52f341c4025a2a616dfa92d3e81fc6348a7eebd2a8a051e292db95c33491241cf7751fe7b34e6e36c065e1a8fec4553c75d82c14bd03a04343f02bc0bec2d38208e00471326bcb08c999941472281ba4e8e39abecfda27a093b3ba5a757fa48a9ba2ce420600e8aa949eb155fdce8d574b0d3dc7d605eaf2a078d710a7dddba64790d8362c705783fe5de8ae11e6806d75bb614a3645e3e061a0484fd1e3f1b8e8c4332071b769cc643119b8796f8ac58a7247604daab341943fa045ea2d5a69fc52ba2a3d05945115bec52887fd0050078890dfaecf58459a34caa06ef46c69fdd3ffd0b782f3da0b75a9e1d6a7ec94d5303b94593110623b7a3541a055fb3766acd9933acfc2cd84bf14d82504d3cbd2b5392d97e9a1e54695d4ff38a0d2da817a544b8f565d626b3cb27c7804aaa07f2ff880a900f380959d801b8018a0fac2a9aa8ebffc56e678ec07e538ac28832c7045c144c181229c904e55cb9cc1a0d877a3d0068a06f12f1aa81452b6aac252c445eaff43fe195796a4dfe47e3033a0cc6a0d408dca2ade5ef16cd779523872c91659f80682ccd1dc667f81348df95e80b90214f90211a095c452358fd7a518f32440a403ec29c678ee86bfcc7a5f72d9e5352722c627efa04cacea89610c7941ea9aca954c8681e0cf2a167af16e9de1ff744ef065233da0a02db703b71f4ebc92e160f1d17d152e7a2052eb953cb709a82ee5fb1ace8f4917a0bc330fb0e9422ce69d116a0de46ed208462490c8bef8c1261cd36ca9ce4af036a027004230874bf9669e893e70a88553a1a6c13f601d40949f5cbb0eff96d09d79a0e8155cad3101c3decd8d043446499bcb2e0a22e9319d15fab34573a34ec19df0a07a77eb7b8f35b57189715135fbcd5ee8850cf13fbb7752bf1509915d912f863da0851de8d10913c40bd40fb20a9bb1bd204801a9ae4005f86236c2645dfe2ce13da0db148f8117a6f3ac6863934388c051f2c1ee51c9dc1e00d43a1efd547c132a40a065b2b3e4f211eff07887ef2a8374615ea966d7bccfce81d0a461c698358e95f8a05b23af55f254bfd3f961fdc4d054a4f5a63be740a21c5a512f63ad6a52473a6da0a5c668ff901230bd7e2641f63295c73e5a445228bcfb4002ac418b66c3cdb8fea0f1c2825343919207067ffbf9a581b8c0b5d872c7a5b339401f508b4f13c93c60a0453ddd8ade68adc990dfe14520606cb985a77997560ba008048fbb990300e594a09625622e334dae5076f4c1f02716e091bb68d3b1421f66a9425a4e7ad5ea0455a0bf571510489dd63e8470c734ee1166c640be4cc7354463ffa055de631d9a2a7180b901f4f901f1a063a49043313cdbcbb9ed4d2c2fd0a3e98341bd5b13c8fb1a0b58f337b0748aa9a0743a4ad2e97c5a623104ce9f3c2ed52db8bb11a29a60284fa381adfe89e0030f80a0db265bd9780eb2fff937b6c1e8e2c86ca73b2ac666c76458d8a653c6b023a2a2a0f9d0461085a834eaf581bb0f2692b75e6c5359a6e1ee200ddeae91fe8c33aa35a017e00f5e01804f6b0ff11fdd969f54f7f1f7565d0e0fa433b6fcfdffe8863b68a0251ca2e24db02ff4625717abd77c467b92de1b56064fe6a2dc270da153fbc9c9a0f259bb82461bfd025577c374095ee0150352f43f9a35a00c2f7d001db4900dd1a02e3015986261e59ee1f372ed2ca7d77aeb431a2a6d1a5e5561d0c895fcbad7d0a09277ae13c12104e451e551d91e9cdfe540f082b97a44068b387a811c70a10d6ca0ac27f258c739871db087b6f6c8aae6fc3b992ccaf748e0fe1df663448d4b1874a04d0580a7759939e6cd6427bce262b21e8fdd03da03eaa2f5e06403dce9630564a06e9c659551afde67297404e9849ea4a377270c81750e9d6fd60e94804bed30d6a04580f2a08a0853dcf397687d1e5d612ddee5e6e225be5f7110e37447c9300120a00995a3c6f2dea5ac3b2cd123db95d848fbe32c5cf6819b87f1abdf8a5f150800a03bfd9e51f7a3b7a038793088aaf5d2a79d30a2d80c54e184378d53d6af2158e880b893f891a0ae545972f3e9e98f3cd149eb023ed6e02256ba0d4ad35dc34f92e6a79f41df87a02fe9eb7cedc92f07773c7178869cae1642f320f66d67281b1a63dbb565d5f31980808080a09c55db20d816736132c79cca2d55a16e11b1f881af0062f9b18c2f78fe83cca6808080808080a0f3d730258325ddf904af03808116affa7aa30f3547958460cf63bb31256b3219808080a1e09e20178801ccac85d63fb3a0280b76926559f49e557334d16ea03c6222892401000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a095075c4a2fb90b6320a9454a9c993806b3954e39d6fccec8ca23941bb5bc9572a06bc690adc7357d6a7f6dd25fd0efdef94b7f3ddd052a598812f6aef0af9b40f8b90eb302f90eaf83028c6083037729090b8308b95494167008000000000000000000000000000000000180b90e44013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c5800000000000000000000000076492a477d75f16f31f4f05110f4782a9bc08a5e00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c6000000000000000000000000076492a477d75f16f31f4f05110f4782a9bc08a5e00000000000000000000000076492a477d75f16f31f4f05110f4782a9bc08a5e00000000000000000000000076492a477d75f16f31f4f05110f4782a9bc08a5e00000000000000000000000000000000000000000000000000481ebe10f0c0000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000b2df90b2ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0b7253b218e38640343cde06204cab029a5b5679a4b58a80c68e7a71a0467d9d4a0a49a43b78d77212ab2bcce49035171cebb9099ec99721ae06194f394ee3800dea0e7b4994d9672530e31eef3a5400ba2bee8af01ded6b65c01ab7b2e4b62c4b923a008af6c895761231b2bca4142ef163bfc63d555f676f0b90a930087815beb4f1aa058cd3e6a07d54b1503b43672db448e43d0be04c0319a963a645ec59bcd4c5de6a0bcdb5526bdbdd86c85f11f48922328377aeb8a91a3f2d5f4bd26b894053d9be7a0bad0bc3eedcac3316b657a150dba35a0c216ea7587f9f658b97d2d5220db8f56a062994164f2464af91c1af3ccaeae7df28b1683eab795cc47bc929c20222cf117a03d6b92ef3136602b816888670bac079ae019c90204721baf5238147c4177a84aa075df0606e0ec4e3084a04fb37e27765e7940a3f94289f75a9df8b2da9cb8efafa0f65b95772d0961496c8f7e6779ae624310422d8b6471151c8235b96b5201a8b7a05971301703358e8b7e15499a21f067019bbaac5aa4d1cddc61334cca41317c6ca077d74d6e13f2e5833ddc400d81cd4286e65b0b2fb9f5071b6cc2c590f713a3cca0e09c8b4ab674a64aea3fc06408a736d2fd40d7416082ba9a8d2312a1002d4781a0f66c49e2be644ea72f8b4b2ad4fc0f27b1acaa3fef145ca98ad9fbc4b2e8127ea0fc25ce629e605e2a2b7dc284303ba0fff6181b879b3a8743719c027b1a12622b80b90214f90211a0c5478fdd86ff659f94d5e5792378d961a7a109c0f76ad24280abf74967928612a094b9014de90ef8c5c10f855485ebae93c17dfa59f5857e6e484e8f3cc7cbc841a07f7c2462ccb35abaccc74a952677bf7ede13cee1ea6ccc1da1ed9ce39520067da09b12163b50ae7eeba7d496018e602ebab93c61115adedd13179df920a7d1b9d1a0f8dd875ae3b57a4f5d038577cc4a409fb259153ce5e7b5f1bbde2f872ef5901aa06ca6628c8da17bad14a554b4742c00dca0b093226834babb0f0ae933dd07c4eca057d909c0e10cebffce3ba61144ad8465596527a9ddfb8b35e542ecec86769a8ca09deb8da269c6d2c7355d3a190483fadc8b25e88032ff899f15809738bfde6c01a034b0833a7ad4ef0167a65ac6852aed57fae22acf55f1342f7b5a86440f8d29fda009acec484d784f444f70d17e9e236137f82d2b407a6078958ad0077a5c84fadaa00d041d246ac8af14af4fcad213a20107ceba9ca3bacb7076da2e62376b756d13a004ca4026fc36cc40f4386a1e7af7ce07184871e41117a109182ae9aa2dee3ea3a07f84e516fbbd7936fc6f67216b7aa56afe412a849db14f28f070b46f727dce33a0fa3365780a1a36ea096e33b30298b4aad6af1f19f0969b0fc951b2502becf6dea0ab9ac3d580f5464b2ec8f69903c91cc22b6dc7fbac7474998818e95ca22c7cb2a0d0af93d6505e8bb13bf3f1e9464fe3aa82a7954394e7f577db06ebd2984ba6ff80b90214f90211a0534e13cd038ace0c7bee09628877ca88a9f899cb93a78f292514eb3626389306a0cce6ae3ea539f92baae79713e84249392271fab03cc3b8ef3aeed1074391933ea0fd14fd473e3e89f7abd3fa7d4ce453e3de61fe0a66242b67d833d2c1b48d57c2a0b8a36a7e7155195ad914f9bd9db3a6a85ba6d4002b39af2bc031728c23096f65a0406834d312a98b58284a4390bb0bd299fc01b237c6cdaa5ec679bdc3d279991fa06183705f6e0a38f8605f71282fca5155840c1fea35d3c218e673b5411ba605ffa089d6e14b33a967f9578422aa3520b3d07d4aacf40c1c7f0ea06ca563b9d5cd3da0e9d5e653f513557608ddb04e1abce180b6b7d0a70d1a4d3578a0b5a918acc4d7a0b62847c903b3083af911a6ba969822c2ce4ac507c887735cfdf5f8c7469ad3f0a00befb913f4613367d5a746cd5f675f373caffa0f64723eaee9025f689fe5b36aa01d57aee475c35851c95cd0b0057b5711e65ef589b4d93e5389581d6803cf304aa08ed627975d652fa0e5e09a9e1e6cf94e46ae02dc56043aee69449b8de5a0a5c7a089850e5f6af652f1c07b4d4db6595b3ce7f6874edbc610d5a2ab65ec77e6fc51a01220d0264110f598fcc845f1b3f4a6d69e1f0b33146664eacf689989c0dd1ecea01da7527225f581602bb1ef121262d4ec0618715e860e33bb476affe3fda0a86aa0ecbe2d073fd44be15d06da85d9eb2515eb63d9a3b73cb7ba9833b479a1852c5180b90214f90211a04db7026ed0715cffdceb2625247b1ef1f9d030eb4fdca76ac4d37c9ea45fa839a039a096a7339ac15f16fc7fd1aef72ae039bf9601e3a6b994281aa229717bf3cea0a64f857eea97f88844fdb0f7d35f08ba9b318b9097632206db4b3ce7db7c4d11a02df29c6240fc44bbb591ce4809fed463619430833fa9dcbbd11590141b41d78fa04f6361820a7985fc85bab4d68585a5b61b0b927e162e9a5c20cb0c656b70f2eca05dca590cdbe436ca643a8ec6dd1af227ea087ffe481003e5f04b823f866b277da027392b73a249ccfc7cea65bd179dc61f8fc12fd9d5a1844161e8e3c390856f13a04ff37b9106d96ead2994f85ca20fa4b927b3f81f5627e9fb5f0e62b1f7018a02a041bcf3df920ccd40fbda54e6e95058598bba66045af662ac5c93d84a4a462eb1a01c07324f08d02c326d4558a50a24a6d7f67deeadf0013dc51da539ea44d9196ca0c10a691b1a24e3353072d48e5aa6ba87dd6427802e4f5a8aa4bb36fa40c23195a00727b1d3462175a5f069ab19a6deda73d86bcf2b91e87c4a6f92a1275cd67f5da04d382d10480f503adfa9d222145bc0b4c4dd513bcbdabbc68ee1339fbb92bbe9a00233528a7cd6cf4854392c046fca2880f841df611f0b7eb7ef99d510c8102982a02eaed516ba59b765486a4259031fd471890af11053de7a6ced06b4f896cba566a0ccc8f2787d6e8e0bfeecf38ae0dfdd9f3413feca3d6ee17544b56eba54194a7b80b893f89180a0246a0278f65f993943444248ed081b673903f711c492a2517286a1a885612c5f808080808080a0a4ed6d139a8f3737762c6aeb8cfbd58f14d786b18ee4f79651a7390b817a42fe8080a06a1df03c56d9579c98356191cdf5c7f5acb4dd558f3f4b770f31ae15a2fecdc880a05e4c719f942e5ecd2244d2902780fb267df3d3f3686cbdad3f73f9caaa74a064808080a1e09e20149c3a00e5f99e9ba4299fdf9492a457bd1ae020409a93825bf16b595701000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0469e3589fd8c27495a2b8cbc6656490d1bacaca8686e5d0cc9686e9aa857eba0a0494785724c174203217c6b878d7b9d9425194413b5427b101f6419f08d04470fb90e9302f90e8f83028c6083037651090b8308b69a94167008000000000000000000000000000000000180b90e24013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c61000000000000000000000000432f8821047d6204ef25710cf3adf0622a78cd6d00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000432f8821047d6204ef25710cf3adf0622a78cd6d000000000000000000000000432f8821047d6204ef25710cf3adf0622a78cd6d000000000000000000000000432f8821047d6204ef25710cf3adf0622a78cd6d00000000000000000000000000000000000000000000000000426f8d094cc0000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000b0df90b0ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a026f93469575e7ca18b6ed52f5616781748719739d433f28fbc96846f89f19e4ea061d85a1b32424a58ed85ad9585a2c02309a3ff7469c0e57077744bf2e9f86beea0822c856d94b9b099d59415ce5f15c8fc94266cea4d21f85858ef24157dc00b69a0b8c3f28586b8da9e0986fce31aa800437a9aefd1946ff50daa6ca0b69292d7e7a0e4118df3b34b9aa2c443dbd2ab2dbb14f1dbc03963d8a3c300dc90c080f92b46a0ff2c3bdff946facfaf438d478683a47464ad75683a16c3b449b097e446da7af8a086ead228abcd15b2da34aee018017d62d1e293e0f189d18e938097cf04ac557ea0f3cb42cef2211c8542ea5beb17c7b952e38754971a504873d0a82f97fb997997a0b5770246f4e383270775a8140ada94f4292fa57f93203a39170658f6d3045e92a0f8167f8aa111a4230fb4ecbbb283b6b6595d5b100dfeda73aec2bc055c7c22b9a0aa8887275aa18c7d6551c63dba53a8d8ee5068fe54cd9883471449536695ff70a0b667193da4e2b5050722a251172515267df4b45c8b53bc5248b28501bcc49e90a05582fe73f4bc23bd817b5e347b056a80334fade8b0884fd78b23ab2c9172929da0bc01ddadd5bdd1bc7c862451fc00545ce9f6bf91ce2b5c80c801a2dc85567030a05c6c0ba2944aac42c0bf4698b8e5f7100a13db4d52d5ce5e764076da945d4601a08227d6e164048d39ad888bb317c7d4cdae8bc1c233b16294b3c4a3fedcc98e8d80b90214f90211a07342b8ca6605bda8ff82781162f0655e98c4f71b1065bc35a278923bf8a7b12ba0c6c2921c1a99f8d65823043e4e53565f97133bf777a7ed1ba2c71ee4026a269ca04f622a67ca6ff8f3eab4e50b2a63e6380b1ea016a4c46b928b9f7a95b3dca6caa0d7336cd3f49aedf5a3b0c67d0d7c7af77a82faabb6a1d66e6dc9f39da54d67fba0a5b7e3f60a02ae4a957b13f63675be95f44befb7507e23680913e1001f8b9539a012ce2fd4037e61e86e3699ba73adf5fed11d602958dac225904724069d3a8f38a0b4618609fd3673da34a1a77aea5551b795c991072edc5f5dc7d0324fcb8259f4a087d99e84c343922dac191541b6a0f7b15dda18549a7ff298ba64caf0d92cd6cea0700f24c38e04cb9861f73af8e4734b17e72a7f4b5349ebcfba2261846590b544a053a7ba9f75369ef67fe7ffbe797d9cdec388f4d7bfd218e9f861eb7de8729966a03b1ac3ce6f5972158e53ba154217c8f76e9be7a4077d92a9a930f54deacaac11a0404a390bab10498320f843256a48679367e060b5688d3193b4d4c35ce4a5f292a0ec37271d9c6fa9cd2200ac479918264eeb36635d9b56f112066587c49a8d2e07a0774b01ed2c9acb2beecc207bb53c675281775a7cf7dc57767c334e3bcdd2cc46a0f30f77d0e2af898a901aeec7be76fdf1784476ea1355d9f3ee2bc643e760d3dea08a8e27ab277a1e9c58242c4ac538e5c5802a77fb865f3a899cead2d43ad22e5080b90214f90211a01268a83388a435f737c868815b52b67c3c8f08a06744ca8d2671fae05d705da9a0e057f6c91f8fbca233e4c691bd6612b6fd70a704ac7f6414a2e2d44e0a206246a0f51267542f3f367d8e08c59f85625633b42eddca732c6721994a9dd87b9defa4a08565aa8bf825a83904e6e984f076b5f2b7f52c2f13c10ac9b6b92f8634bf6b7da04338596efb1d2ddb81bf9fff9f76a2c18e913d0f800cd345883d1af922bdf6a0a04ab63fdf092d17b2dec2e67294363883258cfe467ed6ec702b15b077c281e3c0a0fec54978d8197aa649606a12407f2112f9b34d9c4d36804b4bc319582d7f107da0e6238e392edf547f42b1ea5ecdbc965770ee9e4d24f2d21a869d694bdaeb2f8aa00bcc793a8582e7647ac2e8364b15e6a6fa44fb8c74ad096126e50ba230a015e3a07dfe83a8b0171f3767db97a67502e3582dfeafd3159c1700b4b75cb7d4a8b9e1a0170104d23cc807199f4755896afce891922092d473e10be9ad889ac8468afb4fa080f3c243dfb478a64a0dd182f84f862884e4bad306b83dacc7c5f68a33d0192ca0c174bddf2d2cf121f2ed14c99155407e01334c0e5a0d0bf58a970e97081c597ca0c0d064915799128c95da92f74c08e87fda2974b2427c38e7ca9f8ae96d118ee4a01de26fa361cc0cd9af2e466b3f39c468dcbae39e4c78571a0b796e65fe7eedb6a0473dd50f788b92e721d38d784367dfc3939a79a45e88cb8e46a7dcfb3cfc3b5280b90214f90211a0cb9bbfbd930f070a5c986b4aa30fde0db05a08230b54e12218fafd910713e32fa012c941dd52a256201d33be6dc31327139f6dc0323499fcd481bf5ad9c8064cbfa0b0bdbede8c35e279ba045231f172eca88861b4cdc80357ba9840a53f9c698f8da05937162787a1d0aa49c956448a8f880a4e4cfa08ee8277fbf524e3a18657a779a0c399118a9d5604763db5651aae604581267a6fe1d17d9a1515861ab0cb3d26cda0b25d30124f3aed7c17542a73d8bba2cd80b1f499d0076ba66c8b95b0d7a15d77a029b9b1ed99cc9c964746523cd2017df33389c6ff13654bf067c538dc433b2d34a0dddb625fa97ace383772139c1f716b7676211ef62cf45598937e0e1e2cad6546a050517794d63bb0ad3f8d598e1ff65d96f6b0d39eaeced3a36d2a9db796799bfaa0a8fc091fd2948ece3fa9b837be7f02c02a221966ac800154375de6f8bbf42a8fa0f5e7cd7b4f0f5cff25bf2721a46e1ad05dbb6923ede94eb3a8e8983d4455d9e5a0a1398b28cc4c7517e99bbac600d6ad7a0bdbfb61b196cacbf60e1554f213000da08d623db7cbd3a350baea59bf3f46250b966249bd97ae1ee46fa210a4dc15fc3aa09f03b7d8e1f0d479ace05238232a43ea45d7012c29ca47875990000b5b9efac6a003cb1d2dbbc4b18d822d6438073a91327a5038d771ae7337e40cc84ad20597c6a0bc8d12ac53d7cde4feaaf225cad300c8f121dc04b690799708a7d39ecbfd184080b873f871808080808080a07861a1ecd218e2be14c48ae89872f9c2626a566d6e5890295bbf58c3de274d5c8080a052e291be09fdc1f88b319213a6becd59bcb07ab0d09fb1718a56688eca2292888080808080a033b093b3bd4255ab3f1e5f43e2a57256cd1c7c0c1f761ba6189332b3eb2cba6480a1e09e20c901b684dc2973c669adfb86ccad2110322cb14db4b918925b5cb312df01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a06a88bbf34ce31bbbef5eecfd472f2963514cc7c670921c460c05e7ce6c7bd38ba06f5ab029def2c6a270e41b5ce4095344a5d1f4b6048019350fb6541421bc1f2fb90e7302f90e6f83028c6083033517090b8308b43e94167008000000000000000000000000000000000180b90e04013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c6b00000000000000000000000017b71838bbaf50018d6af13b89714f55af74309100000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c6000000000000000000000000017b71838bbaf50018d6af13b89714f55af74309100000000000000000000000017b71838bbaf50018d6af13b89714f55af74309100000000000000000000000017b71838bbaf50018d6af13b89714f55af74309100000000000000000000000000000000000000000000000000859500338e00000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000aedf90aeab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0761ae4038e2742836158fea5c074e7edf78bd4cce5e0f66bd6dc721e5c85f775a01b2a5fde589960147cfc9ece3b84cb0fa6e056d4f426ded53d0bac2f385aa85fa0280afafd7bf9707084a5a537ad270fcc3fc92efa9a7bbe1e8cd22843266b6782a06f386076c231cf449587f885b121a1271c2a9f639ca147e1043941a61935251ca0fea2a607baa108b4d5b58960d24ef5b70402753b5bc5cd6025f25f6ee74da50aa04af82a814cb0b0e9755c95326dbf58a032405bf226a1da75692e0730caca0490a04db71e7674982c4ec882e380388e0cb490e0df0e52855c4a981aed9c909a6dbaa0024df9b65bc0b252e11a16de6aca6d1a47ba8863ce03f02c89e7ebae5eff39ada0d7fc15435db683f6202d3b6b72b559fcd9e61d7e26ca1eb4a6bccfcddc7ec24ba06719f335dae11422a6e135185b829e1babfb1b937e939411c31a12e9f8d35649a0bfb676dee4a0219797fd162ccdbfb63e33b3be8f0cfd1d579da754e47bb060aca008e06f2167c6b3e1dfb5ce3a10c2680d2905601bd1e392296ebc917196bc580ca07d97d76b748d8a5c54976206c62886d05a5b5423c768d0031b0d48c9009fff9da0d269a0fe461462d3504214ab4b4fd10396d85c2e6b293df7758de394e201d502a0f110b7ea826f72b02aaac97c0a299c3fab7c7852c070cee3d1d003dfb0df360ca0bbff1b235ea6d9e8bac8ece338063a25884e6eec6982be087dad7ffa772d587680b90214f90211a0dc4ca774d6612d003dc0a6dabe7ae4d7b651abadf84b4bdb67aa4b3adb5e023ea0e5587bdc6d246eb0a84cbcc1d2975f09ebe3304d4cebee9b96f4951a69af8d7ca0cf2f3deb3730292e7e7e4cfcf7806fc2398280763c233d27e0664b582f2aa05ba0f718dc88c8a6edd5b9280665c535f10189339d908bf6626b02a67a7fa369e6a1a0b6110337746e6e03cd772f1c2cd1e4f09564fe766d6a8e7fa5bd6c89dade806fa0e2c21612886f091a7dfaabff21b5861355cdf7f61447a2009d5a1fa6551039d7a0536a652fe6798dc84e19ad9d3abf494b3bc0e52f41948a16d5d999ed14c74a4aa0af7810aeea5fbd32ebcc1d5282df126bc0c5bb8525b3153d14e18918b38747e6a067017e6ba9ae2bd5155f89407025949c8bf88f7be0819e980c002d3770fd5881a0152494a017e7090fbe5ef7f82c169544522049b1ee5119d916d480f8a0477edea083b68798facce485b6039b3c2ca2db53697cf9ff4c53454056e04c06d41a8cffa0d39466058bfb7b1743ff395a49720fbac9bfb4c16b20f51231d9e9e189a27578a0608c6fc97fd7a851410c4e2e9ee16a059f5745c986c4ee6c66fc8b7f5aca5858a0a5d3635f0190d811eb309d8cae0151a9e3cb2c3368a7dad83288967795b35452a098a223b22e2caba138f0d19c1dafe4dd7e422218ebe2d391e29bceec63a03ff6a0c1f39deb7f3c4c6ec0cfe08e5f4250b08ce86089a6ad727f8fa25339f4663aa680b90214f90211a04b2b4af0a76920f93a6dfb7216eb16cf2d02f2275005a2f3291a5cad713b3fbca00219749d08bcae64a4b2994e991868c93d184ff5ecf214c179e12a852b4427b8a0ada8b3c53ee22b1ef0dafd5123e322fb25791b7074bdbb0283438af3f1866ba2a0d4ce80ef702ffba39119bb5808e1482e23677dfc953cc402567b3fd895064d85a021ed66258e95cfa6f424f6162215a1f23d2febca231661dec3dd12930189fdd9a0243cc252882f96fcad65709f6584ef8c50639964542e26f766c18aaa7dd7de9aa05267d0247cf09d981d3eafa12500e36e25aaadd831080e4a986aa18c625f9c4ca0e953c482f6a6cbb9c2a23c8e6871db83963621807d690c1dad5f17881251b8f7a0bb842f9b4654af7d08f9bbd1ab930d60f87e14d4829aa99fa4c3a8018174caaca0265cd1ba2032e6ed218a8903ecfee8f71e9f64218db3da3a23902b7f156942eda002c5d4d573b11714cc580adbfb25864feeea25ff9ef7fc2b0340e1b469e83b4aa02d29456d4bfb111cad623b2f0f7b8ae42b859b4989607d05be430f0e59706faca0cca9a3dc7ea3f63db8b6ccde293770200ea222d84ee12608f7c5f53ed571e76ea031cfbec72cc9ff450cc46f2988098db23941b3b54d6e8bbbcabcf0d842dfaabaa0bbf7144656f689b14deb8243c31afc6e1f223e37afe7d87fc3de4798e0c81378a025c5ea1cc22fff92c95a27f96b2191185854a516397dd52e5be06a3cf883af9880b90214f90211a0a8776fd8641759caec4d6d3c5279231b9344a9261bd92444f4d49b908ff3d78da0b849073f4cfe458d995b8dbe6bcde9cceacb4bc8653bbf697a03f84387b16385a0d1f45b01354b02e28e4a16859061c6e8f9a2608c087fa7d52d062448b9d65ba8a0fa1c253b904417f27f033fa9f96c56a8cf86fbdad96130d33568c3bf71bc0aeba0c179c52e4dc4a4dffdfb56a5251e8911f8fd522bd7bdb754eba9de4307e45e0aa07dcfd39db99a9cc08758f061822c3fdbd222f541b3dce79bf3f2f400b5a192e9a0510db0f3ab6af10d9cd970675f9d9e9cbeff269cad879a1c8e682e66987427bfa09d7cf11b7b21bbd5a3b0585a775012346cdde565a5bf3756544975a5a9dafb69a0ba7c9f2e3ac6bb22e7344eaf18510d3fe9b64a6e279a28fe2661d7e3686069fea044b835fdf643123dcfcbc3c8214ce8633ce94a5eff635b2b5ee1359a8d418829a03caa9086647ed485a61ae72713ca55eed773cdd7689fa760f096c5f1a6c8ef79a042f916bf500b9fabf71048265aeff4c11366581b3ecec338421d05e1ff4052d1a0644088afce1a9bf6b65238e7d34565b8d380412ba03c52358c28ac2134450b34a0dacdcb6ea6b14d77c4f445aadd02b88767db3d4ff00852b7f169db2359a58466a0e6af7bcb6ce12e504393bafa647288e2e5e4caa946b164b041d99d4f8688317ea0b7e87d906d5c1df48ab7e1292121a6988e9853f89c251b967b0f7407916231d980b853f85180a0227674433a690e19440d73f1e478b715a096701fd4834347a377f9ea8d9e05dea0ae5b888b41744d1201e7c189a8616fa870215c921cdc0a5e07cd5f82c393d04c8080808080808080808080808080a1e09e20e14ed4e2cc3c829cfe5d40a8c2c59f8d60d170b9982e7c18fe4cb177a601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a00b8c417ac24830ed7f71def3fb99c3acbd01400deecd7277914c81c74f869d08a02249098cbefcba7af509bfb5359f6ee713af21b28df1fe2e31a624625d6a2569b90e7302f90e6f83028c60830379c4090b8308b46394167008000000000000000000000000000000000180b90e04013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c880000000000000000000000002a76be18ec7bad66862f5517e3a0bb223a50d6f200000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000002a76be18ec7bad66862f5517e3a0bb223a50d6f20000000000000000000000002a76be18ec7bad66862f5517e3a0bb223a50d6f20000000000000000000000002a76be18ec7bad66862f5517e3a0bb223a50d6f20000000000000000000000000000000000000000000000000044913f6c2a40000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000aedf90aeab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a07272c8925cb012e02ed54023927e8c2261ef5d3b1f437e5b2f92bc5b870ffbbaa0bbc5cb8dc10c33b047c6f279cb3b87167124cfc4de2b60eb1d1e36f089edde52a0527886f9386cb8fbc54db0c083dafde70d367bdf8a8f50b13c74548927962441a06989cb6073ca89e6737a04c7c834ab14bdeee51369ae3ba83e6876b5bfcbff73a0a416439377e5f75ff62f1547f1201e2a8ad804f042b54e8a348d5403a5b9661ea0d56ca8d817db357f387b648568bbe90d99d2b68ce6cea935c15f4aeb67bd5942a070ce7404232f041c62a63eb4090569f8677b67627813007ba6a8c94975502da9a0bbd3085ac80f731abb5681669571d83cbdb28edac273f69a8d0e0d7c9c2f2f41a089a87118f59724dd6e07d2e40ab79bc87547f4a22f81de8365ceca0ee94a9d86a084b5229f86aa55e2aa84c10370277a6cd6ad9659ff7556d9bdc7031e3e1873eda00db81e6c341ac3c8b5242269592b22fa35746e510fc02776b40c15193aed10fca0ad0bd4420a2ee3c7aef52f5772d6aed18cc0ba15fdd52dc7540bf8eefabdeb53a0564776deadbbd1d0f354aa93f2f827d8f4045fdb85efb8f0274755d3247487a4a0673c5b4903282addfd77c33ef304e4b77d8bcf12ab8119725e97e36e846d0166a01bb331c3dc2eb752de61d3eeababfa9ceb5633d18c592c16bbbe1b8958cd2adca0794a7e8c41354be687b640ae91f62046e5803176cd7718e97dc234df47a2f48f80b90214f90211a0106523a71974c90e0100c810116e39fc91148ba05f9f5f839075044b11b08892a0c1895b0b0e7bcd5692ac4e705ebeed5c0e32d1dd708347ca65aa9eebd0ae92b9a03eabe6eb1ea54945853e2c37948d2c0c5ad0f486bed4625301ac9c2eaee4595ba0188614b918019c8d3ded2cbc1a010524b0bb3bdea3569f3cf425632592906fc4a094581cddff3d2f12fb8cdbe980294e926a84d39add35e4a3ff51dfe26f8ed6d3a08fb7e23e1d4848eedbaeec4f352dac5f1dc243ea9a119ec33a54eca3295a8e59a07043d2aff67e3e540d7e047cd869cf10f14f4c89026b8cb4ecbd352511dd3c53a0fe07ac18872f65f35953394ba63dce4994f9eac2cd7eaf9a8ebfae36efb1c91ba0267cee0d482716c587a702b0be46a0837a866c0a946d3d43ff1d3a88806071c3a06bbd8c26af880df2f28157dfb769575caddc2c8c20c749fec49f06769d9cebafa0c291c0277db9e87720fe649e989afcc8532c538b989bc1891714d4a385a9011ba0bf2a1b0f3c262f09fa10b05fb06e94211b38af17276df02f2b0e21aa9dcb337ba0759af17e50ce55f3c13dee45f960de64c40a555a304878a273460c8c00d6dbc4a0979ddd1bc61db61126c27faba89a2edf2bd114775476254c9f31181f77f3452fa0a4b88fe506e7047e456bd3411495d4aaecc97df81234130dce56c65a305e23c6a0899a7b9d77f11aac86362bcb510b9117703d29832ab1d899757538e1053b182f80b90214f90211a03ff5111b1ebcf9ae567faefabbae80995583217b384c605d3eb076fc6ba5e0aaa07cdef04c000ee65582ef40796dd9d4a86b79b4d64040b60e3cd94b218f361b74a095929d4db4a614f90291296c42e2415d930803f6ef7f3563a53dcbcbd8ff1edda0338195c157791945ccd9c368e055bfdd17c894651fe00a18500b4ca537c8c82ba05f4bf357bf1a388c9d5691b776899eabd85f8a7b4255dc57f725c4a89fb3b942a05ce6dc870c8de18f5a6c0be524e8b9e5f746cd1ba4ecc8a2b4570cfb12d27167a0f2cdb4c2e7c844447da52f7ee7d3d8351aa06f1faee9be048f7d98920ddddb0ca058aa5cfbaf3d3224fd03ce598ffe4fcdccb8b9c1b0246dd575863192260bffc1a0af6feec70cfb96d862a93eb351808d84b48e1a8f55d2e114bfcf3c9812630b43a0ae2764ff2a87fdb77c4a1bdd3248bc816b7d47232ccc90d7aa027a511eecf036a002b6dc3d51c06729c348354412c2c93ac858bdf0f36b8e9ecfb539ab2e65f183a0db1eb21b516262ab952083d1a1e12cdaa6dfa46b2552efe8c045f16b48506816a04e7bd4082295916516899d4bace97297bf172a4c684bbe79a4037b17657c8857a0747c02e645ea028819f3c63750dcacab60cdf1fd22631d516603c232af3a521fa0e91349d1c2cb246c9f01c95ae6a604d00f4d467d239a9776235a75ce9cf51a59a02e9e09234a7521d13810a64e2772ec614b1ff54cc022705f0a47fc0321a4905e80b901f4f901f1a0b3df6882e1098f04b7a9ddc9d238c85770dba80cc5f1415c5046f528298bc102a0b31573fcfaf5ca257d687037e2184baf05df531b5b873c0ad9dcd4af4980a24aa08d79f82b22d4aec294a68c8a0695571be2a2818f3093a60ddbe5e2629378454da038f38a2a85ffffff831d31ed0a5c9d26995f58ef8e56408fdfe0980758a13ac1a08b06914219a80d985c4d58a77ebcc0fcc2b05b11ebfcf1b5715d9371025047c080a0d275e7a4acd50a1c0934aac17bc9f498f34c4f7e6ad16f79940a3b2af2046d61a04478aff0daa267dd78f975edebd5423126200f4c97d80b21aa1b44b692d15a8aa048f6867fbd4d7c0cf757b08b8b90534a649fbd7f7d785685c9a83c67ed93e251a0cd8dc7ac78e8bd082a79ed6c3574a24e0b2051cdbd164e567b60297f70b396a2a0bca856001fb88096995f560be5eebd23aec05f305371106eaf48cef3aed8f890a0fae95e621bbf82fb06c538783602a57e454dd37baf06c0f9bf0fb6bdea6c1d78a00de9ef911e703c4e72e863dc2cc6dd45117b98141689f5ef2a2b88d5975b4aaea0337e2356ff0e04c3ca388a2c363e4e86bfa62df1febee84b55e084c61d6e50f7a02e2c41082845d96b1667c86e7728778ed7d6632263a7ae74a11adae90b5a9da8a0465f6cc31cb188717e89a3ab5dc1b7aadb4e522a6985ee50743b7c3dfebdc45380b873f8718080a01fb39b0decfbf00cd2ae282f03da4e776c6ee68d9f16ce8fd944c63acc6d67f5808080808080808080a00e4fb059272183a854296fe2b6b66e83c1791fc4ba78f533f31c0d8ae83971478080a008059384ececc353495740c55aa6b605dba40c16c869e9486e02053975692ce780a1e09e20f36a3f091746b8e26857b8192b53181649c32d3cb759311e24d0ca50cc01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a052d43406ae5568b9f8f390bf14fa87c055e6772eeda142ead05e20024b69ec41a05a9a16b60cbbc0cb2c371374bf3296e8c8e5ae2f4fc22c9e0267d9b9fa300a78f868070a826d60942cbc10fed5d537219cad987e0dec20944d385a0386075e64d4fc0080830518e4a05d1d87d1770f19999d752ae7ce475febef8624c6295c027ddc58d47c254e9e8fa016350a654f414c8558d0dad865e8fb1978ec0d2e1d40c81486d92545f70d1277f90170060a83073bd494e02d9f7a4c98b707de05ac9dc1cd8b9c13465bb787050aae9f7e6000b90104286fbb9700000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000f170a521039f7ce36089141cfdf9240cb84732700000000000000000000000000000000000000000000000000000000005a39a80000000000000000000000000e629cc2ca21ae1945dd3e64051627a2dde78b1fc000000000000000000000000f170a521039f7ce36089141cfdf9240cb8473270000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000066b776c7477790000000000000000000000000000000000000000000000000000830518e4a0958681d6cb5292d6926276d142c54ff7efd43667a4cc1b76fd22dbe6048ff81ba02b535de8caa3e4a58e9a66053391dda84924da6bcc3d820fdb871531b8a8590ef868060a826d6094b8b3a335164ea73cbf922b9ace132c96163b66bc860676f5d0a80080830518e4a051f1c38aa7fc07d154a1e07650293f66ec87a00638ec146f295994e8f545b9d2a03fadbd3e70c9156fcabe2b6ea4cbfbd99b36827238b449652640011f119083f4f868070a826d6094e2c3246535fe1b4225db6e32345576396cc46cad8602dfbead700080830518e4a003a327023f724690ecfb2bbe4cf6ab16ada60d1c76b594fb3a97145cbf9b650da077232be26cc6521aeb7fdf1f9620925b7d5dad5dad10a6bfe4d3b422c25ea50bf868080a826d6094c656f27347a49a328a5cff9a751aaee0886b72df8604ca51a9fe0080830518e4a0c2331ad7858451e9533d9f23c13412baccc5e165aa6eac2b362fd5d89825856aa026759cd81664311f2710bc570bb479a5e6d3d0b4d47b7a21e5ac3bea0f1ca6c7f868070a826d609474030f0e2460c1ebbcf41ec5e1095ec9962fd21386016c25aa180080830518e3a0a01af9e5ac5d953816a03a54fd8e825d5440cd2a258c5e428db9c0d636d708cea0327d7d0926953f9c014916a75987ab43c9502b656303dcb3df7b587def9e117cf867090a826d60948971f576ddae27efeda36e36659d151fcef42b3885efd0c8bc0080830518e4a0cedfa814d61f61fed78a7f8758ebf493f0c2298bd769e2087e4e38cf6084a534a037822de5fd374293318435466cfce64365188b7f83ff8c3a16cb36268a15feb3f868090a826d60947a94930f20ef8edba35ec974c79f76c18f81b5238604ae2580840080830518e3a0720b1d63e399f01b259dd07a7cfd2c874a38a8599e0545f291ef935780f7c182a04f69fa364cc9e4c723a6116e9ae174a4cb0ebe05a1fbb9f419206aee150003f0f8680b0a826d6094bd3ec30e7e7053ae985ba14e48f0521cc59a26e986088e3ce4b60080830518e3a05578f79c21cfb74e28d283b68f0fa4138456ecd2c6de1c77db9a4dc255223682a06d57d0ebe1c59eaf8a31a1def33bde85f3434be656309541340641083842d526f868090a826d60944977dca482ee1e7b5cee52baffc2c1ed93e5367b8607e08bd4120080830518e4a0dfbcfece944703047bb5c535008a6e8393e72717954b5815aca0493e1ca86d04a00f1a6b91fe846d6db43a5cab83ba3a66d960e248506476ec9d5b430562837acaf868080a826d6094eef208b3fb97449fb68b42c348cd4681c4cf2c7e86046633aab20080830518e4a060579c45d57d51933c8f09fbb188e6e615beb01d500642fd1a5c4b8116415527a045d45461eb201ced505b6bea9d4351ccb83a9729204368cbd24430280771a14df8680a0a826d60947fa5117de288be7717aea9fbf74617bf4036c8478606d936f9a40080830518e4a0884eb476030f389a917d392a8e4ae02be24756acb451e692610ba2bef737633ba03c27888a5de8fec6e0edd009a2e60300f378f927221aec13b792649779d06aecf86583190aa60a82520894054fbfedd05874ac0972b6aeacfc82804fda72d70180830518e4a088c5d67d3bbadc4626ca2e1ffd965faea5b88012314c3b1dcc62a8ff194dd486a0420b8d223163a9e5bf2a99d4e214788b6f4869b28fb6ce2d7fb33d16eff81a55f86583190aa70a82520894054fbfedd05874ac0972b6aeacfc82804fda72d70180830518e4a0689dfed22aef48368bf3de5487946f5726a61c9384e75baf0ce1f5ba2c20551da02f848dc35869b9c52d77e6108595e38c3b6b8e67ed2ca4f490fe4d4286903117f86583190aa80a82520894054fbfedd05874ac0972b6aeacfc82804fda72d70180830518e4a0732fdf6198b55bf63402cf2f8cd21ecd69223dac07dc27bf89e3e762e0155d9da064b40ae09e975d222d76a900470e6ae23a2fc8bf0434d0de9c37c4c6dbbd21fef86583190aa90a82520894054fbfedd05874ac0972b6aeacfc82804fda72d70180830518e4a0fb410e9f8229243b1717bd85f7365b2ab2978a0a4ef17ec075910a37ce954f37a078fb8ca59c2ba0ceb13d1d02767f75985416ebe2bdf355b4a1f04ec06f98be07f86583190aaa0a82520894054fbfedd05874ac0972b6aeacfc82804fda72d70180830518e4a0f9af8e1ceb0210dc29d554ca2ff2d515da54efc0b279a8dd1e8c0116cb332147a0298fb02ce7525ee888088a688d9000713926677bf4798e963946d99b7bc8b0310000000000000000000000c080a0a4bfebb7c64d7f2f7902f7c1d2e295f38e06cab52d538083c7610b0aa6475571a0751a2c1aebcde0534334b071ee640c4698d75e4d523afb388f3eff5cee2af076", + "0x02f9c018824268830d6ec9840ad6f2f68499384074832dc6c094b20bb9105e007bd3e0f73d63d4d3da2c8f736b77820466b9bfa4ef16e8450000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000004a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000006415bda9cebfbb54d81278e6b4c8a160c33bc55302e31382e302d646576000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000041e574f051bd887024b4dee2a7f684d6936c4488000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000662fb9bb0000000000000000000000000000000000000000000000000000000000160a870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000046600000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000004660000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041ec1e4eda09aef3417fe463d8415352880ec8634b72b3db32b5b6cbd175a8acd041a19fe5bc7979b129e9bef208be3bd61f021c36f739df21857fe97f584764ef1c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba6cf9ba69b90e3302f90e2f83028c608303772a090b8308af3794167008000000000000000000000000000000000180b90dc4013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c5d000000000000000000000000ced8b9059d6ab14a0681b702e98d140e9bec843100000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000ced8b9059d6ab14a0681b702e98d140e9bec8431000000000000000000000000ced8b9059d6ab14a0681b702e98d140e9bec8431000000000000000000000000ced8b9059d6ab14a0681b702e98d140e9bec8431000000000000000000000000000000000000000000000000002f40478f8340000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ba000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000b600000000000000000000000000000000000000000000000000000000000000aadf90aaab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0402d30afb7972eedade42bbe54a4fe163fbcdf49c8cc2a3778a6909b890754a7a0d9995d1e7ea32abb11b1fb93abbb16160ed607d1a056b45237a014799bca4f4da00aa83456c142901fd3327929009eace9f652f4ca7eae3bf3e0401e322e32e367a07dcdb69d6ffe3c2f119adae076d7cd0296e8776bb6de4d3c8b194500b33e74fea03047cbdb11b0ebdeb1c7c9a368035df3a3c3a31cbdeb0fab007d7e375583657ea081b6709266f7efa2ab12014689fab794379e54a03926d71f2dd4fc4d5b78d2c2a0437b43ce6fcd63a27c5e06f932ef4a19153948faf983ecf73b96ac2969d3debea045093c3bca3ec4629dc8ebde10a426d679333a54a9c5b56e1d2e3314a5a343f6a0948bd73d3e8ead561da6505264822d5bc3ce0d47bc30b8037001952b30f06c6ba04d65154812e8d03947995de5b3ee358b423c7a5007e9b6aaaa60bf9c34d23f85a0da34ad5e3ccef7398bc112af8475fa52ac11acac41e0af52ae9d215d68e8a38da0509ba6aea3dc00e005042565af104984dfaafd7adc9e3a32b008b56aafb4a67ca07b8d860dc327a89668fcfb2091aff0db8a0567c1e16faadc04331c29370e1646a06bdf42e4a60c7f2209a34716146c0f02ed902cd85d2f1d70f084e669693dd711a09c6880346b317cd0922ce73022b4bd21b2e2e3c6d42625bed067110ad158f1aca09266f9dc7653175bd9190a516fc05d109bbd089c3397f604e5802d8313477a1b80b90214f90211a0bb972caa8dfe0f4905487fab4cc300705ee21ba28eeee8475bd15465e9dd07a8a0748e96916034864a275063011351f3af884accbe31b46fa6f8ca000b47878a25a0bae8223f57927c64120ec978112cef06e2ba9747ddff7e613e2b69f7df2e6120a087a1d9eb74ea0dabde592248a6b851ba35e6fa56fa9e939cf01bbb41cb73b2fea0d272049f13725c87160a922d5d7c23e5a1844373be0a379ffbbf5abd842da47fa0b94e9d4a7c4d13479ac06c7cde067cd661fc2c244443657f96ea5f926d30acf2a07c75205c04fa4d92c4eba40db72ceb46b6db0bb137177a7787cfb6034fc24c60a0a0a4dfe607d39a978307d7678f27dbf7984be898cc450f748455714b09107341a0f115125aed1f1a9f4da14022a7013da755778560d29baf2e1539b3804bc1c913a005c41545362d55fa5a15658725ef8059739beac983b192ce204711587335b2c1a0e0451eade5bca596123654017e949c81feb6f40c7275609abca6f11a6a187fc1a0d5061a36f4bf739d8865b680e81f7fd9f0fb81b782d44a9df1714780bdf8cc6da0b3ca302582418dd627dfedd18b7dbcb3ae7b37f50e1502c38c6a47295aee3210a0f447da8ad9bb953dc00acc643107ea7b4cda664e59df0b2dfa592e42afe442d6a014f1c1abcd90ba81fcc408815983abfde2fa9edc44616939111c5216adcbfb61a076dfdf3afd2ed3e927e248c060f18ae038b5aada88c60958d855c00acee0a32f80b90214f90211a014f6ddff10a7b371b59bf7b398219a47dde130005a7b32f576da651f554cef0fa0776d8ccf93ce6b43ece4fe46bbbc0508fd16fd7ed0fce03e8198755eee188578a0dc9cf847de528ba4065dd7b8caac100e8c5361164a4acb347a997c1fe8fbb5b1a01516199cd922bbd15cf17e9f91539f0ca449f031677179cd17c95336dac22d86a0be2678f01fea698ba186bb9eedffe3cfde9d4e1e2081d23f711ba81629eec2b9a06ee969df4b3806029838b6efd1f9c67c1da96bf056e950c6796425b9c91b0269a0c52fae6f045adbd8a57a13f631a315a5712ff6f197035941a48134d9ba4879e3a0e50870f30d53890c02b49e5d1c2cfffaa01449df68dcc43945d159eae856133fa0c4f12926ca86845bc5af5b78acf1a92d5ba6cf5991ad12a446143dcaaf57ac35a0759542664e94f94d6d4d90b71720cc7fd2c7aca3a9ececff84747deab14a4ff2a022e386aaa08881d85bf28e1b8d04f36dface0536410006501f7f23c0762ca8e2a062f24bbfdba3e75cd5844343cf2915c7b0505c73bbff6fcfcd7f0f53a3d76b20a0e0de9312c32536bd0a2b8e49a57ab47cae68068282d10d901aebcf4e1fabc2d2a034fd7cb615c600baa573198fab8775ea55ae539a291f4f9b59053eace2f02f58a08abe67ad828f078787adfdfda27c31a187ed36cd32423de282076c1bdaa92598a03695dea87047693952415a1c7cd2810c6d0590025674f9fccdcc3b567f5d4bce80b901d4f901d1a0310fdd7ff0661c08bf9ee675ee07fc2418c05b58675b785d9b38aa71d1ea2868a0f9fc3239ed348b40d62571bd49f1effea2f8103aa8f28603fff641b31f9778e7a0a2dccbf24fd1cbcf7f3e7ea8a1bd230bb82afd85d419deffe6a2da8ed19012b8a0249420de584fc7228a5d0fb126e0490ca599518a6aae7e1c99e6df34a0248bcca0b6282509131e5a9bba7623e11f3afb38558290108eb725767069f5a54d4d3989a010d716de5093443e0738dbb0944880309d4557dff4e45cc83c1099882143bd7ba028b22bc70e4a118a0370df33dc58648c88cbad668f651264780b221af721d21ea09537db06749ddc1e6a862550a11afda0fece157873c8985ea404205db2f0e9d6a0cb082d84fd3a53fd5f952392352218fc01a4ea4fccaf2abea44e192fa47d6ba5a0ce6c298bba58a219386deaa0c635fa2f59b088c92bfbe9b8f418824f45df1cc8a0b4c4470fb3f15de07ae3ddc4fc479f725dcf5a75dc4873d7ca541e77e3a5a6aaa06f95c101f4904dba9fe7a9722d052be9e051f81da374f720e36c606f95d70d158080a03f27e8891ecde78ba8c8785b981cd545cc7bba01558783562bcb204629b56b84a06bc062938585c1974c24045b2ca83b4c9dde9c3d98c4bff8b3233f4a0d53942d80b853f8518080808080a0ffa68a6c71fcad45178567639eea17dd700637965467603964c5fb6ffa394eab808080a02a307fb352c4a169d61c0a1a72c644a81b76747c2f88ab56a694845cb7df5ee580808080808080a1e09e20bb7675c9d571fe15ecf48630e10519a8533f7b9dd7a459ddde42b7c9a701000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0b1f8f0a07cbd96b63403be350ac34b53c53afef2513a2babfbfc013bd37486b1a003d6cbee264f7034bc2baa58ba9364b3773cba847a3a873205ff9f2f8e39b2b5b90e7302f90e6f83028c6083033654090b8308b41a94167008000000000000000000000000000000000180b90e04013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c5f000000000000000000000000b1fa18036a114eab03ca76c0e2a7c6712531c7b500000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000b1fa18036a114eab03ca76c0e2a7c6712531c7b5000000000000000000000000b1fa18036a114eab03ca76c0e2a7c6712531c7b5000000000000000000000000b1fa18036a114eab03ca76c0e2a7c6712531c7b5000000000000000000000000000000000000000000000000005d14c2dd1d80000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000aedf90aeab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a00ea7599086a524548ee2a638de6d1b52ccc3188782ade3b0fad03d0f332d5ffea0cd9691d86d7e34295657462b278c2d9e5719ebed807cc2904e13917adf985458a0785e5cec04b56c1b3f7cde086f0f145b59e03d6bf13cca0bd49417da6e3e493fa001dac040644be7d313330ab4f13f065c89014b39477d1b448f2e93b429240fd8a06e8b5b7bf2d33de94a4bc581c733362bbd9cc54063d4600845c50fa84fe989f7a022d5f1374e8575537e273ddf4b29d1f43e11d3b5d88433322a489f94cfcf2b7aa0ffaca60185d5788e1094068decde5cda96e5d3fbd0f4ee55509e5788c40ebfa0a09a257b4b401c68511b52b334739d0d48d28d60f4edf972f33af234bc81d3a79fa05b9ac0a6d36cd949d40978d739a3d6a335d2a6cd16bd4e439d4da9cd846ea1bea009a40d9c0fa70997ccd467192239b516fc68ad52b8814048abbc21e758c21a97a028100a8f9a52026bb3ddddb1fb33cf134625af387f98704bd5da57d3aee9727fa0c908b5a96966e855d3b2f86a6badfc28048c0b156fd56e7aa99213184393f6aea0cafd8337464d52b2788536e434bd4e6df0bf4222c087c4d4bd9a5147cb36a92fa0757a8e45c33d0ff69e87f850999fa4877ec0e78923053d089620e3675612b837a0e8d7bcacb8f8706dd7b0209331c1320024e4a69dc353b64e189c68821ecfb7d4a086b0dde605e175c6cf33c118b11c6de4719edaea09ba18eae150a6bd82aea90080b90214f90211a0c149e75b716178f18a7703d898c4176015bcf78d262a0b4587737f5c6c744dd1a00feb2ee242944a1fe0ff652242db088bbd789a1de143cca289d150b5de57e96ba0577a60a00b2c71348e07a135947d739c2afa307b17bd6455d76e7351ef0ee439a0a8e27ee08864272f9dd0dd6ff0cf31c9372e5d6b99d12c3f30cb41d76af57826a05bf3f81d61a95c65369ec7b667f28dd47dca50203df7b99ed7c2dad539f75d12a0944103065594ae3195ebf746da1d430ddaf761fb92dd552e02a6ffebb0068ee5a07894179c686a0986bced29afdbe9cfa61da05d873f49a5dc884e8f5d455832a6a068e3c9faf171a2ebd1be984d21ba442fcdf1368aa2e0815db57654c67a413fd1a0aee02fab5c58dab2307c67ebe922c09679d0a2a2e629e10013cdd67663384be1a074ebd2db209b25229fed11c6bb98ce4ff7e0baf174d40983b1efb3883f925e62a0a4d4c7e530b8fb680d78d451477992ccfc9500e9cee3511d12494eefd4d423ada03ac088f7b4ccec1bae3984f72817f20d4e6e14dfafe92a9e7f3bf685efdd51f1a05225ef77af9384825f753ee44ecbd955b0654679c3186102e70c59838e99a83ba0039f5eb05ab4e6d541f2cdd45d428edbd0eb3b66b1bd1e762d725f53fd1af05fa0e250a1d2405c8b8e37f48038597c4bb73e90938200880b48e21e08e39cf73c3ea0b0cdbe66241b75fbe450bcd6b34a109ba73a935dd359909229b4ad19c4dbba2780b90214f90211a0b99d2719a230ddfee6bf06012388e6393de8a00a76c9d65217439a8eb591ad87a0b39ffbcece00fdee11d5a2923ce0a4fb392dc2cb24d14d22acea6ed2cb564b31a0085feacd9995bcf7bd51aacff7fce02eec9db21b35fd113df37b18029337795fa0e486b2562917f56dd70cacd28ac605e0326da88630ce925f22d7152b587ba0baa0b2505c72df2f0d20a05478b843acdd725d6952590a97f9755f5079824393e3cea03c16c944f3f67a82a3bdf4d24f7207a3001cf607ac117dd06d3ec73d1bf4934da0d447ce16771eba5fd230224e6ccad7c9947e1addc2d5e8208b3ee82318bb1af4a0e64dca16783f6633662b1a749540e8abd106ab47ee9d3ef27a65eb37b6669907a03f696ffd2b3dc3a0b62d7b6545fde1e7275548ebe4980c6c4c52e01aa28255d1a071bfa792f6123f41e84e512f7b70887f986ed38a2f2707da194fa1859ed57fd8a07bf45eb331829b81350cc7e685e25633699ea605e8bd2eee2b7a7ca229ffe83da04269b8453a4409ba66454c8e20177e972dde66241a1b0660820d05f1faf80e16a027153c0f02f8e12a4868327c34a9d78b0fe04d1227b31c5f0c59f076ff5ac9a5a00575a8f620eb27d8c49651d347a47342c69c0939440b4916db0ee9ecf7ee6d46a0e4d6e28f2a8dfa3d90c3581dca103110a938463b9f930d346fa3d9ea6f29b89ea048dc9e604fd111dfa0c46a0c9abc09e5e3cefabfc164bdcadec21d1e81b3abd480b901f4f901f1a0bceb46be71f841a3d395f8f5a6834e39c5c6bdb22537978ebd4b6911c028c36ba09311a12e98d523cc48e503a5330c79e36d31b12fa536e737adb842dc25c6d9f180a02fda1f24def895ade01922417dffca3340cf30dfacb472ce4c1bae565b322039a019f2c7fe57fb79029fde39c54c1865b04589ed20542d04f35d9c2870d53b7338a0783cef4d505287a4fad00eb84afccd7684579ef0b608767854bb3382948c6187a04fa2001cfd89651b33869f2990024cd52f40189acbf4e8b9ce771427c72bc2bda053041e9d1a3dd1a6addab1f2559bb04d232d2158db8539b814d29c5ce7714ddfa081645bb5daecf099fb0c1239a5a0f052c175de7c00f152a17fe8186b1ea93ad4a0043a318b4d50a759c5c3f03c994be4830269f7a7a50ae0196945acbd239ba370a0114970857f5e1987dda45cb521edba95096808c788e07d89dbbe403c72f41e6aa01ca8b7b528e8fba461b87e135bc8f852b6796f1f599cf17a44b68900a5589aa1a00c4546c7a844ddaa726236f0c8c29e16ac3f594cb4c2cd741e6d25b776fdf937a0c153e23334caebad454ebb27a9154b0d1715176dfd5f8ddf9c7188b6d37b6619a0e275285613f6a369a6ef3588894fec88429a081b3565ec4de167eed32b84fd73a04790ea4febd7ca7a10aa33ea552baeaf03cab3586ddec57506b56b64a2cbd90c80b873f871a008281ff98e42a0ff7a75539af128a39b056f0ee89a8b540098f574fc3b51ea328080808080a06dca01425058c46cb9a0e57fb4ea652f55fcba0efedfcfa12d68d3c8685e14528080808080a081a2405e16b1015ec0bdd0183738891df9dc9d4a0606c4f0bba2c7125484380380808080a1e09e208f3aaf3dc5ce9c6d288e942076d1239fc377e7619c14a45286d2a23ec401000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0a50f80bf99a0a8e92359d07f909d78804240577d75de1121f76b72eb3ab184bfa05a7a5f35f3d1a6cacd5c1c3fe4c7678390d48a6c6f6beaa5ac788de75492eadcb90ef302f90eef83028c608303382c090b8308be3994167008000000000000000000000000000000000180b90e84013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c6c0000000000000000000000006f197546aa9527d96724e773ad57d95537cb3f0900000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000006f197546aa9527d96724e773ad57d95537cb3f090000000000000000000000006f197546aa9527d96724e773ad57d95537cb3f090000000000000000000000006f197546aa9527d96724e773ad57d95537cb3f09000000000000000000000000000000000000000000000000004a9b63844880000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c6000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000b6df90b6ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a09591d235231196568d434755002a6d5947a58c34f77531a9c86ac3fc2b093b77a069368bbef45f706c2c14e5aa027146d788e6fac74f59b46bd407f0248bcd0d4fa068ef1adc0891f35bc2fae8495dc1c950c151c1ce108f66c0fc23b97f20c2da51a0daf7b9335c53a0deca87e98909726d8445cf30ee2c95e2181cbf77aae17de6c5a03c3b514e72a3414b9d17f87a7d268b2b838303ac2de439ae45d0619e7406d703a0e2429a5b6d7da0dbf2b99bfab3fa8355bf3a283a43a6571a99fa95f1e437cc6fa024eeed393b3dece2dd3f0356fcad84b9f9e8fce33388d4a7ba75f828dbed32b5a006ad72a9c5df7c3539f258997ddb6cf2c07902882ddc16f1b4bfd8d52025ea39a0305e5744210ff4e80529a039d3c91870e69568e232b27b3f259fdb2d005a0b64a05c92622b3d684e9bf0fa4d0ff90b02c6ea9ee44672efd63d5d2537eaf8fcf8cba0b22d9a89ad697c7436b6b13ca45f9c8548c6bae159fe7626c131cd0ddbb81a25a0a2b88ab0cd6572ed505973e66cc12cf5653c47e5b8d33118ff58a3d1e90c78fea0d1af0f2d79aa45f6a5f1667087ed0780ced415f5b31381ec705e28e5cc58d2eca01210e66bf57cebdcdc549dbabfaa3b99ea1ee57c14b9fe01ed5e8eb76c01d541a0dcb5547e96bb514cafd7fe53e31777553dd957628d7ef1bc267cdd6a532792a1a0bbc7f1181582829e3d8d3c4a7c9a1433c6ca19ead2a2cc720c0548cdcb9e726680b90214f90211a0755f1381596dfa40c4c9f739d4b59e6a09d9cd237aed6563090514bef1c17df7a0018e943f70b2436fdca886547fd3d5c9baa97f0e9d5f8c3eb0dbe358b4c78a8ca0e29dcab3967194fa9d8190fdfe02efeef65e66c03a3b3ef23dba186176c3a70aa06668675a05c4c9106280660409abccc181c905b2bd60943f0cdec591df06f974a03b8075b29469329f6eedc8f17c385135a4f6adc7497600aae9a0c9681ca0f216a0a89e918be1d2f5ed497b081337f7410be0afd8dcb0e90a0112b26527aed6fdb8a01f079778ed399b8047b53f71304e967d76d68bbd8853438c599b1938199895b5a0b615af701ab18ed73f1c60dec1730382d3a0da395658cfc97a21e0ca7b509488a0187beae5a89fc594f07644457c915348a334d958b728f1bc0a74ccedd209f8a3a038ec9a85b6e92405daeb3ef646b020808eab68d281b9b0a24b2fff7c2aa0ce1ca0a41a8fdcbaca0e1fad59b69335ceb3ed78a860f6a084ffdb3c6b14af52b5accda0a9539a84e55b61431b55f3b594a4c82c934254b5396f892116f3c2adfdcd995ea07e4fb1856ea9aab6e749eb7d12331c12a6d791d4922f06530923da9434748b3da0ba4a4bbe82a31fa07ea6fb8e8cdab330c7502f1159e244df3f9c64fb2bd4655aa0944c45615ee57f41af65855eaf86ba692a61ba1e4a7116e62d6cc636ae40cc35a0f55a53c4bf225f94e4c31a43d598c4377405154148542a5ece924685f3fe9f6780b90214f90211a071841ad6ee3827496e5696f9406e603be9451ea2aa7f727217e61c65b9ca535ba0b5a23b812537f1f12b857e131a87f493518f44edde83fc7a85d76823c12be3a5a04775cc9385d4972dbf92b2c0a7806d7652c4e500e925c3186eb35afe4989c4cfa0a4b477f3d044757d52e22a58b051b09108bed8a1586963b2e86076197832d486a0c9ec27b8b82912eca1d2d6175b765d1114a8977284fa74ac22c844149227672ba0bb0c90a6cd3c868a502d18f91ca842f8c15d700e3f72a778ff7b2cc12692aec1a0061ee26c8ba9400a21fa30805e16241af339321832c83a1a28c69913b129bcf0a03f492fe83350f96b61a70c16af1eadbb743f11fdc54016817445729179473482a0c1be0b7829b505e7e6c2dd39b0fb26829af330840c08d8494ebe38ef9bbeb8a9a01f50afb324ae9189c7b67636a839e71c1a1e4ba475db47477376f844c641ffa8a0d2acceb41a36b527416789a8ca7ea630602544b5091f3a3a8087cda01d10e8afa011aa365a45db592554b74f0e488f563a61c5aa95c2e2984147efb11f3147abaaa073b48b06f970bacd4f8df0d9b953e4c12fd1d37233d3cea23bc3c7d894a0e5f6a0b4cba9a77313e9f0d62fe6d7adfc9027f53dd7957706c96f3044276ecc17a202a08bcc3061d4e19d7101dff6a9313adf6dc5601fee8c01b0eae717167be271e057a030879800a48030f11f4858d3ecd6c16f840fd08aaea3b21fff9e6d288893c36780b90214f90211a014c906904561825cb42b398ca79e23a475cfd4ca8682e0777f4f6967d52f8084a0f376bf2409fc300900e84501260c61f11a9fec33bf57d8d90d84e9cfd4757c2ca074aa2d0bcc139a57560b85d09a22702d50df6160afbaacd04663ceb807e81d44a084e880409759653337cca84a485361a5a2cb1fe0720568a1cfcc589729b2427ea029039a90c47707981ace16688f04ba7d2b2d16d4eb72ba6531b0eef2685213a0a080ac0a02ea753472a5eb39c891e38db55c0c415a4818efd5faf31d29d5989885a0841143a50d92df9d895fa68f5461b3945e6a234443bdef48862142dfbaea94aba0baaf89f2a846bbe3f6d6037194911269098a89d61e09db5eb9b7c0dc23e98c62a0e527648c7805394fbb55097c8f60652c880be9cb5e52ef3da9b32ae86d36eb2ba0fad8d719a43474e1f7b59c77d23c4348d032b9745ba77af7aed2b67be000ffc5a0bcca449c112db1ab186a022ffe28edd35073a28061b2d322255e8a8dac107db8a02233db9baa1c27f0b3a07606406c82a9e80cd0851d536da865ad67ba6e0e5323a0d7c52716bebed36a7b584ac1f11d870dc18d35e0ef53ef116e8df0550581b3d8a012858def96e1fbdce77da83c3140234c0bfc242f28e148aeabf30fc0ec212227a0cca179f9dc5af41df0c29757f2477ad983874da8ec0d63d1fc412322f9f29d0da0f109fdae3a587ba52972f0b72f9a7c7baf6faca8d94629468e75beef1232330f80b8d3f8d180a004ea0dce15d27b08b8b01fc216e88d89afbfeceb019ff9577118b12bc8028839a0a0389971e50dec15817652010fae6e2bc800c3a04db0460136f055a0a44a22948080a06c299b4056d616b889e1daed6edd60e2cf43550e318e2c06d7b96e110f4d9d9a80808080a05fc8173977d11e1a8d3073b0b2ddb1dcdc4928a3a38e099c7711513f3c1d5eb580a0fc6adfcae0932bea99391c4f63e3ddce3d487104622eef02f4f2935fedbfd46180a02e34c63d841e5e337201cbf4845b3317f37d22306fc0aa1ee945706903a37e278080a1e09e2047cd43ef323a40900a7ee666b2884a0977ce6d4eeea228d533cf3264f801000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0eca5bebb2c79f85dc2d7243fcc3119e89f475fea47b5fb9c5b4f42665f352612a07df0a6834315e9903faf3b4f8ef8029fd039e8f033c2b55579cbecd6d3e1c105b90ef302f90eef83028c60830336df090b83092f4c94167008000000000000000000000000000000000180b90e84013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c8f0000000000000000000000009956c81487bce9aae122070d64058d7f5c588a7200000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000009956c81487bce9aae122070d64058d7f5c588a720000000000000000000000009956c81487bce9aae122070d64058d7f5c588a720000000000000000000000009956c81487bce9aae122070d64058d7f5c588a7200000000000000000000000000000000000000000000000000aa87bee53800000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c6000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000c200000000000000000000000000000000000000000000000000000000000000b61f90b5eb90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0ec69c97154c6ed2e589338293a7b94c2073c85bb8409feefcbdcc6d1e75c0560a0037075516c34666ca7a14c39818e1405fab2e017eebaf79b02d293b7e39ab449a0847219295de9deb3e5b2a2c444839984611fe5893dd1421fc56caa4cfa579e14a0f430342e2a3a80837607f3be47f32d0ace0d1a7deb3938c6a80e7b2c73928c40a078d50f96b1cbfd4a5a3c7e7b96b08d417ba5e8de8a56c41872c9a10f4cd2ec9ca0e6786cabc29a7aaaadbf90525bb7f418999dd80341b05b59bd6b0873abf962a7a070f2b4ce7a33ccd0f09337635081e3f38648282956c919f8b33d14255449716da0aa6848ee293a4965a6ce8777d935b8f1ff3517c8e32a6b08d5b0f274378878bda0fbf2bb3735c4d69d35ddf54f5bbcf97ee6d7e1c9e1bab1376a9813eef693860fa01bb555fa5d93db302e81e45b42fb72473473ffe917d7004d9acb50b8babd1e42a0647209cab7c8c2334d3b893cd4ab8b7d3397b6f97010af3d4bc44e998782c841a0d2a03eb8efb1958e15af7a2469f4eb8b468a7497da26ffa213a9acb9a4be2529a05a60e5d0b43ff36ae0897b7ce2b3e7b74e8f9f64e4bddf60d3bad3783924d00ea09a6ff32071bc15eda24791fdb8e2c64440f080f9c9f0e45f48f0c064e7407ac3a089b21c6573ce770e48b2dfe2cc73fc7f0eba58dad2e4444045826e01acf6373ba0e8057364a116e37df84e61b27f7d302265dd617ed820d3a928e1264c1d0333da80b90214f90211a0692bed18f064d46f3b3667bfa0d6563f2abbbcf5791757159f9f57ac5a9e4d94a0b631ada134c3338594dc5ede6ff19697b2895cd99c1ac21eb15a773540e224caa06476f9296aa7c0709958ef5cfda67f14925f736cced04313628432be62661996a06f7c215ea408d7cbc473b315d71bc76c20af679571378a654472661481f71849a0af593130a8da20b04985d18aaeb811fab99e529d4e88418bc893e0086e43bd28a054445f754e699905949fad7857a242522ea82dbac580dc6125bbdef90d358184a0aee684649ec3117098cc9fe19c1de31739eccdacf8b5f7f67d1b8d3e4c26a84da0971750661f47b7abb43a42cfb5200a91096c2e97794db72098a16e91751d9a95a0ab34930b7f651751b2897212129b8dde32d314eda590b585ebc3d30ff49f0556a0c72993588a5348fac00723972e9995f9bf843d249c73b5949fa9845261c73bcea0065a00d92ca759040819d4a7f1e0109e7ffb7a477dbcd2765e6329736890806da0a48e265eb11a09e27de2ffa78b1b3d7e6e893b82e1327dcbc749624dad5a1e62a09f17a2f47250e652ddd22f46b31a5e594cec2c2610bb3fcb147c80f18be4cde8a0f60a01153e06ee314b5fedb9638d5a2d8d4fa2c35f6a369c5838fb8514a75d97a02579c6920f87b0bd747d91e05f30e242070c27e088bb7778e2f1a5a1ec43e190a04af9e7149ca9eecd340cb893adb7525539629ce7fd2f51260d5d85dd494df9fe80b90214f90211a00234144398753d59de02f8fec500d30e4f9b276ccd3279f9845600c6707b96a6a00dda9aafd37f387ce3a72819ca76a487248972bfe5940f3736943dea471b47e9a0ad24ac6f4dbb342b2cf7d36ca9f3b05ba88e8d93170cb528b4cc8cc2e00cb16ea034503e6c6c8730366570bf5eadf990819b26907e6509fa104a0c271900c1bd68a065be79a053ce71a1f961cdac1fe9dfee6b28074fb9ce1245982b114ad567cc61a0580de54675a74c5f6fbe754a77bf489659e9b5f38f5e733492026e11d36995b6a047a68bba5d9fdf86b631de6bbbe43f03216cbcc38f99a8cb5e8ca697b3c4164fa0e767cb4b92f7dfaa081910cdd9c32386b5ef6e586bae9f16b151367f0df9f813a070d78a88080febac3bdb2fc6d1794655d616becc22ce133ac6824e35dc5a6325a07549f9704fcee465bf5397f73f1ef9d7e7bc1118d9e4594cad819c8bef91d82ea0c9f02c6be637610161454d8940b5951abb4e93c17126dd6023ed1ed020d418bfa080be9e62b684f198b9b19eaf27636d2e6b67a276e772876bec681b610ba2d99ca045c01c64e106b5a8154e81768372c54a72a99ec8ee90168488573834727f7d31a026014dbb7364fb7d432247015337ae905e623fb8394f998aaae32f23428641dca04574b2225343dae6c12c585e433fed2ea5b63a4553984192e120cf72b432dfcaa0e0cf0b27ac394e7fe9092216ef6bb0670c6729aa6546237618a09432ea28f28880b901d4f901d1a0f43f492a9d48ef391e6aa1ca098d6569933280d2bc6024065fd483f2369f1730a07b4aca8bbcc363e151fe007bc35a25cae5b2ed1c8a68653156ca2387447fe9cea00f5972fc1b9897d78374f0d3bd34d26b1ddc157d979cae3edac0d0b7318b51aaa0a32610cea2295fb956e1e628d0cdb8a5a85dfd25b37af35d5ee05f414bad1fbfa030f527e61fef54e92c6c51373453c07b834ffb4b89b46f015cfd18f24f01467580a0570c052f9bdc2cc26f43db9bbbf953b9125f7f96da57127ddfd8127d1159983e80a0bef6eb1fcdf0d238962bd4607ab93a4185f17651ca1c17bac1b64ecce33daccea0821fb1daa867c34d2ef429083f8642bcc122f95093bad49a9677b173033a7562a0b11ec92c5a2145806c8de61d3b418fff163ee31fe5a8db3e605d3be099efbbe5a041839e2b48702ea4ce8154b9eae186f1b68fc57938d1f31971afd56eb427f50ea020e143d19537ecfd2b1d45f404ac0121817f36b084f68a2f927d262585abe058a0ce7b8bd6c6f6018019f4b03b15a334a0a1df521b37ed1a3720dc0381d1d77bd8a0bb36dd59a0b37c0d394e7dfb1d6150fc6f44b6a42b0c4f7a5422160ae195d715a05422f4a457778db6066080348bee8689154bdad647a8993a27d132d4da15612880b8b3f8b18080808080a07bba9116b15d47559a63a15ec3eca861729e518a5e68f27bdbc141f7ef486e80808080a049b64899bdeff5af2619817f0316ab1611d9fb4dd44c75b63af45adb31767f8aa00538c50d9d9b05be066ffabcf389de74e4d200d5a497daf6fa76dc80c509913980a095af87e9209dcd8f3161c1431b15447d302f50acd07f8d8811facdd4999e9dee80a0ea419ee968725ff2914fe1859d30b727e4e82a2755b9104ddd76c71b69b47dc48080b853f851a0a13c0f1aa25826a96ecd9081b4c234faa17e06cf183ed26bae4a37c8b38ad64b8080808080808080a03fcb551476446694ad8a1cfe3b5de179584c729d14d76db5afe2f503f2e39ab080808080808080a0df9d3d998207d1fab0e01f7a8bdb7a1b04e6f31e0bbd46347a37948f1dc5e301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a04459673c0e19dcc547d2ea0082868f60aab0117513d9de8815d6f038a8f49997a001e03ce816b3fcc17f37eaffb1730eb928bf6f8b95ba83ed30ded3cccf0b3dd0b90e9302f90e8f83028c6083037652090b8308b6ef94167008000000000000000000000000000000000180b90e24013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c83000000000000000000000000fd04a2f8872c0fccd9aef21eda80732d1e04968200000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000fd04a2f8872c0fccd9aef21eda80732d1e049682000000000000000000000000fd04a2f8872c0fccd9aef21eda80732d1e049682000000000000000000000000fd04a2f8872c0fccd9aef21eda80732d1e049682000000000000000000000000000000000000000000000000007e7a02ea0100000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000b0df90b0ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0eb73706621c2757a66b8ed1535f0252a8008f15ef401004032a0236dd4149966a014cdc85462819c4f3c660cc2a732aee11a1b1b60011c96f35bc51838835c8601a0f48bd20f032e24fc9a1e6b080d44171fce0e9e8c9909a889883325b79dec9989a033245d23e9b76248cc3db418fd30fc058da1c5968dd5e811f77b27e271c32292a0958d10af1229549b7faff4bc5072a587f8d124591952327544b2bb0dadf38cb4a0782b61af439bd6f0f749d40424269bce896accca1ab5ae22e157543f4e803f2ba00c81d177183aecf97c55844b109e02a86b91fa09bf1df7274536e519e835842ba064d499f74397919979df3f3ce80c35cb13d616e8604aa4260b2d882991cbf016a06328b15923059d23ad0f2c6acca21e0520b958545acaa487edb573ac8ba2e8d7a0cc8796cb8f8c2283d5daf891a906d0de3858aba6414050975c0c926d1e5e74b3a0078f6cc580ca081aa2feb3f79865129e9b3cf0066b19e032fa373a3ff8712055a0a85b8ad92c7da1d62ef8bf7bfe79ccc2a6c36f7ce671772c6fb6806a212bc0d0a0f7d7c580ba4956bb1cba28cf621217e945b00daeb01722d56bef7ec8beb93ec4a0ed5f21c63e65d50032fce217db02976167dc6d17358e1e1180a342a499214459a0aaea5b81f3b9220d78f9a6673b023d7c7422e3fe65b3d0838cc5d560c5c83510a0c6ae66b11c85645ba5dc2a12e0769aff511c352ab7692b7203ed5da7033e1d5480b90214f90211a0fc322966b72083786d03376e12b6d0b85c7501aa48e25a57f110793a7d61a6d8a05c9998e2d51040d3c52efb884ce663677e82c39abb33825a13139253dc8f820ba053e54cd5ecf29a15b190279513a77aa345f2aa5b48343e36a21ddfd2d568e6e4a0abbd7b96b7c9c4e84352302e8b66aafc09f3e0baec6230d1f3542e89de926dbca05a78f195c50bd016a28b6e6b98894f93ce4f3488b55620b63248a42b04a597eaa0da4ad5ed52be082b7370ad22f11820e0817b9826414c874b71644d8d4ba67daea016dfe522d44187a1ba1078798d8817a223695d928ad27d88cc8e62896d9a0e12a08502713a0c89b038407a92b850207769eb21ed27b1592d5bf77b801917b08ae8a08def5725cd311a0adf85adfbe12f8070f2838bcc19f0b932f273f77c674da24fa0141f4c4cc34351d7e7256d6e9a24011fc0c3d34a117304b5b7d4a01575d4faaca01e7ae9ac4783f3ed116ff82bdfb089ab1822e8fffb02b722e14c67799377a77ea0c793caa406af753ba630942b4f422bb22284b7b11c97d29b2dc7dbd16639fe4ca0d84504cd46ffc10de4ad4ae669e0f2725831bb6e720c417c4106fcdd138e7622a0161df8ff1acc2b065507e655447d5a483615a80f63aa3d54aba950895ec5ca1ba0baa7901ece3b2d32b39ebce6f72968025323e775eb570f87407fe325e4d732e6a06ec0bf1c94146c984cb5b890ebcb0418f1c8d3efe76369541d3ef6adfd338cdc80b90214f90211a02bffbc2919494604cf7fe56bfd9ad16277633dcfb409e1f6d14f0e6ae80fde09a0c38c09a3b140e1d8a468e8019d8b86cf2d7077c28697d2ca065a0509e417257ba0bf10cdcb75810fa79e44f2c3e080a1027c648152ce72775b7128e6d4f25222d2a05613571ffee5dea25488d169eaafad4344dcc62e3578a17fe53c8d30f79519daa0b1bab6880b6fc4e533cf81df105a667c5636f4064e436b71b4a4ddaae658de32a09f8ab48b06d07ad1f7aec7ffe362de3eafd40465e0d696bf909ac08770b6f694a097b0604de1567cedbd9839474ca4569995f3327556c8956e81a889a9e9377519a00eae6f93740bc13bdda7f0229e1e5e818a5ec49e87ba137a71f8a3b393213e61a01260bcb1e580cddff8a7e0c9a75dc73390f2982ac3124c9473fef9106dcd6b8aa0d0a00bc56734e9608abd1ab90751080f2c34571474c69b1e4c345da27ecd4cdfa0440efa5160b85654a60eb52766d4aa36b3c35c95388a8da197b5e3d9ca67f024a0fe2632910e3462bc4b4e3aac2ea133458d914a65cf2102c256877faf18faf1fba0b4457fd424e088746757b9b703ba683714ee830573bfbc1712f83aff7ef6ff3ca0c6c0cfbe4e92efa6c6b0a6478d9c1497431a8ce7512ca7d91c436673316db56ba0a24bcf82605d160230c779220407ed4ead0c90706a0befed2029d97245362a84a0e9bd59fe7f498f3a1f87a2e1aaa4e506fb470f96d5f2ff7fbfd20e54312bb37880b90214f90211a06883d921aee10a66c673e4ac993104245b754c095852c6188a7c6e8d5c0ff3f9a0385d61fce51c1ecc5299a476c5d821b269550a99199acb2f5c088608a56622f7a0e31ff426fc408d90744dcf3711b98a6377bafba627a6681969cbe1a23b42eeeca07b1df787d358dc9f8a17ddbcb07e4799323c5e314a5bd80762ec8d9badd0eeb7a081eaf6d3ae829d3bb9f9a20a1df5f2b4f3d483ce087b68b95b20b0078f0e96c7a0f5f393e6b1ed24a40b5dd11ca9a1e467708813cae61abf70d358322381602724a02b4bccf92628db38b5fe2bcdf00ac2f2aa97cb364f0b62a540b91cbb7aee026ca05d2c4d71d5cf6ae4b2c4f97434ea24e4377ced894f2484afbb03d4359feb2656a073e43da306db498cbad3026305af2949cc25f03ac97289d13988dd6fe2d45f6ca01b1ff0b6257630fdd013fb9049c07af643cc28227b314c03f9684165cc36f7dfa06cdfac619d89e9be38aa34d0e5f7978373413752041582b6ff467b50ec1a6ac6a02bf67b0bdb099df8225d7887d2b591053b03249ce6ced9c23866a4e4a757349aa07d6c90301036afbb843f9784729a90dd6ea58631af236088fdd1446fb6826f53a0ac3e26a05f6ec7c1736ca6ed510eb245f84d3e782b225634d5fb530b3da32ae0a03876f2a9ac56cdc0a5d0bfe38bed843f415447493772754838f824c8167c296da06d0aef736e8d953c4d1b11f10d395e632197a80bef9f79eef41d737c61cf6f2e80b873f87180a0b24065cb4de9dcc860454a05c3ec892f7cdc52c357faec53e93394f13046be90a075ac979131ca391ebb6f70e8263f36da7e9f502a29263f99a6a9a8328a0a527780808080808080a027cfa6d73557b6089a08c0047baffbdbac279ce794592b54c214d59d7c051f70808080808080a1e09e202dcd88d75c3dcf944875a17c9940732eeb2b130920234d5bd8cebee23401000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0a94b7bb27209258f238d1be5192fed47405899f02f3ab8bc3db05c6db2ab1cdba07214768e45296a4471676a980242e5c991f83faf3e4aed1e09db4c1530e033f1b90f1302f90f0f83028c6083033807090b830931cb94167008000000000000000000000000000000000180b90ea4013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c9500000000000000000000000010e0990839caf2b568c6bce5f11a6c897cd3ff6c00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c6000000000000000000000000010e0990839caf2b568c6bce5f11a6c897cd3ff6c00000000000000000000000010e0990839caf2b568c6bce5f11a6c897cd3ff6c00000000000000000000000010e0990839caf2b568c6bce5f11a6c897cd3ff6c0000000000000000000000000000000000000000000000000067bd3ecb7100000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000b81f90b7eb90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0761ae4038e2742836158fea5c074e7edf78bd4cce5e0f66bd6dc721e5c85f775a01b2a5fde589960147cfc9ece3b84cb0fa6e056d4f426ded53d0bac2f385aa85fa0280afafd7bf9707084a5a537ad270fcc3fc92efa9a7bbe1e8cd22843266b6782a06f386076c231cf449587f885b121a1271c2a9f639ca147e1043941a61935251ca0fea2a607baa108b4d5b58960d24ef5b70402753b5bc5cd6025f25f6ee74da50aa04af82a814cb0b0e9755c95326dbf58a032405bf226a1da75692e0730caca0490a04db71e7674982c4ec882e380388e0cb490e0df0e52855c4a981aed9c909a6dbaa0024df9b65bc0b252e11a16de6aca6d1a47ba8863ce03f02c89e7ebae5eff39ada0d7fc15435db683f6202d3b6b72b559fcd9e61d7e26ca1eb4a6bccfcddc7ec24ba06719f335dae11422a6e135185b829e1babfb1b937e939411c31a12e9f8d35649a0bfb676dee4a0219797fd162ccdbfb63e33b3be8f0cfd1d579da754e47bb060aca008e06f2167c6b3e1dfb5ce3a10c2680d2905601bd1e392296ebc917196bc580ca07d97d76b748d8a5c54976206c62886d05a5b5423c768d0031b0d48c9009fff9da0d269a0fe461462d3504214ab4b4fd10396d85c2e6b293df7758de394e201d502a0f110b7ea826f72b02aaac97c0a299c3fab7c7852c070cee3d1d003dfb0df360ca0bbff1b235ea6d9e8bac8ece338063a25884e6eec6982be087dad7ffa772d587680b90214f90211a0fd442a7fd6e80d01aeee80955453e3d11e55630d48a0c59290477586f1dcaea6a08044e31f752e392eb0d989883694861685454ef3f47ef3243586a90d7d85b180a0f118df6860cb633297403a1e087ffddbf57b0c5804c4d3d8bc8abd39f006cb79a07614270f2ffadbef1501c2096b7ab55cb9a1d838493e8f3a15c16e17144b0096a0052a874ed4a389a50c5720e37f9736c1a71ea4ac42f8c116f20dbe7b3cb0a300a06d5bf772aa90d6f6d8b97ee9604900454a73edb8c4fc26690d45474375511311a0ee48101217cbfc52c5d865e2fcdcb66b6aa54852f11c6abcfab9768de6ee0b53a0664b22f90fda451381a6022aed3e249950ff2824b79563c585b542bf4de8f751a022a911e01e559bd9a9244b0bdb2d750a87552ce033aba1db9031df4df0bc4107a07609da05c300569c65c5bda4bfb5a9f9752b85659c97ef25dc33f9efb5e938dda0b9d843328cdd205c466d137b684931a8aed4f1ba2e662d4a0aed94f6175ed3a3a09ba21d96c6f590d680cc3faddf3bb4d95b375c59b458b24ab8962ed90244c3c2a0e3e1967b742ac2b8204d06506a451de73d72afe046c4215e1737755dacca8f22a071be6852c5bf41522ae23912cba3f5afa0c91159aa0f9920247d4eb6549d9e37a09f086a47ed8aa47b8b2a7e87f850602ca45df0a14e7837bd8fa02ba2d0fd2d17a0a61d450daa482a605f601aa5c503aa786948c8e54b635bf252cf06150bc8cc5a80b90214f90211a068491b71004c3fe894a9970d74eb09c78ff3f5251012ad2b1df5eb43a427bdd6a025a351eab6b9443fb3e9da52a17d775ca943068cc71e95888501405b679840fea012f3dbcb9ec20fc69bca06d8933a2f4b3a8b95e5d3ac4059e27f7a56c4f17824a0cb31fa81e74c191dfbadb8727a6efd26c86309aff21bf64908c9dc7e2ed52380a020c3920c72297bd7c2a0c86fb0cd4a654d4fe1bc208571ff86768ba28819428aa09d8c75c94f7a06500e7ed6f66a631af42f28ac95753356e5eb71176e16cff152a026e07b60a3aab17343ab67a6e7fc713bd879a82dfc5fbb9a2834135835b95f19a0af37a720a00446f38190d444f802828d174a2dfbcf2f9eb0d7ef8b3f3f92b4e6a0e3ffbdc6c670fdedc23bc335420f8a2629e1c1103d26cbf1cc3dd5bed44ab277a09694257c7e1f626dfec97a524aeb6d6a8a2b6a5653b81d97c8b4dea0622a8c27a048cd7c060a63614f4391a1e84f9ce15eb55c7183ea2ca842572478155fe0475ba0e71cc744cda15abc3d164a86cae92bd0b76ae26cfe059d6cebfec0bb57dc2124a053ba769aeb07a19aac044f1a27c0e91b105fc9b29ca67f5a36c6f9331bee1006a018f396df8415230096b1bb1aa301b8a47a112e0a74850ff43144d4d5faaf7941a08a181cb4bece2c059ad8ec5dfbb1f1f8739f1b443f0e2f147ddbd454c0bb8409a025f25704b899c08e21df44e2b01a97456168da823660a7f5e59fd80945cd34e580b90214f90211a07ed46a34da0a661b8e8f70ee5a9ee974243d2e441785a408c6c56a1da49c5f21a08837c86a337d956a388914358004021d376367170c25455020bfea7fe2ef23d2a04266e4cb90c71e563c59aa337a9c35c561a174027379e469d37d60ce2b8ff7eba06bb4bf25804df9d59f6e042731aa25063d705cbdcb8a54157d2ee82746384292a011dc286f5ffab7a002670ef1153cd6e82020ac016383d4ec6ee608327173426aa02a3107ae1bebd41af636eedb7b609aaf95d5cbc90f12887fd9ba5430c78ecc73a0422fe935a16d9e86e3a65284d7cbb4b3b87598afeb986a08ba1455a196adcba9a052f0448ac4d3b999f8a2633224ffc989d1d5111c72da2ad3fd075cc6f8be027aa0cd8c9ca9bf29296abb3652c78ff62c523edfafd366f802e054eda66a044b4fbfa00bb680ddfccd11ee9c182e8326025b0ee8428e2c3bf88e563934f4550fa1d681a01dd5fef616395cea8daa425140f996f369fb75f7a350cbfbf9fe139c1958692ba05cb366b33c7b22415c60c2c5e02be6528a66bad8cf74d9c9354fa3384d47b45ba0eedc2e1169b96dd8f9afb33861a5c5c8b1477412853a2ba01f949bc90faa52f3a0588c8bf2020ade8415575c2a21153b2dea07b0e6effed2dafd371e725c4c5f84a080fca59e94eaf43856e9b004b6700f8a2d0720d7d818cce132d5ddc0cf5ee1e0a0661b80141ee76cdffdf2ba4312edd7d8d1b2b4aa662b9015db7acc0fe9b5580980b893f891808080a0cc501fe0b3ff430e66fef7df4667c3dac09ce01cdac9fd23c496dd6bf8b3981780a05b1e0fe11e4f6879f6d6f2f0620875372b69d0afadc30d4d655e4a6178eb0257808080808080a0a73455d6d9743c5f0f592864746e25e52dbd259d1e6801c36a77fe921b57c2c98080a07e91ee9e788a65eeb3d98bc8b92abbd05ca148f6e84ed0ad08a8e9188276029d80b853f85180a04e4d75f260a7b55c844ca6383a7049c6e74c0903cb79a661667ffa2507e8e6f5808080808080808080808080a0699f1c3c3cf8cb7d3d771d0c5e174feaa226b294f394330aa1f01b5ca32c4c9f8080a0df9d3d3d81aee2ddd05eba89def7300b551cf3bcc85e68137b8f5bb93c2a2e01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0d94811814cd7f07dbf500190d9669ad3bc1d1f671cf2b6794bea064601c1b6a2a01cd5004dcbffa138dab58f2e31d4fa778ad0cdc52aadb76ffb480667bad3b621b90e9302f90e8f83028c6083033655090b8308b6be94167008000000000000000000000000000000000180b90e24013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c5600000000000000000000000024bb74029d230c92c42d6cd1ed192bd6df05c7cc00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c6000000000000000000000000024bb74029d230c92c42d6cd1ed192bd6df05c7cc00000000000000000000000024bb74029d230c92c42d6cd1ed192bd6df05c7cc00000000000000000000000024bb74029d230c92c42d6cd1ed192bd6df05c7cc0000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000b0df90b0ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a075a15dac85825db006746d8d89f89d1ee5a7ad77ae36fa3cebf7657d03f73bdca0bab252bfbcf9c800f50ba4e6bd8c3a5d49737ecc3791f12beb9c22f3091948bfa03e0ef6777ad6e9540778460020b008b43532260a1822d2e588c5952818ffa934a0e0685596d8f0b0265729b63f59c8b1fe9d0a9a07233319ffdb0cdcfca884f28ba0bb1313b7b1c0227e282d9e0b4c6c9aeab74cf3b63b7d6d37dd40fc309dfc5330a089f29221cc392487f90dca69a1fd0d133698e035214ce262e3321585b89fa145a0251c251705d4d4df77ec07b8c50dcc298384b607ed89c679bfe5d3e1abd0aa61a04c9daf84304d24c4702c9b628bbaf23757b00d99fbb344b419f3cf24d079f54da0ad82d13435c18c5cc3b903046cd7539818db9f0c93e33190178b7f2a30dad6dca0d534d45ee651c67f6af178fd59d0b3bcc08dcca0e81dbc27df1c57dcb828ad38a0fffe77bd96a94d4073f82e7c450be16257a5155f738e6553e9f2631eba32cacba0af06e1d03609a8bd3a4cc734c203bc263bde89de488fef23c50c53749ceaff5aa02cb562fd6bd691762de0477eeedaf283a8d8bfb831bf68509aba310fd3fa2bd3a09bd021e9c266e1013a07f2e69176eda41a425b8382b6bbffb2f7c3efb6bc8d09a012bb07e99a39555733c79d2338910d473d5b539cccb32f1335228c37a5fb05d0a052903fd8c05abb315645e2a78375db0257eeaafa1c398957c19130523a66858f80b90214f90211a0813e66a0af33c7c19212061c55c395e74ce01feffdc24afd4885e9cd3cb257aba02ecfa10efa063efa02cbda6a349215396389889412e1ee17106faee7dd41c183a099ee050e1fdac1db0fffe64a686bbd0eb0318fd6168f0c17788c7071787d6803a0596eecd21e4082353860e34a34df10aef41e6711b1ea28cc3c212507e33df6d9a04779c6f535d7a68b8e97f1634029b62995852cc08b16b94b6d57293cae544b02a0ea5f73f31051396d51b0e9cb856885bd187c251ba71dec9fcfc721f883eccd10a08c3d0c44db4c665766babc45e2202c2d1c14f740b1a87e0c80b9c1e771dde473a03e77cb1e1ec5b64bb70d67414afb3e277e55af195e3b98bb980499dfb684046fa061f3edd5293a5171d60c48f14d8656b1bea32a5eedb4e0701f60fac4fa195a10a0e2af6a35528df9f219775f984c9b4974741f56198362e0ab9666bc33b53a600ca02d41dcfb4cd6879770a4a1975a55dd6a8991e3c501db53e3bd15559fe9aa4a14a051a3db07fb5806fef5d69791eac27f689f06685a8d358ddecb9fa78eab43ea95a000d959140a282e22bdeb21f4f9d94bcc50699bbcb8cd0d4cf0f34050a33647a3a049c04699c39130a42d5833da2054b40cfcfd27b5862195eddd9ebdb9672d94efa0c6dcc5448649fb6f4ac8404f12b0eed2ddb27583102c5eef56ed061db410a120a0cebd0a13cb9d2c7c1e479d6fb99cb7d5cb7355eedb96e31dcd3eceeff5edc25280b90214f90211a09c29e8689193fdc3c5297783bbe21614de9ba05b89b8e605c5f93ae44cbc30c3a0ccbce1d257030ffd0a897cb50c7254f2e9d93ffdea0eace6d4e1beb3f4d4e624a007dc6285b9221ef73ace45680c02f916e41980295e5c6fd05f4c50a5db42b4dea01f63b6d6f70a55b95c4b362e6b3b24e8f43f3931932f6ec22382c79bb45435f7a07538275fb3405b41d0db03820bf0a0ad2a411cfb2d384aafeebb0a94648c0e58a07c1564326b262466c4567daa0816f9545ca6c38c6bde89cd9e90af2d8560f38ba0e6f07faf269021feafc52b618ba54f9b2fef79a48d0134a79395b7051abcdcdda0f1fc517a6d224c068b6a9a798ccbbb569a9581d29faed8b7b74511717508937fa0831248d5e48502a8310664f9d648cc9f325f7f153ebedf08b19d144be7f8fdb0a05627f8964207a1121f0ec4ae0b29d8f28a566e6ef778faa0f0d1cb7128821958a0b485a2df86ef6d3d5cb3f2f596a4030cbcba595f7543a719a426ad3040f2b748a0f31fd10f514820128a1ddae2a759c9361883cb5d499c326063871190a89c2283a06d72420dde59d731c703c45063907a8004344d52858be040c243176bfe95baa2a0c53d94424c781149af4324b33b01842219089eea7429f8e52e4cfcbefe91ca25a0439d5568c7b2c9456f1c43b1e51a2f26881384845425f4143fcbed06d266d7eba029e306c20b330eaf4bd91b424d995b0f502d3ad02f918d7ea6f55fccbc70eef480b901f4f901f1a050b214c4afd934d05f1ac2b7dea4fe47a3e2cff606f484605b9f259c7f5dc8d2a04d7955fa9fed9dc45dc1149a2c3e8e0a746d042367017affcbdc396e673c0239a0429446b009a4909bb1f51f3d6ef4ceb352648ac3c98266c2c5714f96c923b8c0a0f798727c6ee8cd7e00c56e4a00e4309c2598a0eee08bb563d82b89676449a0bea0386775ddf7ee6554361e034fba71876872b625eb99f835e3e829910af5398d48a05cc323d729b60a4f11023a79c674b579f9e6b9b9b3efb1a6c7a05fc1186fd1dfa07673d5cf48241270e672d11add062e78afbf8b46180c80c8790526ea47b952f0a0a8cbd5404aead377f8f7b5481e974d3f8741229d599b558634cf8eaf62716b8fa0920e8f5e7e21d1817d2128bf529ed57e7acbcdaf6618ab14e802865afb46d14ba0d15f4154ea7319cbcc33b843fb1a1b43965b7e3cddda76267a1a6b4a09373ada80a0a5e79a4707bbb807ef40b0514c490be5dc788cb7e2bca2a0361aa006bd3f2ce9a0cb6130073c91166a1535fc8ac750f647f7fef297ccc9a9be6956305090863f58a0a8becd1a11f729998bb8d7f8ab70f071896e3f70d75227c7752967caf0ddc964a016fe9de99145489a09fe0a8ed623300978e7f1e4f3ccaa2a94b76fea06b3de8aa0c04b256272b3bb8fa9007a46221854242c6ba9b15157e18a510b809c315a16c080b893f89180808080a06107b0bda8d6a59eeef59b6a10ef8e64755f62eca4c9f34e9d44039eaf43ac7d80a038f20f6b3682bbacf5f42b6963f26a3ee4d405d9ae4e946b1485b342b0300e5e808080a02bdbff094337ba6a282a8b3f2896424c67aae2c51a28e7e8b59afa4954adada3808080a06980cfd4d32bac25f597dab960625ad0b430f6a049c8c14531acd7a9cdcda2298080a1e09e20b588b2c419279c1596efa2ea3f018e486b2f2af9d5756284b88ce6086d01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0a477608b3adb63dfe5ca43a7c1c569a6a1d4154778e649060384abb121d187d1a057c3f0e17f1f4d8f655bf13921e5fc201b2fb023ae2bb65bea3e9e708a6b7867b90e9302f90e8f83028c6083033518090b8308b68e94167008000000000000000000000000000000000180b90e24013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c7e000000000000000000000000d89f0c7fda178c9f3c83dc44cd05a2c624490aba00000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000d89f0c7fda178c9f3c83dc44cd05a2c624490aba000000000000000000000000d89f0c7fda178c9f3c83dc44cd05a2c624490aba000000000000000000000000d89f0c7fda178c9f3c83dc44cd05a2c624490aba000000000000000000000000000000000000000000000000007154e18855c0000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000bc00000000000000000000000000000000000000000000000000000000000000b0df90b0ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a075a15dac85825db006746d8d89f89d1ee5a7ad77ae36fa3cebf7657d03f73bdca0bab252bfbcf9c800f50ba4e6bd8c3a5d49737ecc3791f12beb9c22f3091948bfa03e0ef6777ad6e9540778460020b008b43532260a1822d2e588c5952818ffa934a0e0685596d8f0b0265729b63f59c8b1fe9d0a9a07233319ffdb0cdcfca884f28ba0bb1313b7b1c0227e282d9e0b4c6c9aeab74cf3b63b7d6d37dd40fc309dfc5330a089f29221cc392487f90dca69a1fd0d133698e035214ce262e3321585b89fa145a0251c251705d4d4df77ec07b8c50dcc298384b607ed89c679bfe5d3e1abd0aa61a04c9daf84304d24c4702c9b628bbaf23757b00d99fbb344b419f3cf24d079f54da0ad82d13435c18c5cc3b903046cd7539818db9f0c93e33190178b7f2a30dad6dca0d534d45ee651c67f6af178fd59d0b3bcc08dcca0e81dbc27df1c57dcb828ad38a0fffe77bd96a94d4073f82e7c450be16257a5155f738e6553e9f2631eba32cacba0af06e1d03609a8bd3a4cc734c203bc263bde89de488fef23c50c53749ceaff5aa02cb562fd6bd691762de0477eeedaf283a8d8bfb831bf68509aba310fd3fa2bd3a09bd021e9c266e1013a07f2e69176eda41a425b8382b6bbffb2f7c3efb6bc8d09a012bb07e99a39555733c79d2338910d473d5b539cccb32f1335228c37a5fb05d0a052903fd8c05abb315645e2a78375db0257eeaafa1c398957c19130523a66858f80b90214f90211a0f14ff68acf07a86b06f6f9578854b088256be96b3853f8a56787b2c9dbac1ceca0f6f1852ac971399358ad55121e0c23d41103a09249c74d0afd06f6b3d9b34e73a078cc49ade5169624b51105545335a128f89dc802d7a5f9e1e0a1ac032185b2b7a06beff70870e352dd17e990341b4f6bc1e6ce681daf50b872e8cd8a2ab57c0e4fa0fbeb2484db1986d23975789b7605e967f17f6106e432d0d2dee04a115f16e227a0af4e201a523f4529011cdfc4b8bf302ab0882504a3bda9eb8fca72dbe92f1b79a0593b19659b78fd05b3092919bd8729d1750c62737325f5364b168bb84938905ea09873de8a3e2923ecf37bec3c413fe376b37b76262025f6356c761ba1bae3e9f7a0c5ec1e87904eefb499bb33a8215ec3da3b71ca60f975d0c19f6f6649940b4b88a065e4a24e33a325742783ceb38a0186ae2f76d5e0aa5b0022eba1cca76521c604a015f96427b30f71599c3a9bef93b05ea7805bfa54de45d999c11856ef45e11f96a0626175f67f6b1387e4ef8a20dd56abf3339b995ce9fbd32c85b1fc6596a5a762a0e80e66ed52838ac589f6f38bcb32605a8b4f894d72314d48edf153ea32b92dada0e4adfe1bb2bf17afa966dbb0518fedb02b8c8de63ac1c5ff1e84ad899ebe17a8a0087375b1d7f9593cba6b83ddda5459fa44c754304dc4e88096331218cdd8f5b2a05d6d593b0cb0b43dd130654458ce43a8b3b5f95dd936f56f9f875af7fd5a60ab80b90214f90211a067d0143059aaf663cb9a0b00026817a28af9c534ff00697622c938cfd45f49b4a0f36346e7b8e0ebb0d749b98b98fe198e5619843f2d0dd5aad699cf5c7a7906aaa048925177cb8af070abf4f3d6c4c22f8484ba78bd78c8e43c88dd52d7f5e39609a0c945ac1123b96fd29cd0593e95cc4c3fb2f57b9a0da0b109e611f91688e2e66da0a2e283496ba0616586d40cf533431aa84849f7a441adc4f30feec25ba648a7cca0c0f3e89892515c063dcef180a3378bc78bf2587a8d9fa9bf5d0ab0ed6ef2305ca0a0fd32c3d2ed4bc3bb3edc4871a702e6a6b97aff450c840ae1e6a78abacc4b67a010ac2f131221683fd5fc5c5d66799d0093f72a7c5cf74c98326f8bd846ca25fba0927ccb037f67aeb90147360eeb979ad3081bc53280ef9a031de29f54cd20d5bba0cdf7d22d3ddd438aeab6eb2bdf05008a9d299d0e60c119b4324f14a973a9f631a0aad61e1e59c92787a393d6367ec11a1b54757583cc64b6fef8c0d9f993e29445a03bf4068013b999e32048709da90674d83091c87c89caf0f08abacd7b4845acf8a04d9a44b78ae22b8318036e2067a110034dc8aa91c99c1b03ceaf09b8147134e3a093faef8423ea38a8064d163680677eed8dd6db5d46e236f38363a4c16be0d25aa00af2d44a64e4d4e07576e618ea848d4121f650788382d087c80a64161a164a01a03ebbf723bfda72f8d1be19022e52ecd38b97b48376377a39a53b3a7e395158bb80b90214f90211a086bc5382e8ab3b7d6dec16939c57a3586c8eb3db62ad79741efc9782b5d6fc53a020caf4835b2ff633a713070b3db7682700606271a0bc3a790d314cd1098eb84ca03bb68211386b0695b44394da305bb65454e6b3158af2bb606914bf308ec1660aa02055eb1801d68ce15b858e44f690aa77460e11ca15e58bebdb2ab4516c6c5685a045fa7fcd476bc3107c5ca614d61b608f3cb3da1d431c6c68b9ffe4d554f65fc6a0a92a5124cddafc48a77536450298edc45e20b8f46ac161c36d1e7b3254f013bba0fc66be4aa7f3f18143d2c84dc72b50e24d2e03ac99087dac00f14a17c44bf9dea0f9e7905023b445f40a4c93c538e4d20175337b8cd2f643ae2ebac57f6616e6e2a044dcd257b9909fa81d985197abeb1d2f06b38b12f3c3e163d32cea0a3b3f26ffa077b1e70e272e5a01180fa4e113bc1043f604390d086ecc85d9d7539eed6fedada091246848f8cdab66cb1e58b5855dce278a200c936d7c8551299baf95611f6b9ba0b7f4d864a6bc98d28b12e3fc46e1b9890019a5717db1a1bae5ee8339737e70aba02f8b63222f3dff4630dd8d3058410c0bad0957c3feef315ab896a45b2420a3b2a005f70465d9f5fd33377dd1cb1af97cfb61f8d0380d2575886f7cdf58373a55c4a07f9bf3614d26163cf0ebcef1a8b9da169e828c84e7ca02b4e6d198543acd06b0a0609df06096a40cb2907eab85a89a1ba967f3eeb2da4801f6a1aebe9802e63aa180b873f8718080a04e8080e5c2c6199aea160eefb72ca717b77a938c8b7818aa71ce8727c3238b8b80a0dd2dde437625205124b7b00e3214dea739e06f0472ea1e5e1a0f6ed60ef13f428080a00056424d3056406c456699200241d5a13ccce6d640ca49a23473cd9d8e4fe3e7808080808080808080a1e09e2022b47854de9a40ff8aaa7446c16cc074301797f333c2ac94975ceb6dcd01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0b01305364abd2f64663c3da7d31fe864c56e91c500eca1e615606119f21c8d36a0577fc867ec2138c42a88c8036e03c2398ec1a44c351c3ccd6a79979ff560746cb90eb302f90eaf83028c6083033656090b8308b93b94167008000000000000000000000000000000000180b90e44013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c5a000000000000000000000000aafa2a761380ee7712fba1f5218923ad6a4f886600000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000aafa2a761380ee7712fba1f5218923ad6a4f8866000000000000000000000000aafa2a761380ee7712fba1f5218923ad6a4f8866000000000000000000000000aafa2a761380ee7712fba1f5218923ad6a4f8866000000000000000000000000000000000000000000000000008ae93e2ab7c0000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c2000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000be00000000000000000000000000000000000000000000000000000000000000b2df90b2ab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a026f93469575e7ca18b6ed52f5616781748719739d433f28fbc96846f89f19e4ea061d85a1b32424a58ed85ad9585a2c02309a3ff7469c0e57077744bf2e9f86beea0822c856d94b9b099d59415ce5f15c8fc94266cea4d21f85858ef24157dc00b69a0b8c3f28586b8da9e0986fce31aa800437a9aefd1946ff50daa6ca0b69292d7e7a0e4118df3b34b9aa2c443dbd2ab2dbb14f1dbc03963d8a3c300dc90c080f92b46a0ff2c3bdff946facfaf438d478683a47464ad75683a16c3b449b097e446da7af8a086ead228abcd15b2da34aee018017d62d1e293e0f189d18e938097cf04ac557ea0f3cb42cef2211c8542ea5beb17c7b952e38754971a504873d0a82f97fb997997a0b5770246f4e383270775a8140ada94f4292fa57f93203a39170658f6d3045e92a0f8167f8aa111a4230fb4ecbbb283b6b6595d5b100dfeda73aec2bc055c7c22b9a0aa8887275aa18c7d6551c63dba53a8d8ee5068fe54cd9883471449536695ff70a0b667193da4e2b5050722a251172515267df4b45c8b53bc5248b28501bcc49e90a05582fe73f4bc23bd817b5e347b056a80334fade8b0884fd78b23ab2c9172929da0bc01ddadd5bdd1bc7c862451fc00545ce9f6bf91ce2b5c80c801a2dc85567030a05c6c0ba2944aac42c0bf4698b8e5f7100a13db4d52d5ce5e764076da945d4601a08227d6e164048d39ad888bb317c7d4cdae8bc1c233b16294b3c4a3fedcc98e8d80b90214f90211a08ab59d83e469060ee5a570d89f22bb49dbab1e9defa91ab7e34263beb9aa90b1a0d07edae38a947707889dd055e963559e66fbbe00cc9aeb5098d0d399ae071760a06e51096391720f919aa5d4148a18ea2846fd158cec27a9eea73636fe8a0c4dc8a0f3f7cfc5f00a2993ab05f4a928aeee9767e8a1836c2c613df7e6d7bfd69fef9ba0956264873a39e947a303a7477b71be24d159e9c5c3184c0c94662e7efb06dc94a02eee36e96312005f36544649ea68ff739db626804dd11ccc44001e3a99337f17a0e412d0d3354d2650972e4f72721bae064daa853c28829c2f48906b57041d80baa0fb062df87a8eddaea89ba9aee4f5c0fbd0f03804ab6dc69c456d55b1becf9b3ba045d8d7e7bc15db0ae08b104b89c870368e29bb26a43adc9ac8f001aa72e70ebaa024a0d7db96d45925f03603b862f2b907faaca59e971b371f509eb26863d429c5a01871d8860d5cc0d6e7315b4ffdc3df3989961b4406c31fbad5b785d7ec22cc1fa0e0ddef1c96ac0c76bb7e15e8d3f749971870ec012be34b2945b9a6aeffa7b7fba0b682fcd05d064561258d673ceb55804a025e0c22036e896894ecd6771fe8cbc0a07fd582bdf75377631f92a8836965f6c417302f2879302ced6e2960042c01c28da0fd49c42dbaab3de7949c7627fd6bb9cce17ec07affa44a0eaba57f0c84277b61a005479bfc8aa0e4822f6af1d8ddbb5cfc4314bc3dff8caeaaa1394154a7048be580b90214f90211a0a1e797e2aff0655de327cb6b0e5dacf8bfa538cda92ea472ef7042c8228eb6d8a0450032ce34297f4911e7ea2f27bc77a2a388fd62c46d0b698bc6c6e43f9a6e1ea0e592f5e8023e8d5737f56bbc01aa7505335918241465503c3f1949f351fd1706a089a57f7b04c7e6d0722ec4934c304f29574171c5e4a0585ee1048a8dcad6935aa02be504a73d541f5e9149328b486a3a335f69983d775d3f261f627e8efcef1ae2a08fbdd6c51d2be5601fa087c30a3ee096fb916e44ebc2e6a48470dd956fb9cd42a023eaa7d6dcc4efedc42af7ef834a6bc03b3ded9c86519d73783c1d4bef033bd8a054af283c193ba403ce69792d1a187c3c9401697ccfcf8acffaddb31f184264a0a0e959761df07a485e8ee814d061be45002d37ca1bd068fcf8d5e08e8dddc08641a0c782d789e752cff5b5edff816029c8d777344082862bf2db623f08d86c06d671a001a3432803bccc3be60c8c9ee369f4a9328eb35d65ee5b09ba65c149315163f5a0992a85772df92fcf3d9d642b8c4ee8430fb89526598c7382f7f53ce6dd13f0bba0b1231a6f2ae2b66a0348dd9c98ee84051548130f0bc88a873fe75911e202c209a0ccb9703af639181a79f1a82543acf87192d813b33b570fbf31bacce93528a507a02dc0e3a204f7fff2ec22898113cbbb539d8f92323ec5e8a87412cbe07db6874da09afbe58baa7c72921a266a3e0927bdc4222156e1a20508ee4edb64ab3f3398ea80b90214f90211a0f5518b14d40241221158fc4e1d56704cf46f56ca44ecef3005f814edba2d8ea1a0cf954e863a983a7da4d13cdf950406f612da507253b377ed0ba50b99c20db730a09f2fc9766ba5d4a07788511924939fd449962071266ccfb19fc377a2de7d3623a0f5231c8310bffa42e094ac6d80a3bca563ad44c57c6590d8823952d160137a0fa0aef20901bf95c84e054e9e9e656dcfd639092da7e9809a31b51923faa73f86e9a086a6bd777376953a8deff64104fda6bc61904312246162f5e44d7a74aad46beea055515356eea012fcf998503cd374b70275b43d9711e78a466641e2736a9ff560a09707a6fcc68bcb4e451bad2416fe2f7fc644a8c10e69280927a09afcba6e792ba0d0ee093f88780833697cd6c06e7d3be0ee1714c8bc22a25ba459b06e447c9aefa0e2f83a1065cb5e8c6b805d3a24e54ca4c948797f9121d98681e2fbfa1bbeaf51a0a0c79077ed4ddccbc8d4a1a260829cf372d137ed996cda721979daefd7a13d14a063ffc5d54a3c0dfa9e8e6b6d297e0ce5bcd7668368690f6d856ce1e66b2e58e0a04d6f790b3d0e112bdf272402c7cd6ad6e06bb715edd28a320924dfa9f9c086bea09502ef062e022296f98dede6d215179753f8b84c989195ad6e1d4d9f017f513fa02bab66ba0e7d50fefb5382f184a6f2b83e194e91ceeb96de027b59a1515af0fba01d06489b69d9d9f05912b296201f8da1b18548a78b0bea854eca30bc1f58cdae80b893f8918080a05e7dfee9a556908ff8a3d5764318cb9314bf518d8a2bc254ec3c9624a8133a3a8080a0eb6911f11b4b9629631be41530ed1726cbd88e0c88b4678ceac67590a84b0ec180808080808080a0950b0265708a52e33bcf2b6fdff704f73d28debd3f27ad61e7ae0a2905f8ec8680a0ff4cd8750a3cdbf0d8b2d44281ea8cf555be55cba219fdb2946c1df756ceee2580a1e09e20463b169ab7ed8a58d43b99b197ef62c27e0a734a81aabe0950a9397d4501000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a00b070960630dd0e3979d97227b9c625ffb87b8279280e3e71c9e28e3af88270ca04100530f7d250fd79e48a3257463da3abdd63b948a1b4ab2b1df946faed32298b90e7302f90e6f83028c6083033808090b8308b43e94167008000000000000000000000000000000000180b90e04013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c6a0000000000000000000000005fc67b5bd83e5215eb9f5899b028d5c7015cde9200000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000005fc67b5bd83e5215eb9f5899b028d5c7015cde920000000000000000000000005fc67b5bd83e5215eb9f5899b028d5c7015cde920000000000000000000000005fc67b5bd83e5215eb9f5899b028d5c7015cde9200000000000000000000000000000000000000000000000000426f8d094cc0000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ba00000000000000000000000000000000000000000000000000000000000000aedf90aeab90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a075a15dac85825db006746d8d89f89d1ee5a7ad77ae36fa3cebf7657d03f73bdca0bab252bfbcf9c800f50ba4e6bd8c3a5d49737ecc3791f12beb9c22f3091948bfa03e0ef6777ad6e9540778460020b008b43532260a1822d2e588c5952818ffa934a0e0685596d8f0b0265729b63f59c8b1fe9d0a9a07233319ffdb0cdcfca884f28ba0bb1313b7b1c0227e282d9e0b4c6c9aeab74cf3b63b7d6d37dd40fc309dfc5330a089f29221cc392487f90dca69a1fd0d133698e035214ce262e3321585b89fa145a0251c251705d4d4df77ec07b8c50dcc298384b607ed89c679bfe5d3e1abd0aa61a04c9daf84304d24c4702c9b628bbaf23757b00d99fbb344b419f3cf24d079f54da0ad82d13435c18c5cc3b903046cd7539818db9f0c93e33190178b7f2a30dad6dca0d534d45ee651c67f6af178fd59d0b3bcc08dcca0e81dbc27df1c57dcb828ad38a0fffe77bd96a94d4073f82e7c450be16257a5155f738e6553e9f2631eba32cacba0af06e1d03609a8bd3a4cc734c203bc263bde89de488fef23c50c53749ceaff5aa02cb562fd6bd691762de0477eeedaf283a8d8bfb831bf68509aba310fd3fa2bd3a09bd021e9c266e1013a07f2e69176eda41a425b8382b6bbffb2f7c3efb6bc8d09a012bb07e99a39555733c79d2338910d473d5b539cccb32f1335228c37a5fb05d0a052903fd8c05abb315645e2a78375db0257eeaafa1c398957c19130523a66858f80b90214f90211a0db8a9cd26ce6dbebd8646b31ad3f55da82d00250cb72eca5a243f720c60c35e7a0e2d85754cffaf6e620ece5d54c82d0096a78822bf3d7d52641815fe2b50d272ea0d395e0fabef762c6205c75e107e87ee412a4f303005d4b475bc03c34b8a60ddda0a6163748b857801ea2998fbf5d3a83bb26c19e5e26a6167352842b5f916fcd79a0df6663e2ef39e15b4472281077b0504b2c5bbeca934e0fae5f75fd69e2bc2b6fa07ae0a5c573951c9db9a026e254239e1800b936ed7f460a1e9de171e0d5e888d9a03bfc728bf92d784b9704a0816f44e82472512834484d06cdf46b80373b9296e8a0f3742e1638b7af9637df3621e7658ff129477aa934b93787545e0a36a2d57f7ea0df36615f2413f65479d060fc4766563828279eaed529ee679eae408d97674693a07a436ef23c0ab020119749b6bc0bfc3cfa6063ec630dce18de60e60ef4ac037fa0d6d74d4f9aa722755df57e64f7ea5d57fd5ee1a833fe6f11fb86bea2dc512564a0e1a3100e232e86aba1fb708f1fbd5bc5a92988111121f20fc9a8f640bc9932f7a049303e8aa151cb7448aeecaa5d07e71ee9a747339e7ad16f3c419ac342521334a0e5e482e689cd5880f47607f427d6a1bda7f8650eb6a8ca39e8610c1bd42df2a7a09c227739c8ded5ee59fc0369a1d5f6aa430db7fdf3aa461aacf3fe31fb1dd019a0158005146e8f7bd088094834b1505ea92006897ef6790e1db86a3420de31c53980b90214f90211a0e7069f09349bce9fe97cd966910953d5252867a4c71224874ad57210ecf5bafca0971d8311a7ec49330b1a5e41077e9770230e8da6afd71cb68db04a344cc34fd7a06b847d1486f9b0c38d5289ef681fd09bc34ff10ce38e5753722eaef035a3b7dda0938c216ed34fc92ace28ae5d5aad074b3f00585260a9ea47ba0ad1d964b01090a0b5e4ee2003acc76d426dc60b80907e428c34a4deda0edf197f1a7e25047457f5a0f5c480fc7ceac5e1b310f5978a40079e9f829dcaa020734b907ef12ece551acda044b587d6774472749884577c7ed082a0173bf0105ab5ed06820a6aeb557c7de7a00658d26b0a88d53167a332c86934ce0f5ec98dba7d0a763c2fe38c6c6da3d667a00ef343a0df329218590e9948598346b036629f93a4ea01d6cf8186b74e801b70a0ccde62510bc30203e8e6866abc78a0db5e4dbcbbb2ea16ec1713fc13ca65e263a03e53d833fd170b22d6d9255b3ccf78580b3d6d46efeef18cd254a7e955fd33f8a0e0f7f9d6ee971aa9e78c981ef5987d89ac36a7392136f73e621625fce4fe968da022ed524db3a6835b8d4795c72ca263de31790b01dc0c42d1f96b29ea577f9512a08875fb839bed6982edc4dea7b5adf7c8a5de786f113f3d1edb343daab75ef685a02aa1b77a6d08243e66e522626bbb7f368a5d95f5914f67cff54846a3cfbba3e3a0dbd4fb193e9f55934e9cdac0e4db1f65b541e102ec456ff950fd1561d4d3e8e980b901f4f901f1a007905ecaef42acf44df204842809622ce9b5644b56ca33ca44e3d395646c2478a0d5de40b9a639c928ad694bb94c0b60561d333445e9124be37186784b48bb7485a04d6f32de54b76f67663df57d7c4e9e3a31cf181ea62afa4216761da65da33f6ba0cb7c1bb196debd55d45ee33b2c3a76de0bcea818b509fabaa2b4fe863fbc6bdea06a413f9af5da1e11c82b54e779df60221f0be22e61a35160c2947276c4a543daa04fb5992cb01f672da1a18474d7bcbec94ab5c4111119c0368530bdf7e1a9dfdca04f97ee9eb859882dcca6ad8c0b58fd504e18828b69b90720b7f2b8f92ea0841ca01ce308c8db34796b44ca5804f5bf28fcc725b8cd5cb4ada84d96f8b9cdfed9d4a030f1ebf5607dfe59fb6763340caa2d21ffddc6a8993576f7a2c23edf0a9ddcd4a00611d8c9c460f76061c6d9d7b8cd3a9204cec2fb26a6acf500e35c8527710c7b80a0da2e2e6d11f345d796c9363fb94930c9be0fbeeb8811f6d47d53c12d6a447b7fa069e952eec0dc798c841f312c2163510448d48a6c7f58650f7deb55c278749b07a0c5fd0c75dab359a5c5028b353a605336b773811557b5a5303eb80e6915d6c4cba068aada0b73f8642a36c651e42b0495723b56a0e5974b589577829dd6ee255448a0d0d39a59ade6ba52e4c8200699b134e31149b37090da2ac526bdbb159802bde280b873f8718080808080a044b84711b30b2ca51df94ecf8665b9ce58b51451f118567184429421798ede7780808080a0afbabdc637b1f2c3bba21a5602722a57166e3939912574413d58dcd85ca595e9808080a038a141d18c004bbdc700df20de046b30a5d1e314da193e45d0be733917d5865a8080a1e09e204855a57808a2a6df67af48251aae55b207907e6ad5a74cf3889958a9b501000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a05ba32eda02af594b5419f19e149b8786293740585e72bf88cc819852f7ac3c8fa009bba4d3fcb5241851ffd2a9d94102a3c62f8bdd7952d5e627c5be9cf4850a5bf86583190aab0a82520894054fbfedd05874ac0972b6aeacfc82804fda72d70180830518e3a02ea706aa5c9b2150a4c389d77585a35a9a377e16f654e67bc890080f3d06fa25a04bec745b58740729d26f7fb6b0e4cb9a5f3debd3ccc87042f1dbd4658054c015f86583190aac0a82520894054fbfedd05874ac0972b6aeacfc82804fda72d70180830518e4a00eaeed2a69f4f51de0721a4e35716946ddf11797880bba725e510d82f0e8effba06d0a75c9ab7ee660b3b070b42a7f8e3b65b6992a7e531b13a67a17da05d77a0df86583190aad0a82520894054fbfedd05874ac0972b6aeacfc82804fda72d70180830518e4a090e7bd2cc98bdd5b19816bcb14227c563c33f798db205992720a6f3ac2788bafa0715b203161377622e868195fb229b6936cb5003f8a1649cba934def6fde9e627f8680a0a826d6094dd9b5a304421f6cc773bd232fc13f810c9d477fa86062b85e9000080830518e4a0a5af8cc0d92e15de1e59d148a0e10657ede49e0d8f9e5a7d42b714d05dd3a256a0608157389157ad982d8353f9a48363aeb23435cd02df90058b1eecfed3b52f48b90df302f90def83028c608303772b090b8308364494167008000000000000000000000000000000000180b90d84013824080000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000002c6c600000000000000000000000006c9d4bcd0cb9d0e5b0b3d0e1007c627367a6a8b800000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000006c9d4bcd0cb9d0e5b0b3d0e1007c627367a6a8b80000000000000000000000006c9d4bcd0cb9d0e5b0b3d0e1007c627367a6a8b80000000000000000000000006c9d4bcd0cb9d0e5b0b3d0e1007c627367a6a8b8000000000000000000000000000000000000000000000000006c5b96a1a640000000000000000000000000000000000000000000000000000000000000e975a000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6000000000000000000000000000000000000000000000000000000000000000200000000000000000000000001670080000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000016068500000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000b200000000000000000000000000000000000000000000000000000000000000a78f90a75b90214f90211a0363f9940b2e36282970b2ca02fdbf698a362792014816ccf474eb2a84c4fbfa8a0b91661e84f42316b0740bc162f468398c7f61b74169bb954efd64848390088efa0f796acfd8f3c4a74deb36ebb6a3ad7f5a6cdf1e911947733f245ade962e5c2fca097b7a19b2493fadf1b7a8b263a0931b20dbe4db6d235bdaa3784a1db896ccfc1a06f9e82e579e8b7b369dfff0d20416ab0cbe432a1f58c97a1291a811c4c1622d3a0d74bba8a8bc35205f6377a85637b385288a635fe28b30307cfcc4a10313d5cfba0c389157ab9720eb7c727b1f312c55c533efed604697d8b6f6695433c24b1f209a029d8cde321b4c05518efa507f7b99075818bf2d6d2064f7ab98122ef67256b22a0c23c3bd977b50ab6cfd27068268be5d55f2a47c474153c4323edb58fbb75835ba06110175c1983ec29da8d0af8fb8963ca3c1a201a69d16a3199d76ea0f044dccba0aa96c56840455703b74f7b6f146d160ccfe7672c42ac8cd8aecd310dfc0e2aaba0eb81eb2961be3c18cb12d75959e3aa48cadd2adadaf3e84f0659ed53aa045443a029e089450c9d8e8fbe187a17fcada52f384db3b263fd4038cea374dab3bc1f6da0f613858700b4868bd5afb92a8bcd39975e70253a11474e1db8a072472065d7d7a055f8df8b45eb8a99317d137817652408f5181772011d1730ee9a0438c8150b5da08a63e0f888def7074e99452212ba4ee13a4e362053934883ce929981b9455af280b90214f90211a0b7253b218e38640343cde06204cab029a5b5679a4b58a80c68e7a71a0467d9d4a0a49a43b78d77212ab2bcce49035171cebb9099ec99721ae06194f394ee3800dea0e7b4994d9672530e31eef3a5400ba2bee8af01ded6b65c01ab7b2e4b62c4b923a008af6c895761231b2bca4142ef163bfc63d555f676f0b90a930087815beb4f1aa058cd3e6a07d54b1503b43672db448e43d0be04c0319a963a645ec59bcd4c5de6a0bcdb5526bdbdd86c85f11f48922328377aeb8a91a3f2d5f4bd26b894053d9be7a0bad0bc3eedcac3316b657a150dba35a0c216ea7587f9f658b97d2d5220db8f56a062994164f2464af91c1af3ccaeae7df28b1683eab795cc47bc929c20222cf117a03d6b92ef3136602b816888670bac079ae019c90204721baf5238147c4177a84aa075df0606e0ec4e3084a04fb37e27765e7940a3f94289f75a9df8b2da9cb8efafa0f65b95772d0961496c8f7e6779ae624310422d8b6471151c8235b96b5201a8b7a05971301703358e8b7e15499a21f067019bbaac5aa4d1cddc61334cca41317c6ca077d74d6e13f2e5833ddc400d81cd4286e65b0b2fb9f5071b6cc2c590f713a3cca0e09c8b4ab674a64aea3fc06408a736d2fd40d7416082ba9a8d2312a1002d4781a0f66c49e2be644ea72f8b4b2ad4fc0f27b1acaa3fef145ca98ad9fbc4b2e8127ea0fc25ce629e605e2a2b7dc284303ba0fff6181b879b3a8743719c027b1a12622b80b90214f90211a07b8d6e52a94e40e7288f99f486414bc9f2918c768e490b90174f73cf8b353fc4a043cfe71aeda7c6193346182eaf300f3c0fc1c9811e0229b96ee86f9b79f141d4a03bef43c8915eb908d9e46f2e67d4a872bf5f21ad7823d6d7ce249e3649ffa740a097fd5da57211129c62352c6df435c0d5d16dba8273fcba7126597cf74262163da0fab83ccb98ebe79a77f818790159b8d71e48bb08da862caa6f22b8cf1f4a7230a069a58fb0fcac031ac6c8451968bdbff060957670faaa8b30c8ff30cd27b52dada0b87879b508498ff0200e4a1cb193a616505605ccea14dbd4f2d26e92fb95de9fa0a73322e28703f5fe4f866a222fb27a796d82c5ba0b41ebbc60ad8d042a2eb569a0443c7ba85abe441f3e1e4acc61c0585ff03065e1677f0ce83b2cdd3659cafb44a05b98df8592460d88db5a359672da6efd042a44256847871a50a2c617231247f8a06e6c52da102b0c0f4ffe0d42bc4aea1b05f4055bf160260eb38a0a0f1ea3bde1a09ca5d211b20c9e78f95d1366a23740f7a2a81190841327d66fe594906199bb9ea0fd22d10285d7bec6af30e963fa8be4377de9bd7a42812d68e5f8d754a5bbc9cca04063e8b7b81be6d84c5d5ce6ffc509e6724e0fbc167ff1d1a3e75673e3856e10a06d56bd0e6edc12e1cea5b4ff514a1ddfd1fc420cfa7a3095e8866d0e74b69c56a0f30975b2d6ef46e6f6e6ea6176b686ed44d0a79427eafec21f06a7a1fa8b5a7780b90214f90211a0b1801dae9073c196bd1ef2ee84040b23403a083a8ab8648062e1e0ba4213d28ba09127bf30475bb3cdf695b9ac538954b4563a742cc44e0b5bd4abdb2b339e2a16a096cc25c5a47f839b58c22c675ba4b7b8e51738ac10f202288076dc710094164aa0da66039f6b8d2060cf0ee8fde36ebcd9495636ea52d611d14b25f5bc1557ae9fa09c4ae53db701c4875763ede1f2745d969bdbb6274a1a371d4d9f079309f194c3a02a051c66b1496c80b01a2922813b73da1ed1e27c512145a021e265901d9c36d2a045360b122cef55524193f55ab381758dfaa960712b36f7687a4ef829e5acc3b6a0033b5aa5727a7f4e434201a76fe81c09f7e25bbd50f0cb9e297ef905a06c5142a0e85f542eba9532b05fdf3ec86e228c06793a0e25ed9a507bd74bde28a4017183a01e844b089774ca038a85a0ace3338f9ddf136370da08560375e8b5ed19443a7ea0a1966c4af41e159dc43dedd39779f485068a4fd66b83e7ba73e6eff9e3206304a00dcbf3db10552bb5c2d0bdcd70eb8ebf389cf354a8c1d0b99fbb3efb5e661cf3a034dc389024b861e52f2221b850336e7e00ff0b25242104825840428ece534130a0ce65e625498d60869d2192995d50259eaa083ef7d3eb1201142255513595b00aa0a712b8f1aadb469b1d7bea96d90721933cdd7909b621a7e8166fd969d13ca705a004c9ccadb735a9fdb55463ecb3e1e1524639224008a89069fa70ec7a48c898c480b901f4f901f1a0bfa266f5da758e19c7932c685b38458a99001a64ecdbfe1c5550cff524d8f850a0e318ecdd292d15946fe01268f4c0488d7ffa563de84bc67940ea397e267b87a7a0c88424470f4f9ac9a8fac65cfc7419849670404fc3e34077825b1c7fe1bb349aa0a63a54fa149b4a532b91208df78381560694117e7d59a0598945937b4a689047a0385e0641a88f9b9872739c7f5f5cee0da14530f0a1287d5bb6aa307cd5290b70a02641712d76cd0c4e40bdd815ec01b2ab2b4f65702c16b324761c7d7121abd6fca0c8da066440cce05339d445f54043970c983f7605785923eb829d2f42e7134395a0d93c46aaf158df9ff59adbf7a7a51499aa03f2c206e36bd7a1a3fe5762450b0ba0c6e16c9f49fa4c73906ab9275e43e00866fa00a4e384d0da397ecedf3cefe3fea04ef766aa9b19bc78d24b0a788e1524dbecafe3cc22b96c5c8451cc46f060d894a0ce75e368206ba15ce8167db83e87ef5a2998ac3f1197abf1c36dab33f6a42a39a0004560069d7b8fbfb8f63bc35d0ee5ca9ba9fe1817fdb324027aa900c169fc8ea068a9e5c2b689a5a289cfd94a1795736f492f9cec5f3a398aad0b930eee208ff980a09d0bde4cff404efead8e07f7a2bb62cad2a2e28f5b61f7e02a6d0250c0938ab0a0162eb76cc679f75d31f91e4cb95479915f062e8bd1cf24c648afa32db114a52680a1e09e361a9432f0f97d729075f324cd06e55962d0f77a80f4c7cf2edc40bb93050100000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0b1c50a9383423829abb9599d0a10180e3321f869239f75a4f16490316084f966a0047b5e05252c07db2d61b5c6c974346bbe7de7724573f7e4fa91d06a0d152b1df86583190aae0a82520894054fbfedd05874ac0972b6aeacfc82804fda72d70180830518e3a0f4e42606c4f79308b9122dd5af10f2303c9988894c481f1665ba179949599cdda04caae54392e067ef70428f0e2d23008ae1487ddb2abcabed29c5d529d8e6232ff86583190aaf0a82520894054fbfedd05874ac0972b6aeacfc82804fda72d70180830518e3a07917df204794476d643eee4a49cc6bf0d7d346683d558aa3bd8769db6e8f843da02803b391afbbca8445878ec9bbe52512901c33600ee5f863ab89e0bed2e02047b88d02f88a83028c601d090b830267ac94edd0ddaedbc3fbf67ac4ff2ee14ace669821eac180a440d097c3000000000000000000000000aba71610d914d105179d44035ac576b6dc27d7d5c080a0711771c52612ccaf95b7542049d9e7ebdb573f27feb1c41f76d2333be284b70ca009083ea2de68a3884d08c5900e2626477b1287bed8a2c7bb5f041a8ebd929b55f868070a826d60944fec7076d23c24e7b6c9598a45670d12ce910c558608ec1190b40080830518e3a0b3447bf78bf2b7e0c2efa32a6fa7eb4b60821fa2628a0693ae708d9bf67885c9a0728086160c50d72459c436f5014c34c487a512b82ea2bd25f81b9bf4e26a451ef868070a826d609412302cdbbb28fc764758dd46166465417c62b27a86064309fab20080830518e4a063495db7e64cc60207ebe892c64d75b4ac9ed13db613a193df418f4c41f3a3dda02f0559100bccc7b11459b8a711c47545f48c08d882783cb302749119eb545314f868050a826d609459cc33ef2f73acbb860454b6470b97bd7f1a8a3286013e478ca60080830518e3a048af03ac0d2a7a0427d435fd7884baebdae64108952c2c8c2e45460b64b4a8baa070edb04695cfaf6114f9e4a7f2d40ae845eab31dff5c974499af0a3c8710de44b8d002f8cd83028c60820135090b83012207941a0ece8a973be50bd44842960d842dc35e3e83a480b8640c8b6379000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000001872e1de7fe52c00000000000000000000000000000000000000000000000000000000000000000001c001a0749998e81aeaa559f81b2e3ab92f3450fc4ca1a3f20b6e4a9af0a8b9babde5fea063c26eeb3f57b9d47e9e9c1dceabd68e753285490386f89b17dc491b3622d537b8ce02f8cb83028c6013090b83012207941a0ece8a973be50bd44842960d842dc35e3e83a480b8640c8b6379000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000012b3d6381c95c400000000000000000000000000000000000000000000000000000000000000000001c080a0e72748908ad5a92732b959f1d45213d3c5696aeb6fcc9a862e9cceb6eea119dca0637a1affc9e9b0d60d7efa2b8241694d56a3016c7ff40bd878042c94e91aca50f868080a826d60944c20c1f2e5d11b3054496b0d078eb36f6ed4eb92860150351b680080830518e4a0f81d480af0831a2550e8f632637a2f19ff538e7a35e9e19a3f2db809b5926efca0351a394746c2d3bda6ba8314f6bc1e9dc8a66112093955d603713b95d09dc297b8ae02f8ab83028c601e090b8301ca9994edd0ddaedbc3fbf67ac4ff2ee14ace669821eac180b8447237855400000000000000000000000000000000000000000000000000000000000d3cce0000000000000000000000001670080000000000000000000000000000000003c001a0d55aeb09c2fc9851303011a97e2dd5a825d7da73b39db8a3810bf03f27f3b6f8a040013286ad30e61cedf009cea00239124d41f8b05a71cf06b1e41cf9bf80f084f868090a826d609454a189d06e895393116385cf645e73a0f7acde938601709227160080830518e3a00aa3307527e2536b4ce3b36f9dad336df4839dd0b839875485405699f47d185ca0447fbd8832541f88cf12f48006aed35f87aaa6b3dd4e0c45ab213f49b49c6d51f868090a826d6094e0ae1c2298a1fa81e02d7f007a12cd816755ad21860240b8b4820080830518e4a0f85072dcbd3cae487297317835918e51ae6b72d48d16e621a9173e82dbe3dd5ca01ddaf33aa4664b035da9acc4b81ec08f27ac8a14a2e433e28d6abc257b592068f868050a826d6094bae4f5a01be929f9beb1d6a33f21d92e2d5dfbe78603ed5cdb2c0080830518e4a098df2b9b5701f35935bdda776e83baff0e96b13d8b8a71a91b0166b9cc31f13ea03f3d51b737674e2730e1435dcee843962b2f27f13f378494de906c9e68981e3cf868070a826d609493cf296f486bce00dbf28ff6628c574de506f94f8603bd664ca00080830518e3a05eadc3b7b206f195987172df5f0c30c472cd7d76e9c8128d9ad7b7786f6f30cea0645a67d5e7eab944d2defff017ef265359367b109197de73430a11733918ddf1f868050a826d60944956f74ebd8711db57e055acf3a188eb87cf6c5f8608fdff1f760080830518e4a0ba9d2245a4d259606479799b60266779c082178ee7a481e385e2db596045d794a004456ec79d8d41b3037bd55865a3afec6902676901cdaf4dfb5d1bae40add8d7f868070a826d60947d6e2e0e25d30f430d8d1874de3543a224ff1aae8604e94914f00080830518e3a09c97e7d31b755907b3ed0a4a79aa5f07f4f85763742e762a5576963672d3fb7fa048b7c30dcb407f3ac3e69e70584e076b5fbf8226265685863c1c1290a0dfabb9f90409350a83030fb594d2c3cbb943fed0cfc8389b14a3f6df518fd4634680b903a43593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000662fb3b000000000000000000000000000000000000000000000000000000000000000020a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000001600000000000000000000000002a99837850543e223c134687f0c2b7e059873047000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000066573f9a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d2c3cbb943fed0cfc8389b14a3f6df518fd4634600000000000000000000000000000000000000000000000000000000662fb9a200000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000416547884919cee94bc2c8a60c275a052343c98f32db12c782bb4d281612e3af8b45f0273226eeb20c88d23f8fdcc3b67b30f4ce60ea2f6ed49e8dd49e5a0d00bf1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000015b1682ee000000000000000000000000000000000000000000000017872c0572bad3c5c500000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002b2a99837850543e223c134687f0c2b7e059873047000064d69d3e64d71844bbdda51cd7f23ed3631e9fac49000000000000000000000000000000000000000000830518e4a00d57467ccd2d18658c67b96a1f715b1cbdc92d205d78b734edbe47164a303d3ea06f9abc5007a3f89de41721eebe217dbdbe2e470fc781410afffa3aa551b7eeadf868080a826d60949a2ee5b58bb262d41e88a02708b62bbe1d3f91378601a3cb2cae0080830518e3a019a9f61364520c29d013d7bfe68f433e735945c775e4869a04dcdd2af4c1a473a0112982fde0ade300c4a1f73852a415ff67c85121cc77825775f58db6f84d3674f868080a826d60947405e7a08745b68f33703790d7667f29b4e8ca1286079bdc754c0080830518e3a08c52cd49d2d24d0ef93a4827666ad90cdf964360a22018f429ff876cdbbb1fd0a016e94cff9ede0800ef9a3b95cc929f7d921ed5c8e637d3502aeff1c83acb9395f8680b0a826d60949d02a4292028b71c47b7580368820141f5befdd98606a851fff00080830518e3a0580e1eacf7c9a5020d78fdeada87db0a7e2119387bae4e5ccf03e8602922ffe2a05944062c71f668cac0294c4e806bc8dcf9dada9896f93b80f354ad4306ec0035f868070a826d60946b21f5b5be3c8418b86a650912798fd9021d8ddc860518159d8a0080830518e4a064c53fea1efd546850fb0004490f6912507359d162c739998c3ca922a2de98faa019249bd6303d7177229748e537f05379547f9aa348b404da808cd04b1e455664f868060a826d6094d1d9805fef1ad46e88644a950af722b082cfc27a8603026fc5020080830518e3a0b5a5a36d14019707969d52c72c47770e3be97dbaf15d5a9bf54f8f2742d0782ba068c6f987d67af055479639826225f59da5d77d854410fa74dfb36ec388788f6eb9025702f9025383028c600d090b8301b5c5941670080000000000000000000000000000000001877d7b5a55778000b901e433bcd0cc00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0c615d478710307037f92d9758c994af8ba60f30000000000000000000000000000000000000000000000000000000000028c600000000000000000000000000000000000000000000000000000000000004268000000000000000000000000f0c615d478710307037f92d9758c994af8ba60f3000000000000000000000000f0c615d478710307037f92d9758c994af8ba60f3000000000000000000000000f0c615d478710307037f92d9758c994af8ba60f30000000000000000000000000000000000000000000000000078cad1e25d00000000000000000000000000000000000000000000000000000004b088731a800000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a061363878e8ee8defa1a9ce000a59fa08d614ae19b2cc9225b6b42753a904cb3ea01680cc2bbc3a6fc0adc81e78a29517046b808c79b0e85f6a97b3aceb43dcd012f868080a826d60946e4e6b702738d29e32255e97843a6c797fdf67528606a9406b180080830518e4a084c172d4661486f43100bec3d6e734fee38264f7d30602108d6deb9107e8eabfa01d32b5731a963d4f58c04ce377b38cdaadc0aaf8632a161d06b1241b633ca3f6f8a74e0a82fcbf941a0ece8a973be50bd44842960d842dc35e3e83a480b8445181c5f700000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001830518e3a00bae179ee90cb75c25db57126dd40c6c5e274808c4373e73c36db28643b767d1a0644efd99f6311a0752446fbd207f55429dd7f5df5b69e846ec347e15552c191cf868050a826d6094f65e4473cf49bc5a305b31525b865fdff6f8110986026f853d1c0080830518e3a04a01f91eee7780376187441441ce4cd04864e6310b64118f7aaa48ec5c859739a02da29ad75e75267cf1814530653cef1bb4e46574c643546c171bf5d5b15fcc40f8680c0a826d60949c96b17fd67d6640b0493482a9d42d1cfdaf2b3d8603e01764320080830518e4a0363fb79827b001dc9b6717eb29d0881ce7ef292246d5ee6080f10793fb7be6eea067f80cfd48591e803ae192159282a870494f32ceb1a9da1916809feeb4e5d383f868090a826d6094af521dd4ddc2829e557f8dced8127b4eb627f26e8604874386be0080830518e3a0c2a2647d4df7265ff54faf25acd8b2c8b216eee6fc042a5bdfe896dafed2e80fa010fbdefe8cefabdf86c828d88726820839c5399d2c90c979d984810b13591e76f868080a826d609426bc7322c8c5f5ae100b6ce688ee98afbf56df8c86015211f1b80080830518e4a033535eb29875b135883a3e0d54cb58f8bfb8c673f06da4149f2efe165a189464a0165d6fc88fab676b34935d8914b26b02408de8eab9a96790811e504a65561198f868090a826d60945136032365abcc55ac7ec806bd6f49b1a108db3d8608a5c0f6680080830518e3a09887943c7b7b50a7ee10b420d23724f6565c60323b5f0ba668b1f821b7816c65a001cb39869251140b282aa9f461593439627ff66a2c4efa1c131a2527b7771c0df868090a826d60940590ce0eda02181cb4e971226b14ee4089eeceea86010cafc2940080830518e3a001eefa9d4fb093c37ae02eeb723723e156ba689f83940b5e0e60dc0ec72c87a0a0536181d5d1ac529420e13abcbe7c1b7d323ae46a3b6a98f50aaa61e42fa2158ef868070a826d60941d16686228e2a1e9d63c48332b121b36a602a69786076abbe0ce0080830518e3a0e6103578c0067b8154f711a4d972be0111aad62ab9b8fc3aa8c8cc9a6f998925a019cf76903980aceb4b6252503f051e5e7335d9df6909fc930ec4d60b7270d0bfb902f802f902f483028c6080090b83031d1294d2c3cbb943fed0cfc8389b14a3f6df518fd463468802c68af0bb140000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000662fb3b000000000000000000000000000000000000000000000000000000000000000020b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000002c68af0bb1400000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000002c68af0bb1400000000000000000000000000000000000000000000000000000000000001eb8d2b00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b0011e559da84dde3f841e22dc33f3adbf184d84a000064ae2c46ddb314b9ba743c6dee4878f151881333d9000000000000000000000000000000000000000000c080a00653c24521de375a347e8ac2bcd67d0b53796b08d7bd49cc15594edcd5cd646ca0563a6596e940bf4615345d2bc67369c25ea02cf3041fb6c2b5aaed57ff3646c7f868070a826d6094e468e59f9d0215fbc3ce2b34a3fa14683ee396158601e53814680080830518e3a0e549ef33c2739526c3b4984e36b9471596051eae0eb9de7c6f45ddc0a1bd1d63a00aa2b163492801179910353773c10e91f8d4f3580b0f9044506a8873c1f17e2ab88d02f88a83028c6016800283025cb094edd0ddaedbc3fbf67ac4ff2ee14ace669821eac180a440d097c3000000000000000000000000b59ce2c705941a841c48773d9d998ddd4a71ad09c080a030b8b39f5b8fc677ba24c2258f7ce0d6cc5adde2359cb0b3585e020cce9420b1a043f34a202bab5f115a30670bd53731175bc430314a8adc560350a2e562cbadc60000000000000000000000000000000000000000c001a0bf6133bc4ca8dd2444d476839c5047f40d2fa4c188aafcfc62c18bfd42a2f40ca0384afa5f355cb4b2bb02be2b4fb197458b76e907baaf29fad706bddaef69c34c", + "0x02f901d882426883021681840ad6f2f6849938407482680c94ff0000000000000000000000000000000004206980b9016700e0e9ececfafce2a74a89d521edb42ee300000000014f78dadae1cff0c367c10fce95e9ab7e7e9e6c5de196d876bbd6d2fd0ac3c5cf1b2eb2f40ae5054c5c9634a3598cad7e815fa667969fc653b3276c6dc527fc7266ddd9c8eb23bfe9694bd4bb35afd59d17ac6d49d3df54730062e033e61a9333875c3976ae9b6676a759715ff5cf7bf9a5dbce387ed2bdcef49aa7c5996803eba0064ae775bc0d991e11f073ffda0b9ccfb4264fbca97dfa6345a0f5cc25ec0f6a73bfb1116d6003d4c0e939f3e62d3d1e7ae855445de4f7cc5dcf585f976f750cfd992e5bb2d640f7f392ea6631b686051b365d60e3fb5bbaf7bfe0d993676cc24bf38c3a2e5f092dd9365fde40e5f3d5b7ef410636410d340eaa3c297e41fede6ae7b24deef122c5f74296dcd6e1f15ad9fef277c9d48df2fe441bd8023590fb8749b3daa243e2f55f76eefa2b165272714ab650d893aa4fff99a7bedda2f7ce976803db0e00020000ffff91e8f76901c080a04aba7d17cf69935fcb5d0d3e42e2a1f76eff584f338881aff935653590fedf8ba068b8fd2f4e16d8f22ac57b95b77c6c7f14b6ee1e2ef7cdfc16cb683792758a3a", + "0x02f90435824268821ef9840ad6f2f68499384074832dc6c094b20bb9105e007bd3e0f73d63d4d3da2c8f736b7780b903c410d008bd00000000000000000000000000000000000000000000000000000000000f6f5a0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000036090a75a39318db84fffa3357d14dda3bb3aa2b83b1d3633ac348b7309df9ec0e2fadb5c681c07768ab4932a6305d4f495c23e326c5db9eb3c3adfd5407668f39b84e41a404512e7ca4d430d5de65e52d7c38a71920957402e0f72508db13fb71f302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd00000000000000000000000011968b5b805943a259d93f270323349428e8210900000000000000000000000000000000000000000000000000000000000f6f5a0000000000000000000000000000000000000000000000000000000000e4e1c000000000000000000000000000000000000000000000000000000000662fb2a800000000000000000000000000000000000000000000000000000000001606860000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001231400000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000cf916379b7507254c066dbd2ae3ee6661bf3a8d4162ede56ea56b224eb16facbd19ffca09fa9740dbcc6f38e88a79f42103b6d6d04f7896302ed95267cfdc63c5d15710cd45885d65a239bc621486f91fb7fcc46d45a38979a9a3e626ce7947123084b4a1da39652036c41c8a6a4b8389478430016b6b49d1163baa7aea2799600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c080a06a3f3f21617c2315ec389b84758eea68143efced4c281c773dc3e84abec968ffa0467acce063c7cce62ce82a99c20eaccdf99e7c8172452a1b0f88f590f4e058a0", + "0x02f9072d82426883032f70840ad6f2f6849938407482bcd894ff0000000000000000000000000000000003200180b906bc00c90e31bb98d88b43253e8a81afaa45650000000006a478da8cd6fb3f13fa1f07707c8fcbc86529462564d1c40e59c5369784a6cb199593d31276105dac552eabb6984b7c91934be4b22543c4e4962fe536b996a3398aaf4bf6e8e098d9f96a9decb87e7f381fbf7ffe81e7e3f1be3c5e8f57e30f0af2135ccb51dfd8ded4d966a12447d52768f5af5b3477bbb5f79101249a2e933633b1cad65389e13a55aa235b46c59441896caf506b9e304cd6583b928b4e7a83d40c89d9b335242e185b4369fb073c459c56d05fb6f33856dfdfb1fc66b166897828779cbc30a8c8f62b70fe7cb1141af4032082f63536cff6d49e7e2f8d797733dd6ea9e2670fa7af732c5e1fc90b398c6d8206fd01388172ede875902429ad0f2048da2c3bc9b33bb9fcd1e14cfd1d1f17be44d662a1c14000eadef8d462af764dced5e414bb7b2f1aa55a136f3cbfcd4346fe58746ea80fb9040dfe0cc09568777461cbe1b2c8eb95a30dc4fb7b8ffe647fe1421dfe854ab26fa9bca0a30f1a0c06e0332ab7a136982c4f7449d8cf764a882a283b71e1495388ba75c570bb3249770b347809807d6e224577236d49b8c0b4747d67bfad2607373715f8b29cbf6af51f9160f9053418064025163565e0c0e5d35fc9a1bee728f1e63a847bc693161cc1bca143759cfc2d191abc024076a0f960f2d1862c069d4d27a2ceeca0db5a68c452ee0d16e16f311a4d97a2a1c16b009cc12a23fc3ac8421756e25498b3d047ff7bc22cd62c7a62da95f7a6e852e7f7d0200d808c6675ccceae0f47ee8d6cbf6be893343264ac9387e104877299c3093364a6141aa403f0fdc4759e9a0e46b179cb30c19597d8831e75c67788333e8d45ed0e38a0e7a0090dde04a0f40fd4b15f0e9b150704f9ce2fe0f6b885e3d15fbe6cfcfa3fbf8fc787f2c4dc0168300280e2e209fb836a862ff57b29f66c741ae7882c528f2f5b886dacbd5337f5f7200b1a8cda1c395fbbd07364156982fbec891d0e62accd09dd06947e121716ac9ab68653a3a041c6e69559f8864ffb6f9252d34e8667be9b16a3ac0fc793967ad4fb857119db5b436ba0c13b006c4b1d4ab1599fdbb3712274403be6e5325fd09c44d8faf4b067448924f53687070d320178e7a20b4f1e71bd676ca7fda0fa0429fadba91cb4bec5b50d014e4cd5ea52c14083f700e8b9bd7ad5518fb2523fe3e93ddef16caf7c5f4cf61a33d1b1b9296c8549cc0a8206630138f7175fb5a23abafd910ce3658c1b1b0da5b7786cd911c498353f3ed2e743538006e300f847eb3114bffd039f82d1ab3b2840b43c76ba525559f59c9dac6d4a14fd3e79161a4c00603de37429a232a761dc58bef131a431c668c296beead88d71711b4bc04458e2a1c1fb004c14ecef168c275d9775abf0e37ba91ffc2e46346917fa58954a70272da26ce0c32119801a51979e0cd91374b3df049e1c317332aa331f4391ba5c0b8658f9e1b65528f8b7490160397da88b464a7ff04079fa4149caad8a0cf3ff3654649c45e0d351432ba8b267d0601a006b985636496a2561fe2dbf98d6eb3eadbd615a3943165505edada65a7ab8edde050da603f0ef167dbe5ac02ee71dec3f2f23e557ca6e75ba6a30260d23b5d213b4fc725232a1c18700fc9376aa75b8f868756076845f308195ffcdc14434d8a9f2d0287ba0fa6af25b11349809c0571e0a0da773b75dd1bcf4a542b3b9dd5c74f59b54e95707cfc7154fcc2cd29dff0d0d6603f0c07c9eb52a7febb9b7f1c4fd611eede56de52fa4d430f5f87706d8005317cf62683007804ec99394aeb9ab562e283bfca3334ebd8f8895ef67156b5e777708e6124f0894a0c1c79b209bfef19066e2abf89be3dd620f119777b0cc52f2dd6ec5ac60679d5d7ceffbd060fe66627b2de8bd1c292ce2041a86f8dbb514a1ad944be5bf89176f5372b4f3a56fd3a1c142002a774eab66e0aace76dca5060d30bd32f6398fe33c9f0ae58a3d9954f3188bafd02077b37d65ad7d0ae6859fff8d5f98b72fac5563ddcc445163e3b50de36a1a4e38a0150c0d1601b087aa2f1d397edc3b5e2132ebc7c877de0cf71a835975950c0309fe5f72d90cfc0e8b0168e0d06d99e98b2e12d49bae7be49e416c1b6c7ca8705efacaa82dffb67e4aff0634580240952d59071c7ec76c3be315683075b775fca1506db18ef3dd36ee03c71fdef1d07468b00c8025d192f35aaf9b9eba87db99e4b11b08e4d8cb47a72b9a7fbee83fbf5da6ba640c0d960390b0b2cc50fddcbb3435e6425d8c4fed2426fb71b0871863992974c73461ea5d68f0390027313aad5948fb7a968d6d2db22873168b60890e55ca8ca7f310d6378f09eaa0c12a00c6849c8d89b354a03b5e93089e2799b0aa93175bade6462427ebfd6bcb694c78b0baedff010000ffff665578a301c080a070eab71b0864420716712b04d1ffc3b30f419f599c51538eda86abf48958a8c0a070f54348af53f740a94437b0bd8e1a81929a7cd1c5302779b38390c73aac1fd5" + ], + "withdrawals": [ + { + "index": "22935027", + "validator_index": "370513", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6594477" + }, + { + "index": "22935028", + "validator_index": "370514", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6597837" + }, + { + "index": "22935029", + "validator_index": "370515", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6606856" + }, + { + "index": "22935030", + "validator_index": "370516", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6622934" + }, + { + "index": "22935031", + "validator_index": "370517", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6664927" + }, + { + "index": "22935032", + "validator_index": "370518", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6609863" + }, + { + "index": "22935033", + "validator_index": "370519", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6574283" + }, + { + "index": "22935034", + "validator_index": "370520", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6569498" + }, + { + "index": "22935035", + "validator_index": "370521", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6630315" + }, + { + "index": "22935036", + "validator_index": "370522", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6608962" + }, + { + "index": "22935037", + "validator_index": "370523", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6572292" + }, + { + "index": "22935038", + "validator_index": "370524", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6587858" + }, + { + "index": "22935039", + "validator_index": "370525", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6574843" + }, + { + "index": "22935040", + "validator_index": "370526", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6599096" + }, + { + "index": "22935041", + "validator_index": "370527", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6604354" + }, + { + "index": "22935042", + "validator_index": "370528", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6462643" + } + ], + "blob_gas_used": "0", + "excess_blob_gas": "79953920" + }, + "bls_to_execution_changes": [], + "blob_kzg_commitments": [] + } + }, + "signature": "0x991c703da501811717cb3bbb365f0e69ff9f558dd27f8d2e58911cb3d5cc84bc98e5fbafbe44fc314bd6b68efb1cbce40398b0497d876744300ba876e787999a39016ef81bbd59f3fa5319eb3cc59b2e6dd947266b7307ae6ba9d0c159083c14" + }, + { + "version": "deneb", + "execution_optimistic": false, + "finalized": true + } + ] + }, + { + "url": "eth/v1/beacon/headers/1541625", + "params": null, + "response": [ + { + "root": "0x477dc6f925e0764ec7ecb334a9b3dbfc8423ff8245642504e51340bc438cf292", + "canonical": true, + "header": { + "message": { + "slot": "1541625", + "proposer_index": "1451194", + "parent_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "state_root": "0x540cd88c1420717bc026508abef54db29100b24c56529ed89bfd43264eea545b", + "body_root": "0xb2f3f523455c612df7ccab341b23b1c98e48e894c648c0c8e6fec83810dbef81" + }, + "signature": "0x8ae6a26a3e80a0cd6ed1d3c27dc96960f498e7b9dae37bf34aef5df26b0fbdf38d807c020188a8487910cc6646f062540b7322cbbc14c3d605ca0d61dd6cc242a142f2292169b7b6bce7bd7ee06ffa73ec6d567cb58d6066c08f56881669df26" + } + }, + { + "execution_optimistic": false, + "finalized": true + } + ] + }, + { + "url": "eth/v1/beacon/headers/0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "params": null, + "response": [ + { + "root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "canonical": true, + "header": { + "message": { + "slot": "1541621", + "proposer_index": "629824", + "parent_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "state_root": "0x008372b7bcb5b75bd733efc48a5f7f07a3d27681bb46affb8fcf5b3cb758e090", + "body_root": "0x27667556e198e4fe2506662d2ea5376f23be6983bb5f601d6e11488268a5fc40" + }, + "signature": "0xb7db4deb448ed10af19084bce7cec1dee7d548f2e0cd97c611b14d6cc953c8edebde2ce75e1abbca8775fb139bb0e05b04d106a3a46d72ab2338b0eb32caf3e3fa5b6963500b5ac12f987920d1c2c031020eedc53a757620aa8cda7db2f70c0f" + } + }, + { + "execution_optimistic": false, + "finalized": true + } + ] + }, + { + "url": "eth/v2/beacon/blocks/0x477dc6f925e0764ec7ecb334a9b3dbfc8423ff8245642504e51340bc438cf292", + "params": null, + "response": [ + { + "message": { + "slot": "1541625", + "proposer_index": "1451194", + "parent_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "state_root": "0x540cd88c1420717bc026508abef54db29100b24c56529ed89bfd43264eea545b", + "body": { + "randao_reveal": "0x850f64ce120e055c2ba2232ae177ca294fa82375be0c2991f93c1ee48e85820888d54182928692ee781c9e2d39b7ebc80b921192e61c69bc4eddbdfc30ee87bbe1e0fc00e02a7d5d95ff7b5e8c574abf03101d4a0cc41ba65d8a9877b45c2a76", + "eth1_data": { + "deposit_root": "0xe224c112700cfb2a9c9f5e3297a77fea6afa82e0fb831f79f0a04d8516274123", + "deposit_count": "258908", + "block_hash": "0x38dbdfdaed6826f0cbce3dd711a944fe8edf832a57221a5971a543e7def363d8" + }, + "graffiti": "0x426c6f636b206279205374616b656c792d31323120544b636400000000000000", + "proposer_slashings": [], + "attester_slashings": [], + "attestations": [ + { + "aggregation_bits": "0xffffffffffff7fffffffffdffddfffffffffffffffb7ffffffffffffffffffffffffefffff7ffffbfbdfffffffbf7fffffffffffffeffffffffffffffffbfffffffdfefffffffdffffffffffffffefdffbdf7ffffffefffdfffff7dffeffffffffffff0f", + "data": { + "slot": "1541624", + "index": "19", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb420792e7353fdc370934c4b03c8ad2e463c6355d2f9da841e5acdf8a7c56c38b4fb96dc9f00a0e50b8065a63b84fd3304d122d03a9453c64eeca32964ed3477138c367e529778289d84135c0b3a59ab2b86da21001a4ce2a9392a699c09aa92" + }, + { + "aggregation_bits": "0xffffdff7fffffffffffffffffffffffffbfffffffffffbfffff3fffffffffffbbfffef7fffdfffffffffffef7ffb3fffdfffffdfff7effffdbf6ffeffffffffff7fffffffffffffdfffffffffff5ffffffffffffffffffffeffffff77f5ffefffffff71f", + "data": { + "slot": "1541624", + "index": "33", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x99e15e20fe242f370a8e5d34355883cb3cf612cb33e33408ed1a1aa61e39ae29a06642f51e56304cb92972830ab491d80a6042fffd378dff0ea1ac056a85352e58f0e84f94d9db807b8fbc398b2254d72739e08a81f6bf418f8e87a05e3e8cab" + }, + { + "aggregation_bits": "0xffffffff7dfffffffffffffffffeffffffffffffffffffffbcfbffdffffffffffffffefffbfffffdefffffffffffffefffffffffffffffeffffffffffffffbff7fffffffffffbfeffffffffffbfffbf7ffffffffffffffffffffffffffffffffbfffff0f", + "data": { + "slot": "1541624", + "index": "21", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa1a119b013d6cc45dc12257a87367e9ecb72f4c9a1c257446cbe6ee221eee9d34d4e6a922d619a83c5de3ade89e001ae18929cc8a562e4016a4f95ad8f3a6fdddab6c6183d08c672ba862e18e40937cad326689ff2b1c180ad484484a41abbd1" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "1541624", + "index": "18", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa9145b1239fc5737a702b2f83a4eb891d8df3e5c42f1b04aba01c0ea7495259c8651b705f13dbe5d9b2a919958cb39bc098581c7322040d3606119a24b3299cc44203d7146f2474c6a33a4d51f40aca35b819313e3d9caba934ed2ea7928b279" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008", + "data": { + "slot": "1541624", + "index": "30", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x984ec05e54c8058c1b3f8dd1502059089840cb493909fe29bfce1f0eecaf6de92048bc067eb3926305cae9a43e12be1a19fa7a02ffb8e5a0feb0c073f2a2740455a84bf472ad755e361153a204ddb431d274e6de6775c431de75335c0483c759" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008", + "data": { + "slot": "1541624", + "index": "11", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x96c59b2bdab5d3a8ac562df7de3ad1d42a05aff42ea2e9217bcf2b59005459327cab92e72284871826ef7a4dc6c932310ecf2fd730e712578ab3c9ebc80647604d58aee3c077bd28292d36ec58973acf6f0e2c0b391edbb91d9a9e29ef3b0824" + }, + { + "aggregation_bits": "0xffefffffdfffffd7fbbfbffffffffffffffffffffbfffffffffdfff7ff7f7bfffffffff7fffffffffffffff7ffffffffffffffffffedffffffffffdfffffddeffffffffffffffffffffffdfffffffffffefffffffffffffffffffefffffffffbffffff0f", + "data": { + "slot": "1541624", + "index": "15", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xaaf9e68e62f36b2adea19fde25943815b371803e63cbb3bc871edec38f3f941e2fc3a697d1cc8049abb2ebbbf2efe20c04e1be0d49038157cd69a5f340f84aff5b0dd5d3d7f887019436b6b62c27730115ec0d579a8c3a926129a5ea1c6213d3" + }, + { + "aggregation_bits": "0xfffdffffffffffffbffffff9ffebffbf5fbfefffffffffffffeffffffbfffefffdfffffef7ffffffffdfffffffffffffffffffffff9ffdffffffff7fffeeffffffffdff7fffe7f5fffcffffffffffffffffffffffbffff7afffffff5ffffffffffffff1f", + "data": { + "slot": "1541624", + "index": "61", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x812f949186c051bc96aeb6b17c1f3d8c78aa9b929a5baa0658d9f300da5e9529d0ff9c9bbe9f72a0f7a2849a512f8a09162a830f63d0f70ac89ea6e010478dd780548817bd8708b5d8da3bfc70934f93d4833c558ec1647f01092c76cc6c11ca" + }, + { + "aggregation_bits": "0x10000200402000000000000000040040200840000100000020100000100000000040000000000040000800000801000800020000000000000000000000040200000000000000000020000000000200000008000040000402000000004000000000200010", + "data": { + "slot": "1541624", + "index": "61", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8fe9b1468b2b2602c866b7ca0c040e9992c0ade8c4c5c89fd309ef6dd72e58e499e09163571c971997d0361e58d1038d16936e9565b6a4e3b081bd13bc6d5c7584c40fde3770299b35e347322f94ec858398c56394b96366ae74fbfd3c7caea6" + }, + { + "aggregation_bits": "0xffffffffffffffff7ffdfbfffbff9effffffffffbf7fffffbfdfffdfffffffffffffffffffffffff7fb7bfffffffffbfffffffcbb5fdffffbfffffffffbffbffffffffffafffbffffebfefffffffffbcfffffffffffffffffefdfeeefffffbfff7ffff1f", + "data": { + "slot": "1541624", + "index": "18", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa27bb7a7a91d75fd03e73dacc677aa1fe262ffc1ea1f43474c6f87bfb0c99093f23b4c628e20a2cb1563e9bb10c806281743c277f5718e1da5ffde1e9ac1e7702960b3e6a574524f12e7029f62e3b91537647c0584710ee9c9581e27aa7565fe" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "1541624", + "index": "22", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa8543329d14cdf732b7e9a5eb33bc6a6394875bea4077a1b7e675ee654f7650c65404340af06c063d934fae41a08a9120ca09eb978c1ca6cc78afb9968346baa64e9b281142d803cf3ef7ebe0357640c854bf3632e09b1d4e53e92ad67f4dd9c" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000008", + "data": { + "slot": "1541624", + "index": "38", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x85075489ef1a17c69222dd18649054fc369b62a576fb8b5961bf87050abf01b40415d49cecddfc8cf076c3fc95fe4418177d7ae446bfe130bd6cf83df58d63a8f5f15ad3754f830db1e6e6ff31ccb74776773c7b2eda60a3fe1c0510f5f28b11" + }, + { + "aggregation_bits": "0xfdfffff7fffffffdffffff7ffffffffffffefffffff5fffffffbffffbfffffbffffffbfffffff7fbffffffefffffffffffffffffffffffff9feeffffffffffffffffffffdfffffbfffffffffdffffffdfffffffffdfbfeffbfefffbfd7fdfaffffffff1f", + "data": { + "slot": "1541624", + "index": "39", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xad91350efd4f9eb93af34ebbc98234525b0b1515c2b90e4b5810601dabeb51e484d9bcb1324d34959446055b2e413cc901ae5a0b6c15728df37be9e115e8bd4295a46278f697a3b6b011fdb7f327ac19ac65ca7405086c444a7fd006664d6abd" + }, + { + "aggregation_bits": "0xffff3ffffffeefffdfffffeefffffbfffffbbffffffffffeb7ffffff7ffff7fffffdfffffffdfffffffffffffffbffffef9fffffffffffdfffefebfffff77f7ffbffffffffffffefeffffffffbfff7ffeffbffff7bffffffffffffffffffffffbf7ffb1f", + "data": { + "slot": "1541624", + "index": "12", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8a61f555cde4ffe41a31432001411eb8368693b5d1224a33fac4e0e858e0c2eddeff5fd0b062b0b74a89a6c15386e8ac12f84ceda46bcc6db18cb63f84d6225c8ef18a9f4ad54f3cd871cdeb0f7cc3f7b1b940591869e42ccdfcfaf51764b02f" + }, + { + "aggregation_bits": "0xffefe6fffbfafdfdffbfffffbffffffbedffffff7fffbffffffffbfdffdfffffffffff7fb7ffffeffffffdfffdffffbff7ff7f77ffffbffffffbfd7fffffffffffefffbffdfff7fffffffff7ffffffffffffebffffffffdfffffbfffffffffffffffff1f", + "data": { + "slot": "1541624", + "index": "2", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb8764bcc45d16c1c66704dfd33dfce3f3218439cd5e6ccc9f62c4cb3e1e836c9b56471c6fd59b95b43f923a36702672810161c1fbd2cee78f7aa3fd950c61f240e91cd1cec07a6c2d5fa9d28795cc9699df7fca02b58759a821f3e10df509d7a" + }, + { + "aggregation_bits": "0x7fbfffffffdffffffbffffeffffffffffffffdfdfffffffddfffffdf7fffffeffff7dffffffffffffffdffffffefffffdfffbfffffffffffbfffff9fffbffeffffffffffffffffffffffefffffbffffffffffffffffffffff7fffffffffffffbffffff0f", + "data": { + "slot": "1541624", + "index": "5", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xaedb850755bb6713fd724ea99ebe531bef4308e9a2134d3da73488be2a34b3969f7bc6e0dc322e9b615b6f5b18ffb5460bc2013cdf20afb135bb707667bfbe712a228cb8265c189b8205ccb76505499014fd749306209ae1fa3a896f1836759b" + }, + { + "aggregation_bits": "0xfffbfbfa7ffffffffffeeffff7ff7ffffffffef7fffff7ffffffffffffeffeffffffffbffffff7ff7ff7fffffffefffffffffff7fffffffeffffffffffffffeffbfbffdfdfffffffbdffffffffbfffbffff7fffffedfbfdffffffeffeffffffeffffbf17", + "data": { + "slot": "1541624", + "index": "0", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x94780460d6690c83caf1f1f2a7a217478c5fac13b4f4f62d36aa3127999c147a14c5e3e67fd22951f88a03313e652a07144e4db6816ff4ec2966ad705f09b486af08f042dcfc2fb17ecb448b995f259f62de9ac11a9689fb6c829d76c01bb36d" + }, + { + "aggregation_bits": "0xffffcfffff77ffbfebff7ffeffffffffffff7ffbfffffffffffffff7fff7fff7fefffdf7fefdffffefffffffffffffbeffffffffffffffffffffffffffffffffeffffffffffffffffffffbfdffffffffffffbfeffffffffeffffffffffffff7fffffff0f", + "data": { + "slot": "1541624", + "index": "62", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x880455cf0e1f401db0d9547ff51a4c1c1279115192bbf78b79473534824b66e335e17ae878ba9926478d10c63fc65014057fdb8a2cda839552916055bec554dba5d86fe78066837301263d18648acfb93254d0638f7d111bc3b4b6198ee274c1" + }, + { + "aggregation_bits": "0xfffeffffffffdffdfefff7feffffffffffffffff7ffff7f7ffffffffdffb7ffff7ffffdffffff77ffff77feffffffffffff7ffffbfffbfffffb5ffffc7e7ffffff7ff7fdffffffffffefdeffffffbffbfffff7bffbfdf77ffff7ffffff7fffffffffff0f", + "data": { + "slot": "1541624", + "index": "52", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x90cef3936e780eceb7892b6170948dda6eb5fa83d8c3e97a93aae08a47359d122973e5bae47adf057535ef3a8394436113cc5460d2ad6594162e3656be8d8e54e2d1dff9102e5569ad9f506bed6b7ec665c6855406991c26abce31638507ca4f" + }, + { + "aggregation_bits": "0xf6bdffffefffffffffbfffdfdfbfffffffffffffffffffffffeffdffffff6feffffffffffffffffdffafffff7fffffdfbffffffdfffffffff7fffffffffff7fffff7dfffffffffff7feff7f7fffffaffbffffffff7fefffff7ffbf7f5fefffffdfffff0f", + "data": { + "slot": "1541624", + "index": "3", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa2bafffea195e420376d771f4447a6e6b0ef1ac2cbee0e31525f25027792a6e6f9bd09029292182f2f2b9fb99e115b0b19578a14b2d8e898caad4bda91a3451bdbe475e0a8d907876c71e8e1c2e367b8e0532b59738c663ba84248978d2399b6" + }, + { + "aggregation_bits": "0xbffeefdffffffffffffffffffffffffffedfffffffffff7fffffefebebffffffffffffbfffffefffefffeffffffffffffdfefffffffdffffffdffbffffffdfffeffeffcdf77fffffefdfdfffbfffeffffffffffffffffffff7fffdfffdfffffeffffff1f", + "data": { + "slot": "1541624", + "index": "22", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x92e8dd4da13b3a2b3d5516b0468fac54f84398df33f468c8ae8668adf473604043882dd497d056bfe3f1513477bdd2ef069d2601201eca7634d9f4b234296ec1a7575ca1e07b92703cb1793c42fcc36bbaf60f6bba067c6f4a76baedf8ddc31b" + }, + { + "aggregation_bits": "0xdf3dffffffcffdffbff7ffeffffffbffffb7fdb5adff77bffffffefffeffffffefdfffffbf7fbfffffff9fefeffff7ffdfffdf7ffbffffffff7ffb7ffbffbffffebfefbfffffffffdffbfffffffffffffffbfffdfffffffffffffffbfffff7fff7ffff1f", + "data": { + "slot": "1541624", + "index": "41", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8d4cd0a6f65178db4221e7f820ba6c1962022e150ec7ffd37dde4827c5037bbf6289037691f9f558e86b5db5a33082bf17027129da3f370f28291917bb54f7a9ee595ad7981f45acf019a6ee8222601590fdae11e91d86b50e9c633496156d89" + }, + { + "aggregation_bits": "0xfffbbffffff77ffffdffffffffffffffffefffff7bfefbfff97ffffefffefffffbfffbdffedfffeffffffefffffffbfffffffffffbffffffffffdffffffffffffffffbffffffffffb7fffffffffdffffffbffffffffffffffffefffffffffdfeffffff1f", + "data": { + "slot": "1541624", + "index": "29", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb2fb69803ceb36891ce39e9a32f926cb35a504037bc76b1e3c997d8fb5468dc1a7646476c14d9644e442b8e95f769c81028313952f9c8726880adca5917a1c0f0f563deb334427a6d2264f248b2ef26dccac5a0aa100734bd39761a6ed3e48ba" + }, + { + "aggregation_bits": "0xffff7fffffffffffffffffffffffffffffffffedf6ffffffffbffffffffffbdfffffffefffffffffffffffffeffffeffffffffebffffff7fffdffffbfffffffffffffff3ff7fffffffff7ffffbfffff7fffffffffffffffffffffffffeffffffffffff1e", + "data": { + "slot": "1541624", + "index": "4", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xaf822144b96a156e4444e8a4575c4c4b00171e876b3badd28372e07d73ae5f74afa164e38a182054d5ed0da7854d1c6c17c3991b1c26d19342db477442b451fa4e5af4d41d8b506678ce5a27823182bbd4a4646987e71601fb5fe69223fb4094" + }, + { + "aggregation_bits": "0xffefffffffffffffffbffffffffffbffffffffdffffffefff6bfdfffffffeffffffffffffffffff77ffffcfffbfbff7b7fffffffffffffffffff7fffffffffffffffffffdfffffffffffffff7efffffffff9fffffff7ffffffffffff7ffffffffffffe0f", + "data": { + "slot": "1541624", + "index": "34", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xad437e90a4326b9c0ba392fda3f50b2e90889c72728ac5dd8231a4f5e51cd98cab524e804ddf2cf174e4a90bdd4486570567174a09a2010a18d16d038465d8872770c07637fdebbada214b063b4f459802bb02f61f12b73fd18b3beca8554fea" + }, + { + "aggregation_bits": "0xfffffffffffffffffdfffffffffffffffeffffffffffffffff7ffffffffffffffffdfffffffffbfffdffffffffffff7fffebfdfffffff7fbdfffdffdffefffffffffffbffffffffffffdfffbffffffffffffffdfffffdffffbffffeff7ffff6fefbfff0f", + "data": { + "slot": "1541624", + "index": "9", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa2fef99498294566c0893101a856b59bccecdfece0fc19acdab441d5a2509d267186de67c45ff56c11f20bf84b66386701e38104e319481c3e75afc8ed279da5bc8338cb831c6dbba092a5061072e7e78fe5fdd1f0f6461117d877bb3bd43bea" + }, + { + "aggregation_bits": "0xfffffffffffffd7ffffffffffffffffffffffdffffe9ffffffffffffffff7ffffffffdffbffffffffffdffffffbfffffffffbf7fffffff7ffffff7ffffffff7fffffbfbdfeffffffbfdffeffffffff7ff7effff7dfffffffbbfffffffffbffefffdfff1f", + "data": { + "slot": "1541624", + "index": "27", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa3b05baf0596ca60110c8890b6f2313ebf7551d2b054341117a8e455391c13a90127bcb9e46f3ac9a47405325007cbad0ec786d0b31e66671f0fe332fa9c5e12d1347492009459df6ece013fb0846320c6fdf98776ba63f80758042c33f401da" + }, + { + "aggregation_bits": "0x00000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "1541624", + "index": "47", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb827f1eb5dd775dadb263c571c60d876e31356e0b314cfe3fc04fd0e59a0e7a3838d4d4e9f8a89c03e7a3d446964f6820936d5c29764667d85faf34e8873fb2935d1bb68e2757af705470c48dcd0a7d81c2dcd3f8b199e2c349870b5559ececd" + }, + { + "aggregation_bits": "0xfffffffffd7f7ffffffbffffbff7ffffffffffffffbfffffffffffffefffffffb7fffffbfffffffffff7fffffffffffffffff7ffdffffffffffffffeffffffffcffffffffd7f7fffefffffbfffffefb7efffffffffffffff9ffffffdff3fffffff7fff1f", + "data": { + "slot": "1541624", + "index": "43", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa1eb7a8fb811f5c7038072eee5ea3bcb9870856e01f31ac9e2ce158c2e39e506d7142d1926d5edb67fd33af15c1b28170c3d325e6d673cea8bfcab0d972994b16a0391c1ff171ac2e404d017ad153d6ad6a8bdc8904378a83ce37a93e95eed8a" + }, + { + "aggregation_bits": "0xfbf7ffffffffffffffffffffffffefffffff7ffffdefff7ffbffffffffdfffffffffffffd7fffffdefffbfffe7fffffffffffffebffffffffffffdfffffffbf5ffffffff7ffbffffffdffffffff7fffbefbeffffb7ffefffef7dff7efffffffffefbff0f", + "data": { + "slot": "1541624", + "index": "38", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8aaa8152c4616ae599eabee1eb076e720f15c8bd8aff2acb8f51039f95f92c8f60493fff887b3a33396b2c76acc3716115630a2fa55f8e941dd8352faf2b9f4b280be0845218f30c7b0cc4e9fadca3798436bc2724f06a80e3d99d7b44b68060" + }, + { + "aggregation_bits": "0xfffffffbbfffffffffdffbffffffffddfbdfffffffbffaffffff7dfffbfffffffffffffffffffffbf7ff7bffffffffbfff7ffdbfffffffffffffffffbffffffffbfffbffffbffbfffdfffdffefffbffe7ffbfffffffffffffdfbfffbfdfbfffffdf7fd17", + "data": { + "slot": "1541624", + "index": "37", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xaf98232e360e5ed8c00b0c0396a0179c41549e5e4283832ba1895fae012c473bccaa5bd6ffc4a2b0b17827b7b5a9e45c08fc1cec540b5a5c59018670eeb980a8b81f72fd5f1c1e4b362f2bf2275d65b68bad8fc8b65774022cc63226be7988a1" + }, + { + "aggregation_bits": "0xfffffffffffffff7fffffffdfffffbdf7fff7fb7fffffffffdffefffffffffffffffbfbffffffffffffffefe7fffdfffffefffffffffffffbffffffeffcfffffffffcfffffdbffffffff7ffffffeffffffffff7ffbfbf7bfefffffff7ffffffffffffd1f", + "data": { + "slot": "1541624", + "index": "20", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xae0ba8b56d5e1fd833ddd0a34a90b95532410b379e52b738f28a9e1f05b64e20405bf272c4b0b19b3df75d01b825aab6034149da931888d6e89f3d1d4dbd077de6c9ab47a1ec51a9052dc9dc5cd299876d788a3d7b8d3cd6eed4f20b11d0f3dc" + }, + { + "aggregation_bits": "0xffffffffff7fbf7fffffffbef7efffffffdfffdffdfffefdffffffefdfffefbffffdffffffbafffdbffffffbffffdfffffffedfffefafffeffffffffffffffefffffff7fffdfdffffffffffbfffffffffffffffffffefef6fffffffbffbfffffffffbb1d", + "data": { + "slot": "1541624", + "index": "14", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x974dc67c008e5dc29dfb14e0cd9fb59f4534b18e640849f0a7170d4f9448749fb5b63f3e76b8f71f1d486301b2c9d8b707a1b563de554070cf4ad4863c3603a9380156b8e9728591a9f8035db01d88e2a060bdce8c1d902ef106fc2da595fe82" + }, + { + "aggregation_bits": "0xdedfffffffffffffffefffffffffffdffef7fffffffffff77bffffffffe7fffdddfffffffffdffffbfeff7bfffffb7ffffffff7fffedffffffffffffdfffffffffffffffffbffffff6ffffffffffff76bfdffffffffffffffbf7fffbffdfffffffffff1f", + "data": { + "slot": "1541624", + "index": "55", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb47f50899e606dd6194cebf7855e10b22e4f5e21d61b24bf5dbd9355b82be475fad8aa9ed503c97497adb8a0e6ac80e4126c12ffa4878dba9caec493ba3f9641c194eb7f323d60827af35d71633111849b864f67c61114022805193082e70881" + }, + { + "aggregation_bits": "0xffffffdffdfffffffffffffffbfdffffffffffffffbfffbfefffffffffffff7fffffffffffffdffbffffbfffeffbffffffdffffffdffffff7bfffffffffffffffffafffff77fffff7fff7bfffffffffffbfffffffeffffffffbffffffffeefff7f3fff0f", + "data": { + "slot": "1541624", + "index": "28", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa39974f3a44e1870ed4c163310f3969bf8d457eb96fcd2f96b452de5d704110794aa2ed6c6c3e8aed340ebca39b9e8a61977398f2d3656e4a3dae23bb6b8fc2cc46ce78861d2d0dfe14e0d55be3ae0ec9805cfbbc640cb2da6279f143b7dc230" + }, + { + "aggregation_bits": "0xffffffdffffedffffddf7fffff7ffffdffffffffffffffffffffffff7fffffffffffffffeffffff7f7ffffffffffefffffffffffffdffffffefefff7f7ffffbbbfffffffffffffffffffffffffffbfffbffffffffffdfffffffffffffffeffffffffdf0f", + "data": { + "slot": "1541624", + "index": "25", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8b051bd5212831061a9c76ce7af3d16113ec1a8153f30f59153a05ca2a74b4430337125ce849a094b8af698f47d2972c06b4e435f262bc68774539df4cb88f54620464d426f648e69b8f7ace3085e3640896d9fa061457a9cf3cf3bb8aee0265" + }, + { + "aggregation_bits": "0xfffffffdfffef3ffafffffffff7fffffdfff7fffffafff7ffffffbfffff77bffffffffeffffffbfffbffbf7ff7efeb7ffefbfff3ffdffbeeeffedffffff6fffffffffdfbffffddfffde7bff7fbffffffe7ffffbf97ffff3fbff9fffbfbff3fffffff9f0f", + "data": { + "slot": "1541624", + "index": "17", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x94ec097c1d4faf7a34988df810331345970d4765b810ecda44fd3fabc92f7aec92d568e88bc819b3dcb2f54bfe6f8f4109ddcab410b3d52eded582b7a9b66d19ed37e26205fc92825bc1c0cac016e60d000bbe177932c4deb9872a27bb4f0cde" + }, + { + "aggregation_bits": "0x20268c690004828ea35012cb03c04242434c091104aa440049223002d59f0280c2223020bd0283c13046984d2420892800203001e44210e24a000a90805100148518346d1481305111c190410a2042a354418510c581a0c10a901230180303003c30470b", + "data": { + "slot": "1541624", + "index": "17", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x86d47c765a9a8aa08c6ba8c92652a88d4b45b6c6c7f7648467f98c602c00dd17fad667d2e7b48985dce0b826ac99d0c80571bba3e13eb5843ad4bd810129a6d77321dadfac1095c1735937a13e1d1978d52d2af9f6d677a402a72390b8344f09" + }, + { + "aggregation_bits": "0xfffffff7ffffffffffdffffdfffffffeffffffffbffff7f7fdfb75fffffffedfbfff7ffff7ffdfff77fffffdffcffdffff7fffffffffbfffffefffeffffefff7fffffffbffff7fff7bffffffffffffffbbffff6ffb7fffff9bffffffefffffffbffbff0f", + "data": { + "slot": "1541624", + "index": "60", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb74332c766f6309ce1842de05c282c78191c390b73776731897330d2661a2edcc929ac4d6a0e6791d72df5ea8274676e0351b454fcbc2c90ffcb07367efc0ab9de87fbdd91224be49ca8ec25eb91311697347c19742fc7fdaabb0adf7043a30d" + }, + { + "aggregation_bits": "0xffdfbffff7fffffffefffefffffffffffffffdfffefffdefefff7ffff5fffeffffbfffffffffff77ffdfffffffffffffffbff7ffffffffff7f7ffffffefffffffff7fffbffffffffeffffffffffff7fffffefffefbfffffffffffffffbffffffffffff0f", + "data": { + "slot": "1541624", + "index": "48", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb0929f92cfcc9cf9505058191d7422587b4c23d526c1c2f4bb8fba3118f03fb7b820e9ac048f2ded8a6f895961cfdd7a0f2a8e55f01e9577a0c41b89a53c788d062eced591beb07114f8b1d4ffe68bc821961d5b7440b70a892e1c92907441f6" + }, + { + "aggregation_bits": "0xfbffffffffbffeffffffffbfffffffffdf6dbfffffffffffffffff7ffffffffffffffb7fffffffeffdffffefffff7f3fefbffff7fffffbfffffdffff7fffdffffffdfffffffffffffeffffffffffffffff7ffffffffeff3fff7ffffffff7fdfffdf7fe1f", + "data": { + "slot": "1541624", + "index": "24", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb043a95fd8d53c33c1a9a5b6a88e82b4ed660ef01fc1c2efc6e9da8b30c431f22c67d05d4c8387377b846a519943a2d30391521a08508781a5b15da5633f7f781e25040e89bef83139ebaaa30c148802681b3b500efa991414de6b58f5466762" + }, + { + "aggregation_bits": "0xfffffffffef7fffffffbfffffffdfffffbfffbfffffffffffffffeffffff7ffffffffffef5cffbedfffffffffff7f7dfeffffdfffffffffffbdfff7ffbfffffb6fffffffffffdfffff9fffbfffdffffffffffff77efbeffffffffffffffe7ffeffffff0f", + "data": { + "slot": "1541624", + "index": "36", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x848c45721c7a4013f51584a666b1b6f00efd6c254bdbf12cc3b20697ed535d34d774b42bd4511209cbf88621b2ba80c60ff834ac0441593e6436cbbd767a55c39b2bc7c450efbe653b113db6cce26190d5761765446dfc736abef6b9fd74cecc" + }, + { + "aggregation_bits": "0xfbbffdffffffffe77fffdffffbffff7ffffffffffff7ffefcff7f3fffffffff7fffdfffffffffffffffffffffffffdfff7ff7ffdffbf7fefffd7fffffbff7fffff7ffffffbfffffbfaffffffffffffffbfffff7fffbffeffffffffefffff3feffbffff0f", + "data": { + "slot": "1541624", + "index": "54", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xac183199670896435f43604865e8c84ae9e7ee7b4e5d2a64e97421cd6f38ef644380397e41e0a7301199a24e3531c3b9140bd1debd23c4a162d2c2f23d037a0701a9fbdaa0f6914ffc163eb885330935ebd8524ad98e786189cb8c51c600c889" + }, + { + "aggregation_bits": "0xffff7ffffffffffbffffffedffeffeffffffffffdbffbbffdffffbf7fffff7ffdffffffffffdff6fffff7fffdffffffffdfeffffbffff7ffffffffffffffffffbf7fffffffbfffff7ff7ffffffffffffffffffffffdeffffffffffffffbfffeffffeff1f", + "data": { + "slot": "1541624", + "index": "53", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb807a3f46fbbaa89e6918056ea688bb7c7205472db3f51f7fcafc0568ab9b35c7d2d11e0a1fb998557471b2d52d56b02120c35767cd504372cc343af6f25b143e019523999f1d7610514565be43dc12caf27d772f853d5dfe449fcd9107f9bc5" + }, + { + "aggregation_bits": "0xfffff7fbfefffbffffffffffeff7ffdfffffefeff7ffe7ffffffffffffffffffffd6ffffffff7fffffffffffffffffdffffbfefffefffefeffffbff5ffffffdfdfffffffffffffdfffbefdfffffffbffdfff7fffffffffffffdefffff7ff77feffffff1f", + "data": { + "slot": "1541624", + "index": "49", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8e2ca4613e08739e18b7febf43e9c82e2e243dd7411d641c5a95c4860f8478d1c5f9e6046e1c6fb26cb36fa52481515f03e206fbfa673c2f55625b23ee30344d09ee773f1219c4d0be77474556ea2f26fb21aee0bfb4d8be40817b062367edc9" + }, + { + "aggregation_bits": "0xfdfffff3f7efdfffffffffeffffdffffffbfffdffef7ffffdfff7ffffbfffeffffbf7fffffff7fbff7fffffffbfffefdfffffffeffdfffffffffffffffffffb3ffffffef7fffbffffffffffff7fdfffffffdfffffbffffffeeffffffffffffffffffef0f", + "data": { + "slot": "1541624", + "index": "7", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa221ddbdeaba2ade2055c95453c3ceb5e0f536bbe568c87da6250f40b09b0c9662dc07427d0fa3673dd449ab6524a5d20ec176e81b86a1a0f46d73eaab77228c04c597874e04bfc570cde2876cd0e3254e87d831b6332f155d0d7e6efb42dad6" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffdffffffffff5fffffffeffffbffff7ffbfff7fffffffffbfdfffbdffffdeffffffffffffffffffffdfffffff5ffffbfbffffffffffffffffffffffffffffffff7fbfffffffffffff5ffffffbfffdffddffffffffeff9fbf1f", + "data": { + "slot": "1541624", + "index": "6", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x97c8bd9beafb7186d82946ff7f45bd12a176ce1804a2642c2941e2a79dc50aee146498c09c51bccebea4d969c9157c010f361fa064c74ded965886389f7b5b03cb55a70c8c15649eead6d1c2fbe82f864a1d6bbf97792ef6ec194e3e330848d3" + }, + { + "aggregation_bits": "0xffffff3ffbfffff75fffff3feeffdff3ffdfffbfebffeffffffeefff7fffffffffffffffdbfffff7fffffffffffff77bf7ffffffffff7fffbffdffffffbdfffbffffffdffffffffeefffff6fdfffffffeb7ffffffffffffff7fffffffffff7f3ffff7f0f", + "data": { + "slot": "1541624", + "index": "58", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8811e67f822da7245565c8cf7e1cfb834b7cbeb164483e261b82cda223086d9bf3aadcdc988e799be6de63004fa4f74e092dae5996897cd9abd1ffba0ee35909a6e75f96d2e8a4e6df16d4bed103e0c04f11ba9a7e83bc0b922ed5d52377bcd7" + }, + { + "aggregation_bits": "0xffffffffff7ffffdffffffffffbffffffff7ffffffffffffbffffbfb7fffef7bffffffd7bffdfffffffffffffffffffffefffffefffffffffeffffffbeffbfffbfffff7ff7fffffcffdffffffefffffffffffffbfffffeffdffffffdfffbfffffffffb0f", + "data": { + "slot": "1541624", + "index": "44", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x9786b3e14694fc5a4af35ceee887beae20bc262689de897e98da969f2a418929483e35e664af1c1e7a2d560a5f7a8bd317ccfb1d7fb7c65735866e8e63f19e15076fa5154de957495dec0def82469ed34e3effe59a9b8505a3b3f17d9cfb1cfe" + }, + { + "aggregation_bits": "0xfdfffffffffffffffffffffffffedffef7ffffff7fffff7fbfffffffbffffffffbf7fffffdffffffdefffffffffffbfffbbf7fffffdffffffffffffffbf7f3fffffbfbffffffffffffff7ffffdfffff6fffffffbfffffffdfffffffffffffffdfffeff1f", + "data": { + "slot": "1541624", + "index": "47", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa814b8d829ac9dfe1b75f501f005d82855b00db355050bdd9dffcbff990581d79a49c01fa9a3586eb6b8514435f7dbb803ed6d2d4e2506875647fe464590f21bdb7f09541169e41a9760fcf41f3761464ec227f72ed88da77116da030c89c1ff" + }, + { + "aggregation_bits": "0xfffbffffffffbfffffbfff7fffefbffe7fffffffffffdfeffcfffffff7ffffff75fffdfffff7fbfffdfffffffffddffddfefffffffbfdfffffffffffffffdffffffffffffffbfffbf3ffffffffffefdffff7bffffffffffffffffff5ffffefffff7fff1f", + "data": { + "slot": "1541624", + "index": "10", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa14cdb4fc55c8d1bcc7776417c7e08b9d1adda3086a82086678e216bbe24a9444ec1591c93af8fe47d033a3b34846d1c13b847c80c8b9af8da48a0613e32628b2649554bb37e98dddec20266a4545ab26ada3aa2f1cbae704d992cb96676c21f" + }, + { + "aggregation_bits": "0xff7ffffff7ffffffffffdfff7f7ffffffffffffffffffdfeefff7fffdfefffdffffffffffdfeffff7ffffffffffffb7fffffffffffffffffffffeffffdffffffffffffffffffffffffffffffffffdffbdef7fffef7df7fd7ffeffff7fddfffff7fffff0f", + "data": { + "slot": "1541624", + "index": "32", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb5e3f0c666528ef069d31f5eaf10145bb820c4a4a12321716bd572f34a500e0170b71276db046efce902e87ed7d1314817124884689e7a68e5b3c2b4ba50ba62abd881456fb2f533e09e3b6dc8ceeeba656f730bd5a95617e05b78f568a7a655" + }, + { + "aggregation_bits": "0xffffffffffffffebff7ff5fffffffffffbeffffdffffbfffffffffffffffffffffffffffffcfffffffffdf7fffffffffffffeffffffffffffffff7ffffffffefffffffffffffffffffdfffffffff7fffffdfffffffffbdffffbfffffffffffffffffff1f", + "data": { + "slot": "1541624", + "index": "8", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb80e922db81cf10bb28d86039a6a2f5d61ffc112344811af5628c51b28b1cefd6aad701f7f7084746758c056d8aa920d105407b8f126953162aeddd75b4073825115bc07e6f2202ac75f7003296f7249fa62f1d6fb8a21709af62ac1e743d846" + }, + { + "aggregation_bits": "0xf7bffffefff7dbf7fffff7fffffffffbffffffffffff7fffffffffb77ffffffffbfff7fbfeffffdfffffffffffffffffbffffffbffffffffffffffffffffffffcffffffffffffffffffdf7fffffeffffffffffffffffeffffffffff7fffffffd7fffff0f", + "data": { + "slot": "1541624", + "index": "30", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x930fe7237aae841001a380e70e0b58dd7a6a4c3bf617dda703641655dcfc7f93f396a85a50fd36b858ad9e1fedab0648111a28cc107f6585b4fc592401701ae05a98ab769d4c965b1db1b2bcb328360ac76a38ad88bef5d05b5142064816cf84" + }, + { + "aggregation_bits": "0xfedffdbfffff7ffffbfffffffffffff7fff7fb3edf7ffffbffffffffbffffffbffffffbfffffffefffffffffffdf7ffbfbfffffffffffffffffeefffffffffbfffffeff5fff7fffffffffffffffffdffffbfffffdfffffdffffffaffdfffbfffffdfff1f", + "data": { + "slot": "1541624", + "index": "31", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x937b603a5dc77383566b99610472110fae678dfcc174943beee3819b8ed949bdc0a5534dabc291b5da5840607b4021f219d9735a8c915d14f6d3bd088aeeb53b230fafc92361261b367e29ac3416ee6d064cf60e66c9b6800a60424c478c1113" + }, + { + "aggregation_bits": "0xfffdfffffffffffeffefffffffffcffffffdff6fbdffffffffaffff7fffffeffff5fffffff7fffff7f7fffffffffffffffff7fbfbffffffefffbfffffdfffbffbffeffffbffbbfffffffffffff7df7fffefffff7fbfffffffffffffffdfffffef7cfff0f", + "data": { + "slot": "1541624", + "index": "11", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x81d5b47442f92c70b162ab67a6fc3003b13a5b91133879ce09d4bf2f436524e29ca0fb34a2a18d5f45d7396cebdcbf0f0160814dfef1a1c2e758b627bc90f8969b615b096b907c83892b716d12f760916aedc53fca29df9a3c10adf9fbc22c15" + }, + { + "aggregation_bits": "0xfffffffffafffffffffffff7ffdff7ffffffd7ffff9ffffffffffffeff7ff7ffdfffffffffffffbffffffffdfffffff7efffffffffffefffeffffdfff7ffbfffffffffffffffffbfffffffffffffffff7ffffffff7ffeffd5fffffffbffffffffffffb1d", + "data": { + "slot": "1541624", + "index": "35", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb9ff7a72e822bdf669eef83f21fd64d1ab732d24089b8a96c1a038c42f1d0fe405789415ba7237de02bee28f4fd3b77419b8ee09c5548b20cfb0a8ebca3ddd345eea99bf7544ebce625f8d9f4edf35ead99437cbc67e8e88e34a70135f8b77c6" + }, + { + "aggregation_bits": "0xfffffbfffffffdffffffffffffffbfefdfff77fffff7fffffbfffffbffffbfdffffffffffffffffffffffffffffffffffbfffafffffff7fffdfffdffffffffffffffdbf7bffefeff7fffffffffffffffffffffffffffffffffffffffffeefffdffdfff0f", + "data": { + "slot": "1541624", + "index": "42", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8baaa78ae40aa59140f6818413c089eeb92db9c5ef35b5f476daea197e397e4f3a80be82a7588b8e064ffa79d33dbe9d111d8a32c5c80da088b1aec000f5c94090c7f9e337a12ff98576aa997c645340b25465b094df00d7ea494e7109ca5866" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "1541624", + "index": "57", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb736c4413f71cc719fef76e100c5d38aad3d2427d05051e542757cc23cbe0289c92b421e9d4de3feae9dcc71d22e60c107e7431489e6bc25f70cbbe87e502f6e480f1361a8a82e6ff81045235b9453edc4685a74e8be566832f7bf1dd45e9aad" + }, + { + "aggregation_bits": "0xbffbfbffffffffefffffffffffffffffffffffffffffffffffffe6fffffffffffffffffffffff7fffffffffffffffffdfffffffffffffffffffffbfffffffffffdffffbfffffffffffffffdfffffffffffffffffffffffffffffffffffff7fffffffff0b", + "data": { + "slot": "1541624", + "index": "46", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb4a7c5e3cd0c32a5d733a8b03ff32e36eab30657bd10185642548dc7168111bca376635f8bea36049b18edb71b761edf109a769bb9fea3c65763c3d08b3b6a919a9673fab42dda1b9a7b645ef8d93b6738b3cb77d01c7a4049f0db4461ee4fb8" + }, + { + "aggregation_bits": "0xffff7ffffdff7ffefffffff7ff7ffffffeffffcffefdfeff7ffffffffffffffffffffbffffbfff9fefffeffbfffefefffcdff7fffffffefffffff7bffbefffff7ffffffebffffffffdfefdff7fffbfffffffffbffffbfffbfffffffefeffdffffffe6f0f", + "data": { + "slot": "1541624", + "index": "1", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa9e2ef3ca0446175911b46f7b7c7f08139f910791d00e3109a36f7d91bfa3ac19504ef08fb85346ffc89cf92e2f34f9c104c3c57a80b8bcbd0dbdce1a10e086211f7933d9cbfbd31908bc8d4cb22e181f34ec054980c66bc77c130a05c2c5186" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000008", + "data": { + "slot": "1541624", + "index": "3", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x823837647effb36dba8d91686e650aa2855659b5e361df8db2af30eabf36a0a7058a52f5ebb07bfdaa3809fb883eecb80592df71b2d58d90cb08fc6e0acab732553bf02d543be6e2a537cc7f32c4031583e5e1b63e6a40f75c0edf55ecf4867a" + }, + { + "aggregation_bits": "0xfffffffff7ffffffb7ffffbffffffffffffff7fff5fffffffffffffffeeffffbfdffffefffffffffff5ffffffffffdfff7fffffffffffffffffffff7efffbfeff7fffffff7bfeffbffffbfefffffffbefde7fffefffffffbfffff7fffffffbfffedffb1f", + "data": { + "slot": "1541624", + "index": "63", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x99f8b3fc08b2036e481b3859576c0c86b6196e1d36b17e084e6522bfac635d527189c127a2b08882de4a1845e2c860420827b85adaf5a2cc0113f07712068ca9bb39ad39db199cbffac6d55317b42cc02ef5b449a3004e18c666df0db4fcc09b" + }, + { + "aggregation_bits": "0xfffdfbffffffffffffffffffffffffffefefffffff77ffffffffffffffffffeffffffff7ffff7ffff7fffffffffffffdfffffffffedffdfffe7faffffffffffdffeffffffffffff7ffff7fbfdffffbfffffffffffffffffbffffffffffdeefffffffff1f", + "data": { + "slot": "1541624", + "index": "45", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa05a0023820288f42a92aa7cd280f307acb8879992614940454db1bfa3777cb47c1b5051b22784eddd6db814df60a7f1115425dcf771da38616995bf2f2ea06d86036b9029fda1eeb4deb37d337ed82b09261e00622ce320ecb432c6be2d4688" + }, + { + "aggregation_bits": "0xfdffff7bdffff7fb7fffbffffffefffdfffffffff7ffffbfffbffffff7f7fefffffffd6fffffff7ffffffffffffcffffff73ffefffaf7f7fffff7ffaffd7fef7fffffffffff67fffbedf5ff7afeff7fbffffffffffbfffffffffbfffbf7ffdffff77ff1f", + "data": { + "slot": "1541624", + "index": "16", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa71856fd6b77128ce75b44d372c1cd1202069cc2f6284f916fbfbe170002c85b1b61d6d1bc77a65db79f8e1277c312fd0f9d3c65b5dbdbab1bd9f8556c08e05ed76dcf1dc33dbc61bef9a6e4e07f55da529b8b2fe10d249df6152ca1404f5cfb" + }, + { + "aggregation_bits": "0xfffefffffebffffffff6ffffffffffffffdffffdfff7fffffffdfffffdfffeffffff9edffffffadfffefff7bfffddf7fffffefbbffffffffffffffcffffdffbfff7ffffbfbffffefffffffffffffbffff7ffffefbffffffffffefff7ffffffff7fffdf17", + "data": { + "slot": "1541624", + "index": "57", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xaa1bb53be395d0864d9e7b8bb8aaa92a040f063a374d7e767b0766907393f159e8f0262138d19a29f06040b9f3351f1a05f8cfb84cdebc1482f4f8c04c09b87df92ff838bbec8a79c093bfea47ed6affbadb6b9256ab935e21dab97b595dd92d" + }, + { + "aggregation_bits": "0xfffffffffffffffffffffffdfffffffffffffdfffffffffffbfdffffffffff7ffff7bbfffffffffefefdfffbffffffff7fffffffffdffffffff7ffffbffffbfbffffffffffffffffdffff77fffffffff7ffffff7fffdffbf7fffffefffbfffffffffff0f", + "data": { + "slot": "1541624", + "index": "40", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa280d7adbbf46376b60143abc539a837e3a16df458705a08701db3fb915f5e4aa16704c646d26fd1be65545f9bb56de5164c51623dbd3a3c3d5762f4058c52a6cd2147e0bccf7d5d5bd4630ae2507120d1bd4b368ba5047b1a74d231f5ee5c84" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008", + "data": { + "slot": "1541624", + "index": "40", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xaebe97234bd34cd5d2870594ae4d4793fb1042c136be51e44ca8f4262aa92330d9768aff683ad663631fb6cfb0461d0c031a71def67d11c193372d9fa8192e4ea53dabe0c01d38fb52ab5412802215e485135fc2d19e9c9d4998dba7dbc38217" + }, + { + "aggregation_bits": "0xfffffffbffffffffffffffffffffffffffeffdfffffff7dffffffdffffffffffffffffffffffffffffffffffffd7ffbfffefffffffffeffffffffffff7fffffbbffdfdffffffffffffffdffffffffffffefd7fff27ffffffffdffefffdffffffffbfff1f", + "data": { + "slot": "1541624", + "index": "51", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xaa0ce1b22082e442daecaea13de7bbb9863dc8ac33b2359deb08189543ebf999ad255b7ee9d898a545e4da9fa50b62130fbcf566dd5234859f7f4854b9dbd10361f15eb7bdb8e42f21aed5c4afe286e3e377bdaa38557116f59969bfad731eb8" + }, + { + "aggregation_bits": "0xfffffbff7ffdffff77feffffffffffff7ff7ffffdffffefff7fffffffdfffffffffffbdffffffffbffffffffbfffffbfffffffcffff7ffffd7fbfff7ffffffffeefeffffffffffffffbdeffff5ffbfffffffeffffdfffffff7ffdffffdffffffffffff0f", + "data": { + "slot": "1541624", + "index": "26", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa7402d530cd8e214b084c6a165766121fec149c2d265c3a3e94afb75ce8df5dd5d0ba6c0c49ba49d3b0660156ab573bd06bb763dbc83291afc22a97398588cbd4952e14c51a21c0e43732f70ffd5a1330ea92e2702566395ba372ac79d1e257c" + }, + { + "aggregation_bits": "0xffffffdfffffdfffffebfffffbeffffffffffffffedfffffffffffbffffffff7ffffffffffffe5feffffffffbffffffffff7fffffef7fffff6fffffefff9ffffefffffffafffff7fffbcff7fbffbfffffffff7fffffdffffffffbbffffffffffeefffb0f", + "data": { + "slot": "1541624", + "index": "50", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb96802cd26a8fbb1ffe37291f54957b16126cb38589370866e57839311007bf43ec0a23ad96cf7770fcf00c79502a14f16457e589436e9892d4dfcb343bd4dcb0849b4022dbb3e6ec5e1862c6fc2325b98f545b7e89ba8047bf9b167adb68519" + }, + { + "aggregation_bits": "0xfff7fffbffffffffffdfef9fff79ffffedfffff7fffbffefffffffffffffffffffffff7fffffffffffffffefffdfffbffeffffffffffffffeffffeffffefdfffff7fffffffafffffffd7f77ffff7fffffffffffffffffffbffffeffffffdfffdfffd7f0b", + "data": { + "slot": "1541624", + "index": "13", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8ee45d761f0cf008e2527ac9ecf1740f77e29f799c25f6925318e7fb37db42315fad7cd703ed63ef527cf7e3b59e8dab1155283e49041c6474204d519a43e09435f1f06c0a19ef7d0b1475069b84420796b7105c847cddb2f92f5e7955d3bebc" + }, + { + "aggregation_bits": "0xffffff7f7ffffffffdffffffff7fff7bfffff7fffbffff7fffffffffffffffdff7fff7fffbdfffff7ffffffbdff5ffffeffffffffffdfffffe7ff7ffdffbfffbffffffffffffffffffffffffffbffbffffbffffffffffffbffeffbff7ffffffffcffff0f", + "data": { + "slot": "1541624", + "index": "56", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa4dd4772d7d822dfb0ce143c9fcdd1d2557b8ee9e0da5c459cdb088e3c7280d16d2d06155295b6e524ce05c57bcf3c130ddb32390a112b1b2d35b82bfe73becadfef4fe34413a678bf2f12e6fc427b25b974734703ad04a635f5449a3b212fac" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "1541624", + "index": "35", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb26e60c9db032e20fdf55e83329a9acef156a6db14faa149551030b98fe3cdc5e14555ab1aa2246c503afcc13cd6e1a303bcefcd94587a99587452b0f52c1713346f9876e3374dc3fc76f3b5ef9f2ce9f552239b3de920d5d982be525b91cf29" + }, + { + "aggregation_bits": "0xfffffffffffffeffffffffffffffbffffffedffd3ffffffffffdfffffdffffffffffeffdffffffffffbfffffffdffffffffe7fffffbfdfffffffffffffbffffffffefeffffffffffffffffff5fbfff7ff7eff7bffdef7fffffdafaffffffeffddf7fbf0f", + "data": { + "slot": "1541624", + "index": "23", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x965c67eb761c8185a1a3d5cf9a91fca95b10187b3f409ee6decea5e3fc573991fff86ff93dd37d9dedeef0896d1a480712bb17a6215aad57a0d90f416fc8b3d04915b34033961be5ef0708914628801f9daaabdd7acda1c2cf6847b7e38b8d7b" + }, + { + "aggregation_bits": "0x040000000401840000000000100004000101012080100100020040040000000000144182001080000060000040201f202400000048410100000001000002000000010000011000280000800820022800000000408c808000302021020000100020000108", + "data": { + "slot": "1541624", + "index": "23", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8147aa317db894f87a46b7ce2c0c335bdfb6470e9d2254a8ce6695466dd1ca894a8c69c4890601a2bc74782a336fff6e0851a1fa3638a0c5301b079d4bcced50a0a79cf1db4df13e83d7af26f17db76714be6619ff878a1bb0b8e13dfdf44849" + }, + { + "aggregation_bits": "0xfeffffbffffffffffffbfffffffffffffff7ffdfffedffdffffffff5fffffffffffffffffffff7fffffafffffffffffffffffffffbffbffffffff7fffffffff7fffffffffffffffffffbbfbfdbfffffbf7fff7fffffffbffffffdfbffd7fffefffdfff1f", + "data": { + "slot": "1541624", + "index": "59", + "beacon_block_root": "0x1e420f9f1a7c02e84e7f99ce7592c8ee4f725b999fd1302c4971d42f08cbd8aa", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x92a1cc4ad12587529eacbbe84b580c694494f3d8f5e289952b268c75393e8a5d56b35dc1f696919048f6916deed7b4530732081c333441618c07fd6c625eae9f51308352f3555932bd7943750ac4a6234a398c9454c23657bef450dde68f068a" + }, + { + "aggregation_bits": "0x000040000088440080000000020202000000480000108000010000242004204002000020000000022800000000000004910000000000021000c00002000005380040000080000808010004a0400040000004204400010000a00800000001000000000008", + "data": { + "slot": "1541623", + "index": "6", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x83c0ac196e29c97eeeefc0aa2dd8a221810ec759c658d74c5dafbbee8498a8fd1fb79b74bc961779a814f7c8c0384a3c0526f6cc9e1c44b368b564bd0141c52d9a62befe1b5a7183ae924930596ca1461e91f3ffeb612209aeb7f46f0498d2a5" + }, + { + "aggregation_bits": "0x00001800000004810000900000020200000001100020040800001000800002000801200000000000000000440400000000000000000000000000000000000000040002000000000001020008000000400020400000008004000120000000000000000208", + "data": { + "slot": "1541623", + "index": "39", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb0c8bbd7d098d068f6a3165f2a66c0e81c163633045b07f248aed09be4b57214dc17203d074928442eea0b8356f2f4ce165c7ec9e3f47860e73513fc199ebbd08f71d7857ec67b8cf62a3e9e526e29377e28fbbdfcee971b451f938f5ea62f31" + }, + { + "aggregation_bits": "0x2000000400000000000000001000000040000000000040000000010400001000000000000000000000000000000000004011000000002000000000000000000000000400000000002400000000000020000001000000000000000008000000000000000a", + "data": { + "slot": "1541623", + "index": "32", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x97de8366cdeafa2c326fd4477663ef683a72710127cd59fa8a83a4b1e8fedf0136608c68b3c73c9e2ae9221dd18298b205866fe417bd41cc740e0c9b804f806e54c4df4fa0572d2610a15c1b68ee990f75b2ded7a370cb298618870a007bbcc6" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008", + "data": { + "slot": "1541623", + "index": "41", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8704fa1574c4cd55fedeb9382dd96dfa8ecd6b54aa1ec7d0d24756f8ffeab6d01bcc7f417d9e0296ed8a45b5d60d365b11f0b75e09c7f5e4f64145ecbe8f9cfd0ba48749aba9d91c5eeb1661f03fca27830f1a01abf3e376ed65ea91a81b6c39" + }, + { + "aggregation_bits": "0x00000000000200000000000000000000000008000010000008000000804000000020001120000000000000100000000020100000002000000000000000000200200000080000000080000000000000000000000008000000000000000000000000000008", + "data": { + "slot": "1541623", + "index": "14", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb84120a2dde0158c5ce7a6995bc23f1daf9c699da338615978b89a5dc78c765e92857593b228eff9a788e12efefd272013abc688d31535ed55d74837ef56b3bf2638ab09772ca8f7369aad0b70cc08b10f74e0aaabbc1ac2d89cad753fbb0af8" + }, + { + "aggregation_bits": "0x08000000000000000000400000004000000040000041000000010000002050000000000000000400000800200000000004008000000000400000000801850000008000000000000010000000000000000010000000000000000001000000002800000008", + "data": { + "slot": "1541623", + "index": "53", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8979295fade4481ecbe093f6796e4f4101fb27addff14bbc803b8dff26ed8587a892295a3fe8ba5b12cfa4f8e14e638a0345e4f5cbbeca329dd121914ac2e7f38cd6482fc208a27c84d89700032dc2d7606934962ce9a31c8314db2b98878df9" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008", + "data": { + "slot": "1541623", + "index": "37", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xaf2399078580627ebacfe308009761c45d3e2d4a85c24bb55ca08847a01cca88ad53988500c28304fec0ea1b73feee3a081b59abe21fe26ec349b9136e7c01a7a87e26f5e9da5c74c209f1313ae079edce0a043bcd88dd9c9c0a13537bf06d2a" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000008", + "data": { + "slot": "1541623", + "index": "12", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x955de8b501bf1a0d2860676e09ebb6aeb1b4b24169d35933a5e1c33e3b3628af623de1b378c192417112820b3f49def0017aedd21e14973ef8459cd9fd9ac839e28335405a8e46fa689cc08d2df258b4d440bde6aece1382966b4401c3581f9d" + }, + { + "aggregation_bits": "0x000004000000000000000080000000000000000000000001104000000400208040000004002202400300200000e0000000a84000804000040040080800100000088200000000000000000000000020000081806001000004800028000800010000000010", + "data": { + "slot": "1541623", + "index": "15", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x826794a2c092159e48241102536ea79b4b17f2bcce5f284767247de302315e67a3eb3c9d48e41dc90601d6ed5897c7020a554448f1ec4ef29987982051e5a5bc37893a991a8487693a15baed2d9841b3c69c96ad2ed998a7b266e11cb8eb035f" + }, + { + "aggregation_bits": "0x00000000000000000100000000000010000000004000000040000000008000000001000000048000000004000080020800000000000000000000000008000000080010084000200080200000020000020008000000008000000000000001800002000008", + "data": { + "slot": "1541623", + "index": "2", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x89faf17bbbe0ea97443a0aea3aea7a07b085de41a75652af3d02f334ea461f42180dda6703abb7c2c5c76b48a6a9e22011669e078ea98f1cd1841a99165e38d3a22a304ab62d2d4fc482718ed4b6d90eb7522aa1295b8e019c4d6a30fd6c44ea" + }, + { + "aggregation_bits": "0x001400000000000000030040820020080000400000000002000400000000c00000000000000800020200130010000010000a0800000020080000000018000001010020080000000400000000000000002000004040100000000042000001000810000011", + "data": { + "slot": "1541623", + "index": "54", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb6e1d2d44eba258e1a8b972e1af58c77e41c61d63c3e2a74bbd690becadef1bd548c6d2662af4b36189053865c5075e50783b6bbf887b68aae103334c018cba65e65a115ad152f14d72c6925b113d036b5ecf6a2c06f4ddce5f0f2dfce222f89" + }, + { + "aggregation_bits": "0x08000004000000004001020010010002002020004000002140021584442a08480220048058808000274000280000020040400d02004004100540010400020500281000114000002400028000100008100820000030000000004608000000002280004109", + "data": { + "slot": "1541623", + "index": "41", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x82e63d872ca01bc463907ff9dfe784f13946a6e0dbc8b1ab47911a4fe70facd4f078adb0dbfd926eaeaa810b1cb3548110523ae819ea4f72f2cbd1ea8e93dbe70a301e94ad2d8384142c3610f4db684fee2d7a51efcbcfa3d28ba9750a88609d" + }, + { + "aggregation_bits": "0xfff7eef3fbfffefdffffffbfffff5fffffbffffdfffffffffffffefff5ffffffdffffefffffffffbffffffffffffffffbfffbfffdfffffffffffffffffffffffbffffffffff7ffffffffff7fffff7feffffffffffffffffffffffffffffffffffff7ff0f", + "data": { + "slot": "1541623", + "index": "8", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xabdea5621e1f987055a604d350b16962f0065ca5c8c9b50ffd7eec354eb728675237f2eeeb46ddbfa7225847752092b90860e21919f91d1dd94781f32a97160b7d58f3999f67eba65c9b33756e4a6e8e2f625e294f8e458af6ec145e3ce971f9" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "1541623", + "index": "5", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa686fd0467235310b5d0363dcdac5b79aae5e349e1269d26b1d770ccb854a321ffe5a63b566a7004eb09120927f708f003115c01c0fc7763be67d0c3999fb153894f448ac698ccaac1727be53c2b3e3857aa4662dcb723d0352b3608d778db38" + }, + { + "aggregation_bits": "0x9400800000000101000080000080100000000002000000082000021000040500000040000000000400030800000200004000000004042002000000000000100002080000404000000008000020000100052000008d000040000100400000000000001014", + "data": { + "slot": "1541623", + "index": "17", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x83b1fe9fcee46844b7fa6d4bdf951ff797a6063206ce4e1c3030a607599e87731e93aae15e1b5b6a9a46478e3b9b04cd07bf7c544bc29e8af4e389271092f7cf5ef52d23b1e55f96c84085096cd102cd4b1a558455f061346217d24498d1d1a4" + }, + { + "aggregation_bits": "0x0000000000000000000001000004000000000500000000000000000000060010400000000004000000001080003000001000900000000000000400400080004015000000a00000200000140004000000000a000140802000020100000040000001000009", + "data": { + "slot": "1541623", + "index": "43", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8bc4fac5a3d1b2c185f78c50a324573daac65dc5beadb9a85ba35143ca26ed5b86f78010d764876c4abf12685857e45f09d3ae61e38bd117763d1e4d75bebdd6b95eb787fda05c25c3a7b04cb9bad3dc5f97a518b3ba48999fc10687fedb1e90" + }, + { + "aggregation_bits": "0x00080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008", + "data": { + "slot": "1541623", + "index": "8", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa7a3d5aefbbf8fccf4084ace1d055e830d1012d57e5f09a8de78a8aaf6cea046661ecbfd6e6a10a80bd5e65c8efea3351800b8df496e53e8043d383be5520ea2db93a65f62492c6dad84d1df059a74a8d945e900ed2c94806e7c48302397172d" + }, + { + "aggregation_bits": "0x00110205200001020000000000000000001000000002000010004000000680000030020400000800400080011000101000001000000400200002000000000000000000000000000000000000000000000220004000000002030000000000000080000008", + "data": { + "slot": "1541623", + "index": "34", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xadeacf85077092ea8bb4815ab94999d1cd40fe98b7bd07db84ea027f35669ebe047f53b16959c2c4e97181569ceca7d015031655a37d03ed24ed45f79bb1497a16053e5a7a5d9cdaaa41c85c50a3fed9e10faf2d5a3889cfa6689ebbf0828248" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000008", + "data": { + "slot": "1541623", + "index": "14", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb4cee2528c1445c95f34fc5d0a86d542419bd2a49d4975ccf88496900652e2829978b78c22d49d11df68df130ef1c53417d3054316d9016755080a33558400d4fef18824c688b885dadb9a53701c3c8499b282a5011e4ed2326af7dfc86e777b" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000008", + "data": { + "slot": "1541623", + "index": "26", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x90690a70f11d3c0f5dbfd1cb99daa4f77807c7cdcf812ac4a2270c4069d5255a9c68dbd3c0c6bcd9643126f95ccbc75902e6d643bfde64b6e56e37106ac4dc908becd93d7fbf9ee350ebf79b05661830ed3f9618fff17c88f6ee36190978afc9" + }, + { + "aggregation_bits": "0x0000000000100000000200000000000000002040200080020000000000000000200008000010040022000000010000202000000000000000000000000020000081000002804000100002600200400000400000002100000001004000000000004200a008", + "data": { + "slot": "1541623", + "index": "57", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x9638844feeade740efeadc5bdf01c3c5b2c24fce5ee06265011fa8b9f26632ca04922f477dbabbdb515400eb3badc5180a25d655adf2c4e92937eda2fd9eae80d30e92891516ff5e9b24c783c2d604aacc23f3c7f0ba89418bba8b94203138e7" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "1541623", + "index": "29", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x982845aeecfdbc71c2a2b5627144a2582237986540eb5446ad3a2ac2872180e7af500fb9c6ac4dfeec60217e66a2ff1c0816cf37d9aae31c9e71679bcb7550dc8ea3ae029294a3bcde27c0c772d2116b157cfd67c2051acce555427bfd4a4e91" + }, + { + "aggregation_bits": "0xdffffffffeffffffff7fffffffffdfffffffffffffff7fffddfffffffbfefffe7ffb7feffffffffffffffffffffffdfffffffffffff7fffffffffffffffffffffffffffbfffffffffffdfffffffffffffbfffffffffff7ffbdfffffdffffffffffffdf1f", + "data": { + "slot": "1541623", + "index": "40", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xab1fd2fb5a40564bef3ee0740e934280518aa7e9be5e4f3ee5571275305efa6380184cb5f3e4b1b1a2898eb35c3846600c6ff5b39915b79c439955ecf46dde929de52191f62869dd52ba91b212a4db7471239c763c510229c4d7556f3773302c" + }, + { + "aggregation_bits": "0x00000013010000400800000008400000000000000040004000004000200600000000004001000020000000800030000004108000000000000010001000000000010000000000000085000000010080000000000000000000000000010000020002080012", + "data": { + "slot": "1541623", + "index": "13", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x892690ad665f2ae32661243e938456f4c8d7d973cdf4f6e9ec7f4a29180a760a29d441231b7483869d90e43cf12c5487118cd725d3b1554d89c2140795a45815e3ad539c0090d0cd829749dbf3d6e6bf60db8fd7361a16b9221a0176eaba1cd2" + }, + { + "aggregation_bits": "0x00000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008", + "data": { + "slot": "1541623", + "index": "43", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x94d19ca003e3e6caf059de92b949e0e0a7770cef6e211893135962f59cfb43cca8f4a1ae4511e54c57f79b3e4e22aa560aec2b17d4d0ec867b686fdbd44697da655a7ff02853668ccb6f1bd8ed4309a3fee7beeb1bfc77f1cf155950d99a0e01" + }, + { + "aggregation_bits": "0x00000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008", + "data": { + "slot": "1541623", + "index": "32", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb1e57d739960b92b256da8e6c1e2bb3a1db30af1a27a3472130b312baf48796896df3f965be40940005f24b99b7eae1014bb7a6cb5ef29e08ac4a2a3767162b508b02d4c7a06da20dc2c3d418fd9a730b881a9e93468bf55a240c7ba001ec890" + }, + { + "aggregation_bits": "0x04004200000002000000100000000000000000002181080800040000000040802002000000c000000010000000040080000000100002000000001100080020080000040000100010000000000000000000000200000800010000a8000002000380288014", + "data": { + "slot": "1541623", + "index": "42", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8861bd33cb8c461cfc5a9a924a0b7da95f416f0cc8061bdfc4aa41569544528e19f0b655ef3a9f048454938b6d4c14b919b23455a5fe001f280b284c5bb5e89f3fb79fe980106a316dfcb3b0f3022227af223f16a245d920b24856b56cd98d36" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "1541623", + "index": "33", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb72769ec4131782b87b249b263c726ad6d57d9ab14c40d86b9aaf6437127cd8e46516bbd5d89d6c555610f324986e35b0cdf3f477e1a69331d04b1a9fe45e9480487135bec9b7b4263a3ff5ff01dfeb520828a273a0d7dca0bf209de80f6d9d8" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008", + "data": { + "slot": "1541623", + "index": "55", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xacd9d416a11ba935c4154f82d6d6780858fc102f5d945061e7d1ddb886941cd68a8aae95e0e61291da83bb106aa72fbc0a75e4caf5b9fe4ab000afef575ccdfcb9d6e0820b86cd4743e7724f905fb4761143c47d57090d9b0e743648d5a749c8" + }, + { + "aggregation_bits": "0x20000000000000000000000004000004000000040000000000200000000000280000000000200800000002000008c00000000000000000000000000001000000002000008000000000000000000000008000800180020000040000000000004040008808", + "data": { + "slot": "1541623", + "index": "0", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x880cfb7a96307357adf7d4d58cdada2a87b9ea30cb8b80f0f1834c35a49af21b48f962bfe2604be27e6dadf125e7c8520ccbbf7c80bd49045a8944164350a3acd016784d244d26b6102dc33a51e3294b0896f79be7e820d72cb8043d7b1668cd" + }, + { + "aggregation_bits": "0x0000000000000101000004210100000000024220000000040008000000010011000000000000000060000000000000008008000000001001200000011000800002800000080001004010000100400100000000000001020002000000000000000800000c", + "data": { + "slot": "1541623", + "index": "24", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8d5a262d60d3b7dcf938f62216c6b85ede3617786ecf77cf031cccd7831c7ac710a64657c6b9a88cae724449adbcfb6b1774f8e1448be033965db8ba111ac1524699e68a0a7f07836f1bcff262d02ce0e7e02682021459d370d8f5448feaecc8" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000008", + "data": { + "slot": "1541623", + "index": "28", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb83ad504850b5107aba1ff347efa084e4ec80a45d175e975960d71da27b6e62e2ee4518e67360371891e4b90692b34910817d1d34289b29f9e6324b5c640b86770ee5fb503ad80478c8d6e85e46d0f9e8cf916f286bb825a947f65397c2db373" + }, + { + "aggregation_bits": "0x0000220810000100000000000000808000000000000002080020090010100000c004500000220014002001100010000000200400000000004000040000004100000001000080000000000010000000000000000000000000100008000200200000800010", + "data": { + "slot": "1541623", + "index": "31", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb56656551ee0c29faaa91b04fce5917d63f0fef97b8e012f4ba4afca26ad4c8b3cff8e4b7333574ad13433877808c3a119e3f55c5846032e4f6c96a979be9ec81ba708e192f2bd008807b8b28dc6ac6a1f0d25c735fd569d3e93791b2df93f71" + }, + { + "aggregation_bits": "0x00000000000240000000004000008000000000000010000000000000008000800020000000000100002000200401000000080000000000000801100000008408000020000000000000010000810000000400000000410000100000400400000000000008", + "data": { + "slot": "1541623", + "index": "47", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa79ec18901d8bc4c50c5ca380dfdb63ae5e100c1c68ae396b0a524e3d82fcdf7f8d7f9f4e53a61a4bb06757e2c65b5dd16f8720ffcd682fca4672d396533fb6bc9af8b6f15ced6d530ecb76c7fa49b0676dc12f713efde96d4ecd7ccde3216e8" + }, + { + "aggregation_bits": "0x7ffffffdffffffff7ffffff7fffffffffffff7bffffffeffffff7ffffffffffffffffffffbfbbffffffffeff7fffffffffffffffffffbffbfeffffffefffbfffffefbffbffffffebffffffffffffffffffbaffdffffffbffeffffffbfffffffffeffff1f", + "data": { + "slot": "1541623", + "index": "29", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb28599b3915858eaa77fe965ece4f48afaf47e59c8ea7ffe64774e7b314c6df47937bd6a3b7ec3d3f7df6bd7f5b712d911ac048252c1ea820fa237335011ed237465cd68bbfad485b672f9e2c68c1811db5723fe92951f2edbb4fd65e6c63904" + }, + { + "aggregation_bits": "0x020008000000200000001040200004000000000004200008100009000200000120420c000000000000000002001000000001000000004000000010002000400001008000200000182003002020000c200849012000000000120880000201000000000008", + "data": { + "slot": "1541623", + "index": "22", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x99bef08f36feff89d2bf8ada1dc23cb0a6343e73215c82dc916d80aee69d398787762cabd28defdf3b321a3f67a3b0a60481d4a46ca9e99305d1110cfa7d42056d92efc69b3fe405aa7124e8462338be13957388db2d158d5f05d11d55fcd150" + }, + { + "aggregation_bits": "0x24400004002000000090000020000000000040080000000000208050220100000000000000000000000002440000010008800000248000002000008000100000000240000400100100000900000001400000000000000010200020000c00000000000010", + "data": { + "slot": "1541623", + "index": "5", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x81c4b94282f688916830cd2582a1a3933fe82b78d1b4122aad176f6ba8c9ce9195a70ba903f977d5b47c7aeae01932c51312b16fab59eb16cb7f9e7de966100ab6c6b2ccd5e0a3bf5528ef6d0d8992843b8dd41c132c7b673dadccf256619947" + }, + { + "aggregation_bits": "0x00000000000803008000000000000000000000004300000801000000200000000840000082004000000040000000000000001200400000000200400000002000000040040022000082000000000000800000002000000028000000000044182000400808", + "data": { + "slot": "1541623", + "index": "37", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x89dc74f9c7d7d568a84e937946d2f6cfc1acda04a810c75cac42f62a2d07bbecc66845fc9532fb48e24889c0775318810d61e70a1aea9f3010ad86f894c3e475236c8bb1317f389a6687984aab410b74c8578181ae9df0f6e2b4046bf9b691bc" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "1541623", + "index": "54", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb8fc53639e01e6ff3f67baeb44176e7946866b177958e5639fe2af87412768a81c405dcbdb288c63168476d457e95a630ad5fad065494a833c43f759fb3b9bfaf6227bd67cdea7bbb6bbfb7f939d227df9a10a162f2dec522a80b951ad1243c4" + }, + { + "aggregation_bits": "0x00001000000000000400080100440001000000482080480000000001000000000000000000010000100440208000000000000400000000000010000220001000005000180004000000000000000041020008045000060200000000000000000300000108", + "data": { + "slot": "1541623", + "index": "63", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8ffeab58a80a9f690ddc31bdedea782503ae23ac84adfc8850a8ed5000591af0ff1af9140d527865b4919a8405bdd98910b0c7d55cef89c5e035f1e541ef0ebd34113f6f46b02bf3c098181c7b743b3cc995550176ded0028f238cd02eda883b" + }, + { + "aggregation_bits": "0x00200900000020100000000000000000000000000000400000014200000000000000200008000000000010000000c00040000000000048000000000000000000000820000002000000000000140020000000000002000000001000000100000000000008", + "data": { + "slot": "1541623", + "index": "10", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb937e39fe738e75fb4f3d883eae4e7bcc61a4fc061c998cfc8fcbc0a13f2cf184802e3e67c2066046dc0930ae4e0868616eea405410c7b7fa71cd14178311d872a18e192af4d95a8957e1f38310111756f5e66bcffd0664ba2e0e122424758ad" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000008", + "data": { + "slot": "1541623", + "index": "51", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8d5ba9660a574c4d8f3051d23783ffff6723543bdf7050a77f442313b4aa8cb83b0cad68911e36c8f5bbde9836a4db540bfb28f9f0ce00bef1f4efe53ef884f92eefd8980c9feab3cc1354fbbc21260eab7b15cb8e5c29446f9e3bb8d54b1702" + }, + { + "aggregation_bits": "0x04002020048000000000000884800000100000000000400800040240000010000000000000020000000000000000000000400004100100000120000000400200100010082000000000000040806000010000000008000803000000000002000002000008", + "data": { + "slot": "1541623", + "index": "26", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x951dbb049ef9ab0d484c9caa4ca4389ff1a41b47754230147d9db544c3a56ee37b1b16e984b459cd52f993d272533af20e84ce4e57f11091835d67ebf40f183df6b2e4bf598826dc4e8b28f44a1925178db57578a7b4a729c665c17ca3036484" + }, + { + "aggregation_bits": "0x00000004001000020200100000000000001000000010000010001000000000000000000400200000000000000000802000000000000010000000000000040000010000000000000000000280000228000000000000000000200000000010020008200410", + "data": { + "slot": "1541623", + "index": "52", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8e1eed255efad2770cb011b548f96a34bcba6965851e355249d4ad85808dd64c45c400e967ef2985a38aceb44fe997a908bf8dfa0798e115aea3782c9398479a8b05a0d34364bc89722d42bf09122f126bb4e49a3f663a615e26c8251d054dc5" + }, + { + "aggregation_bits": "0x01202000000000000000000101000000000000040000000240000000000800000084000091000000010000040800800002400004000000000000020000000200000080000000400030004000100000000002000000800000500000020000002000019014", + "data": { + "slot": "1541623", + "index": "46", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xb2dafd81c30c5b9b99f54225ee8ea3f2ab4a474cce24ac9372675ab261fdf0ace9d4a8d96edb455364d3986a73bc8dbc1296d2a0164045c5aa9cfa47ef4ea3607f45e017583ea2e7d847d1a0882161cb52eada9ff598935058888446fbd67396" + }, + { + "aggregation_bits": "0x00000010402004000000000000000000040010000000000050000808000000000000040040000200000000000100000002000040004000004010000000000404000000001084000000000200002080040102000800000000000000000000080140108011", + "data": { + "slot": "1541623", + "index": "11", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x96530f922916b319860cc6788937b62da04d62618f37bc73071ced77a0ea3fdf4b0f4aae4b3f7970b767dddb597eea4618d543dc5f2c561d9a156b51ab4a1424027b75c577c383195f90373bb86b60727c2a4440a30ec80e5257ec3f98771aeb" + }, + { + "aggregation_bits": "0x0060900210850008245884d1011014c1da48d12048043100244c08483001096000122008245504b042805a0c0008980a04040000040117418c854390104801444402321c22033dd001403000087900002000904023aa682100a335408aca940414048c15", + "data": { + "slot": "1541623", + "index": "21", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa576135203e0a2fc0c66049886142a6491099ecdc1af2b05a454b67bbb17f3030a234247670fb3e52334db0136b2ebf2076c4fbbb0ca00fa057a1b31f154d1706eb4ea134185abe674b0414f9ccfd196f51e399c76a5a4ddba8ebe1892afb2ba" + }, + { + "aggregation_bits": "0xf7fffffedffbffefffbfffffffffffffffffdffffefffffffffffffffefffff7fffffffbeffffbfffaff7fffbfffeffffdfffff7ffffbeffdffffffffffffff7ffffffffffeffffffef7afe7ffffffff6ff7ffbffffffffffffbff3fffebbff3fff7ff1f", + "data": { + "slot": "1541623", + "index": "9", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x80fb9273f7b96c941ef11376d3324a2ab3172f08425ebb438f85495102c0b5a4ed0bc6ce87c044d7ae6088aef7d141b21865ce4e1198950f34c3dff0d347a66ffa016128502cedf3bd7f02706f53e54e9378d2a9fc0fa3b259158d3db8099758" + }, + { + "aggregation_bits": "0x00000400000000200000000400000001010118010000000080120000008910000000002008020000800000004080000000002008000800800080000800040010200080000000000000000000008000000000804002400000000000000000200202000010", + "data": { + "slot": "1541623", + "index": "3", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0xa1960002692259ba5c3c32d5c24cf6bb0e746e3bb0dd1c5b47ca4894241e42fa4409e3c6409890cdd4c0031230cab4bd15b153897fb881dbcc9da83b5e970528a1f8b511e6f4d58ed7daf299512966122bb44fbb894288f39162e6eae2e7a47e" + }, + { + "aggregation_bits": "0x00001044400200070000001000040000000840004000000000010000900000800008c00001010200000000600000000101000003000001000000000800000003000008000038201000000000018080480000084000000000022002000000209020201008", + "data": { + "slot": "1541623", + "index": "16", + "beacon_block_root": "0xcdc243119842e862ac01a8da1d818db0f242c405c3f9e46b8db8149f49e46931", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x84da0fce78cb38e64ee4466b8418ec491a1ad6dea26a772fd7c9c41a8adddbb4332dde5ba509985a37da7ed9f07350ca0e18527c9db86c2536af01369994735878a4af0978420afd9e363ff5b47510bab8dc3054f332bccc6314ea4e9cc55e83" + }, + { + "aggregation_bits": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010", + "data": { + "slot": "1541623", + "index": "48", + "beacon_block_root": "0x48d6c8db9f2b42e58dff3d5f526e695a63b2efd743efb01d6a056737f9479014", + "source": { + "epoch": "48174", + "root": "0xdb78bf053edf5b1c06f8acee78a62585115e095e4dc7461e0cf58ca6bc66584c" + }, + "target": { + "epoch": "48175", + "root": "0xdd210e22cf8c3364d232ccc769331839fb06eedfb0f6e22d0848604ade1182dd" + } + }, + "signature": "0x8bac84d47f483440fc967ff0f9c3a5ac000c582278e29252bcc9fc7a23856cc94b47b644eb5e04e8263d9d9ad6da089209d3afa21bca1ba70c72892f57887fbe9beda06d6fa1550d0b3aeea761400ac171de09661358d3275e2c4f93ebfdd377" + } + ], + "deposits": [], + "voluntary_exits": [], + "sync_aggregate": { + "sync_committee_bits": "0xfffffffffdfffffeffffffffeffffffdffffff7ffef7fefffffdff7fffdffffeffffffffffefffbff7bffffffbffff3ffff7fffffffffffffeffffffffffffff", + "sync_committee_signature": "0xa78afcaaae02f3764ae84b1daf9fa0ea5e5d4985513c14fe780fea1dddbf89ab2ef6c5b72171118c6a638596f2edc0f4047ec8f38cf2ccdb6d5e33d9060a829f771a02a9ff9c5e32c2c309fa62bbabbc20c36e2094fd5ad7b924481782661788" + }, + "execution_payload": { + "parent_hash": "0xdb430eb8fbb387b0e1c7febaa6a0c7354cc353a530a78700a02ef89889d374f1", + "fee_recipient": "0x2b1d879b5e102e60166202de79537b48e2f18a42", + "state_root": "0xb7c01048c61410602b181d43bb6a3572e220b4749243621c432a502a5b3ea625", + "receipts_root": "0x791b50e9b9746d71bbe5747f4d27e222a06232f6a68af94a6eacf54e10a68680", + "logs_bloom": "0x04810914080102020120030004000105400882024500a04404c00013084040002104010010001040002420800010040180060093204002300054000001610000010282810082842000040029140c40051123402a000102014004058d10803000081008000a00008080d002840200080010290002848070aa0022103438b214480100100000014420002000c8040000000214302490000ab2050450002024040103004a900004020008a002102101c20088000000000006041450042401212001905a2003101011001040400084100f10082510a2001045c44080181103002002041208404800444a00300140828860804800080040110300c00010001a00b000", + "prev_randao": "0x2de8f08ad2baf5b8ae0bed90efd8eceb0aad2f8551d31b84bb266f7f7ed3cdba", + "block_number": "1443460", + "gas_limit": "30000000", + "gas_used": "12565605", + "timestamp": "1714401900", + "extra_data": "0x4e65746865726d696e64", + "base_fee_per_gas": "1276466965", + "block_hash": "0x4d3299a228554c87d52066c768c106967a7ee24a3057100357f5712d05057ef9", + "transactions": [ + "0x03f9013e82426882add8850165a0bc00858bb2c9700082520894a83c816d4f9b2783761a22ba6fadb0eb0606d7b28080c0850df8475800f8c6a0012ddde9edbe9c2703133acf949560633c2ef0de37eab6e94b15a503a89be5dca0014137a90affe5b2543caf4f61dffdebf3d39375ca6ddd7073cf59f28cdd1425a001e1855424fc77233a9c1d898ceda1d886a274ef9aa68c5c61cb4339d00dba63a001be271a65c0341cf0b0fe39e208ca38cc12a502d94457295e8890bfb9d67dbba0017a8baa485cf5ca83bea6aef89fff2f4a18e74be1043049390f57e43eb05e30a00126e9190e90ffe014a7180527c73b3c43f7be82cd9785d9749e0e0fd807923e01a0fa23d942f18a265f9fb95c8221333f5594069ecfbdd1ebdced01505d299a24e6a05fda4b5f46a527246e4ece813d06bfca694e747c46a0cd9345800ff2759f8306", + "0xf8ac02850c22b20b27839ef8e094ce658e386fac0646cedaf810070f0525af14d11d80b844095ea7b3000000000000000000000000329d0c4a58b3cefdb40c5513e155228f6cc7b6c500000000000000000000000000000000000000000000065a4da25d3016c000008284f4a00c9aa03147729dacb02a303a3d8a6934803432355115162950a42a2f050b0feca023193e86914d16e2e25746ee88dd3e33b34f84bd0ddb45acc275edb6d5741a15", + "0xf88e8303a6c48502dcf592808259d894ce7a8c6c061e4c618eb66eddec61bcb507788854880de0b6b3a76400009d5472616e73616374696f6e206279205374616b656c79204661756365748284f4a0b42e033fd033ce71e0e87cfd45c2c6c88c79549b8548d8901b3408515e985054a072a5bd7f1cba2a514aa27c2f739e0d195e616cc6d77d87bf1ae06b80624a07af", + "0x02f901348242680d8502540be4008502540be4008301926094a44151489861fe9e3055d95adc98fbd462b948e780b8c4eea9064b0000000000000000000000009631af6a712d296fedb800132edcf08e493b12cd00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0eb688b39ccf0327154ec9fd46e7c9e23a18a3fd4ad7da9ddc022d2ab0740c804a00c3f3a0dde3c623bd29e9dc9fee633b832fc5664e4f841af503c313a4f6e8dcc", + "0xf902940485022fc98282830191bc94f458747c6d6db57970de80da6474c0a3dfe94bf1872386f2704a5440b9022433bcd0cc000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a242ffd3d65153185567b4fb11e3fbf0a58e41300000000000000000000000000000000000000000000000000000000000042680000000000000000000000000000000000000000000000000000000000028c600000000000000000000000001a242ffd3d65153185567b4fb11e3fbf0a58e4130000000000000000000000001a242ffd3d65153185567b4fb11e3fbf0a58e4130000000000000000000000001a242ffd3d65153185567b4fb11e3fbf0a58e413000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000000000000089544000000000000000000000000000000000000000000000000000000000000222e0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008284f4a0f22517906df9f14655c6f04d00809e677fdf0bbb30b9195d353301703639da7fa079756d6321da05c85e75a6bb5700a36fa927bf02742e5cec075cb1f42cb55a86", + "0x02f879824268830f8c2185012a05f20085746a528800825208941a94ecf77cd4c49cb829cd8487fe76f0b3103e958802ef8687b9771a0080c080a0d2ee250fa158d75a24f96c94e9f395689a50622a3fd2f39d64ef9e7332a7c5f2a073b6d4783b1555fa13859251174dfcfe1058d404fa54dfdbce5fee0c621ff937", + "0x02f879824268830f8c2285012a05f20085746a5288008252089499ecaa71319f4c72f5615ad20833cc2e1ab2beb48810470b72116f7d0080c001a0950c440022c2685b71ec2d34f01e6e8be67ccaece11582771369080733e02bc1a0185bf51a7317ff93606a437dc613b8519fbe7a77d773e61ac9edc92abc668d83", + "0x02f879824268830f8c2385012a05f20085746a528800825208948aa48e9472879937dd46208e1962fdd262272547880444960583e71a0080c080a0e7a72994261c823240e5a12b63966e8826293ea340a5fe4b86756dda10b5c15ea056bb1421146b68844365710bf5fc9bbc3bfc68d008644fb25cf9826de17be873", + "0x02f9021c8242682785012a05f2008502540be4008301895294a098b76a3dd499d3f6d58d8accafc8efbfd06807872e9ba936cef000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c35110000000000000000000000004529c3950ea5e59239f11ab39b056e7a3274f43400000000000000000000000000000000000000000000000000000000000042680000000000000000000000004529c3950ea5e59239f11ab39b056e7a3274f4340000000000000000000000000000000000000000000000000000000000028c610000000000000000000000004529c3950ea5e59239f11ab39b056e7a3274f4340000000000000000000000004529c3950ea5e59239f11ab39b056e7a3274f434000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c001a020409371c60bf4d57f57d607872b5b6ddc0ee18acfdd3b67740c8d852bf3261ea072e277208f8969d1a0cef8cba87f87f622b59afe9e4ef3f017e98081a14b2c94", + "0x02f89182426801847735940084da13fd0d830123a994a960d72f83a8a163412520a778b437ac5211a50180a46a627842000000000000000000000000c29d086a47618ac1a0d07cd6df8a45b3552efdd5c080a06919b148a24b388e92cd6718491e17ad98601d440585d35f3ee8d965e84dbde5a043113d12eb186b404c07192bc014f09a0d556115fcef451b08cc9a739a85b070", + "0xf901b30784c27a7abd8308c29a94095ddce4fd8818ad159d778e6a9898a2474933ca8724982f29327c78b90144755fc20c00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000028c60000000000000000000000000921077931f313b4f7cd554449c230099a909c889000000000000000000000000be9c135eaf73a91b89386ba8d80366faaa48ec670000000000000000000000000000000000000000000000aee1be53eb6228000000000000000000000000000000000000000000000000000000000000000222e00000000000000000000000000000000000000000000000000024982f29327c78000000000000000000000000921077931f313b4f7cd554449c230099a909c889000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000008284f3a0ff503c3ca80552f6f536d20541962622d6b62e966e27030435ce7f752004faeaa0454e60091787c7a72294eca7d93b857dbece938fce5c63fe74a44519f80bebc5", + "0x02f8b18242680284b73d64a084b73d64a082b76794a960d72f83a8a163412520a778b437ac5211a50180b844095ea7b30000000000000000000000002259662ed5de0e09943abe701bc5f5a108eabbaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc001a053dda6b47004f32fa02a346e8eca6375d1415e0ed04a1c58abaed98c94261f0ba03d266abcb4c6849b7644b942d6617a6aed4317fe34657d427393e6fe2bf24be6", + "0x02f8b18242680284b5c16b8884b5c16b8882b76794a960d72f83a8a163412520a778b437ac5211a50180b844095ea7b30000000000000000000000002259662ed5de0e09943abe701bc5f5a108eabbaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a0cd401c0446b1904c422d8829eabd41f12e42f2c76aa38cda5e4f0eb03b5931eea01bbda2c4c40f3b22a5c63a5cb1b12caebd1c0232e555471e3d0e42c9eb102dc7", + "0x02f8718242680284b040285784b04028578301abe2941828eaa3cde0b2373bc869a19cf5b4804c21752c8084359cf2b7c001a009f6a2b62f3c9fdde753c9b233e7161a3a22a417f5d48cfd2f94bc97871933e2a02041ad8d59c351e49bf1b30dce52a65a1b0d2b9f49fdf8691c88cf0b5370ecb9", + "0x02f9015982426802845b9eb25084b73d64a08302f064942259662ed5de0e09943abe701bc5f5a108eabbaa870e7dd43209f000b8e4b84d9ffe0000000000000000000000000000000000000000000000000000000000028c610000000000000000000000008d0cb731e1ceb607a0e64f6c6b3f7f441a8959f40000000000000000000000008d0cb731e1ceb607a0e64f6c6b3f7f441a8959f4000000000000000000000000000000000000000000000000000e7dd43209f000000000000000000000000000a960d72f83a8a163412520a778b437ac5211a50100000000000000000000000000000000000000000000000000000000000f4270000000000000000000000000000000000000000000000002b5e3af16b1880000c080a051b7588e853edcb14572247429f6c7c2ad4ba6838bb074542e6861dbedacdc78a02390eaf695bb6cb59865abe929400ca01b02e9f888c0ca92dc25e6c1b8e02e31", + "0x02f9021c824268808459682f0085014a09da508301895e94a098b76a3dd499d3f6d58d8accafc8efbfd068078801274c4a4515f000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c35110000000000000000000000001721305100ebd1e800c680c05d148622d965ad3a00000000000000000000000000000000000000000000000000000000000042680000000000000000000000001721305100ebd1e800c680c05d148622d965ad3a0000000000000000000000000000000000000000000000000000000000028c610000000000000000000000001721305100ebd1e800c680c05d148622d965ad3a0000000000000000000000001721305100ebd1e800c680c05d148622d965ad3a000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a0f225a440e8a1b46fb249a2c5742f13c9593c8968dce72103aeda5b828afaee25a04d3ea74caebf5c4d5da816225ea288ad438279569047ee1c7b0c8f5f8d849ca3", + "0x02f9021c824268808459682f008501494bddc48301895e94a098b76a3dd499d3f6d58d8accafc8efbfd068078801274c4a4515f000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c351100000000000000000000000059789faa25f20514401019da3ca6a4b51ba8b431000000000000000000000000000000000000000000000000000000000000426800000000000000000000000059789faa25f20514401019da3ca6a4b51ba8b4310000000000000000000000000000000000000000000000000000000000028c6100000000000000000000000059789faa25f20514401019da3ca6a4b51ba8b43100000000000000000000000059789faa25f20514401019da3ca6a4b51ba8b431000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a00da3bbd57f6433dfcf93272722e2d7da29131f1bdd5c4e4b9af15b11be7e3ba5a02fba92280cf44f555acf98cb4fae85da422d7f12f92344704702c05c555cc5a4", + "0x02f891824268078459682f0084b936294e8301b57d94a960d72f83a8a163412520a778b437ac5211a50180a46a62784200000000000000000000000079f56aa60b627ca4c8db80e958dc54bb70debe52c001a0535ddd349596c954dc6eb76de0c7ca60d0e324f06676a9975dbd986f9ce97323a04b85263912dd89fd9d576a3ad8ba27fd0f41a065c5ad548ff9765bfaabe896e3", + "0x02f9021b824268048459682f0084b936294e8301892e94a098b76a3dd499d3f6d58d8accafc8efbfd068078805511cb35db3f000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c3511000000000000000000000000042f241ff981b3becf79003c8b81ae406e398d050000000000000000000000000000000000000000000000000000000000004268000000000000000000000000042f241ff981b3becf79003c8b81ae406e398d050000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000042f241ff981b3becf79003c8b81ae406e398d05000000000000000000000000042f241ff981b3becf79003c8b81ae406e398d05000000000000000000000000000000000000000000000000054607fc96a6000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a04b25266e0eba74ff7d8858e80a9ed83af04d04e3b4f51f8a08bd851ba9b98a79a054635cd5edd1fb529e18217e5e5f70b7907ba5bb235354c9f1c22ee7f34f274c", + "0x02f9021a824268088459682f0084b936294e83024d9f94a098b76a3dd499d3f6d58d8accafc8efbfd0680787038d7ea4c68000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c35110000000000000000000000006894922371ba982a57aa93c33953bd50772001db00000000000000000000000000000000000000000000000000000000000042680000000000000000000000006894922371ba982a57aa93c33953bd50772001db0000000000000000000000000000000000000000000000000000000000028c610000000000000000000000006894922371ba982a57aa93c33953bd50772001db0000000000000000000000006894922371ba982a57aa93c33953bd50772001db00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c001a07cdedf58a30ad5e310074c50004cf13e62956175781e70cd0341d12eb636e7bba0389a623038144df7bbf5d554b4667848986c0ebcb71c4d266d3b6cd406028399", + "0x02f9021a8242680e8459682f0084b936294e8301895e94a098b76a3dd499d3f6d58d8accafc8efbfd06807870ea2356bd47000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c3511000000000000000000000000ff26343c7a8fff2e8b1174ea2d14c1aceb84c0bd0000000000000000000000000000000000000000000000000000000000004268000000000000000000000000ff26343c7a8fff2e8b1174ea2d14c1aceb84c0bd0000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000ff26343c7a8fff2e8b1174ea2d14c1aceb84c0bd000000000000000000000000ff26343c7a8fff2e8b1174ea2d14c1aceb84c0bd00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a0ff3065170aa49321b95f61066b22c467219da4daea669bd135527771cbe9ae56a02a32aa9b6a11a13741a4d9d51597832c43a7235bc6b8a063ffef78c2008f246c", + "0x02f9021a824268088459682f0084b8522d738301891594a098b76a3dd499d3f6d58d8accafc8efbfd0680787038d7ea4c68000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c351100000000000000000000000032cbc8d6b679b9119e59eb6938aab875f56b0cb9000000000000000000000000000000000000000000000000000000000000426800000000000000000000000032cbc8d6b679b9119e59eb6938aab875f56b0cb90000000000000000000000000000000000000000000000000000000000028c6100000000000000000000000032cbc8d6b679b9119e59eb6938aab875f56b0cb900000000000000000000000032cbc8d6b679b9119e59eb6938aab875f56b0cb900000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a002e9ed1c12c62f8d5ec7d036639f93425993098aafe7bcb3e53ded70e4b03f1ea00e8f5ce447e3410fd0b6e145f93ad073cd411d3ffe1f823695169124f63096bb", + "0x02f90159824268038459682f0084b8522d738302edbd942259662ed5de0e09943abe701bc5f5a108eabbaa870e7dd43209f000b8e4b84d9ffe0000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000db33357a78adcf53ec4fd79488cda6d79df5bed0000000000000000000000000db33357a78adcf53ec4fd79488cda6d79df5bed0000000000000000000000000000000000000000000000000000e7dd43209f000000000000000000000000000a960d72f83a8a163412520a778b437ac5211a50100000000000000000000000000000000000000000000000000000000000f42700000000000000000000000000000000000000000000000000de0b6b3a7640000c080a07af05351997a092ea62f11dee2444ce64c894f3d627785a62480c0638bb78709a05292cc0817f44c7f373b1b88556f963f48c4b611b580956a470feb7280175264", + "0x02f901598242683b8459682f0084b8522d738302edc9942259662ed5de0e09943abe701bc5f5a108eabbaa870e7dd43209f000b8e4b84d9ffe0000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000766736591ca7218da10106359df177f90d53486b000000000000000000000000766736591ca7218da10106359df177f90d53486b000000000000000000000000000000000000000000000000000e7dd43209f000000000000000000000000000a960d72f83a8a163412520a778b437ac5211a50100000000000000000000000000000000000000000000000000000000000f42700000000000000000000000000000000000000000000000015af1d78b58c40000c080a06a9bb47f92b15e6766692c467164119dfb850d1dfc95cbcb2fe60f6f1373c94ca04130553aa7cc13a2ca879cb06ea9822b63b97ee082b5524222dbb2adc994af08", + "0x02f9021a8242680c8459682f0084b8522d738301895294a098b76a3dd499d3f6d58d8accafc8efbfd06807872e9ba936cef000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c351100000000000000000000000016ef6c68628683a8b06386e79ba17b9da5a5780b000000000000000000000000000000000000000000000000000000000000426800000000000000000000000016ef6c68628683a8b06386e79ba17b9da5a5780b0000000000000000000000000000000000000000000000000000000000028c6100000000000000000000000016ef6c68628683a8b06386e79ba17b9da5a5780b00000000000000000000000016ef6c68628683a8b06386e79ba17b9da5a5780b000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a084260cd9ab7a3287c41d52c9ad5017e3bc9b1455bbdaa2ce70684db8136f2e20a06cd2644f3ca3fd9b6ab2f1e909f8eb30fa7b2d618e34ffdcedd99a8f13fe5e55", + "0x02f8d48242688201528459682f0084b8522d7383026e5394dfb5f6ce42aaa7830e94ecfccad411bef4d4d5b680b864e7a050aa0000000000000000000000007d704507b76571a51d9cae8addabbfd0ba0e63d30000000000000000000000003f1c547b21f65e10480de3ad8e19faac46c95034000000000000000000000000000000000000000000000000001c6bf526340000c080a069aead5be9cd9d21ee7db9a85cae8f4e8909cbc2e89b4537cb55d19add5060fda006e96a0d393a411de15e62e01dfdc29bbc5aaaca1aad4eb35449b3d6ed49f961", + "0x02f9021a824268108459682f0084b8522d7383024dfb94a098b76a3dd499d3f6d58d8accafc8efbfd06807872065aea3b4f000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c351100000000000000000000000059d340f435c1a7ea39b28879f8ad56e0425e985b000000000000000000000000000000000000000000000000000000000000426800000000000000000000000059d340f435c1a7ea39b28879f8ad56e0425e985b0000000000000000000000000000000000000000000000000000000000028c6100000000000000000000000059d340f435c1a7ea39b28879f8ad56e0425e985b00000000000000000000000059d340f435c1a7ea39b28879f8ad56e0425e985b000000000000000000000000000000000000000000000000001550f7dca7000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a0672187b8d066754021e41ab8cc5a35e40e551f3ab06427180e3b429d7b3b32c6a0565ecb503f60c8c2a2c1a53361cac3bcf953f4a4f50d337f0fc7c06ccf71d221", + "0x02f8738242685b8459682f0084b8522d7382520894f0bdf451ab41aec9fbb38cffa3a4ff1cb7250a4687011ead1dfe5c7780c080a08133fc3ef33b8c9ee942b431d3bac125b6b8fb2d7710847af9b0788176bbee21a015bca2ade84f525a1e2ca988fa7720416b7c2f97cf6a622c154b102a5797412a", + "0x02f901598242681a8459682f0084b8522d738302edc9942259662ed5de0e09943abe701bc5f5a108eabbaa870e7dd43209f000b8e4b84d9ffe0000000000000000000000000000000000000000000000000000000000028c610000000000000000000000007828dc393b5de25cce316afbb98befbc769ba19e0000000000000000000000007828dc393b5de25cce316afbb98befbc769ba19e000000000000000000000000000000000000000000000000000e7dd43209f000000000000000000000000000a960d72f83a8a163412520a778b437ac5211a50100000000000000000000000000000000000000000000000000000000000f42700000000000000000000000000000000000000000000000015af1d78b58c40000c080a062d5aa7c17b16ffb284bac9a44b3acee7e221063e6f65aaffde9840ddbddf50aa07ef8cf0d8288100229e1558e138b8384216328a6757bc565ad49508fb424f24f", + "0x02f9021a824268138459682f0084b8522d738301895294a098b76a3dd499d3f6d58d8accafc8efbfd06807872e9ba936cef000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c35110000000000000000000000006e67512014d5790a7bdf08c0ba7e82aab60d65ed00000000000000000000000000000000000000000000000000000000000042680000000000000000000000006e67512014d5790a7bdf08c0ba7e82aab60d65ed0000000000000000000000000000000000000000000000000000000000028c610000000000000000000000006e67512014d5790a7bdf08c0ba7e82aab60d65ed0000000000000000000000006e67512014d5790a7bdf08c0ba7e82aab60d65ed000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a0e900227c51d6299f9672052b312c7aff2dff5e18bd4713847616a3f62f9f6c81a053c2c3e2e3c392a780fba214ce63861c1103f6abb43f4b5115ad5fcc00507cf1", + "0x02f90159824268088459682f0084b8522d738302edbd942259662ed5de0e09943abe701bc5f5a108eabbaa870e7dd43209f000b8e4b84d9ffe0000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000095e56c8d9b8bf98e7452e9225d6273a1a32668b000000000000000000000000095e56c8d9b8bf98e7452e9225d6273a1a32668b000000000000000000000000000000000000000000000000000e7dd43209f000000000000000000000000000a960d72f83a8a163412520a778b437ac5211a50100000000000000000000000000000000000000000000000000000000000f42700000000000000000000000000000000000000000000000008ac7230489e80000c080a043cc1c3651edd72564b5508f19a24b0401bdbfc2ba579ca2086b4d2fe3f7bcf9a04d9af7e243374c4901bbb344d05fca78e5c90cd2dfca7236432dd008cfcc92be", + "0xf8ab28849882c37f83035d4794329d0c4a58b3cefdb40c5513e155228f6cc7b6c580b84447e7ef240000000000000000000000001317106dd45ff0eb911e9f0af78d63fbf9076f6900000000000000000000000000000000000000000000000098a7d9b8314c00008284f4a0ee18c1ee02122b8421779c698a1cdc5e63e8e42a44bc25f37789011ebc01dc4da013dad06cb753611c2e446d91db5e45da3d3375d315bfc26913fb825808772308", + "0x02f8b28242680584828ef14b84896e0b788301154594a960d72f83a8a163412520a778b437ac5211a50180b844095ea7b30000000000000000000000002259662ed5de0e09943abe701bc5f5a108eabbaa000000000000000000000000000000000000000000000002b5e3af16b1880000c080a08b1f426843aefed8770c8016264c7b5b5134607d8dec31bc3321f8e6a093a6b6a0061feb7d2304228bdb86dd7e498f5e76b9c730b49e036ed05cc696d798f1b7fb", + "0x02f85a824268820be1843b9aca0084db476b2e82d221808080c001a05a9f4e596b9d2ac079eba506c32addd5a24f80e4580dca298a4afd4344ad625fa07d1010717490d7b9f0d2acd17bae67121ace281d0dd732d32734d049138242b6", + "0x02f90161824268830129b4843b9aca0084d9cb72168260a094ff0000000000000000000000000000000004206980b8f100df4fb16ea80754f2287ee4565cc006ee0000000000d978dadae1cff0c367c1b3a52e2a0ad9866782573ebe68a17d4c7ddb5533bbd47abbd0ef1792963498a7e4368bb1892db8b2e5c87fefb3734d1f6c9c18cd2b26e2b060c57cfff73d8e219d2215ca85c2738d5ad2f4d74c3a003150f1eedfbb72b7a31363eebe3cf570b988cde91feccf5c0f3eabf97b22ea5daadb3f0da20d9c0235f0c0ad4d0dee6fa42c45cefd639977fabe5b422ecbdf2b91e90db605496959899f198836701ad4406d53ce02e57bfbeed904df48d63922b0c1d73d769e91ecef258c1f3ae74554eafc27dac0190700010000ffff9dfa9a3801c001a06ffba60ee97b5264f73b25590defcd27cd8f6ca33342b2fa3ae4ac4d470c21d6a01c1966a7d1caf328f2c47ae2b7ec0b5e41ce03efd3f5df34e001e650d78f982f", + "0x02f9041582426882fc44843b9aca0084d9cb7216832dc6c09479c9109b764609df928d16fc4a91e9081f7e87db80b903a410d008bd000000000000000000000000000000000000000000000000000000000000f72a00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000340dae5b038c23dc1809dfd17938cd437468f78c4a1322cae884b415504c626357507c06c8f184d05952618ec810dc471e652efa75ec9147bc9438f75bc58bfbeef0141fc19aaf5b3519865b6c18216540940bc84f8583819a42c02da2140255e09302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd0000000000000000000000001670090000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000000f72a000000000000000000000000000000000000000000000000000000000e4e1c0000000000000000000000000000000000000000000000000000000000662fb1f4000000000000000000000000000000000000000000000000000000000016067b000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000014f9054c34b3bf622e6c888adfbf254d320f4adeafc5abd1df283ee73ebe97eb6000000000000000000000000ed1ba0ba5661d648c7b3988dac473f60403aff1e4e2a2708544396232c9e2d1eb73802101b01a57261ffbf01e17182a2cfec39b5dc2daedc29ee57ab6c3bfc57c6136264aecbffb5e3a5c13adeb1995a199507f9f6cfa5d24de1ab0307d1d207ff3220ca8b5ccb9798f14383c5f3b6f07ce8765b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c080a04a664f4e808f111c09aca1ae132c2d65e0bd1d4d3655cd108c2e7d7eb46dcd3ea0434d5a91ab13321782c2bb7d5d9843cff6d799ecb8dd9039ced35b8ba4612c32", + "0x02f9041582426882fc45843b9aca0084db476b2e832dc6c09479c9109b764609df928d16fc4a91e9081f7e87db80b903a410d008bd000000000000000000000000000000000000000000000000000000000000f72b000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003404bbdd910a94aaf2a080fa6bc5ce3113c3425a4bcadd038f0501ab7b87632811f1db66e40e2e0bb1b62385b2c78e9d7772b6dbdd282e7d04af15f57125fcc03c901c1ac3b4f9c070d777c54009e851e7b911f862c022a1e165fc07950ab86105f302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd0000000000000000000000001670090000000000000000000000000000010001000000000000000000000000000000000000000000000000000000000000f72b000000000000000000000000000000000000000000000000000000000e4e1c0000000000000000000000000000000000000000000000000000000000662fb20c000000000000000000000000000000000000000000000000000000000016067c00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000001c897a2ea3a0d319fbd3a46bef9187af945931bf002470d18eb3b77ba202b3bc9000000000000000000000000ed1ba0ba5661d648c7b3988dac473f60403aff1edc2daedc29ee57ab6c3bfc57c6136264aecbffb5e3a5c13adeb1995a199507f9831933655a60d00a5b336696d83826679ccaa749a2794b2aceb6e084c217cb953e542e3c35b607a7ad9c8db7d0569b24eab16556b05cd465ed6cbc4ae76c473c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c001a02651171825383a05dc1cf0379f8551122d4c549bf11ee095437ab44ea70cea56a06bc0dd6c8c4a9be765bd39cab7bb89ef561da569ec428c2f5a355e4bafb06274", + "0x02f8b28242681584833dfc1984833dfc1983023e0f94329d0c4a58b3cefdb40c5513e155228f6cc7b6c580b84447e7ef240000000000000000000000001317106dd45ff0eb911e9f0af78d63fbf9076f6900000000000000000000000000000000000000000000010f0cf064dd59200000c080a03f2331397810c242c6dceb04da663cd888698464a65c9cfa6246df75c5f6683fa0091925d9511b35538687d7daace5207d3a9b20c8526a63df06fc0daf9d8ce87e", + "0xf88a0184771b1b01830123a994a960d72f83a8a163412520a778b437ac5211a50180a46a62784200000000000000000000000015623ada54d0dc6775d2c85d52ab073f6c5759048284f3a02969a4fb6cf10fd6ccd1c6d97b2af55ca7a46cf862d5060e5d4422768fcc73b0a05647eb002fd9f7066487ab9ccb982de5b3cee6ae01e04ea67e7c8328308ffbb7", + "0xf8ab29846cde238a8303568a94329d0c4a58b3cefdb40c5513e155228f6cc7b6c580b84447e7ef240000000000000000000000001317106dd45ff0eb911e9f0af78d63fbf9076f69000000000000000000000000000000000000000000000001314fb370629800008284f3a09a2b229dbaf4244b96ec0b4d06faea869debb247f6a435e8d228456c1a31354da0070aec75b532709220ddb4afb4030e2fb461dc6dacc4718eec6691d402eb7d73", + "0x02f8b28242680e845f5e32c1845f5e32c183023e3b94329d0c4a58b3cefdb40c5513e155228f6cc7b6c580b84447e7ef240000000000000000000000001317106dd45ff0eb911e9f0af78d63fbf9076f6900000000000000000000000000000000000000000000003635c9adc5dea00000c080a05e6460fe3120735d3522fb00db2312a469bdde9808b9d13b63f4fcc9d0d876b2a055e292785562b2d3818aa7345b3896956526fda5c1d59fb597922442adfc684d", + "0xf9021305845b9eb2508301895e94a098b76a3dd499d3f6d58d8accafc8efbfd06807871cd82ffeee7000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c35110000000000000000000000002ad1f51d91bd020d32af3315dbbc45052f5a0ef400000000000000000000000000000000000000000000000000000000000042680000000000000000000000002ad1f51d91bd020d32af3315dbbc45052f5a0ef40000000000000000000000000000000000000000000000000000000000028c610000000000000000000000002ad1f51d91bd020d32af3315dbbc45052f5a0ef40000000000000000000000002ad1f51d91bd020d32af3315dbbc45052f5a0ef40000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000008284f3a0d3e31f92e635c759e5a2cd2de90bd43676e18ef8fd1309326ee8dae6461545d4a054391dbde98a29c8a5f91f3bcd6885489d71a8a7eec130a5639899ca4e33dba6", + "0xf92d0480845b9eb25083255fd08080b92cb0608060405234801561000f575f80fd5b50604051612bf0380380612bf0833981810160405281019061003191906102ec565b338282815f9081610042919061056f565b508060019081610052919061056f565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036100c5575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016100bc919061067d565b60405180910390fd5b6100d4816100dc60201b60201c565b505050610696565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6101fe826101b8565b810181811067ffffffffffffffff8211171561021d5761021c6101c8565b5b80604052505050565b5f61022f61019f565b905061023b82826101f5565b919050565b5f67ffffffffffffffff82111561025a576102596101c8565b5b610263826101b8565b9050602081019050919050565b8281835e5f83830152505050565b5f61029061028b84610240565b610226565b9050828152602081018484840111156102ac576102ab6101b4565b5b6102b7848285610270565b509392505050565b5f82601f8301126102d3576102d26101b0565b5b81516102e384826020860161027e565b91505092915050565b5f8060408385031215610302576103016101a8565b5b5f83015167ffffffffffffffff81111561031f5761031e6101ac565b5b61032b858286016102bf565b925050602083015167ffffffffffffffff81111561034c5761034b6101ac565b5b610358858286016102bf565b9150509250929050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806103b057607f821691505b6020821081036103c3576103c261036c565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026104257fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826103ea565b61042f86836103ea565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f61047361046e61046984610447565b610450565b610447565b9050919050565b5f819050919050565b61048c83610459565b6104a06104988261047a565b8484546103f6565b825550505050565b5f90565b6104b46104a8565b6104bf818484610483565b505050565b5b818110156104e2576104d75f826104ac565b6001810190506104c5565b5050565b601f821115610527576104f8816103c9565b610501846103db565b81016020851015610510578190505b61052461051c856103db565b8301826104c4565b50505b505050565b5f82821c905092915050565b5f6105475f198460080261052c565b1980831691505092915050565b5f61055f8383610538565b9150826002028217905092915050565b61057882610362565b67ffffffffffffffff811115610591576105906101c8565b5b61059b8254610399565b6105a68282856104e6565b5f60209050601f8311600181146105d7575f84156105c5578287015190505b6105cf8582610554565b865550610636565b601f1984166105e5866103c9565b5f5b8281101561060c578489015182556001820191506020850194506020810190506105e7565b868310156106295784890151610625601f891682610538565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6106678261063e565b9050919050565b6106778161065d565b82525050565b5f6020820190506106905f83018461066e565b92915050565b61254d806106a35f395ff3fe608060405234801561000f575f80fd5b5060043610610109575f3560e01c8063715018a6116100a0578063b88d4fde1161006f578063b88d4fde146102a1578063c87b56dd146102bd578063d0def521146102ed578063e985e9c51461031d578063f2fde38b1461034d57610109565b8063715018a61461023f5780638da5cb5b1461024957806395d89b4114610267578063a22cb4651461028557610109565b806323b872dd116100dc57806323b872dd146101a757806342842e0e146101c35780636352211e146101df57806370a082311461020f57610109565b806301ffc9a71461010d57806306fdde031461013d578063081812fc1461015b578063095ea7b31461018b575b5f80fd5b61012760048036038101906101229190611a20565b610369565b6040516101349190611a65565b60405180910390f35b6101456103c9565b6040516101529190611aee565b60405180910390f35b61017560048036038101906101709190611b41565b610458565b6040516101829190611bab565b60405180910390f35b6101a560048036038101906101a09190611bee565b610473565b005b6101c160048036038101906101bc9190611c2c565b610489565b005b6101dd60048036038101906101d89190611c2c565b610588565b005b6101f960048036038101906101f49190611b41565b6105a7565b6040516102069190611bab565b60405180910390f35b61022960048036038101906102249190611c7c565b6105b8565b6040516102369190611cb6565b60405180910390f35b61024761066e565b005b610251610681565b60405161025e9190611bab565b60405180910390f35b61026f6106a9565b60405161027c9190611aee565b60405180910390f35b61029f600480360381019061029a9190611cf9565b610739565b005b6102bb60048036038101906102b69190611e63565b61074f565b005b6102d760048036038101906102d29190611b41565b61076c565b6040516102e49190611aee565b60405180910390f35b61030760048036038101906103029190611f81565b610877565b6040516103149190611cb6565b60405180910390f35b61033760048036038101906103329190611fdb565b6108b7565b6040516103449190611a65565b60405180910390f35b61036760048036038101906103629190611c7c565b610945565b005b5f634906490660e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806103c257506103c1826109c9565b5b9050919050565b60605f80546103d790612046565b80601f016020809104026020016040519081016040528092919081815260200182805461040390612046565b801561044e5780601f106104255761010080835404028352916020019161044e565b820191905f5260205f20905b81548152906001019060200180831161043157829003601f168201915b5050505050905090565b5f61046282610aaa565b5061046c82610b30565b9050919050565b6104858282610480610b69565b610b70565b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036104f9575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016104f09190611bab565b60405180910390fd5b5f61050c8383610507610b69565b610b82565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610582578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161057993929190612076565b60405180910390fd5b50505050565b6105a283838360405180602001604052805f81525061074f565b505050565b5f6105b182610aaa565b9050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610629575f6040517f89c62b640000000000000000000000000000000000000000000000000000000081526004016106209190611bab565b60405180910390fd5b60035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610676610d8d565b61067f5f610e14565b565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546106b890612046565b80601f01602080910402602001604051908101604052809291908181526020018280546106e490612046565b801561072f5780601f106107065761010080835404028352916020019161072f565b820191905f5260205f20905b81548152906001019060200180831161071257829003601f168201915b5050505050905090565b61074b610744610b69565b8383610ed7565b5050565b61075a848484610489565b61076684848484611040565b50505050565b606061077782610aaa565b505f60065f8481526020019081526020015f20805461079590612046565b80601f01602080910402602001604051908101604052809291908181526020018280546107c190612046565b801561080c5780601f106107e35761010080835404028352916020019161080c565b820191905f5260205f20905b8154815290600101906020018083116107ef57829003601f168201915b505050505090505f61081c6111f2565b90505f815103610830578192505050610872565b5f8251111561086457808260405160200161084c9291906120e5565b60405160208183030381529060405292505050610872565b61086d84611208565b925050505b919050565b5f610880610d8d565b5f60085f81548092919061089390612135565b9190505590506108a3848261126e565b6108ad8184611361565b8091505092915050565b5f60055f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b61094d610d8d565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109bd575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016109b49190611bab565b60405180910390fd5b6109c681610e14565b50565b5f7f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a9357507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610aa35750610aa2826113bb565b5b9050919050565b5f80610ab583611424565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b2757826040517f7e273289000000000000000000000000000000000000000000000000000000008152600401610b1e9190611cb6565b60405180910390fd5b80915050919050565b5f60045f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b5f33905090565b610b7d838383600161145d565b505050565b5f80610b8d84611424565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614610bce57610bcd81848661161c565b5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610c5957610c0d5f855f8061145d565b600160035f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825403925050819055505b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610cd857600160035f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8460025f8681526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b610d95610b69565b73ffffffffffffffffffffffffffffffffffffffff16610db3610681565b73ffffffffffffffffffffffffffffffffffffffff1614610e1257610dd6610b69565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610e099190611bab565b60405180910390fd5b565b5f60075f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160075f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f4757816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401610f3e9190611bab565b60405180910390fd5b8060055f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516110339190611a65565b60405180910390a3505050565b5f8373ffffffffffffffffffffffffffffffffffffffff163b11156111ec578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02611083610b69565b8685856040518563ffffffff1660e01b81526004016110a594939291906121ce565b6020604051808303815f875af19250505080156110e057506040513d601f19601f820116820180604052508101906110dd919061222c565b60015b611161573d805f811461110e576040519150601f19603f3d011682016040523d82523d5f602084013e611113565b606091505b505f81510361115957836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016111509190611bab565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146111ea57836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016111e19190611bab565b60405180910390fd5b505b50505050565b606060405180602001604052805f815250905090565b606061121382610aaa565b505f61121d6111f2565b90505f81511161123b5760405180602001604052805f815250611266565b80611245846116df565b6040516020016112569291906120e5565b6040516020818303038152906040525b915050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036112de575f6040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016112d59190611bab565b60405180910390fd5b5f6112ea83835f610b82565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461135c575f6040517f73c6ac6e0000000000000000000000000000000000000000000000000000000081526004016113539190611bab565b60405180910390fd5b505050565b8060065f8481526020019081526020015f20908161137f91906123f4565b507ff8e1a15aba9398e019f0b49df1a4fde98ee17ae345cb5f6b5e2c27f5033e8ce7826040516113af9190611cb6565b60405180910390a15050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b5f60025f8381526020019081526020015f205f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b808061149557505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156115c7575f6114a484610aaa565b90505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561150e57508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015611521575061151f81846108b7565b155b1561156357826040517fa9fbf51f00000000000000000000000000000000000000000000000000000000815260040161155a9190611bab565b60405180910390fd5b81156115c557838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b8360045f8581526020019081526020015f205f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b6116278383836117a9565b6116da575f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361169b57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016116929190611cb6565b60405180910390fd5b81816040517f177e802f0000000000000000000000000000000000000000000000000000000081526004016116d19291906124c3565b60405180910390fd5b505050565b60605f60016116ed84611869565b0190505f8167ffffffffffffffff81111561170b5761170a611d3f565b5b6040519080825280601f01601f19166020018201604052801561173d5781602001600182028036833780820191505090505b5090505f82602001820190505b60011561179e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581611793576117926124ea565b5b0494505f850361174a575b819350505050919050565b5f8073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561186057508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611821575061182084846108b7565b5b8061185f57508273ffffffffffffffffffffffffffffffffffffffff1661184783610b30565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106118c5577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816118bb576118ba6124ea565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611902576d04ee2d6d415b85acef810000000083816118f8576118f76124ea565b5b0492506020810190505b662386f26fc10000831061193157662386f26fc100008381611927576119266124ea565b5b0492506010810190505b6305f5e100831061195a576305f5e10083816119505761194f6124ea565b5b0492506008810190505b612710831061197f576127108381611975576119746124ea565b5b0492506004810190505b606483106119a25760648381611998576119976124ea565b5b0492506002810190505b600a83106119b1576001810190505b80915050919050565b5f604051905090565b5f80fd5b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6119ff816119cb565b8114611a09575f80fd5b50565b5f81359050611a1a816119f6565b92915050565b5f60208284031215611a3557611a346119c3565b5b5f611a4284828501611a0c565b91505092915050565b5f8115159050919050565b611a5f81611a4b565b82525050565b5f602082019050611a785f830184611a56565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f611ac082611a7e565b611aca8185611a88565b9350611ada818560208601611a98565b611ae381611aa6565b840191505092915050565b5f6020820190508181035f830152611b068184611ab6565b905092915050565b5f819050919050565b611b2081611b0e565b8114611b2a575f80fd5b50565b5f81359050611b3b81611b17565b92915050565b5f60208284031215611b5657611b556119c3565b5b5f611b6384828501611b2d565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f611b9582611b6c565b9050919050565b611ba581611b8b565b82525050565b5f602082019050611bbe5f830184611b9c565b92915050565b611bcd81611b8b565b8114611bd7575f80fd5b50565b5f81359050611be881611bc4565b92915050565b5f8060408385031215611c0457611c036119c3565b5b5f611c1185828601611bda565b9250506020611c2285828601611b2d565b9150509250929050565b5f805f60608486031215611c4357611c426119c3565b5b5f611c5086828701611bda565b9350506020611c6186828701611bda565b9250506040611c7286828701611b2d565b9150509250925092565b5f60208284031215611c9157611c906119c3565b5b5f611c9e84828501611bda565b91505092915050565b611cb081611b0e565b82525050565b5f602082019050611cc95f830184611ca7565b92915050565b611cd881611a4b565b8114611ce2575f80fd5b50565b5f81359050611cf381611ccf565b92915050565b5f8060408385031215611d0f57611d0e6119c3565b5b5f611d1c85828601611bda565b9250506020611d2d85828601611ce5565b9150509250929050565b5f80fd5b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611d7582611aa6565b810181811067ffffffffffffffff82111715611d9457611d93611d3f565b5b80604052505050565b5f611da66119ba565b9050611db28282611d6c565b919050565b5f67ffffffffffffffff821115611dd157611dd0611d3f565b5b611dda82611aa6565b9050602081019050919050565b828183375f83830152505050565b5f611e07611e0284611db7565b611d9d565b905082815260208101848484011115611e2357611e22611d3b565b5b611e2e848285611de7565b509392505050565b5f82601f830112611e4a57611e49611d37565b5b8135611e5a848260208601611df5565b91505092915050565b5f805f8060808587031215611e7b57611e7a6119c3565b5b5f611e8887828801611bda565b9450506020611e9987828801611bda565b9350506040611eaa87828801611b2d565b925050606085013567ffffffffffffffff811115611ecb57611eca6119c7565b5b611ed787828801611e36565b91505092959194509250565b5f67ffffffffffffffff821115611efd57611efc611d3f565b5b611f0682611aa6565b9050602081019050919050565b5f611f25611f2084611ee3565b611d9d565b905082815260208101848484011115611f4157611f40611d3b565b5b611f4c848285611de7565b509392505050565b5f82601f830112611f6857611f67611d37565b5b8135611f78848260208601611f13565b91505092915050565b5f8060408385031215611f9757611f966119c3565b5b5f611fa485828601611bda565b925050602083013567ffffffffffffffff811115611fc557611fc46119c7565b5b611fd185828601611f54565b9150509250929050565b5f8060408385031215611ff157611ff06119c3565b5b5f611ffe85828601611bda565b925050602061200f85828601611bda565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061205d57607f821691505b6020821081036120705761206f612019565b5b50919050565b5f6060820190506120895f830186611b9c565b6120966020830185611ca7565b6120a36040830184611b9c565b949350505050565b5f81905092915050565b5f6120bf82611a7e565b6120c981856120ab565b93506120d9818560208601611a98565b80840191505092915050565b5f6120f082856120b5565b91506120fc82846120b5565b91508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61213f82611b0e565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361217157612170612108565b5b600182019050919050565b5f81519050919050565b5f82825260208201905092915050565b5f6121a08261217c565b6121aa8185612186565b93506121ba818560208601611a98565b6121c381611aa6565b840191505092915050565b5f6080820190506121e15f830187611b9c565b6121ee6020830186611b9c565b6121fb6040830185611ca7565b818103606083015261220d8184612196565b905095945050505050565b5f81519050612226816119f6565b92915050565b5f60208284031215612241576122406119c3565b5b5f61224e84828501612218565b91505092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026122b37fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82612278565b6122bd8683612278565b95508019841693508086168417925050509392505050565b5f819050919050565b5f6122f86122f36122ee84611b0e565b6122d5565b611b0e565b9050919050565b5f819050919050565b612311836122de565b61232561231d826122ff565b848454612284565b825550505050565b5f90565b61233961232d565b612344818484612308565b505050565b5b818110156123675761235c5f82612331565b60018101905061234a565b5050565b601f8211156123ac5761237d81612257565b61238684612269565b81016020851015612395578190505b6123a96123a185612269565b830182612349565b50505b505050565b5f82821c905092915050565b5f6123cc5f19846008026123b1565b1980831691505092915050565b5f6123e483836123bd565b9150826002028217905092915050565b6123fd82611a7e565b67ffffffffffffffff81111561241657612415611d3f565b5b6124208254612046565b61242b82828561236b565b5f60209050601f83116001811461245c575f841561244a578287015190505b61245485826123d9565b8655506124bb565b601f19841661246a86612257565b5f5b828110156124915784890151825560018201915060208501945060208101905061246c565b868310156124ae57848901516124aa601f8916826123bd565b8355505b6001600288020188555050505b505050505050565b5f6040820190506124d65f830185611b9c565b6124e36020830184611ca7565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffdfea26469706673582212202540ee918e4df6d1e3653efd3abe64ef363173095adc5bd653b560c0f749995164736f6c634300081900330000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000074d6174746865770000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000074d415454484557000000000000000000000000000000000000000000000000008284f4a071b604531db364037eaaf0dd2431ae0b7e667519365af3a1401759eb1a4b8996a0757269eea2c8313086763bec2f8f6723cf5543552d1a944837d1a519d44278d6", + "0xf88a01845b9eb250830123a994a960d72f83a8a163412520a778b437ac5211a50180a46a62784200000000000000000000000005bfdb392ec297ad9c7f59cb7f8a6deaa61e17028284f3a04a3c1832ede501709d75fbd53106ec952ed548497b80272dd6da55303ea16102a055fd8435624a6bbc4eac4679af29d2c5b006c448ccf53be1e4aa4fdb7a2a713e", + "0xf8aa04845b9eb25082c1309435d648ec326ec0f3cac402995b0a55e9bf21c4bb80b844095ea7b3000000000000000000000000046b82d9010b534c716742be98ac3fef3f2ec99f00000000000000000000000000000000000000000000000000000000000000008284f3a068bd634265da978a24a0305b5420c0b83c10e465f817150ee2861103315b7ee1a060f937b85236735cec375f68b196e07eb767519091f9f80141c13e9bf618684f", + "0xf8aa04845b9eb25082c13094414c9a4ff84e6a7f610eb5846dedb5ea156a60b180b844095ea7b3000000000000000000000000046b82d9010b534c716742be98ac3fef3f2ec99f00000000000000000000000000000000000000000000000000000000000000008284f4a07b13701ae918cf8d5ef348732dc5794637055531177cd76d8ad300d9d9fde501a01581870cac3348561e0c8df10bc51a60af59ffa9ce05d8508b0db55c78e91faa", + "0xf9170008845ae0b5c4831b9d648080b916ac6101606040523480156200001257600080fd5b50604051620015ec380380620015ec833981016040819052620000359162000286565b6040805180820190915260018152603160f81b602082015282908190818460036200006183826200037f565b5060046200007082826200037f565b50620000829150839050600562000134565b610120526200009381600662000134565b61014052815160208084019190912060e052815190820120610100524660a0526200012160e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c05250620004a5915050565b600060208351101562000154576200014c836200016d565b905062000167565b816200016184826200037f565b5060ff90505b92915050565b600080829050601f81511115620001a4578260405163305a27a960e01b81526004016200019b91906200044b565b60405180910390fd5b8051620001b18262000480565b179392505050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620001ec578181015183820152602001620001d2565b50506000910152565b600082601f8301126200020757600080fd5b81516001600160401b0380821115620002245762000224620001b9565b604051601f8301601f19908116603f011681019082821181831017156200024f576200024f620001b9565b816040528381528660208588010111156200026957600080fd5b6200027c846020830160208901620001cf565b9695505050505050565b600080604083850312156200029a57600080fd5b82516001600160401b0380821115620002b257600080fd5b620002c086838701620001f5565b93506020850151915080821115620002d757600080fd5b50620002e685828601620001f5565b9150509250929050565b600181811c908216806200030557607f821691505b6020821081036200032657634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200037a57600081815260208120601f850160051c81016020861015620003555750805b601f850160051c820191505b81811015620003765782815560010162000361565b5050505b505050565b81516001600160401b038111156200039b576200039b620001b9565b620003b381620003ac8454620002f0565b846200032c565b602080601f831160018114620003eb5760008415620003d25750858301515b600019600386901b1c1916600185901b17855562000376565b600085815260208120601f198616915b828110156200041c57888601518255948401946001909101908401620003fb565b50858210156200043b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60208152600082518060208401526200046c816040850160208701620001cf565b601f01601f19169190910160400192915050565b80516020808301519190811015620003265760001960209190910360031b1b16919050565b60805160a05160c05160e0516101005161012051610140516110ec6200050060003960006107b90152600061078c015260006107340152600061070c0152600061066701526000610691015260006106bb01526110ec6000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80637ecebe001161008c578063a0712d6811610066578063a0712d68146101cb578063a9059cbb146101e0578063d505accf146101f3578063dd62ed3e1461020657600080fd5b80637ecebe001461019557806384b0196e146101a857806395d89b41146101c357600080fd5b806323b872dd116100c857806323b872dd14610142578063313ce567146101555780633644e5151461016457806370a082311461016c57600080fd5b806306fdde03146100ef578063095ea7b31461010d57806318160ddd14610130575b600080fd5b6100f761023f565b6040516101049190610e1d565b60405180910390f35b61012061011b366004610e53565b6102d1565b6040519015158152602001610104565b6002545b604051908152602001610104565b610120610150366004610e7d565b6102eb565b60405160128152602001610104565b61013461030f565b61013461017a366004610eb9565b6001600160a01b031660009081526020819052604090205490565b6101346101a3366004610eb9565b61031e565b6101b061033c565b6040516101049796959493929190610ed4565b6100f761039e565b6101de6101d9366004610f86565b6103ad565b005b6101206101ee366004610e53565b6103ba565b6101de610201366004610f9f565b6103c8565b610134610214366004611012565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60606003805461024e90611045565b80601f016020809104026020016040519081016040528092919081815260200182805461027a90611045565b80156102c75780601f1061029c576101008083540402835291602001916102c7565b820191906000526020600020905b8154815290600101906020018083116102aa57829003601f168201915b5050505050905090565b6000336102df818585610539565b60019150505b92915050565b6000336102f985828561054b565b6103048585856105e2565b506001949350505050565b600061031961065a565b905090565b6001600160a01b0381166000908152600760205260408120546102e5565b600060608060008060006060610350610785565b6103586107b2565b604080516000808252602082019092527f0f000000000000000000000000000000000000000000000000000000000000009b939a50919850469750309650945092509050565b60606004805461024e90611045565b6103b733826107df565b50565b6000336102df8185856105e2565b8342111561040a576040517f62791302000000000000000000000000000000000000000000000000000000008152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886104578c6001600160a01b0316600090815260076020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006104b282610819565b905060006104c282878787610861565b9050896001600160a01b0316816001600160a01b031614610522576040517f4b800e460000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301528b166024820152604401610401565b61052d8a8a8a610539565b50505050505050505050565b610546838383600161088f565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146105dc57818110156105cd576040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201526024810182905260448101839052606401610401565b6105dc8484848403600061088f565b50505050565b6001600160a01b038316610625576040517f96c6fd1e00000000000000000000000000000000000000000000000000000000815260006004820152602401610401565b6001600160a01b03821661064f5760405163ec442f0560e01b815260006004820152602401610401565b610546838383610996565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480156106b357507f000000000000000000000000000000000000000000000000000000000000000046145b156106dd57507f000000000000000000000000000000000000000000000000000000000000000090565b610319604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60606103197f00000000000000000000000000000000000000000000000000000000000000006005610ad9565b60606103197f00000000000000000000000000000000000000000000000000000000000000006006610ad9565b6001600160a01b0382166108095760405163ec442f0560e01b815260006004820152602401610401565b61081560008383610996565b5050565b60006102e561082661065a565b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b60008060008061087388888888610b84565b9250925092506108838282610c53565b50909695505050505050565b6001600160a01b0384166108d2576040517fe602df0500000000000000000000000000000000000000000000000000000000815260006004820152602401610401565b6001600160a01b038316610915576040517f94280d6200000000000000000000000000000000000000000000000000000000815260006004820152602401610401565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156105dc57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161098891815260200190565b60405180910390a350505050565b6001600160a01b0383166109c15780600260008282546109b6919061107f565b90915550610a4c9050565b6001600160a01b03831660009081526020819052604090205481811015610a2d576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526024810182905260448101839052606401610401565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610a6857600280548290039055610a87565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610acc91815260200190565b60405180910390a3505050565b606060ff8314610af357610aec83610d57565b90506102e5565b818054610aff90611045565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2b90611045565b8015610b785780601f10610b4d57610100808354040283529160200191610b78565b820191906000526020600020905b815481529060010190602001808311610b5b57829003601f168201915b505050505090506102e5565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610bbf5750600091506003905082610c49565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610c13573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610c3f57506000925060019150829050610c49565b9250600091508190505b9450945094915050565b6000826003811115610c6757610c676110a0565b03610c70575050565b6001826003811115610c8457610c846110a0565b03610cbb576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002826003811115610ccf57610ccf6110a0565b03610d09576040517ffce698f700000000000000000000000000000000000000000000000000000000815260048101829052602401610401565b6003826003811115610d1d57610d1d6110a0565b03610815576040517fd78bce0c00000000000000000000000000000000000000000000000000000000815260048101829052602401610401565b60606000610d6483610d96565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156102e5576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815180845260005b81811015610dfd57602081850181015186830182015201610de1565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610e306020830184610dd7565b9392505050565b80356001600160a01b0381168114610e4e57600080fd5b919050565b60008060408385031215610e6657600080fd5b610e6f83610e37565b946020939093013593505050565b600080600060608486031215610e9257600080fd5b610e9b84610e37565b9250610ea960208501610e37565b9150604084013590509250925092565b600060208284031215610ecb57600080fd5b610e3082610e37565b7fff00000000000000000000000000000000000000000000000000000000000000881681526000602060e081840152610f1060e084018a610dd7565b8381036040850152610f22818a610dd7565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b81811015610f7457835183529284019291840191600101610f58565b50909c9b505050505050505050505050565b600060208284031215610f9857600080fd5b5035919050565b600080600080600080600060e0888a031215610fba57600080fd5b610fc388610e37565b9650610fd160208901610e37565b95506040880135945060608801359350608088013560ff81168114610ff557600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561102557600080fd5b61102e83610e37565b915061103c60208401610e37565b90509250929050565b600181811c9082168061105957607f821691505b60208210810361107957634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156102e557634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212206ba9dbff097d43964029a264bd2ded61f9b9a1183e1d6616e68d832b8d30b30664736f6c6343000814003300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000d424552474e41554d546f6b656e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008424552474e41554d0000000000000000000000000000000000000000000000008284f4a08eb7af1c5e2671424865713310182a94f0828d14c60e3a2d77ec5c1d0a09f156a04aa24d97a8be38805c0630188b33eea4ca2d71e2a6b3734127dca58d53edb730", + "0x02f87982426880840cf6051884762e867983042b7c941cf3f95312ad9dbe95ed2eaf3cb352d14bf373d088016345785d8a000084f6326fb3c080a07811c6e650c9f3f2534566757005a6ebd21df200da3a669c4d43989e15309247a06619afe0f08a166f55047797ba6c84fa501181cc173bac78eee36331d403bddd", + "0x02f87982426801840cf6051884762e867983042b7c941cf3f95312ad9dbe95ed2eaf3cb352d14bf373d08801aa535d3d0c000084f6326fb3c001a0a5b074935fa9d5ac46d48ff26a002009735c71ac4268ebf74c388ad2baa0334ea0218377bdd175e157b9493a3eab22ffe7427c8cbdccdb32247791321012932434", + "0x02f87982426883012bd6840bc861b985016e7ac940830f4240949e850cf4d0d75da0020e48e7f9a249285c4097c6880de0b6b3a764000080c080a08b6e72199241f600408887bbe28e1498698819e3b50522ca1a1bde0eba6f38c7a076d5846a2839f62e18bc56dfd02a2cd54a70bc38c49a5669ee67d39f32b02abd", + "0x02f90113824268820d38840bc861b984ab7502e782c93794a44151489861fe9e3055d95adc98fbd462b948e780b8a499be81c80000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004c68747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f63616e6479313236342f656967656e2f6d61696e2f6d657461646174612d6578616d706c652e6a736f6e0000000000000000000000000000000000000000c080a09daba84d17b23778c4b7990f08a67fae121ade09284742c77955b5a288e47343a042ddac5a8a4eee1dbdba6050b70875597907f87d92cf243943f16602aa344d02", + "0x02f94878824268830d6ec4840bc861b984ab7502e7832dc6c094b20bb9105e007bd3e0f73d63d4d3da2c8f736b77820466b94804ef16e8450000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000004a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000006415bda9cebfbb54d81278e6b4c8a160c33bc55302e31382e302d646576000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000041e574f051bd887024b4dee2a7f684d6936c4488000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000662fb96b0000000000000000000000000000000000000000000000000000000000160a830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000046600000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000004660000000000000000000000000000000000000000000000000000000000000190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000412695346f26e0642c0ac74b9f656f54baf9b4dbfb4cd0f9b2768386f95c749abf4ac5693e30b306e46413e703f174433fa7cf733176c6df1af0515956121d3ae31b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042caf942c7b9025802f9025483028c60030e0f8302748494167008000000000000000000000000000000000188040436cd1c122749b901e433bcd0cc000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003499109f1f94e3ef9ee7254c2958aeac530c91a10000000000000000000000000000000000000000000000000000000000028c6000000000000000000000000000000000000000000000000000000000000042680000000000000000000000003499109f1f94e3ef9ee7254c2958aeac530c91a10000000000000000000000003499109f1f94e3ef9ee7254c2958aeac530c91a10000000000000000000000003499109f1f94e3ef9ee7254c2958aeac530c91a100000000000000000000000000000000000000000000000003f4e0f08176c000000000000000000000000000000000000000000000000000000f55dc9a9b674900000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a09db7c36051077d2883dd9bd628da1cbb14d0e7d29e78a753a0fe1010bc00d8b9a07c68e8edc4f2ab412fdbbf75647a0d021bb42535f33d3675cd4852c7bfe60a3eb9049002f9048c83028c60030e0f8304a07294d2c3cbb943fed0cfc8389b14a3f6df518fd4634680b904243593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000662fb31200000000000000000000000000000000000000000000000000000000000000030a000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000160000000000000000000000000ae2c46ddb314b9ba743c6dee4878f151881333d9000000000000000000000000ffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000066573f5c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d2c3cbb943fed0cfc8389b14a3f6df518fd4634600000000000000000000000000000000000000000000000000000000662fb31000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000041cf2eb680c6e0cee02857e22674fa3600eb621470fa2ec1c9239dc17598080d28256604de0a62688433d0b613783022393507210756c07fb5ce6c1b834616edda1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000071e7900000000000000000000000000000000000000000000000000000000000009d900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002bae2c46ddb314b9ba743c6dee4878f151881333d90000640011e559da84dde3f841e22dc33f3adbf184d84a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000009d9c001a0bb02d2d3c04a2c0693007cd5e6cc97b29a7e0aca2ea231a2fbc4c497617eb7c2a0495863e0d8c0033fb9bf4d829513b7d97a4c3ee11f3f1730599efda57a7b4137f8a8260e8301038894ae2c46ddb314b9ba743c6dee4878f151881333d980b844095ea7b3000000000000000000000000b845ccc2e5d29c30313ff274ea85f417b08ef28400000000000000000000000000000000000000000045be6e5c9b3fa3f51c0000830518e4a010e1c5045734a447199c66e8a9f0801ab3b925196ad3bd36619908b66c342d80a079426ede8b1aa6f8e6c11a3fc18cd97ea8719a762bf90be3a51f7650ad6449fcf8871c0e83014ae794dfb36888b73ee7ee3ab5fa4a8cdd92b684c4f8d680a4a0712d68000000000000000000000000000000000000000002778bae47736f6666a00000830518e3a0f70bf19a580f2c075651cfc95927be3089cebc4d675818272731e2a2e8e3d6e6a00b402c5b2bb3ecf8e1d2d3cf71b2746b7e8a7225c2f596b724cff22660c3543af8a7260e82efb3949e60d01f27dea720d39b6978931b689621a7a48f80b844a9059cbb0000000000000000000000002782ff029c442f60b8675fd383bc9624584a631b0000000000000000000000000000000000000000000002003b378d0d6a040000830518e3a00321d787376f61ea1fb0342ba09436dd0233dce3e68ddd6488e0364fb66a8c5ba01290d77c3a6763bcd043cc450d4f99e10b8703369f8b42ebd63c5f615b64ed1df8871a0d8301497994330c4bca2a671cd214a8de82a06d584f2cfa426b80a4a0712d680000000000000000000000000000000000000000000000000000000000000001830518e4a0a8fd4994c33da87a95499c8767be68e35a05e0ca0809bdfb48e38e33d0ce0a65a071335abf14afab76e334ee168e155fddeb108678bb09ec61f03246f2fd9a1da5f8870f0c83015afc947a7ee86c315bff1c3dc77fa5a5024c0c4d5e77d780a4a0712d680000000000000000000000000000000000000000008cf6763cd4d780b2a80000830518e4a08883da5153c45742deb983be5877849948698604e2872fcc284ca46795c7b2bca02d77e6c5a636b6803c617d7254ea4d3f4e3ce0fb5bc70535debd2a3e1948722bf8a7100c82fd1194f19f2bb01144a76b3158c210a948c1a6354cc21680b844095ea7b300000000000000000000000016700800000000000000000000000000000000020000000000000000000000000000000000000000000001833909cec3973c0000830518e3a0b02b4d39c11a068751220cbce769c90080bf35470cdb1afd92bc77aab9974de0a022b786ff1f25376e76bfb6f476c3536efec56eb75ca80e209a00573bd2c39e66f902ee800c8260cb94380a5ba81efe70fe98ab56613ebf9244a2f3d4c986886c98b76000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000662fb31000000000000000000000000000000000000000000000000000000000000000020b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000886c98b76000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000886c98b76000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b0011e559da84dde3f841e22dc33f3adbf184d84a0001f4ae2c46ddb314b9ba743c6dee4878f151881333d9000000000000000000000000000000000000000000830518e3a045ee6fecdd9431da19f6e56e20be4c0a80f692296ebbaeced67e8c7e4d57dfb6a0092c2d1fb43b1dd3c86ba0619b8310d14cda93c527284a84ecec6ee64245abbdf8a7290c82fd1194ce9efe55f3732e178779fdcfe15dd5dc3ab4380d80b844095ea7b30000000000000000000000001670080000000000000000000000000000000002000000000000000000000000000000000000000000000133e9d5b211fac00000830518e3a008a8031fab77a636e1d42e0f6121db499caa2cbaa1d1f9b2f94030e6314d544ea011f17f9454a632077dee13996e531c74ecedc9fb3b6c8ba471b483c8886889baf887140b83011fdb94bc0d81781f66e0aee3d0e27b943dd2bef680c63b80a4a0712d68000000000000000000000000000000000000000001ed6131bb388ef0ff600000830518e3a0940db6fbd72ca9427309d7921ab8a4a205938155739b2246c56729b9cf4acab0a0220d02aeaa03ba885896b980d15980a64f6de07949b1060ab6b3b3763e772629f868080a826d60946f1fa27210d404d3867150fd8380c77bf630aaf6860386739a680080830518e3a032db9f0267038143385f2a977969a2cdfc95de98ebf0feeb0ff7808f79c0d3e2a0187959b5c5846d1e8ca9a526bcf557bc4dcb1fef978a36ddb408ded090fdc22bf867030a826d6094af2863ba47492aa5e6cac4f154d0b351857a097b85f3c610260080830518e3a0f91d8b5cee702dca53ce8767804607b775de92a2382f1b2be916bbb3f0d81021a075c25932dcddb2109e8842c12d7c5f4e7971223cc8c81c97cbefe0d81662a52ff868080a826d60940189a1e959a4e03200e611e116a7f27d380057848605f026b9ca0080830518e3a040b3f5749a0c80f419c695086f110b712241d76ad1799fa4b6d08327375cb4c8a012b42c1dc216dc9058cdae16ddb18696ccee0965aefd2a9ff33db05b3189da6ff8a7190a82c2ce943efe2d67bf39da475226279ce5677cf78211d7fa80b844095ea7b300000000000000000000000016700800000000000000000000000000000000020000000000000000000000000000000000000000000001adab589e4092180000830518e4a09d50f2911031757c22fe17dc390d0d46a2dfc8f2486dbb47175bc54b65defd8da06773fcc94424bc4f8c845c7345e92129559e7be82d0beeb0ffc26fa97eaf9194f916fc0e0a8317e61f8080b916ac6101606040523480156200001257600080fd5b50604051620015ec380380620015ec833981016040819052620000359162000286565b6040805180820190915260018152603160f81b602082015282908190818460036200006183826200037f565b5060046200007082826200037f565b50620000829150839050600562000134565b610120526200009381600662000134565b61014052815160208084019190912060e052815190820120610100524660a0526200012160e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c05250620004a5915050565b600060208351101562000154576200014c836200016d565b905062000167565b816200016184826200037f565b5060ff90505b92915050565b600080829050601f81511115620001a4578260405163305a27a960e01b81526004016200019b91906200044b565b60405180910390fd5b8051620001b18262000480565b179392505050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620001ec578181015183820152602001620001d2565b50506000910152565b600082601f8301126200020757600080fd5b81516001600160401b0380821115620002245762000224620001b9565b604051601f8301601f19908116603f011681019082821181831017156200024f576200024f620001b9565b816040528381528660208588010111156200026957600080fd5b6200027c846020830160208901620001cf565b9695505050505050565b600080604083850312156200029a57600080fd5b82516001600160401b0380821115620002b257600080fd5b620002c086838701620001f5565b93506020850151915080821115620002d757600080fd5b50620002e685828601620001f5565b9150509250929050565b600181811c908216806200030557607f821691505b6020821081036200032657634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200037a57600081815260208120601f850160051c81016020861015620003555750805b601f850160051c820191505b81811015620003765782815560010162000361565b5050505b505050565b81516001600160401b038111156200039b576200039b620001b9565b620003b381620003ac8454620002f0565b846200032c565b602080601f831160018114620003eb5760008415620003d25750858301515b600019600386901b1c1916600185901b17855562000376565b600085815260208120601f198616915b828110156200041c57888601518255948401946001909101908401620003fb565b50858210156200043b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60208152600082518060208401526200046c816040850160208701620001cf565b601f01601f19169190910160400192915050565b80516020808301519190811015620003265760001960209190910360031b1b16919050565b60805160a05160c05160e0516101005161012051610140516110ec6200050060003960006107b90152600061078c015260006107340152600061070c0152600061066701526000610691015260006106bb01526110ec6000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80637ecebe001161008c578063a0712d6811610066578063a0712d68146101cb578063a9059cbb146101e0578063d505accf146101f3578063dd62ed3e1461020657600080fd5b80637ecebe001461019557806384b0196e146101a857806395d89b41146101c357600080fd5b806323b872dd116100c857806323b872dd14610142578063313ce567146101555780633644e5151461016457806370a082311461016c57600080fd5b806306fdde03146100ef578063095ea7b31461010d57806318160ddd14610130575b600080fd5b6100f761023f565b6040516101049190610e1d565b60405180910390f35b61012061011b366004610e53565b6102d1565b6040519015158152602001610104565b6002545b604051908152602001610104565b610120610150366004610e7d565b6102eb565b60405160128152602001610104565b61013461030f565b61013461017a366004610eb9565b6001600160a01b031660009081526020819052604090205490565b6101346101a3366004610eb9565b61031e565b6101b061033c565b6040516101049796959493929190610ed4565b6100f761039e565b6101de6101d9366004610f86565b6103ad565b005b6101206101ee366004610e53565b6103ba565b6101de610201366004610f9f565b6103c8565b610134610214366004611012565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60606003805461024e90611045565b80601f016020809104026020016040519081016040528092919081815260200182805461027a90611045565b80156102c75780601f1061029c576101008083540402835291602001916102c7565b820191906000526020600020905b8154815290600101906020018083116102aa57829003601f168201915b5050505050905090565b6000336102df818585610539565b60019150505b92915050565b6000336102f985828561054b565b6103048585856105e2565b506001949350505050565b600061031961065a565b905090565b6001600160a01b0381166000908152600760205260408120546102e5565b600060608060008060006060610350610785565b6103586107b2565b604080516000808252602082019092527f0f000000000000000000000000000000000000000000000000000000000000009b939a50919850469750309650945092509050565b60606004805461024e90611045565b6103b733826107df565b50565b6000336102df8185856105e2565b8342111561040a576040517f62791302000000000000000000000000000000000000000000000000000000008152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886104578c6001600160a01b0316600090815260076020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006104b282610819565b905060006104c282878787610861565b9050896001600160a01b0316816001600160a01b031614610522576040517f4b800e460000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301528b166024820152604401610401565b61052d8a8a8a610539565b50505050505050505050565b610546838383600161088f565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146105dc57818110156105cd576040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201526024810182905260448101839052606401610401565b6105dc8484848403600061088f565b50505050565b6001600160a01b038316610625576040517f96c6fd1e00000000000000000000000000000000000000000000000000000000815260006004820152602401610401565b6001600160a01b03821661064f5760405163ec442f0560e01b815260006004820152602401610401565b610546838383610996565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480156106b357507f000000000000000000000000000000000000000000000000000000000000000046145b156106dd57507f000000000000000000000000000000000000000000000000000000000000000090565b610319604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60606103197f00000000000000000000000000000000000000000000000000000000000000006005610ad9565b60606103197f00000000000000000000000000000000000000000000000000000000000000006006610ad9565b6001600160a01b0382166108095760405163ec442f0560e01b815260006004820152602401610401565b61081560008383610996565b5050565b60006102e561082661065a565b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b60008060008061087388888888610b84565b9250925092506108838282610c53565b50909695505050505050565b6001600160a01b0384166108d2576040517fe602df0500000000000000000000000000000000000000000000000000000000815260006004820152602401610401565b6001600160a01b038316610915576040517f94280d6200000000000000000000000000000000000000000000000000000000815260006004820152602401610401565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156105dc57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161098891815260200190565b60405180910390a350505050565b6001600160a01b0383166109c15780600260008282546109b6919061107f565b90915550610a4c9050565b6001600160a01b03831660009081526020819052604090205481811015610a2d576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526024810182905260448101839052606401610401565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610a6857600280548290039055610a87565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610acc91815260200190565b60405180910390a3505050565b606060ff8314610af357610aec83610d57565b90506102e5565b818054610aff90611045565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2b90611045565b8015610b785780601f10610b4d57610100808354040283529160200191610b78565b820191906000526020600020905b815481529060010190602001808311610b5b57829003601f168201915b505050505090506102e5565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610bbf5750600091506003905082610c49565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610c13573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610c3f57506000925060019150829050610c49565b9250600091508190505b9450945094915050565b6000826003811115610c6757610c676110a0565b03610c70575050565b6001826003811115610c8457610c846110a0565b03610cbb576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002826003811115610ccf57610ccf6110a0565b03610d09576040517ffce698f700000000000000000000000000000000000000000000000000000000815260048101829052602401610401565b6003826003811115610d1d57610d1d6110a0565b03610815576040517fd78bce0c00000000000000000000000000000000000000000000000000000000815260048101829052602401610401565b60606000610d6483610d96565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156102e5576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815180845260005b81811015610dfd57602081850181015186830182015201610de1565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610e306020830184610dd7565b9392505050565b80356001600160a01b0381168114610e4e57600080fd5b919050565b60008060408385031215610e6657600080fd5b610e6f83610e37565b946020939093013593505050565b600080600060608486031215610e9257600080fd5b610e9b84610e37565b9250610ea960208501610e37565b9150604084013590509250925092565b600060208284031215610ecb57600080fd5b610e3082610e37565b7fff00000000000000000000000000000000000000000000000000000000000000881681526000602060e081840152610f1060e084018a610dd7565b8381036040850152610f22818a610dd7565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b81811015610f7457835183529284019291840191600101610f58565b50909c9b505050505050505050505050565b600060208284031215610f9857600080fd5b5035919050565b600080600080600080600060e0888a031215610fba57600080fd5b610fc388610e37565b9650610fd160208901610e37565b95506040880135945060608801359350608088013560ff81168114610ff557600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561102557600080fd5b61102e83610e37565b915061103c60208401610e37565b90509250929050565b600181811c9082168061105957607f821691505b60208210810361107957634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156102e557634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212206ba9dbff097d43964029a264bd2ded61f9b9a1183e1d6616e68d832b8d30b30664736f6c6343000814003300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000a4d41434559546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054d41434559000000000000000000000000000000000000000000000000000000830518e39f059f0f20ff24777dff897007eb5b7ab04a3412489e4eaf81762bf00b5c2cd4a0623f5bfd35c490abb2e43b3b1e0a3102582c2b404ab4427910a71790a4a83479f868090a826d6094edce1b90c11d4380bc43d7c18251c840cf89eb198601cc4e61fa0080830518e4a0600bf3746846ca46f7b35c956adc78ac9ed196158c48093319c2e4b66db19d3ba0404836a9531279b423e15c084e4ad7a3f7feb811ee1f25ba3c8ceaf047794412f90170060a8307432b94e02d9f7a4c98b707de05ac9dc1cd8b9c13465bb787050aae9f7e6000b90104286fbb9700000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000caff75a9aef512b335f5e4eb7ab62761b5d013b40000000000000000000000000000000000000000000000000000000005a39a80000000000000000000000000e629cc2ca21ae1945dd3e64051627a2dde78b1fc000000000000000000000000caff75a9aef512b335f5e4eb7ab62761b5d013b400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000009787277646f756368630000000000000000000000000000000000000000000000830518e4a0e3440211048d895a4b960dfd5d72e12a630caf943d2a6e15187f837d832a7542a00e0866be61b08422ed54ec1b600a3a7f6d67ea0f2257f40287e3b104e58813eff914ca1a0a831bba1b8080b9147960806040523480156200001157600080fd5b50604051620013b9380380620013b983398101604081905262000034916200011f565b600062000042838262000218565b50600162000051828262000218565b505050620002e4565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200008257600080fd5b81516001600160401b03808211156200009f576200009f6200005a565b604051601f8301601f19908116603f01168101908282118183101715620000ca57620000ca6200005a565b81604052838152602092508683858801011115620000e757600080fd5b600091505b838210156200010b5785820183015181830184015290820190620000ec565b600093810190920192909252949350505050565b600080604083850312156200013357600080fd5b82516001600160401b03808211156200014b57600080fd5b620001598683870162000070565b935060208501519150808211156200017057600080fd5b506200017f8582860162000070565b9150509250929050565b600181811c908216806200019e57607f821691505b602082108103620001bf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200021357600081815260208120601f850160051c81016020861015620001ee5750805b601f850160051c820191505b818110156200020f57828155600101620001fa565b5050505b505050565b81516001600160401b038111156200023457620002346200005a565b6200024c8162000245845462000189565b84620001c5565b602080601f8311600181146200028457600084156200026b5750858301515b600019600386901b1c1916600185901b1785556200020f565b600085815260208120601f198616915b82811015620002b55788860151825594840194600190910190840162000294565b5085821015620002d45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6110c580620002f46000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806370a082311161008c578063a22cb46511610066578063a22cb465146101e1578063b88d4fde146101f4578063c87b56dd14610207578063e985e9c51461021a57600080fd5b806370a08231146101a557806395d89b41146101c6578063a0712d68146101ce57600080fd5b8063095ea7b3116100c8578063095ea7b31461015757806323b872dd1461016c57806342842e0e1461017f5780636352211e1461019257600080fd5b806301ffc9a7146100ef57806306fdde0314610117578063081812fc1461012c575b600080fd5b6101026100fd366004610d36565b610256565b60405190151581526020015b60405180910390f35b61011f6102f3565b60405161010e9190610da3565b61013f61013a366004610db6565b610385565b6040516001600160a01b03909116815260200161010e565b61016a610165366004610deb565b6103ae565b005b61016a61017a366004610e15565b6103bd565b61016a61018d366004610e15565b610466565b61013f6101a0366004610db6565b610486565b6101b86101b3366004610e51565b610491565b60405190815260200161010e565b61011f6104f2565b61016a6101dc366004610db6565b610501565b61016a6101ef366004610e6c565b61050e565b61016a610202366004610ebe565b610519565b61011f610215366004610db6565b610530565b610102610228366004610f9a565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b60006001600160e01b031982167f80ac58cd0000000000000000000000000000000000000000000000000000000014806102b957506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806102ed57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b92915050565b60606000805461030290610fcd565b80601f016020809104026020016040519081016040528092919081815260200182805461032e90610fcd565b801561037b5780601f106103505761010080835404028352916020019161037b565b820191906000526020600020905b81548152906001019060200180831161035e57829003601f168201915b5050505050905090565b6000610390826105a5565b506000828152600460205260409020546001600160a01b03166102ed565b6103b98282336105de565b5050565b6001600160a01b0382166103ec57604051633250574960e11b8152600060048201526024015b60405180910390fd5b60006103f98383336105eb565b9050836001600160a01b0316816001600160a01b031614610460576040517f64283d7b0000000000000000000000000000000000000000000000000000000081526001600160a01b03808616600483015260248201849052821660448201526064016103e3565b50505050565b61048183838360405180602001604052806000815250610519565b505050565b60006102ed826105a5565b60006001600160a01b0382166104d6576040517f89c62b64000000000000000000000000000000000000000000000000000000008152600060048201526024016103e3565b506001600160a01b031660009081526003602052604090205490565b60606001805461030290610fcd565b61050b33826106f1565b50565b6103b933838361076f565b6105248484846103bd565b61046084848484610827565b606061053b826105a5565b50600061055360408051602081019091526000815290565b90506000815111610573576040518060200160405280600081525061059e565b8061057d84610950565b60405160200161058e929190611007565b6040516020818303038152906040525b9392505050565b6000818152600260205260408120546001600160a01b0316806102ed57604051637e27328960e01b8152600481018490526024016103e3565b61048183838360016109f0565b6000828152600260205260408120546001600160a01b039081169083161561061857610618818486610b3b565b6001600160a01b03811615610656576106356000856000806109f0565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b03851615610685576001600160a01b0385166000908152600360205260409020805460010190555b600084815260026020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b6001600160a01b03821661071b57604051633250574960e11b8152600060048201526024016103e3565b6000610729838360006105eb565b90506001600160a01b03811615610481576040517f73c6ac6e000000000000000000000000000000000000000000000000000000008152600060048201526024016103e3565b6001600160a01b0382166107ba576040517f5b08ba180000000000000000000000000000000000000000000000000000000081526001600160a01b03831660048201526024016103e3565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b1561046057604051630a85bd0160e11b81526001600160a01b0384169063150b7a0290610869903390889087908790600401611036565b6020604051808303816000875af19250505080156108a4575060408051601f3d908101601f191682019092526108a191810190611072565b60015b61090d573d8080156108d2576040519150601f19603f3d011682016040523d82523d6000602084013e6108d7565b606091505b50805160000361090557604051633250574960e11b81526001600160a01b03851660048201526024016103e3565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b1461094957604051633250574960e11b81526001600160a01b03851660048201526024016103e3565b5050505050565b6060600061095d83610bb8565b600101905060008167ffffffffffffffff81111561097d5761097d610ea8565b6040519080825280601f01601f1916602001820160405280156109a7576020820181803683370190505b5090508181016020015b600019017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85049450846109b157509392505050565b8080610a0457506001600160a01b03821615155b15610afe576000610a14846105a5565b90506001600160a01b03831615801590610a405750826001600160a01b0316816001600160a01b031614155b8015610a7257506001600160a01b0380821660009081526005602090815260408083209387168352929052205460ff16155b15610ab4576040517fa9fbf51f0000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201526024016103e3565b8115610afc5783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b50506000908152600460205260409020805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b610b46838383610c9a565b610481576001600160a01b038316610b7457604051637e27328960e01b8152600481018290526024016103e3565b6040517f177e802f0000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602481018290526044016103e3565b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310610c01577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310610c2d576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610c4b57662386f26fc10000830492506010015b6305f5e1008310610c63576305f5e100830492506008015b6127108310610c7757612710830492506004015b60648310610c89576064830492506002015b600a83106102ed5760010192915050565b60006001600160a01b03831615801590610d185750826001600160a01b0316846001600160a01b03161480610cf457506001600160a01b0380851660009081526005602090815260408083209387168352929052205460ff165b80610d1857506000828152600460205260409020546001600160a01b038481169116145b949350505050565b6001600160e01b03198116811461050b57600080fd5b600060208284031215610d4857600080fd5b813561059e81610d20565b60005b83811015610d6e578181015183820152602001610d56565b50506000910152565b60008151808452610d8f816020860160208601610d53565b601f01601f19169290920160200192915050565b60208152600061059e6020830184610d77565b600060208284031215610dc857600080fd5b5035919050565b80356001600160a01b0381168114610de657600080fd5b919050565b60008060408385031215610dfe57600080fd5b610e0783610dcf565b946020939093013593505050565b600080600060608486031215610e2a57600080fd5b610e3384610dcf565b9250610e4160208501610dcf565b9150604084013590509250925092565b600060208284031215610e6357600080fd5b61059e82610dcf565b60008060408385031215610e7f57600080fd5b610e8883610dcf565b915060208301358015158114610e9d57600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b60008060008060808587031215610ed457600080fd5b610edd85610dcf565b9350610eeb60208601610dcf565b925060408501359150606085013567ffffffffffffffff80821115610f0f57600080fd5b818701915087601f830112610f2357600080fd5b813581811115610f3557610f35610ea8565b604051601f8201601f19908116603f01168101908382118183101715610f5d57610f5d610ea8565b816040528281528a6020848701011115610f7657600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215610fad57600080fd5b610fb683610dcf565b9150610fc460208401610dcf565b90509250929050565b600181811c90821680610fe157607f821691505b60208210810361100157634e487b7160e01b600052602260045260246000fd5b50919050565b60008351611019818460208801610d53565b83519083019061102d818360208801610d53565b01949350505050565b60006001600160a01b038087168352808616602084015250836040830152608060608301526110686080830184610d77565b9695505050505050565b60006020828403121561108457600080fd5b815161059e81610d2056fea2646970667358221220d76bf7a600b168590dbb876ff007de1a79846940746b4fd6fc9a55a49611cab164736f6c6343000814003300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000957696c6265724e46540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000657494c4245520000000000000000000000000000000000000000000000000000830518e3a062c45fc1c4e466362ad292d04da502d797c8b98cf325fecc8afda014c125cd7da05e18dac43dff85db20470464c25908f958659212735eec68b13290762445d5a3f868090a826d60945b12c00878fb1ae2e4cf0ef348906b55fdfe53cf8608ee659c980080830518e3a0fe13e6cb0cb04de553aa69e3f5838a77c0e26b4788913947cf9bb1cbe745143da03ff630b2a49575632b844e5b328830eeb49b36a91ed3d8c18732973e2a84fe8cf868080a826d609417731b3156b834f8e101cff78e8dc7f9eb2b084d8605581ce4880080830518e4a0b508f223765198edd6c924e6a8c163d9293261ed0aeddb64d4e1ec5e5577d178a05cc851f38edbccc81c0b102f6eaa2b9603b7b48e9d585a196f3114dbf2d2bd3bf868080a826d60946abf99b62110683d2cb9b79db7b36b1f825185a98603edd410c00080830518e3a095f65eabe48771c56efb37520c1391d46e4881c3dbf3c5444d6904514f402b25a02020e19be7a9651cf0c1f7abf9be4ad3769028d35833f0c606fbb24392a428f8f867090a826d6094ed2dfaa8bd752e19f226c0c53b0700c8522943f0860519b6d9100080830518e3a047635bb7f0ab490225a175f6188799ee26b635e0d01df8101c3e78ddf83e163a9f9741362596a5d917ad4677dbf4a949633ec04cb21182a1818c79d65142d76ef8680b0a826d60947622f9d545734a6091de8f12b79f30ca1c7c2636860538370e6e0080830518e4a0533067115930f29f1dcb249f5cf95ac6a2c13b687dd5bd24bf300ec58693bbd1a06cbf82ee6c566f69dc6e32934bdbc4c57af1e55ddb12ad9caeeb4169c6bb081ff886050a82545294d60dbbdfe2095fd286998beacc0b3ce0d4fffee380a440d097c30000000000000000000000006a000415210b4764732dc7b69544de21152a996f830518e4a093a38cfe248579f3fa0f047353414a9a7dd7687257aa8d8cd99562f08a84b092a0558859b1b3427f56f71b7344d939df511e0a27530143d2c24a1acac8d19af4f2b8ae02f8ab83028c6081c2800282d4aa945cbfccd27db8a3981fe9965b0de59d436b2bd8b980b844095ea7b30000000000000000000000001670080000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000004922dc001a013342a84b1cde8d08fd2869c29dbefcaeb2a01a39ac0b7b97685c0747b6bedd0a00d99a4161ff1e544a86d238077db74a1eb89d1e0e52e6bdb5e0505a43643748fb88d02f88a83028c601e8002830267ac94edd0ddaedbc3fbf67ac4ff2ee14ace669821eac180a440d097c3000000000000000000000000f47694d0cd76eb34a92a1fb1e48d654f7f072511c001a0f6d3247b777be12ec683d149828b90a16e07c5f7f13703b4967df67e51dff0e3a06f54fee1dd0d1781312970a74070cb79d7abdc2b4e88bfaa938f53eba19557e1b8b602f8b383028c601f8459682f0084c1bdab058301ca9994edd0ddaedbc3fbf67ac4ff2ee14ace669821eac180b8447237855400000000000000000000000000000000000000000000000000000000000d3cd90000000000000000000000001670080000000000000000000000000000000003c080a0f4476ac5a1dee33cf20f935f58d30fdf22da67d070498816111332178a9f4aa4a061bd48e1aada637898a51052370e1db49daa89769a778c861212124216830c6d00000000000000000000000000000000000000000000c001a09b24c92d6a5d555ccd81c66a371497768d82978e3f56757bde7abea0e0b83f61a00134de2abfa8305cae6fcea1531b6fba914a24851ea19e82cdedc52244266273", + "0x02f90436824268830c47b2840bc861b984ab7502e783030d6294b20bb9105e007bd3e0f73d63d4d3da2c8f736b7780b903c410d008bd00000000000000000000000000000000000000000000000000000000000f6f5400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000360793a06ed5020760c865c6a1fd7fbc786bef0b54ac46e8875a81775889ca0832ad5de6e888f943f116a10f740707e749fea865e5c8a1a2d2f2bcc1f6ce49637874761aa3c4a6d41f3569ced91e43cc5f207a5957697731c5d26a5d291f1dd523b302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd000000000000000000000000e1e210594771824dad216568b91c9cb4ceed361c00000000000000000000000000000000000000000000000000000000000f6f540000000000000000000000000000000000000000000000000000000000e4e1c000000000000000000000000000000000000000000000000000000000662fb26000000000000000000000000000000000000000000000000000000000001606820000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e05000000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000ea8be2e4ce9699a02a5adcf58d1f3cfc1e03d7c54f0c098d4f911e2841519d325c3458af91dc5f0915d41e36589459521e5119eaccdde3d074bb93f4d7a59b24af6315df27bf66283d9dbf7eaf21d0e2bd9fe0a4fb563e064d023cdfec0c58850fe55a909d150269d8af03c13d294dc5d9280441fa114eadbfe896bcdbb1b78800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c080a0f5216871b2acedd75147ff709f830f0a6c771c6f0ef79301695603de363cbd0fa00b9f79954cbfc0b47137b2c2a47d2e1c6f8dc7cb6248a7590177887f9fd5454b", + "0x02f904368242688301feb8840bc861b984ab7502e7832dc6c094b20bb9105e007bd3e0f73d63d4d3da2c8f736b7780b903c410d008bd00000000000000000000000000000000000000000000000000000000000f6f5200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000360793a06ed5020760c865c6a1fd7fbc786bef0b54ac46e8875a81775889ca0832a04185855280e63767b67133dc32cd55bfce72e0fd2edf75820249176560626e6cf08dec49dd6b1c03d4af82381127db64522bb62ec92af8dae14bf72fe039fb0302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd0000000000000000000000007e162f2a097c535b8e234fabe4c8e6c8a07ea46900000000000000000000000000000000000000000000000000000000000f6f520000000000000000000000000000000000000000000000000000000000e4e1c000000000000000000000000000000000000000000000000000000000662fb26000000000000000000000000000000000000000000000000000000000001606820000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cc290000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000043216b92ddbea5a465772a3263d490588abe81ec0d3ecb9f6477966d3406591a2ce0a40cb935a350b848b0a9fded58014beec9254955319447c7b888add402e33b96e8263cbdc62bcfc30bb510b8ddf5ac1a2ab2d39f1501a8cde3a7032154870fe55a909d150269d8af03c13d294dc5d9280441fa114eadbfe896bcdbb1b78800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c001a05a082976112f610faa228e8dd4aa0a55d342436b50f0b5740bd3d51fc4206869a02da0c1164dbce2454181350c718a0994d37261054e602e3266f5e67895fa9435", + "0x02f904368242688301feb9840bc861b984ab7502e7832dc6c094b20bb9105e007bd3e0f73d63d4d3da2c8f736b7780b903c410d008bd00000000000000000000000000000000000000000000000000000000000f6f5300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000360793a06ed5020760c865c6a1fd7fbc786bef0b54ac46e8875a81775889ca0832a61e0fb67a03f990c7c17fad46a52d09b96560b294166eaae63d8417220ab1039cf08dec49dd6b1c03d4af82381127db64522bb62ec92af8dae14bf72fe039fb0302e31382e302d64657600000000000000000000000000000000000000000000569e75fc77c1a856f6daaf9e69d8a9566ca34aa47f9133711ce065a571af0cfd000000000000000000000000d139df8d8f2088053dcd9084545e77d97b74cdfb00000000000000000000000000000000000000000000000000000000000f6f530000000000000000000000000000000000000000000000000000000000e4e1c000000000000000000000000000000000000000000000000000000000662fb26000000000000000000000000000000000000000000000000000000000001606820000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cc2900000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000b2724e2d0d30fcf914ac30728c939360b538c17bb68a3e2feb874beb17cb44453b96e8263cbdc62bcfc30bb510b8ddf5ac1a2ab2d39f1501a8cde3a7032154875c3458af91dc5f0915d41e36589459521e5119eaccdde3d074bb93f4d7a59b240fe55a909d150269d8af03c13d294dc5d9280441fa114eadbfe896bcdbb1b78800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000c080a08425e65ed8d2789a8dfcc49b1c8ce9744109abbb354c2d995c95901c1b94cdb5a063e7031985b617fe27b5c1469ca065128ca88b28eabb2c94a5e2ed5c53d271c9", + "0x02f903388242688302167e840bc861b984ab7502e7827e1894ff0000000000000000000000000000000004206980b902c70030f155af0c6f5364919997e9100b747a0000000002af78dadae1cff0c367c19ec275dc4feae6af38b275b5cdc138b5fd7b9eacf639784ff69ec95aa13cf3f957629ac5d8aa17dc7abac1e290edc186b97fc527f75c3177ebaf38b2d048675d87b76328cb3135d3d29634fd4d1e07200616b42e493dbdc536f2cfa7536b9ba7d8163d3f68e9bbdbc2ec76ba734ea4d1f68ef5441be805355040f7f3231ba755bc6f6719ae9aacd868df14205cc2fee5f41dc3673b9832bc7711ef421fa8810ddfe5d48b38e6f24ef973ef42a299d8cc5962294f195b4f33ad8bdefc486bdd2b49a20df4831a289d117c99f16d62faa196f55798d72ff69156fccbf7ae31e2e4a92c6935edd28302cd626c350bbcf7de1458e9b55e8b837fd99e98c7823626aa4bf6acbd60f121406afb8e32a346799081015003853d17769e0cf6719337488c727e2c287c67779bf0d7982487d2e9a19fe345cafc893630086a60c6c38d2c3c5c2b4b9f3a17a90abf48be7ed369ef512317663f87a45dae3a816ad7893630046ae0b267733d3d787336bf99b92399fdd8a4dd25f3aeecfffe629fdaf3c3f666cbee1e3f4fb4816150039fbe4a12f416fd6499b99e8fe1c0e17a730ea660ab5746779614d706ef7cbce76613d10646400d9ca5f44973afcfaf77c6ef16bf78baf3b71fc3be9f335bf295b6fa171cf0ef0a9e738b6803a3a006ae3824bf47fcc497139a5d7122258d8bde5e76da9e13a2a598b0de583ba5f748cf966631b6da05eb2eb672a6072d93b03510fe1b9eb197e3fbd5b8fa393d2a3f5f5d53fd20f1bdc00e64600cd4c05f0f369a9b64f27d613e29bff343ff89b32e52465aceae6d53ad4ebbb395ec5a37856803e3a006769c5fbd9f31f4d0dfcad73d5adcf6ed0a36dbafac5da229ae5367bcc371d1a6084fa20d4c801a982659e663baef725389d6ac5d0feeaf71796dfcee9843bafeca08972305b57f145e136d60d20140000000ffff3fc41ad801c001a0679d51e48d44ee7d3621c3051756cb41ad639944c9cb66ebff914a55bb760a12a0281dc2c90ceca592df739f5d6b9908337bb6140ed5bd8a0ca2fc1c08e2196d09", + "0x02f88f824268830c74f9840bc861b984a9f909cf82540894ff0000000000000000000000000000000001700180a00a0ea1855090e23aec512ffe921a176908ae5ec663b08071022e1b57ff86d117c080a0f9f02c2a212a182eff4977e8a303344c6e5de164dfd7d26b9974732510d147d4a03e8f01452cc5325354a1941c7d170fdca7c2bb5a7441dbd9f48f95e4fada5e79", + "0x02f8d482426882434e840bc861b984a9f909cf8303090094a067fc95c22d51c3bc35fd4be37414ee8cc890d280b864e33a8d39000000000000000000000000000000000000000000000000000000000017857fa13b7d738751c853b2291945226c24e3132271bdfbfba866c7c78d77b652dcbb0000000000000000000000000000000000000000000000000000000000000001c080a068957b1aa9fc4e6fb28b1a4a981510754eb23c07e7d037694edf85f6dd8417e2a05c692ebaa8047b9dffe17106267ad1d942c7f945c7d9ab341d998a505f8cd51b", + "0x02f9051582426882490a840bc861b9846b965c078303e6ec94329d0c4a58b3cefdb40c5513e155228f6cc7b6c580b904a45740b89d00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af7500000000000000000000000000000000000000000000000000000000000172bb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af7600000000000000000000000000000000000000000000000000000000000172bc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af7700000000000000000000000000000000000000000000000000000000000172bd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af7800000000000000000000000000000000000000000000000000000000000172be000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af7900000000000000000000000000000000000000000000000000000000000172bf000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000001af7a00000000000000000000000000000000000000000000000000000000000172c000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001c001a025176731828cf0e460b0f99d6fd4bb8d157d4c470db0dbbbdcd2748cfd1dd311a068c82dccf223a9dcca8b1365050a29787b0369900e515bb8b6cd8b7dd4656e24", + "0x02f89182426880844cd8ec93844cd8ec93830140c694a960d72f83a8a163412520a778b437ac5211a50180a46a627842000000000000000000000000555929a61b941c3d9d18a7799dae001af05ecb73c080a0be99311a91bf814a0ddaea9c2e6c535cbd69249cae7d927c6331550a5f58f3eda00cc7a770b332e66c076bb775dc9b013a6e69b9d44e1a2a8051fbaffbabe3a054", + "0xf88a01844cd8ec93830123a994a960d72f83a8a163412520a778b437ac5211a50180a46a627842000000000000000000000000b1c36363bb2a19f5f9de048fba3f2d5dc09409e98284f4a006f18d7e874401ad426e0f024f5e2b9c1ba6a34b441f81116025d8a0de03dd8da06efa1ce2781b27a9d0efce48a91c4be0e8b1d3936e5fbcbafcc7ee4fe423175f", + "0xf86904844cd8ec9382e2b2941828eaa3cde0b2373bc869a19cf5b4804c21752c8084359cf2b78284f4a0329128d760a0557d44eab331f992402a5cd2ce029a4d81db67d6387a5e2d1d7ca0499f7106fd4e3f40c690cfe8c48b0050a960875dc215e7c810c4aae999e42e4e", + "0xf86a05844cd8ec938301225494bd95c31c3035d93c53106cd00a727f7c4664f2c88084359cf2b78284f4a0bdda728e0527e81abf3692af8a7261855a3713220a1a7b3ba31913bb65b4fbbea049df452fd305ce490c8821c80b6b780e33042793978440c180744edeacd38f96", + "0xf8aa068463ca07e282b4c8941317106dd45ff0eb911e9f0af78d63fbf9076f6980b844095ea7b3000000000000000000000000329d0c4a58b3cefdb40c5513e155228f6cc7b6c500000000000000000000000000000000000000000000021e19e0c9bab24000008284f3a0fd48ac363c4462677cfda7949d19a8bc38c0ddbc2f1e17242f54e2dc7c213edba02ce77a24e87278aa7ad49b86579a6c7cec01a07b700addc9dcc20b7ce8fbe9d3", + "0x02f9021a82426801844cd8ec93844cd8ec938301b0b494a098b76a3dd499d3f6d58d8accafc8efbfd06807871cd82ffeee7000b901a41bdb003700000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b14b6c70df00000000000000000000000000000000000000000000000000000000000000c3511000000000000000000000000397c865926fd04eec2336f4ea4e11d8f7d1276820000000000000000000000000000000000000000000000000000000000004268000000000000000000000000397c865926fd04eec2336f4ea4e11d8f7d1276820000000000000000000000000000000000000000000000000000000000028c61000000000000000000000000397c865926fd04eec2336f4ea4e11d8f7d127682000000000000000000000000397c865926fd04eec2336f4ea4e11d8f7d1276820000000000000000000000000000000000000000000000000011c37937e0800000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000c080a0a6bbee93a3fc7e22602b2b1e7bc435d16a524c90beefe360f8c1077babfb1924a00d1aac408ea366dbad4db35bd56e2bcf13bfcd277b400639d861f5cb0ba92a14", + "0x02f8b182426802844cd8ec93844cd8ec9382b647941317106dd45ff0eb911e9f0af78d63fbf9076f6980b844095ea7b3000000000000000000000000329d0c4a58b3cefdb40c5513e155228f6cc7b6c500000000000000000000000000000000000000000000021e19e0c9bab2400000c080a018b9740856a6d230b424990c0e6c2d6ec164b4414740e04d689b70d4061b2d38a069d42f08eb31d7e4cd0e29b1645a446262a08e9bc2838b970d87a23285917276", + "0x02f8b182426803844cd8ec93844cd8ec9382b64794ce658e386fac0646cedaf810070f0525af14d11d80b844095ea7b3000000000000000000000000329d0c4a58b3cefdb40c5513e155228f6cc7b6c50000000000000000000000000000000000000000000001e7e4171bf4d3a00000c001a052947acd2f0b8b31dffc929f8f4c249de631a226fdf16419577342c2d0734f10a063b293c1c005a9338df20a5348c58cbec45f33a38370838f68b91669c741eb9d", + "0xf917000c844c1715228316c5048080b916ac6101606040523480156200001257600080fd5b50604051620015ec380380620015ec833981016040819052620000359162000286565b6040805180820190915260018152603160f81b602082015282908190818460036200006183826200037f565b5060046200007082826200037f565b50620000829150839050600562000134565b610120526200009381600662000134565b61014052815160208084019190912060e052815190820120610100524660a0526200012160e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c05250620004a5915050565b600060208351101562000154576200014c836200016d565b905062000167565b816200016184826200037f565b5060ff90505b92915050565b600080829050601f81511115620001a4578260405163305a27a960e01b81526004016200019b91906200044b565b60405180910390fd5b8051620001b18262000480565b179392505050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620001ec578181015183820152602001620001d2565b50506000910152565b600082601f8301126200020757600080fd5b81516001600160401b0380821115620002245762000224620001b9565b604051601f8301601f19908116603f011681019082821181831017156200024f576200024f620001b9565b816040528381528660208588010111156200026957600080fd5b6200027c846020830160208901620001cf565b9695505050505050565b600080604083850312156200029a57600080fd5b82516001600160401b0380821115620002b257600080fd5b620002c086838701620001f5565b93506020850151915080821115620002d757600080fd5b50620002e685828601620001f5565b9150509250929050565b600181811c908216806200030557607f821691505b6020821081036200032657634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200037a57600081815260208120601f850160051c81016020861015620003555750805b601f850160051c820191505b81811015620003765782815560010162000361565b5050505b505050565b81516001600160401b038111156200039b576200039b620001b9565b620003b381620003ac8454620002f0565b846200032c565b602080601f831160018114620003eb5760008415620003d25750858301515b600019600386901b1c1916600185901b17855562000376565b600085815260208120601f198616915b828110156200041c57888601518255948401946001909101908401620003fb565b50858210156200043b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60208152600082518060208401526200046c816040850160208701620001cf565b601f01601f19169190910160400192915050565b80516020808301519190811015620003265760001960209190910360031b1b16919050565b60805160a05160c05160e0516101005161012051610140516110ec6200050060003960006107b90152600061078c015260006107340152600061070c0152600061066701526000610691015260006106bb01526110ec6000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80637ecebe001161008c578063a0712d6811610066578063a0712d68146101cb578063a9059cbb146101e0578063d505accf146101f3578063dd62ed3e1461020657600080fd5b80637ecebe001461019557806384b0196e146101a857806395d89b41146101c357600080fd5b806323b872dd116100c857806323b872dd14610142578063313ce567146101555780633644e5151461016457806370a082311461016c57600080fd5b806306fdde03146100ef578063095ea7b31461010d57806318160ddd14610130575b600080fd5b6100f761023f565b6040516101049190610e1d565b60405180910390f35b61012061011b366004610e53565b6102d1565b6040519015158152602001610104565b6002545b604051908152602001610104565b610120610150366004610e7d565b6102eb565b60405160128152602001610104565b61013461030f565b61013461017a366004610eb9565b6001600160a01b031660009081526020819052604090205490565b6101346101a3366004610eb9565b61031e565b6101b061033c565b6040516101049796959493929190610ed4565b6100f761039e565b6101de6101d9366004610f86565b6103ad565b005b6101206101ee366004610e53565b6103ba565b6101de610201366004610f9f565b6103c8565b610134610214366004611012565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60606003805461024e90611045565b80601f016020809104026020016040519081016040528092919081815260200182805461027a90611045565b80156102c75780601f1061029c576101008083540402835291602001916102c7565b820191906000526020600020905b8154815290600101906020018083116102aa57829003601f168201915b5050505050905090565b6000336102df818585610539565b60019150505b92915050565b6000336102f985828561054b565b6103048585856105e2565b506001949350505050565b600061031961065a565b905090565b6001600160a01b0381166000908152600760205260408120546102e5565b600060608060008060006060610350610785565b6103586107b2565b604080516000808252602082019092527f0f000000000000000000000000000000000000000000000000000000000000009b939a50919850469750309650945092509050565b60606004805461024e90611045565b6103b733826107df565b50565b6000336102df8185856105e2565b8342111561040a576040517f62791302000000000000000000000000000000000000000000000000000000008152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886104578c6001600160a01b0316600090815260076020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006104b282610819565b905060006104c282878787610861565b9050896001600160a01b0316816001600160a01b031614610522576040517f4b800e460000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301528b166024820152604401610401565b61052d8a8a8a610539565b50505050505050505050565b610546838383600161088f565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146105dc57818110156105cd576040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201526024810182905260448101839052606401610401565b6105dc8484848403600061088f565b50505050565b6001600160a01b038316610625576040517f96c6fd1e00000000000000000000000000000000000000000000000000000000815260006004820152602401610401565b6001600160a01b03821661064f5760405163ec442f0560e01b815260006004820152602401610401565b610546838383610996565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480156106b357507f000000000000000000000000000000000000000000000000000000000000000046145b156106dd57507f000000000000000000000000000000000000000000000000000000000000000090565b610319604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60606103197f00000000000000000000000000000000000000000000000000000000000000006005610ad9565b60606103197f00000000000000000000000000000000000000000000000000000000000000006006610ad9565b6001600160a01b0382166108095760405163ec442f0560e01b815260006004820152602401610401565b61081560008383610996565b5050565b60006102e561082661065a565b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b60008060008061087388888888610b84565b9250925092506108838282610c53565b50909695505050505050565b6001600160a01b0384166108d2576040517fe602df0500000000000000000000000000000000000000000000000000000000815260006004820152602401610401565b6001600160a01b038316610915576040517f94280d6200000000000000000000000000000000000000000000000000000000815260006004820152602401610401565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156105dc57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161098891815260200190565b60405180910390a350505050565b6001600160a01b0383166109c15780600260008282546109b6919061107f565b90915550610a4c9050565b6001600160a01b03831660009081526020819052604090205481811015610a2d576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526024810182905260448101839052606401610401565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610a6857600280548290039055610a87565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610acc91815260200190565b60405180910390a3505050565b606060ff8314610af357610aec83610d57565b90506102e5565b818054610aff90611045565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2b90611045565b8015610b785780601f10610b4d57610100808354040283529160200191610b78565b820191906000526020600020905b815481529060010190602001808311610b5b57829003601f168201915b505050505090506102e5565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610bbf5750600091506003905082610c49565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610c13573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610c3f57506000925060019150829050610c49565b9250600091508190505b9450945094915050565b6000826003811115610c6757610c676110a0565b03610c70575050565b6001826003811115610c8457610c846110a0565b03610cbb576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002826003811115610ccf57610ccf6110a0565b03610d09576040517ffce698f700000000000000000000000000000000000000000000000000000000815260048101829052602401610401565b6003826003811115610d1d57610d1d6110a0565b03610815576040517fd78bce0c00000000000000000000000000000000000000000000000000000000815260048101829052602401610401565b60606000610d6483610d96565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156102e5576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815180845260005b81811015610dfd57602081850181015186830182015201610de1565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610e306020830184610dd7565b9392505050565b80356001600160a01b0381168114610e4e57600080fd5b919050565b60008060408385031215610e6657600080fd5b610e6f83610e37565b946020939093013593505050565b600080600060608486031215610e9257600080fd5b610e9b84610e37565b9250610ea960208501610e37565b9150604084013590509250925092565b600060208284031215610ecb57600080fd5b610e3082610e37565b7fff00000000000000000000000000000000000000000000000000000000000000881681526000602060e081840152610f1060e084018a610dd7565b8381036040850152610f22818a610dd7565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b81811015610f7457835183529284019291840191600101610f58565b50909c9b505050505050505050505050565b600060208284031215610f9857600080fd5b5035919050565b600080600080600080600060e0888a031215610fba57600080fd5b610fc388610e37565b9650610fd160208901610e37565b95506040880135945060608801359350608088013560ff81168114610ff557600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561102557600080fd5b61102e83610e37565b915061103c60208401610e37565b90509250929050565b600181811c9082168061105957607f821691505b60208210810361107957634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156102e557634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212206ba9dbff097d43964029a264bd2ded61f9b9a1183e1d6616e68d832b8d30b30664736f6c6343000814003300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000c53545245494348546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000753545245494348000000000000000000000000000000000000000000000000008284f4a07171b9037c2c623c5e409318ca0002a11fcb48b2e341a424dc1d61fbe8fd3eb2a05fcc94e3f36412ddbbc9f198b9c5926b7dd7c1c6981c0235572cc947b912d182", + "0xf916ff0c844c171522831838cd8080b916ac6101606040523480156200001257600080fd5b50604051620015ec380380620015ec833981016040819052620000359162000286565b6040805180820190915260018152603160f81b602082015282908190818460036200006183826200037f565b5060046200007082826200037f565b50620000829150839050600562000134565b610120526200009381600662000134565b61014052815160208084019190912060e052815190820120610100524660a0526200012160e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60805250503060c05250620004a5915050565b600060208351101562000154576200014c836200016d565b905062000167565b816200016184826200037f565b5060ff90505b92915050565b600080829050601f81511115620001a4578260405163305a27a960e01b81526004016200019b91906200044b565b60405180910390fd5b8051620001b18262000480565b179392505050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620001ec578181015183820152602001620001d2565b50506000910152565b600082601f8301126200020757600080fd5b81516001600160401b0380821115620002245762000224620001b9565b604051601f8301601f19908116603f011681019082821181831017156200024f576200024f620001b9565b816040528381528660208588010111156200026957600080fd5b6200027c846020830160208901620001cf565b9695505050505050565b600080604083850312156200029a57600080fd5b82516001600160401b0380821115620002b257600080fd5b620002c086838701620001f5565b93506020850151915080821115620002d757600080fd5b50620002e685828601620001f5565b9150509250929050565b600181811c908216806200030557607f821691505b6020821081036200032657634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200037a57600081815260208120601f850160051c81016020861015620003555750805b601f850160051c820191505b81811015620003765782815560010162000361565b5050505b505050565b81516001600160401b038111156200039b576200039b620001b9565b620003b381620003ac8454620002f0565b846200032c565b602080601f831160018114620003eb5760008415620003d25750858301515b600019600386901b1c1916600185901b17855562000376565b600085815260208120601f198616915b828110156200041c57888601518255948401946001909101908401620003fb565b50858210156200043b5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60208152600082518060208401526200046c816040850160208701620001cf565b601f01601f19169190910160400192915050565b80516020808301519190811015620003265760001960209190910360031b1b16919050565b60805160a05160c05160e0516101005161012051610140516110ec6200050060003960006107b90152600061078c015260006107340152600061070c0152600061066701526000610691015260006106bb01526110ec6000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80637ecebe001161008c578063a0712d6811610066578063a0712d68146101cb578063a9059cbb146101e0578063d505accf146101f3578063dd62ed3e1461020657600080fd5b80637ecebe001461019557806384b0196e146101a857806395d89b41146101c357600080fd5b806323b872dd116100c857806323b872dd14610142578063313ce567146101555780633644e5151461016457806370a082311461016c57600080fd5b806306fdde03146100ef578063095ea7b31461010d57806318160ddd14610130575b600080fd5b6100f761023f565b6040516101049190610e1d565b60405180910390f35b61012061011b366004610e53565b6102d1565b6040519015158152602001610104565b6002545b604051908152602001610104565b610120610150366004610e7d565b6102eb565b60405160128152602001610104565b61013461030f565b61013461017a366004610eb9565b6001600160a01b031660009081526020819052604090205490565b6101346101a3366004610eb9565b61031e565b6101b061033c565b6040516101049796959493929190610ed4565b6100f761039e565b6101de6101d9366004610f86565b6103ad565b005b6101206101ee366004610e53565b6103ba565b6101de610201366004610f9f565b6103c8565b610134610214366004611012565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60606003805461024e90611045565b80601f016020809104026020016040519081016040528092919081815260200182805461027a90611045565b80156102c75780601f1061029c576101008083540402835291602001916102c7565b820191906000526020600020905b8154815290600101906020018083116102aa57829003601f168201915b5050505050905090565b6000336102df818585610539565b60019150505b92915050565b6000336102f985828561054b565b6103048585856105e2565b506001949350505050565b600061031961065a565b905090565b6001600160a01b0381166000908152600760205260408120546102e5565b600060608060008060006060610350610785565b6103586107b2565b604080516000808252602082019092527f0f000000000000000000000000000000000000000000000000000000000000009b939a50919850469750309650945092509050565b60606004805461024e90611045565b6103b733826107df565b50565b6000336102df8185856105e2565b8342111561040a576040517f62791302000000000000000000000000000000000000000000000000000000008152600481018590526024015b60405180910390fd5b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886104578c6001600160a01b0316600090815260076020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006104b282610819565b905060006104c282878787610861565b9050896001600160a01b0316816001600160a01b031614610522576040517f4b800e460000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301528b166024820152604401610401565b61052d8a8a8a610539565b50505050505050505050565b610546838383600161088f565b505050565b6001600160a01b0383811660009081526001602090815260408083209386168352929052205460001981146105dc57818110156105cd576040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201526024810182905260448101839052606401610401565b6105dc8484848403600061088f565b50505050565b6001600160a01b038316610625576040517f96c6fd1e00000000000000000000000000000000000000000000000000000000815260006004820152602401610401565b6001600160a01b03821661064f5760405163ec442f0560e01b815260006004820152602401610401565b610546838383610996565b6000306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480156106b357507f000000000000000000000000000000000000000000000000000000000000000046145b156106dd57507f000000000000000000000000000000000000000000000000000000000000000090565b610319604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60606103197f00000000000000000000000000000000000000000000000000000000000000006005610ad9565b60606103197f00000000000000000000000000000000000000000000000000000000000000006006610ad9565b6001600160a01b0382166108095760405163ec442f0560e01b815260006004820152602401610401565b61081560008383610996565b5050565b60006102e561082661065a565b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b60008060008061087388888888610b84565b9250925092506108838282610c53565b50909695505050505050565b6001600160a01b0384166108d2576040517fe602df0500000000000000000000000000000000000000000000000000000000815260006004820152602401610401565b6001600160a01b038316610915576040517f94280d6200000000000000000000000000000000000000000000000000000000815260006004820152602401610401565b6001600160a01b03808516600090815260016020908152604080832093871683529290522082905580156105dc57826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161098891815260200190565b60405180910390a350505050565b6001600160a01b0383166109c15780600260008282546109b6919061107f565b90915550610a4c9050565b6001600160a01b03831660009081526020819052604090205481811015610a2d576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526024810182905260448101839052606401610401565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b038216610a6857600280548290039055610a87565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610acc91815260200190565b60405180910390a3505050565b606060ff8314610af357610aec83610d57565b90506102e5565b818054610aff90611045565b80601f0160208091040260200160405190810160405280929190818152602001828054610b2b90611045565b8015610b785780601f10610b4d57610100808354040283529160200191610b78565b820191906000526020600020905b815481529060010190602001808311610b5b57829003601f168201915b505050505090506102e5565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610bbf5750600091506003905082610c49565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610c13573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116610c3f57506000925060019150829050610c49565b9250600091508190505b9450945094915050565b6000826003811115610c6757610c676110a0565b03610c70575050565b6001826003811115610c8457610c846110a0565b03610cbb576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002826003811115610ccf57610ccf6110a0565b03610d09576040517ffce698f700000000000000000000000000000000000000000000000000000000815260048101829052602401610401565b6003826003811115610d1d57610d1d6110a0565b03610815576040517fd78bce0c00000000000000000000000000000000000000000000000000000000815260048101829052602401610401565b60606000610d6483610d96565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b600060ff8216601f8111156102e5576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000815180845260005b81811015610dfd57602081850181015186830182015201610de1565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610e306020830184610dd7565b9392505050565b80356001600160a01b0381168114610e4e57600080fd5b919050565b60008060408385031215610e6657600080fd5b610e6f83610e37565b946020939093013593505050565b600080600060608486031215610e9257600080fd5b610e9b84610e37565b9250610ea960208501610e37565b9150604084013590509250925092565b600060208284031215610ecb57600080fd5b610e3082610e37565b7fff00000000000000000000000000000000000000000000000000000000000000881681526000602060e081840152610f1060e084018a610dd7565b8381036040850152610f22818a610dd7565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b81811015610f7457835183529284019291840191600101610f58565b50909c9b505050505050505050505050565b600060208284031215610f9857600080fd5b5035919050565b600080600080600080600060e0888a031215610fba57600080fd5b610fc388610e37565b9650610fd160208901610e37565b95506040880135945060608801359350608088013560ff81168114610ff557600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561102557600080fd5b61102e83610e37565b915061103c60208401610e37565b90509250929050565b600181811c9082168061105957607f821691505b60208210810361107957634e487b7160e01b600052602260045260246000fd5b50919050565b808201808211156102e557634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fdfea26469706673582212206ba9dbff097d43964029a264bd2ded61f9b9a1183e1d6616e68d832b8d30b30664736f6c6343000814003300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000a4e41444552546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054e414445520000000000000000000000000000000000000000000000000000008284f3a004257ad4a65847e70f17676d390d5864c6262d5b585a85f2670b4a15bad241659f7c5865e3e4e17cb7209afbd9f85afdf88d5683cfd9d311364bf7e2ed7b05ca", + "0xf8aa02844c17152282b63a94a960d72f83a8a163412520a778b437ac5211a50180b844095ea7b30000000000000000000000002259662ed5de0e09943abe701bc5f5a108eabbaa000000000000000000000000000000000000000000000002b5e3af16b18800008284f3a09a49b4700465d018dffd449a85e2634894ea0b64ed664b80ada26d6ce751392da066d02444ae3aaf9c2d9fab1a94e922b348ee2e20b608f06326f00129ade7fcc7", + "0x02f87082426819844c171522844c17152282e2b294bd95c31c3035d93c53106cd00a727f7c4664f2c88084359cf2b7c001a08351ca473d6e2aeca6ace027c88e76b1c1cdd8bdc723cbaee3edfdef32e170faa0543cd190080bd34f984a8ba7f593874192c7059f57d181b0036c93f94e0a7efe", + "0x02f8708242681a844c171522844c17152282df88941828eaa3cde0b2373bc869a19cf5b4804c21752c8084359cf2b7c001a0db1e89679ba028c62c43c95e38ca071c453e8f64f2bbb6a1f18158c1f6ef981ca03323fb48128709ac499dfae15f627bff245a6e38251a3cedb480fa471829cc3b" + ], + "withdrawals": [ + { + "index": "22934947", + "validator_index": "370433", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6553336" + }, + { + "index": "22934948", + "validator_index": "370434", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6567932" + }, + { + "index": "22934949", + "validator_index": "370435", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6569640" + }, + { + "index": "22934950", + "validator_index": "370436", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6638060" + }, + { + "index": "22934951", + "validator_index": "370437", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6499114" + }, + { + "index": "22934952", + "validator_index": "370438", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6605154" + }, + { + "index": "22934953", + "validator_index": "370439", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6615898" + }, + { + "index": "22934954", + "validator_index": "370440", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6601398" + }, + { + "index": "22934955", + "validator_index": "370441", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6560810" + }, + { + "index": "22934956", + "validator_index": "370442", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6511735" + }, + { + "index": "22934957", + "validator_index": "370443", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6654495" + }, + { + "index": "22934958", + "validator_index": "370444", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6614281" + }, + { + "index": "22934959", + "validator_index": "370445", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6505105" + }, + { + "index": "22934960", + "validator_index": "370446", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6682171" + }, + { + "index": "22934961", + "validator_index": "370447", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6524345" + }, + { + "index": "22934962", + "validator_index": "370448", + "address": "0x73b2e0e54510239e22cc936f0b4a6de1acf0abde", + "amount": "6625223" + } + ], + "blob_gas_used": "786432", + "excess_blob_gas": "79953920" + }, + "bls_to_execution_changes": [], + "blob_kzg_commitments": [ + "0xae531553423b61c13968b581974521784c18a082d3fed138e883acf0925cba6011f5b1cb012b5e9fa5131f28bba1f76b", + "0x8e935ff5e71ed858ed806346d536764adc1d1cef96f1472ab7fa78ea9529922e34d26bc952945fa27ae1c352e7a1d967", + "0xabb1aed974641e6bfa422b4313b8d7fa233cd2a9e93eb4c3d1a6dd803dbfb7849c968bc9cb907a7941b2f82fb74081e5", + "0xaf3817738737be131c60c281c71c7ddbd76754a885829927cc72f278698eddad9b335a343d56cb401aab687273fc66ed", + "0xa71fa354b0a08c288f1463a55a8c2b3e8be58cce40fa9cb157d5953405df777026809c0d2ed90ed0de8f4aa3f7ad841c", + "0x976a212a2698a2b92db91430e971c2052f1a22a6f65581454a2663853bd0350913baccfc257485fea5cf9f9c7ac27af0" + ] + } + }, + "signature": "0x8ae6a26a3e80a0cd6ed1d3c27dc96960f498e7b9dae37bf34aef5df26b0fbdf38d807c020188a8487910cc6646f062540b7322cbbc14c3d605ca0d61dd6cc242a142f2292169b7b6bce7bd7ee06ffa73ec6d567cb58d6066c08f56881669df26" + }, + { + "version": "deneb", + "execution_optimistic": false, + "finalized": true + } + ] + } +] \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 6f8f27af8..acb151547 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,119 +1,104 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiohttp" -version = "3.8.4" +version = "3.9.5" description = "Async http client/server framework (asyncio)" -category = "main" optional = false -python-versions = ">=3.6" -files = [ - {file = "aiohttp-3.8.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5ce45967538fb747370308d3145aa68a074bdecb4f3a300869590f725ced69c1"}, - {file = "aiohttp-3.8.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b744c33b6f14ca26b7544e8d8aadff6b765a80ad6164fb1a430bbadd593dfb1a"}, - {file = "aiohttp-3.8.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a45865451439eb320784918617ba54b7a377e3501fb70402ab84d38c2cd891b"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a86d42d7cba1cec432d47ab13b6637bee393a10f664c425ea7b305d1301ca1a3"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee3c36df21b5714d49fc4580247947aa64bcbe2939d1b77b4c8dcb8f6c9faecc"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:176a64b24c0935869d5bbc4c96e82f89f643bcdf08ec947701b9dbb3c956b7dd"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c844fd628851c0bc309f3c801b3a3d58ce430b2ce5b359cd918a5a76d0b20cb5"}, - {file = "aiohttp-3.8.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5393fb786a9e23e4799fec788e7e735de18052f83682ce2dfcabaf1c00c2c08e"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e4b09863aae0dc965c3ef36500d891a3ff495a2ea9ae9171e4519963c12ceefd"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:adfbc22e87365a6e564c804c58fc44ff7727deea782d175c33602737b7feadb6"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:147ae376f14b55f4f3c2b118b95be50a369b89b38a971e80a17c3fd623f280c9"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:eafb3e874816ebe2a92f5e155f17260034c8c341dad1df25672fb710627c6949"}, - {file = "aiohttp-3.8.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c6cc15d58053c76eacac5fa9152d7d84b8d67b3fde92709195cb984cfb3475ea"}, - {file = "aiohttp-3.8.4-cp310-cp310-win32.whl", hash = "sha256:59f029a5f6e2d679296db7bee982bb3d20c088e52a2977e3175faf31d6fb75d1"}, - {file = "aiohttp-3.8.4-cp310-cp310-win_amd64.whl", hash = "sha256:fe7ba4a51f33ab275515f66b0a236bcde4fb5561498fe8f898d4e549b2e4509f"}, - {file = "aiohttp-3.8.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3d8ef1a630519a26d6760bc695842579cb09e373c5f227a21b67dc3eb16cfea4"}, - {file = "aiohttp-3.8.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b3f2e06a512e94722886c0827bee9807c86a9f698fac6b3aee841fab49bbfb4"}, - {file = "aiohttp-3.8.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a80464982d41b1fbfe3154e440ba4904b71c1a53e9cd584098cd41efdb188ef"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b631e26df63e52f7cce0cce6507b7a7f1bc9b0c501fcde69742130b32e8782f"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f43255086fe25e36fd5ed8f2ee47477408a73ef00e804cb2b5cba4bf2ac7f5e"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d347a172f866cd1d93126d9b239fcbe682acb39b48ee0873c73c933dd23bd0f"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3fec6a4cb5551721cdd70473eb009d90935b4063acc5f40905d40ecfea23e05"}, - {file = "aiohttp-3.8.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80a37fe8f7c1e6ce8f2d9c411676e4bc633a8462844e38f46156d07a7d401654"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d1e6a862b76f34395a985b3cd39a0d949ca80a70b6ebdea37d3ab39ceea6698a"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cd468460eefef601ece4428d3cf4562459157c0f6523db89365202c31b6daebb"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:618c901dd3aad4ace71dfa0f5e82e88b46ef57e3239fc7027773cb6d4ed53531"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:652b1bff4f15f6287550b4670546a2947f2a4575b6c6dff7760eafb22eacbf0b"}, - {file = "aiohttp-3.8.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80575ba9377c5171407a06d0196b2310b679dc752d02a1fcaa2bc20b235dbf24"}, - {file = "aiohttp-3.8.4-cp311-cp311-win32.whl", hash = "sha256:bbcf1a76cf6f6dacf2c7f4d2ebd411438c275faa1dc0c68e46eb84eebd05dd7d"}, - {file = "aiohttp-3.8.4-cp311-cp311-win_amd64.whl", hash = "sha256:6e74dd54f7239fcffe07913ff8b964e28b712f09846e20de78676ce2a3dc0bfc"}, - {file = "aiohttp-3.8.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:880e15bb6dad90549b43f796b391cfffd7af373f4646784795e20d92606b7a51"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb96fa6b56bb536c42d6a4a87dfca570ff8e52de2d63cabebfd6fb67049c34b6"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a6cadebe132e90cefa77e45f2d2f1a4b2ce5c6b1bfc1656c1ddafcfe4ba8131"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f352b62b45dff37b55ddd7b9c0c8672c4dd2eb9c0f9c11d395075a84e2c40f75"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ab43061a0c81198d88f39aaf90dae9a7744620978f7ef3e3708339b8ed2ef01"}, - {file = "aiohttp-3.8.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9cb1565a7ad52e096a6988e2ee0397f72fe056dadf75d17fa6b5aebaea05622"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:1b3ea7edd2d24538959c1c1abf97c744d879d4e541d38305f9bd7d9b10c9ec41"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:7c7837fe8037e96b6dd5cfcf47263c1620a9d332a87ec06a6ca4564e56bd0f36"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:3b90467ebc3d9fa5b0f9b6489dfb2c304a1db7b9946fa92aa76a831b9d587e99"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:cab9401de3ea52b4b4c6971db5fb5c999bd4260898af972bf23de1c6b5dd9d71"}, - {file = "aiohttp-3.8.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d1f9282c5f2b5e241034a009779e7b2a1aa045f667ff521e7948ea9b56e0c5ff"}, - {file = "aiohttp-3.8.4-cp36-cp36m-win32.whl", hash = "sha256:5e14f25765a578a0a634d5f0cd1e2c3f53964553a00347998dfdf96b8137f777"}, - {file = "aiohttp-3.8.4-cp36-cp36m-win_amd64.whl", hash = "sha256:4c745b109057e7e5f1848c689ee4fb3a016c8d4d92da52b312f8a509f83aa05e"}, - {file = "aiohttp-3.8.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:aede4df4eeb926c8fa70de46c340a1bc2c6079e1c40ccf7b0eae1313ffd33519"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ddaae3f3d32fc2cb4c53fab020b69a05c8ab1f02e0e59665c6f7a0d3a5be54f"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4eb3b82ca349cf6fadcdc7abcc8b3a50ab74a62e9113ab7a8ebc268aad35bb9"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bcb89336efa095ea21b30f9e686763f2be4478f1b0a616969551982c4ee4c3b"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c08e8ed6fa3d477e501ec9db169bfac8140e830aa372d77e4a43084d8dd91ab"}, - {file = "aiohttp-3.8.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6cd05ea06daca6ad6a4ca3ba7fe7dc5b5de063ff4daec6170ec0f9979f6c332"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7a00a9ed8d6e725b55ef98b1b35c88013245f35f68b1b12c5cd4100dddac333"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:de04b491d0e5007ee1b63a309956eaed959a49f5bb4e84b26c8f5d49de140fa9"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:40653609b3bf50611356e6b6554e3a331f6879fa7116f3959b20e3528783e699"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dbf3a08a06b3f433013c143ebd72c15cac33d2914b8ea4bea7ac2c23578815d6"}, - {file = "aiohttp-3.8.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854f422ac44af92bfe172d8e73229c270dc09b96535e8a548f99c84f82dde241"}, - {file = "aiohttp-3.8.4-cp37-cp37m-win32.whl", hash = "sha256:aeb29c84bb53a84b1a81c6c09d24cf33bb8432cc5c39979021cc0f98c1292a1a"}, - {file = "aiohttp-3.8.4-cp37-cp37m-win_amd64.whl", hash = "sha256:db3fc6120bce9f446d13b1b834ea5b15341ca9ff3f335e4a951a6ead31105480"}, - {file = "aiohttp-3.8.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fabb87dd8850ef0f7fe2b366d44b77d7e6fa2ea87861ab3844da99291e81e60f"}, - {file = "aiohttp-3.8.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91f6d540163f90bbaef9387e65f18f73ffd7c79f5225ac3d3f61df7b0d01ad15"}, - {file = "aiohttp-3.8.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d265f09a75a79a788237d7f9054f929ced2e69eb0bb79de3798c468d8a90f945"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d89efa095ca7d442a6d0cbc755f9e08190ba40069b235c9886a8763b03785da"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4dac314662f4e2aa5009977b652d9b8db7121b46c38f2073bfeed9f4049732cd"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe11310ae1e4cd560035598c3f29d86cef39a83d244c7466f95c27ae04850f10"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ddb2a2026c3f6a68c3998a6c47ab6795e4127315d2e35a09997da21865757f8"}, - {file = "aiohttp-3.8.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e75b89ac3bd27d2d043b234aa7b734c38ba1b0e43f07787130a0ecac1e12228a"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6e601588f2b502c93c30cd5a45bfc665faaf37bbe835b7cfd461753068232074"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a5d794d1ae64e7753e405ba58e08fcfa73e3fad93ef9b7e31112ef3c9a0efb52"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:a1f4689c9a1462f3df0a1f7e797791cd6b124ddbee2b570d34e7f38ade0e2c71"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3032dcb1c35bc330134a5b8a5d4f68c1a87252dfc6e1262c65a7e30e62298275"}, - {file = "aiohttp-3.8.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8189c56eb0ddbb95bfadb8f60ea1b22fcfa659396ea36f6adcc521213cd7b44d"}, - {file = "aiohttp-3.8.4-cp38-cp38-win32.whl", hash = "sha256:33587f26dcee66efb2fff3c177547bd0449ab7edf1b73a7f5dea1e38609a0c54"}, - {file = "aiohttp-3.8.4-cp38-cp38-win_amd64.whl", hash = "sha256:e595432ac259af2d4630008bf638873d69346372d38255774c0e286951e8b79f"}, - {file = "aiohttp-3.8.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5a7bdf9e57126dc345b683c3632e8ba317c31d2a41acd5800c10640387d193ed"}, - {file = "aiohttp-3.8.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:22f6eab15b6db242499a16de87939a342f5a950ad0abaf1532038e2ce7d31567"}, - {file = "aiohttp-3.8.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7235604476a76ef249bd64cb8274ed24ccf6995c4a8b51a237005ee7a57e8643"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea9eb976ffdd79d0e893869cfe179a8f60f152d42cb64622fca418cd9b18dc2a"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92c0cea74a2a81c4c76b62ea1cac163ecb20fb3ba3a75c909b9fa71b4ad493cf"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:493f5bc2f8307286b7799c6d899d388bbaa7dfa6c4caf4f97ef7521b9cb13719"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a63f03189a6fa7c900226e3ef5ba4d3bd047e18f445e69adbd65af433add5a2"}, - {file = "aiohttp-3.8.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10c8cefcff98fd9168cdd86c4da8b84baaa90bf2da2269c6161984e6737bf23e"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bca5f24726e2919de94f047739d0a4fc01372801a3672708260546aa2601bf57"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:03baa76b730e4e15a45f81dfe29a8d910314143414e528737f8589ec60cf7391"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8c29c77cc57e40f84acef9bfb904373a4e89a4e8b74e71aa8075c021ec9078c2"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:03543dcf98a6619254b409be2d22b51f21ec66272be4ebda7b04e6412e4b2e14"}, - {file = "aiohttp-3.8.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17b79c2963db82086229012cff93ea55196ed31f6493bb1ccd2c62f1724324e4"}, - {file = "aiohttp-3.8.4-cp39-cp39-win32.whl", hash = "sha256:34ce9f93a4a68d1272d26030655dd1b58ff727b3ed2a33d80ec433561b03d67a"}, - {file = "aiohttp-3.8.4-cp39-cp39-win_amd64.whl", hash = "sha256:41a86a69bb63bb2fc3dc9ad5ea9f10f1c9c8e282b471931be0268ddd09430b04"}, - {file = "aiohttp-3.8.4.tar.gz", hash = "sha256:bf2e1a9162c1e441bf805a1fd166e249d574ca04e03b34f97e2928769e91ab5c"}, +python-versions = ">=3.8" +files = [ + {file = "aiohttp-3.9.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fcde4c397f673fdec23e6b05ebf8d4751314fa7c24f93334bf1f1364c1c69ac7"}, + {file = "aiohttp-3.9.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d6b3f1fabe465e819aed2c421a6743d8debbde79b6a8600739300630a01bf2c"}, + {file = "aiohttp-3.9.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ae79c1bc12c34082d92bf9422764f799aee4746fd7a392db46b7fd357d4a17a"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d3ebb9e1316ec74277d19c5f482f98cc65a73ccd5430540d6d11682cd857430"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84dabd95154f43a2ea80deffec9cb44d2e301e38a0c9d331cc4aa0166fe28ae3"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c8a02fbeca6f63cb1f0475c799679057fc9268b77075ab7cf3f1c600e81dd46b"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c26959ca7b75ff768e2776d8055bf9582a6267e24556bb7f7bd29e677932be72"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:714d4e5231fed4ba2762ed489b4aec07b2b9953cf4ee31e9871caac895a839c0"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7a6a8354f1b62e15d48e04350f13e726fa08b62c3d7b8401c0a1314f02e3558"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c413016880e03e69d166efb5a1a95d40f83d5a3a648d16486592c49ffb76d0db"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ff84aeb864e0fac81f676be9f4685f0527b660f1efdc40dcede3c251ef1e867f"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ad7f2919d7dac062f24d6f5fe95d401597fbb015a25771f85e692d043c9d7832"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:702e2c7c187c1a498a4e2b03155d52658fdd6fda882d3d7fbb891a5cf108bb10"}, + {file = "aiohttp-3.9.5-cp310-cp310-win32.whl", hash = "sha256:67c3119f5ddc7261d47163ed86d760ddf0e625cd6246b4ed852e82159617b5fb"}, + {file = "aiohttp-3.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:471f0ef53ccedec9995287f02caf0c068732f026455f07db3f01a46e49d76bbb"}, + {file = "aiohttp-3.9.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ae53e33ee7476dd3d1132f932eeb39bf6125083820049d06edcdca4381f342"}, + {file = "aiohttp-3.9.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c088c4d70d21f8ca5c0b8b5403fe84a7bc8e024161febdd4ef04575ef35d474d"}, + {file = "aiohttp-3.9.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:639d0042b7670222f33b0028de6b4e2fad6451462ce7df2af8aee37dcac55424"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f26383adb94da5e7fb388d441bf09c61e5e35f455a3217bfd790c6b6bc64b2ee"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66331d00fb28dc90aa606d9a54304af76b335ae204d1836f65797d6fe27f1ca2"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ff550491f5492ab5ed3533e76b8567f4b37bd2995e780a1f46bca2024223233"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f22eb3a6c1080d862befa0a89c380b4dafce29dc6cd56083f630073d102eb595"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a81b1143d42b66ffc40a441379387076243ef7b51019204fd3ec36b9f69e77d6"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f64fd07515dad67f24b6ea4a66ae2876c01031de91c93075b8093f07c0a2d93d"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:93e22add827447d2e26d67c9ac0161756007f152fdc5210277d00a85f6c92323"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:55b39c8684a46e56ef8c8d24faf02de4a2b2ac60d26cee93bc595651ff545de9"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4715a9b778f4293b9f8ae7a0a7cef9829f02ff8d6277a39d7f40565c737d3771"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:afc52b8d969eff14e069a710057d15ab9ac17cd4b6753042c407dcea0e40bf75"}, + {file = "aiohttp-3.9.5-cp311-cp311-win32.whl", hash = "sha256:b3df71da99c98534be076196791adca8819761f0bf6e08e07fd7da25127150d6"}, + {file = "aiohttp-3.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:88e311d98cc0bf45b62fc46c66753a83445f5ab20038bcc1b8a1cc05666f428a"}, + {file = "aiohttp-3.9.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c7a4b7a6cf5b6eb11e109a9755fd4fda7d57395f8c575e166d363b9fc3ec4678"}, + {file = "aiohttp-3.9.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0a158704edf0abcac8ac371fbb54044f3270bdbc93e254a82b6c82be1ef08f3c"}, + {file = "aiohttp-3.9.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d153f652a687a8e95ad367a86a61e8d53d528b0530ef382ec5aaf533140ed00f"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82a6a97d9771cb48ae16979c3a3a9a18b600a8505b1115cfe354dfb2054468b4"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60cdbd56f4cad9f69c35eaac0fbbdf1f77b0ff9456cebd4902f3dd1cf096464c"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8676e8fd73141ded15ea586de0b7cda1542960a7b9ad89b2b06428e97125d4fa"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da00da442a0e31f1c69d26d224e1efd3a1ca5bcbf210978a2ca7426dfcae9f58"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18f634d540dd099c262e9f887c8bbacc959847cfe5da7a0e2e1cf3f14dbf2daf"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:320e8618eda64e19d11bdb3bd04ccc0a816c17eaecb7e4945d01deee2a22f95f"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:2faa61a904b83142747fc6a6d7ad8fccff898c849123030f8e75d5d967fd4a81"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:8c64a6dc3fe5db7b1b4d2b5cb84c4f677768bdc340611eca673afb7cf416ef5a"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:393c7aba2b55559ef7ab791c94b44f7482a07bf7640d17b341b79081f5e5cd1a"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c671dc117c2c21a1ca10c116cfcd6e3e44da7fcde37bf83b2be485ab377b25da"}, + {file = "aiohttp-3.9.5-cp312-cp312-win32.whl", hash = "sha256:5a7ee16aab26e76add4afc45e8f8206c95d1d75540f1039b84a03c3b3800dd59"}, + {file = "aiohttp-3.9.5-cp312-cp312-win_amd64.whl", hash = "sha256:5ca51eadbd67045396bc92a4345d1790b7301c14d1848feaac1d6a6c9289e888"}, + {file = "aiohttp-3.9.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:694d828b5c41255e54bc2dddb51a9f5150b4eefa9886e38b52605a05d96566e8"}, + {file = "aiohttp-3.9.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0605cc2c0088fcaae79f01c913a38611ad09ba68ff482402d3410bf59039bfb8"}, + {file = "aiohttp-3.9.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4558e5012ee03d2638c681e156461d37b7a113fe13970d438d95d10173d25f78"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dbc053ac75ccc63dc3a3cc547b98c7258ec35a215a92bd9f983e0aac95d3d5b"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4109adee842b90671f1b689901b948f347325045c15f46b39797ae1bf17019de"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6ea1a5b409a85477fd8e5ee6ad8f0e40bf2844c270955e09360418cfd09abac"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3c2890ca8c59ee683fd09adf32321a40fe1cf164e3387799efb2acebf090c11"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3916c8692dbd9d55c523374a3b8213e628424d19116ac4308e434dbf6d95bbdd"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8d1964eb7617907c792ca00b341b5ec3e01ae8c280825deadbbd678447b127e1"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d5ab8e1f6bee051a4bf6195e38a5c13e5e161cb7bad83d8854524798bd9fcd6e"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:52c27110f3862a1afbcb2af4281fc9fdc40327fa286c4625dfee247c3ba90156"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7f64cbd44443e80094309875d4f9c71d0401e966d191c3d469cde4642bc2e031"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8b4f72fbb66279624bfe83fd5eb6aea0022dad8eec62b71e7bf63ee1caadeafe"}, + {file = "aiohttp-3.9.5-cp38-cp38-win32.whl", hash = "sha256:6380c039ec52866c06d69b5c7aad5478b24ed11696f0e72f6b807cfb261453da"}, + {file = "aiohttp-3.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:da22dab31d7180f8c3ac7c7635f3bcd53808f374f6aa333fe0b0b9e14b01f91a"}, + {file = "aiohttp-3.9.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1732102949ff6087589408d76cd6dea656b93c896b011ecafff418c9661dc4ed"}, + {file = "aiohttp-3.9.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c6021d296318cb6f9414b48e6a439a7f5d1f665464da507e8ff640848ee2a58a"}, + {file = "aiohttp-3.9.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:239f975589a944eeb1bad26b8b140a59a3a320067fb3cd10b75c3092405a1372"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b7b30258348082826d274504fbc7c849959f1989d86c29bc355107accec6cfb"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd2adf5c87ff6d8b277814a28a535b59e20bfea40a101db6b3bdca7e9926bc24"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a3d838441bebcf5cf442700e3963f58b5c33f015341f9ea86dcd7d503c07e2"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3a1ae66e3d0c17cf65c08968a5ee3180c5a95920ec2731f53343fac9bad106"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9c69e77370cce2d6df5d12b4e12bdcca60c47ba13d1cbbc8645dd005a20b738b"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf56238f4bbf49dab8c2dc2e6b1b68502b1e88d335bea59b3f5b9f4c001475"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d1469f228cd9ffddd396d9948b8c9cd8022b6d1bf1e40c6f25b0fb90b4f893ed"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:45731330e754f5811c314901cebdf19dd776a44b31927fa4b4dbecab9e457b0c"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:3fcb4046d2904378e3aeea1df51f697b0467f2aac55d232c87ba162709478c46"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8cf142aa6c1a751fcb364158fd710b8a9be874b81889c2bd13aa8893197455e2"}, + {file = "aiohttp-3.9.5-cp39-cp39-win32.whl", hash = "sha256:7b179eea70833c8dee51ec42f3b4097bd6370892fa93f510f76762105568cf09"}, + {file = "aiohttp-3.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:38d80498e2e169bc61418ff36170e0aad0cd268da8b38a17c4cf29d254a8b3f1"}, + {file = "aiohttp-3.9.5.tar.gz", hash = "sha256:edea7d15772ceeb29db4aff55e482d4bcfb6ae160ce144f2682de02f6d693551"}, ] [package.dependencies] aiosignal = ">=1.1.2" -async-timeout = ">=4.0.0a3,<5.0" attrs = ">=17.3.0" -charset-normalizer = ">=2.0,<4.0" frozenlist = ">=1.1.1" multidict = ">=4.5,<7.0" yarl = ">=1.0,<2.0" [package.extras] -speedups = ["Brotli", "aiodns", "cchardet"] +speedups = ["Brotli", "aiodns", "brotlicffi"] [[package]] name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -126,56 +111,38 @@ frozenlist = ">=1.1.0" [[package]] name = "astroid" -version = "2.14.2" +version = "3.2.2" description = "An abstract syntax tree for Python with inference support." -category = "dev" -optional = false -python-versions = ">=3.7.2" -files = [ - {file = "astroid-2.14.2-py3-none-any.whl", hash = "sha256:0e0e3709d64fbffd3037e4ff403580550f14471fd3eaae9fa11cc9a5c7901153"}, - {file = "astroid-2.14.2.tar.gz", hash = "sha256:a3cf9f02c53dd259144a7e8f3ccd75d67c9a8c716ef183e0c1f291bc5d7bb3cf"}, -] - -[package.dependencies] -lazy-object-proxy = ">=1.4.0" -wrapt = {version = ">=1.14,<2", markers = "python_version >= \"3.11\""} - -[[package]] -name = "async-timeout" -version = "4.0.2" -description = "Timeout context manager for asyncio programs" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8.0" files = [ - {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, - {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, + {file = "astroid-3.2.2-py3-none-any.whl", hash = "sha256:e8a0083b4bb28fcffb6207a3bfc9e5d0a68be951dd7e336d5dcf639c682388c0"}, + {file = "astroid-3.2.2.tar.gz", hash = "sha256:8ead48e31b92b2e217b6c9733a21afafe479d52d6e164dd25fb1a770c7c3cf94"}, ] [[package]] name = "attrs" -version = "22.2.0" +version = "23.2.0" description = "Classes Without Boilerplate" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, - {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] [package.extras] -cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] -tests = ["attrs[tests-no-zope]", "zope.interface"] -tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] [[package]] name = "base58" version = "2.1.1" description = "Base58 and Base58Check implementation." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -188,134 +155,164 @@ tests = ["PyHamcrest (>=2.0.2)", "mypy", "pytest (>=4.6)", "pytest-benchmark", " [[package]] name = "bitarray" -version = "2.7.3" +version = "2.9.2" description = "efficient arrays of booleans -- C extension" -category = "main" optional = false python-versions = "*" files = [ - {file = "bitarray-2.7.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:979d42e0b2c3113526f9716a461e08671788a23ce7e3b5cd090ce3e6a6762641"}, - {file = "bitarray-2.7.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:860edf8533223d82bd6201894bcaf540f828f49075f363390eecf04b12fb94cb"}, - {file = "bitarray-2.7.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:78378d8dacbe1f4f263347f42ec0a41cc2097cd671c6ac30a65a838284a5e141"}, - {file = "bitarray-2.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:888df211aafe5fad41c0792a686d95c8ba37345d5037f437aa3c09608f9c3b56"}, - {file = "bitarray-2.7.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fb3f003dee96dbf24a6df71443557f249b17b20083c189995302b14eb01530bf"}, - {file = "bitarray-2.7.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c531532c21bc1063e65957a1a85a2d13601ec21801f70821c89d9339b16ebc78"}, - {file = "bitarray-2.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b8fd92c8026e4ba6874e94f538890e35bef2a3a18ea54e3663c578b7916ade1"}, - {file = "bitarray-2.7.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d19c34a2121eccfeb642d4ad71163bd3342a8f3a99e6724fe824bdfbc0a5b65"}, - {file = "bitarray-2.7.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:102db74ee82ec5774aba01481e73eedaebd27ba167344a81d3b42e6fbf9ffb77"}, - {file = "bitarray-2.7.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7f6540b45b2230442f7a0614745131e0a6f28251f5d33ac19d0ed61d80db7153"}, - {file = "bitarray-2.7.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:99c9345c417a9cff98f9f6e59b0350dcc10c2e0e1ea66acf7946de1cd60541fa"}, - {file = "bitarray-2.7.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:a1d439c98e65ab8e5fbcc2b242a16e7a3f076974bff78185ff42ba2d4c220032"}, - {file = "bitarray-2.7.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:87897ec0e4876c9f2c1ae313519de0ed2ad8041a4d2210a083f9b4a239add2e3"}, - {file = "bitarray-2.7.3-cp310-cp310-win32.whl", hash = "sha256:cb46c3a4002c8322dd0e1b4b53f8a647dcb0f199f5c7a1fc03d3880c3eabbd2c"}, - {file = "bitarray-2.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:5df10eb9b794932b0cf806f412d1c6d04fb7655ca7ae5caf6354b9edc380a5f7"}, - {file = "bitarray-2.7.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:27524bc92fdeb464a5057a4677a35f482cf30be2e920bd1d11c46de533cafda6"}, - {file = "bitarray-2.7.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3cf37431de779b29e5c0d8e36868f77f6df53c3c19c20e8404137e257dc80040"}, - {file = "bitarray-2.7.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8abd23f94cdcce971d932a5f0a066d40fbc61901fd087aa70d32cccd1793bd20"}, - {file = "bitarray-2.7.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7659bdfe7716b14a39007e31e957fa64d7f0d9e40a1dbd024bd81b972d76bffb"}, - {file = "bitarray-2.7.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:da1570f301abdfda68f4fdb40c4d3f09af4bb6e4550b4fa5395db0d142b680bc"}, - {file = "bitarray-2.7.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8becbb9649fd29ee577f9f0405ce2fba5cf9fa2c290c9b044bc235c04473f213"}, - {file = "bitarray-2.7.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72fd7f6f940bc42914c86700591ccfd1daeff0e414cefcbd7843117df2fac4e9"}, - {file = "bitarray-2.7.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23b7bada6d6b62cba08f4a1b8a95da2d8592aae1db3c167dcb52abcba0a7bef5"}, - {file = "bitarray-2.7.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4b2d150a81a981537801ac7d4f4f5d082c48343612a21f4e2c4cd2e887973bd5"}, - {file = "bitarray-2.7.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1502660ab489b1f18c3493c766252cd5d24bc1cbf4bdf3594e0a30de142ed453"}, - {file = "bitarray-2.7.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:91f43f6b6c9129a56d3e2dccb8b88ffce0e4f4893dd9d69d285676bdf5b9ca14"}, - {file = "bitarray-2.7.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:a69c99274aee2ffdc7f1cfd34044ccb7155790d6f5217d677ea46a6ddead6dd2"}, - {file = "bitarray-2.7.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d63f20299441e32171f08fc62f7ea7e401cc12a96f67a36ab2d76439ecfcb118"}, - {file = "bitarray-2.7.3-cp311-cp311-win32.whl", hash = "sha256:0b84fd9dbf999cbca1090a7703aa1404cd01af4035c6ba3adf69d41280611fb6"}, - {file = "bitarray-2.7.3-cp311-cp311-win_amd64.whl", hash = "sha256:76bbbb9ceebb9cbb2b14369b3681fecab226792b339f612e79f6575ca31fed45"}, - {file = "bitarray-2.7.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50d5e2c026b3e3d145f64c457338ea99edcbdd302fdcbd96418251ac51a98a59"}, - {file = "bitarray-2.7.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d571056115bbdc18f199a9ee4c2a1b5884f5e63a3c05fe43d2fc7fc67320515"}, - {file = "bitarray-2.7.3-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2a0313657e6656efca2148cfc91c50fdafca6f811b6c7d0906e6ba57134e560"}, - {file = "bitarray-2.7.3-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d3b5abb73c45d40d27f9795dac9d6eb1515729c13f93dd67df2be07be6549990"}, - {file = "bitarray-2.7.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7776c070943f45cd8303543a6625cf82f2e000ef9c885d52d7828be099e52f42"}, - {file = "bitarray-2.7.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:057f9c53a34e42deed6e8813a82b9c85924f4728be28e3b9b65144569ac5a387"}, - {file = "bitarray-2.7.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8591ad5768860ad186dc94fd58b2932604a7639b57eefbbff2b4865af3407691"}, - {file = "bitarray-2.7.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:bd7f4b2df89bf4e298756c0be0be67fb84d6aa49bda60d46805d43f0e643abd5"}, - {file = "bitarray-2.7.3-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:433f91c8ab8338662aaa86b0677e6c15c35f8f7b65d4c43d7d1647a8198bc0b0"}, - {file = "bitarray-2.7.3-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:31e60d8341c3189aa156ca8cb2f6370b29d79cf132e3d091714b0a5a9097eb69"}, - {file = "bitarray-2.7.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ea33ed09157e032f0a7a2627ef87f156e9927697f59b55961439d34bf45af23a"}, - {file = "bitarray-2.7.3-cp36-cp36m-win32.whl", hash = "sha256:302149aaff75939beb8af7f32ac9bf922480033a24fb54f4ebc0c9dc175247c4"}, - {file = "bitarray-2.7.3-cp36-cp36m-win_amd64.whl", hash = "sha256:7a8995737fae8de03b31ed83acf4f4326a55b217022009d18be19ff87fc9010e"}, - {file = "bitarray-2.7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8b2f31a4cc28aef27355ab896e4b4cc2da2204b2b7adb674d8be7fefa0c93868"}, - {file = "bitarray-2.7.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5df624ee8a4098c3b1149f4817f2a4a0121c4920e1c114af324bc52d6659e2b"}, - {file = "bitarray-2.7.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb1d60ed709989e34e7158d97fdb077a2f2dfc505998a84161a70f81a6101172"}, - {file = "bitarray-2.7.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:748847e58c45a37f23db1f53a6dc16ae32aa80ee504653d79336830de1a79ed7"}, - {file = "bitarray-2.7.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4b7fdb9772e087174f446655bbc497a1600b5758f279c6d44fcf344c13d5c8a"}, - {file = "bitarray-2.7.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:86e9c48ffeddb0f943e87ab65e1e95dccc9b44ef3761af3bf9642973ab7646d2"}, - {file = "bitarray-2.7.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0d1f49cc51919d6fa0f7eebd073d2c620b80079aa537d084a7fafb46a35c7a4d"}, - {file = "bitarray-2.7.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b43d56c7c96f5a055f4051be426496db2a616840645d0ab3733d5ceacb2f701b"}, - {file = "bitarray-2.7.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:01f8d02c3eae82c98d4259777cb2f042a0b3989d7dceeb37c643cb94b91d5a42"}, - {file = "bitarray-2.7.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d089b1d0b157c9a484f8f7475eecea813d0dc3818adc5bf352903da14fe88fc3"}, - {file = "bitarray-2.7.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1362e9fb78ca72aa52ec1f1fbd62872801302001b0156ed2a1e707850cd30ffd"}, - {file = "bitarray-2.7.3-cp37-cp37m-win32.whl", hash = "sha256:2cdf5700537e5aa4ec9f4a0b498b8d5b03b9859d503e01ea17a6a134a838aa30"}, - {file = "bitarray-2.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:1e1553933f4533040491f4e4499bcbbfcee42c4056f56d7e18010e779daab33d"}, - {file = "bitarray-2.7.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:1048a29b3d72b1821a3ae9e8d64e71ed96c53a1a36b1da6db02091a424a8f795"}, - {file = "bitarray-2.7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:10dc358fe29d7a4c5be78ab2fb5aa50cb8066babd23e0b5589eb68e26afe58d8"}, - {file = "bitarray-2.7.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8ab6770833976448a9a973bc0df63adedc4c30de4774cec5a9928fc496423ebb"}, - {file = "bitarray-2.7.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abe2f829f6f2d330bccf1bcde2192264ab9a15d6d00e507265f46dc66557014"}, - {file = "bitarray-2.7.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87851a82bdf849e3c40ff6d8af5f734634e17f52a8f7f7e74486c2f8ce717578"}, - {file = "bitarray-2.7.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a5fc2512bdf5289a1412c936c65d17881d2b46edb0036c63a8d5605dc8d398a3"}, - {file = "bitarray-2.7.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1289f408a8b5c87cdb4fd7975d4021c6e61209ccb956d0411e72bf43c7f78463"}, - {file = "bitarray-2.7.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ee181cc00aaba38d9812f4df4e7d828105b6dde3b068cd2c43f1d8f395e0046"}, - {file = "bitarray-2.7.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:00e93f70cbcbeabd1e79accf1b6f5b2424cd40556e7877f618549523d0031c98"}, - {file = "bitarray-2.7.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3fb6a952796d16c3a309d866eef56a8f4e5591d112c22446e67d33ecb096b44b"}, - {file = "bitarray-2.7.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:0fe747a134f7f5bc0877eee58090ae7e7f23628eeb459f681ade65719c3f246a"}, - {file = "bitarray-2.7.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:2c1b2c91bf991b5c641faee78dd5a751dff6155ec51c7a6c7f922dc85431898e"}, - {file = "bitarray-2.7.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c3956ae54285ab30d802756144887e30e013f81c9f03e5ffff9daa46d8ca0154"}, - {file = "bitarray-2.7.3-cp38-cp38-win32.whl", hash = "sha256:00a6fc4355bd4e6ead54d05187dc4ea39f0af439b336ae113f0194673ed730ae"}, - {file = "bitarray-2.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:305e6f7441c007f296644ba3899c0306ce9fd7a482dbbc06b6e7b7bd6e0ddabc"}, - {file = "bitarray-2.7.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fe80c23409efb41b86efb5e45f334420a9b5b7828f5b3d08b5ff28f03a024d9e"}, - {file = "bitarray-2.7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:16345146b61e93ca20679c83537ccf7245f78b17035f5b1a436fd2b75da04c5e"}, - {file = "bitarray-2.7.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1af9b720a048c69e999094e2310138b7cfca5471a9d2c1dbe4b53dd10e516720"}, - {file = "bitarray-2.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:088e6e9ea7f0eaf8b672679a68096dbc0a7a7b7a4ed567860f7362e1588370a6"}, - {file = "bitarray-2.7.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:122cd70ee0de2cc9d94da8b8ebcb7dca12b9f4d3beefb94c11e110e1d87503bb"}, - {file = "bitarray-2.7.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cb9a8ee23416bd0cfd457118978bc2f6f02c20b95336db486887f670bf92c2b7"}, - {file = "bitarray-2.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a544f99c24b6f658907eb9edf290a9c54f4106738b2ab84cd19dc6013cc3abf"}, - {file = "bitarray-2.7.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:980f6564218f853a9341fb045446539d4153338926ed2fb222e86dc9b2ae9b8f"}, - {file = "bitarray-2.7.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f64abe9301b918d2c352e42198cea0196f3639bc1ad23a4a9d8ae97f66068901"}, - {file = "bitarray-2.7.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:029c724bf38c6616b90b1c423b846b63f8d607ed5a23d270e3862696d88a5392"}, - {file = "bitarray-2.7.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:16cb00911584a6e9ca0f42c305714898120dc6bfbbec90dacedeed4690331a47"}, - {file = "bitarray-2.7.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:699b0134e87c0c4e3b224d879d218c4385a06e6b72df73b4c9c9d549155fb837"}, - {file = "bitarray-2.7.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b508e1bba4ec68fd0ef28505e2dad2f56de7df710c8334c97036705a562cb908"}, - {file = "bitarray-2.7.3-cp39-cp39-win32.whl", hash = "sha256:4b84230624d15868e407ba8b66df54fc69ee6a9e9cb6d51eb264b8f2614596f1"}, - {file = "bitarray-2.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:757a08bf0aed5a650a399f8c66bcba00c210bce34408b6d7b09b4837bee8f4da"}, - {file = "bitarray-2.7.3.tar.gz", hash = "sha256:f71256a32609b036adad932e1228b66a6b4e2cae6be397e588ddc0babd9a78b9"}, + {file = "bitarray-2.9.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:917905de565d9576eb20f53c797c15ba88b9f4f19728acabec8d01eee1d3756a"}, + {file = "bitarray-2.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b35bfcb08b7693ab4bf9059111a6e9f14e07d57ac93cd967c420db58ab9b71e1"}, + {file = "bitarray-2.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ea1923d2e7880f9e1959e035da661767b5a2e16a45dfd57d6aa831e8b65ee1bf"}, + {file = "bitarray-2.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0b63a565e8a311cc8348ff1262d5784df0f79d64031d546411afd5dd7ef67d"}, + {file = "bitarray-2.9.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cf0620da2b81946d28c0b16f3e3704d38e9837d85ee4f0652816e2609aaa4fed"}, + {file = "bitarray-2.9.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:79a9b8b05f2876c7195a2b698c47528e86a73c61ea203394ff8e7a4434bda5c8"}, + {file = "bitarray-2.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:345c76b349ff145549652436235c5532e5bfe9db690db6f0a6ad301c62b9ef21"}, + {file = "bitarray-2.9.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e2936f090bf3f4d1771f44f9077ebccdbc0415d2b598d51a969afcb519df505"}, + {file = "bitarray-2.9.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f9346e98fc2abcef90b942973087e2462af6d3e3710e82938078d3493f7fef52"}, + {file = "bitarray-2.9.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e6ec283d4741befb86e8c3ea2e9ac1d17416c956d392107e45263e736954b1f7"}, + {file = "bitarray-2.9.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:962892646599529917ef26266091e4cb3077c88b93c3833a909d68dcc971c4e3"}, + {file = "bitarray-2.9.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:e8da5355d7d75a52df5b84750989e34e39919ec7e59fafc4c104cc1607ab2d31"}, + {file = "bitarray-2.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:603e7d640e54ad764d2b4da6b61e126259af84f253a20f512dd10689566e5478"}, + {file = "bitarray-2.9.2-cp310-cp310-win32.whl", hash = "sha256:f00079f8e69d75c2a417de7961a77612bb77ef46c09bc74607d86de4740771ef"}, + {file = "bitarray-2.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:1bb33673e7f7190a65f0a940c1ef63266abdb391f4a3e544a47542d40a81f536"}, + {file = "bitarray-2.9.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fe71fd4b76380c2772f96f1e53a524da7063645d647a4fcd3b651bdd80ca0f2e"}, + {file = "bitarray-2.9.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d527172919cdea1e13994a66d9708a80c3d33dedcf2f0548e4925e600fef3a3a"}, + {file = "bitarray-2.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:052c5073bdcaa9dd10628d99d37a2f33ec09364b86dd1f6281e2d9f8d3db3060"}, + {file = "bitarray-2.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e064caa55a6ed493aca1eda06f8b3f689778bc780a75e6ad7724642ba5dc62f7"}, + {file = "bitarray-2.9.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:508069a04f658210fdeee85a7a0ca84db4bcc110cbb1d21f692caa13210f24a7"}, + {file = "bitarray-2.9.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4da73ebd537d75fa7bccfc2228fcaedea0803f21dd9d0bf0d3b67fef3c4af294"}, + {file = "bitarray-2.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cb378eaa65cd43098f11ff5d27e48ee3b956d2c00d2d6b5bfc2a09fe183be47"}, + {file = "bitarray-2.9.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d14c790b91f6cbcd9b718f88ed737c78939980c69ac8c7f03dd7e60040c12951"}, + {file = "bitarray-2.9.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7eea9318293bc0ea6447e9ebfba600a62f3428bea7e9c6d42170ae4f481dbab3"}, + {file = "bitarray-2.9.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b76ffec27c7450b8a334f967366a9ebadaea66ee43f5b530c12861b1a991f503"}, + {file = "bitarray-2.9.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:76b76a07d4ee611405045c6950a1e24c4362b6b44808d4ad6eea75e0dbc59af4"}, + {file = "bitarray-2.9.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:c7d16beeaaab15b075990cd26963d6b5b22e8c5becd131781514a00b8bdd04bd"}, + {file = "bitarray-2.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60df43e868a615c7e15117a1e1c2e5e11f48f6457280eba6ddf8fbefbec7da99"}, + {file = "bitarray-2.9.2-cp311-cp311-win32.whl", hash = "sha256:e788608ed7767b7b3bbde6d49058bccdf94df0de9ca75d13aa99020cc7e68095"}, + {file = "bitarray-2.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:a23397da092ef0a8cfe729571da64c2fc30ac18243caa82ac7c4f965087506ff"}, + {file = "bitarray-2.9.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:90e3a281ffe3897991091b7c46fca38c2675bfd4399ffe79dfeded6c52715436"}, + {file = "bitarray-2.9.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bed637b674db5e6c8a97a4a321e3e4d73e72d50b5c6b29950008a93069cc64cd"}, + {file = "bitarray-2.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e49066d251dbbe4e6e3a5c3937d85b589e40e2669ad0eef41a00f82ec17d844b"}, + {file = "bitarray-2.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c4344e96642e2211fb3a50558feff682c31563a4c64529a931769d40832ca79"}, + {file = "bitarray-2.9.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aeb60962ec4813c539a59fbd4f383509c7222b62c3fb1faa76b54943a613e33a"}, + {file = "bitarray-2.9.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ed0f7982f10581bb16553719e5e8f933e003f5b22f7d25a68bdb30fac630a6ff"}, + {file = "bitarray-2.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c71d1cabdeee0cdda4669168618f0e46b7dace207b29da7b63aaa1adc2b54081"}, + {file = "bitarray-2.9.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0ef2d0a6f1502d38d911d25609b44c6cc27bee0a4363dd295df78b075041b60"}, + {file = "bitarray-2.9.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6f71d92f533770fb027388b35b6e11988ab89242b883f48a6fe7202d238c61f8"}, + {file = "bitarray-2.9.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ba0734aa300757c924f3faf8148e1b8c247176a0ac8e16aefdf9c1eb19e868f7"}, + {file = "bitarray-2.9.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:d91406f413ccbf4af6ab5ae7bc78f772a95609f9ddd14123db36ef8c37116d95"}, + {file = "bitarray-2.9.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:87abb7f80c0a042f3fe8e5264da1a2756267450bb602110d5327b8eaff7682e7"}, + {file = "bitarray-2.9.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b558ce85579b51a2e38703877d1e93b7728a7af664dd45a34e833534f0b755d"}, + {file = "bitarray-2.9.2-cp312-cp312-win32.whl", hash = "sha256:dac2399ee2889fbdd3472bfc2ede74c34cceb1ccf29a339964281a16eb1d3188"}, + {file = "bitarray-2.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:48a30d718d1a6dfc22a49547450107abe8f4afdf2abdcbe76eb9ed88edc49498"}, + {file = "bitarray-2.9.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2c6be1b651fad8f3adb7a5aa12c65b612cd9b89530969af941844ae680f7d981"}, + {file = "bitarray-2.9.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5b399ae6ab975257ec359f03b48fc00b1c1cd109471e41903548469b8feae5c"}, + {file = "bitarray-2.9.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b3543c8a1cb286ad105f11c25d8d0f712f41c5c55f90be39f0e5a1376c7d0b0"}, + {file = "bitarray-2.9.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:03adaacb79e2fb8f483ab3a67665eec53bb3fd0cd5dbd7358741aef124688db3"}, + {file = "bitarray-2.9.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ae5b0657380d2581e13e46864d147a52c1e2bbac9f59b59c576e42fa7d10cf0"}, + {file = "bitarray-2.9.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c1f4bf6ea8eb9d7f30808c2e9894237a96650adfecbf5f3643862dc5982f89e"}, + {file = "bitarray-2.9.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a8873089be2aa15494c0f81af1209f6e1237d762c5065bc4766c1b84321e1b50"}, + {file = "bitarray-2.9.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:677e67f50e2559efc677a4366707070933ad5418b8347a603a49a070890b19bc"}, + {file = "bitarray-2.9.2-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:a620d8ce4ea2f1c73c6b6b1399e14cb68c6915e2be3fad5808c2998ed55b4acf"}, + {file = "bitarray-2.9.2-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:64115ccabbdbe279c24c367b629c6b1d3da9ed36c7420129e27c338a3971bfee"}, + {file = "bitarray-2.9.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:5d6fb422772e75385b76ad1c52f45a68bd4efafd8be8d0061c11877be74c4d43"}, + {file = "bitarray-2.9.2-cp36-cp36m-win32.whl", hash = "sha256:852e202875dd6dfd6139ce7ec4e98dac2b17d8d25934dc99900831e81c3adaef"}, + {file = "bitarray-2.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:7dfefdcb0dc6a3ba9936063cec65a74595571b375beabe18742b3d91d087eefd"}, + {file = "bitarray-2.9.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b306c4cf66912511422060f7f5e1149c8bdb404f8e00e600561b0749fdd45659"}, + {file = "bitarray-2.9.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a09c4f81635408e3387348f415521d4b94198c562c23330f560596a6aaa26eaf"}, + {file = "bitarray-2.9.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5361413fd2ecfdf44dc8f065177dc6aba97fa80a91b815586cb388763acf7f8d"}, + {file = "bitarray-2.9.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e8a9475d415ef1eaae7942df6f780fa4dcd48fce32825eda591a17abba869299"}, + {file = "bitarray-2.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9b87baa7bfff9a5878fcc1bffe49ecde6e647a72a64b39a69cd8a2992a43a34"}, + {file = "bitarray-2.9.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb6b86cfdfc503e92cb71c68766a24565359136961642504a7cc9faf936d9c88"}, + {file = "bitarray-2.9.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:cd56b8ae87ebc71bcacbd73615098e8a8de952ecbb5785b6b4e2b07da8a06e1f"}, + {file = "bitarray-2.9.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3fa909cfd675004aed8b4cc9df352415933656e0155a6209d878b7cb615c787e"}, + {file = "bitarray-2.9.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b069ca9bf728e0c5c5b60e00a89df9af34cc170c695c3bfa3b372d8f40288efb"}, + {file = "bitarray-2.9.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:6067f2f07a7121749858c7daa93c8774325c91590b3e81a299621e347740c2ae"}, + {file = "bitarray-2.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:321841cdad1dd0f58fe62e80e9c9c7531f8ebf8be93f047401e930dc47425b1e"}, + {file = "bitarray-2.9.2-cp37-cp37m-win32.whl", hash = "sha256:54e16e32e60973bb83c315de9975bc1bcfc9bd50bb13001c31da159bc49b0ca1"}, + {file = "bitarray-2.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:f4dcadb7b8034aa3491ee8f5a69b3d9ba9d7d1e55c3cc1fc45be313e708277f8"}, + {file = "bitarray-2.9.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:c8919fdbd3bb596b104388b56ae4b266eb28da1f2f7dff2e1f9334a21840fe96"}, + {file = "bitarray-2.9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eb7a9d8a2e400a1026de341ad48e21670a6261a75b06df162c5c39b0d0e7c8f4"}, + {file = "bitarray-2.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6ec84668dd7b937874a2b2c293cd14ba84f37be0d196dead852e0ada9815d807"}, + {file = "bitarray-2.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2de9a31c34e543ae089fd2a5ced01292f725190e379921384f695e2d7184bd3"}, + {file = "bitarray-2.9.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9521f49ae121a17c0a41e5112249e6fa7f6a571245b1118de81fb86e7c1bc1ce"}, + {file = "bitarray-2.9.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6cc6545d6d76542aee3d18c1c9485fb7b9812b8df4ebe52c4535ec42081b48f"}, + {file = "bitarray-2.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:856bbe1616425f71c0df5ef2e8755e878d9504d5a531acba58ab4273c52c117a"}, + {file = "bitarray-2.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4bba8042ea6ab331ade91bc435d81ad72fddb098e49108610b0ce7780c14e68"}, + {file = "bitarray-2.9.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a035da89c959d98afc813e3c62f052690d67cfd55a36592f25d734b70de7d4b0"}, + {file = "bitarray-2.9.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6d70b1579da7fb71be5a841a1f965d19aca0ef27f629cfc07d06b09aafd0a333"}, + {file = "bitarray-2.9.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:405b83bed28efaae6d86b6ab287c75712ead0adbfab2a1075a1b7ab47dad4d62"}, + {file = "bitarray-2.9.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7eb8be687c50da0b397d5e0ab7ca200b5ebb639e79a9f5e285851d1944c94be9"}, + {file = "bitarray-2.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:eceb551dfeaf19c609003a69a0cf8264b0efd7abc3791a11dfabf4788daf0d19"}, + {file = "bitarray-2.9.2-cp38-cp38-win32.whl", hash = "sha256:bb198c6ed1edbcdaf3d1fa3c9c9d1cdb7e179a5134ef5ee660b53cdec43b34e7"}, + {file = "bitarray-2.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:648d2f2685590b0103c67a937c2fb9e09bcc8dfb166f0c7c77bd341902a6f5b3"}, + {file = "bitarray-2.9.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ea816dc8f8e65841a8bbdd30e921edffeeb6f76efe6a1eb0da147b60d539d1cf"}, + {file = "bitarray-2.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4d0e32530f941c41eddfc77600ec89b65184cb909c549336463a738fab3ed285"}, + {file = "bitarray-2.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4a22266fb416a3b6c258bf7f83c9fe531ba0b755a56986a81ad69dc0f3bcc070"}, + {file = "bitarray-2.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc6d3e80dd8239850f2604833ff3168b28909c8a9357abfed95632cccd17e3e7"}, + {file = "bitarray-2.9.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f135e804986b12bf14f2cd1eb86674c47dea86c4c5f0fa13c88978876b97ebe6"}, + {file = "bitarray-2.9.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87580c7f7d14f7ec401eda7adac1e2a25e95153e9c339872c8ae61b3208819a1"}, + {file = "bitarray-2.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64b433e26993127732ac7b66a7821b2537c3044355798de7c5fcb0af34b8296f"}, + {file = "bitarray-2.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e497c535f2a9b68c69d36631bf2dba243e05eb343b00b9c7bbdc8c601c6802d"}, + {file = "bitarray-2.9.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e40b3cb9fa1edb4e0175d7c06345c49c7925fe93e39ef55ecb0bc40c906b0c09"}, + {file = "bitarray-2.9.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f2f8692f95c9e377eb19ca519d30d1f884b02feb7e115f798de47570a359e43f"}, + {file = "bitarray-2.9.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:f0b84fc50b6dbeced4fa390688c07c10a73222810fb0e08392bd1a1b8259de36"}, + {file = "bitarray-2.9.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d656ad38c942e38a470ddbce26b5020e08e1a7ea86b8fd413bb9024b5189993a"}, + {file = "bitarray-2.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6ab0f1dbfe5070db98771a56aa14797595acd45a1af9eadfb193851a270e7996"}, + {file = "bitarray-2.9.2-cp39-cp39-win32.whl", hash = "sha256:0a99b23ac845a9ea3157782c97465e6ae026fe0c7c4c1ed1d88f759fd6ea52d9"}, + {file = "bitarray-2.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:9bbcfc7c279e8d74b076e514e669b683f77b4a2a328585b3f16d4c5259c91222"}, + {file = "bitarray-2.9.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:43847799461d8ba71deb4d97b47250c2c2fb66d82cd3cb8b4caf52bb97c03034"}, + {file = "bitarray-2.9.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f44381b0a4bdf64416082f4f0e7140377ae962c0ced6f983c6d7bbfc034040"}, + {file = "bitarray-2.9.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a484061616fb4b158b80789bd3cb511f399d2116525a8b29b6334c68abc2310f"}, + {file = "bitarray-2.9.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ff9e38356cc803e06134cf8ae9758e836ccd1b793135ef3db53c7c5d71e93bc"}, + {file = "bitarray-2.9.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b44105792fbdcfbda3e26ee88786790fda409da4c71f6c2b73888108cf8f062f"}, + {file = "bitarray-2.9.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7e913098de169c7fc890638ce5e171387363eb812579e637c44261460ac00aa2"}, + {file = "bitarray-2.9.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6fe315355cdfe3ed22ef355b8bdc81a805ca4d0949d921576560e5b227a1112"}, + {file = "bitarray-2.9.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f708e91fdbe443f3bec2df394ed42328fb9b0446dff5cb4199023ac6499e09fd"}, + {file = "bitarray-2.9.2-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b7b09489b71f9f1f64c0fa0977e250ec24500767dab7383ba9912495849cadf"}, + {file = "bitarray-2.9.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:128cc3488176145b9b137fdcf54c1c201809bbb8dd30b260ee40afe915843b43"}, + {file = "bitarray-2.9.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:21f21e7f56206be346bdbda2a6bdb2165a5e6a11821f88fd4911c5a6bbbdc7e2"}, + {file = "bitarray-2.9.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f4dd3af86dd8a617eb6464622fb64ca86e61ce99b59b5c35d8cd33f9c30603d"}, + {file = "bitarray-2.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6465de861aff7a2559f226b37982007417eab8c3557543879987f58b453519bd"}, + {file = "bitarray-2.9.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbaf2bb71d6027152d603f1d5f31e0dfd5e50173d06f877bec484e5396d4594b"}, + {file = "bitarray-2.9.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2f32948c86e0d230a296686db28191b67ed229756f84728847daa0c7ab7406e3"}, + {file = "bitarray-2.9.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:be94e5a685e60f9d24532af8fe5c268002e9016fa80272a94727f435de3d1003"}, + {file = "bitarray-2.9.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5cc9381fd54f3c23ae1039f977bfd6d041a5c3c1518104f616643c3a5a73b15"}, + {file = "bitarray-2.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd926e8ae4d1ed1ac4a8f37212a62886292f692bc1739fde98013bf210c2d175"}, + {file = "bitarray-2.9.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:461a3dafb9d5fda0bb3385dc507d78b1984b49da3fe4c6d56c869a54373b7008"}, + {file = "bitarray-2.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:393cb27fd859af5fd9c16eb26b1c59b17b390ff66b3ae5d0dd258270191baf13"}, + {file = "bitarray-2.9.2.tar.gz", hash = "sha256:a8f286a51a32323715d77755ed959f94bef13972e9a2fe71b609e40e6d27957e"}, ] [[package]] name = "black" -version = "23.3.0" +version = "23.12.1" description = "The uncompromising code formatter." -category = "dev" optional = false -python-versions = ">=3.7" -files = [ - {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, - {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, - {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, - {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, - {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, - {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, - {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, - {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, - {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, - {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, - {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, - {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, - {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, - {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, - {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, - {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, +python-versions = ">=3.8" +files = [ + {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, + {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, + {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, + {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, + {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, + {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, + {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, + {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, + {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, + {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, + {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, + {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, + {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, + {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, + {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, + {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, + {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, + {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, + {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, + {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, + {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, + {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, ] [package.dependencies] @@ -327,244 +324,223 @@ platformdirs = ">=2" [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] -[[package]] -name = "cachecontrol" -version = "0.12.11" -description = "httplib2 caching for requests" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "CacheControl-0.12.11-py2.py3-none-any.whl", hash = "sha256:2c75d6a8938cb1933c75c50184549ad42728a27e9f6b92fd677c3151aa72555b"}, - {file = "CacheControl-0.12.11.tar.gz", hash = "sha256:a5b9fcc986b184db101aa280b42ecdcdfc524892596f606858e0b7a8b4d9e144"}, -] - -[package.dependencies] -lockfile = {version = ">=0.9", optional = true, markers = "extra == \"filecache\""} -msgpack = ">=0.5.2" -requests = "*" - -[package.extras] -filecache = ["lockfile (>=0.9)"] -redis = ["redis (>=2.10.5)"] - [[package]] name = "certifi" -version = "2022.12.7" +version = "2024.6.2" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, - {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, + {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, + {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, ] -[[package]] -name = "cffi" -version = "1.15.1" -description = "Foreign Function Interface for Python calling C code." -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, - {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, - {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, - {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, - {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, - {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, - {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, - {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, - {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, - {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, - {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, - {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, - {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, - {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, - {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, - {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, - {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, - {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, - {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, -] - -[package.dependencies] -pycparser = "*" - [[package]] name = "charset-normalizer" -version = "3.0.1" +version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "ckzg" +version = "1.0.2" +description = "Python bindings for C-KZG-4844" optional = false python-versions = "*" files = [ - {file = "charset-normalizer-3.0.1.tar.gz", hash = "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-win32.whl", hash = "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-win32.whl", hash = "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-win32.whl", hash = "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-win32.whl", hash = "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-win32.whl", hash = "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59"}, - {file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"}, -] - -[[package]] -name = "cleo" -version = "2.0.1" -description = "Cleo allows you to create beautiful and testable command-line interfaces." -category = "main" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "cleo-2.0.1-py3-none-any.whl", hash = "sha256:6eb133670a3ed1f3b052d53789017b6e50fca66d1287e6e6696285f4cb8ea448"}, - {file = "cleo-2.0.1.tar.gz", hash = "sha256:eb4b2e1f3063c11085cebe489a6e9124163c226575a3c3be69b2e51af4a15ec5"}, + {file = "ckzg-1.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bdd082bc0f2a595e3546658ecbe1ff78fe65b0ab7e619a8197a62d94f46b5b46"}, + {file = "ckzg-1.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50ca4af4e2f1a1e8b0a7e97b3aef39dedbb0d52d90866ece424f13f8df1b5972"}, + {file = "ckzg-1.0.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e9dc671b0a307ea65d0a216ca496c272dd3c1ed890ddc2a306da49b0d8ffc83"}, + {file = "ckzg-1.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d95e97a0d0f7758119bb905fb5688222b1556de465035614883c42fe4a047d1f"}, + {file = "ckzg-1.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27261672154cbd477d84d289845b0022fbdbe2ba45b7a2a2051c345fa04c8334"}, + {file = "ckzg-1.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c16d5ee1ddbbbad0367ff970b3ec9f6d1879e9f928023beda59ae9e16ad99e4c"}, + {file = "ckzg-1.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:09043738b029bdf4fdc82041b395cfc6f5b5cf63435e5d4d685d24fd14c834d3"}, + {file = "ckzg-1.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3c0afa232d2312e3101aaddb6971b486b0038a0f9171500bc23143f5749eff55"}, + {file = "ckzg-1.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:96e8281b6d58cf91b9559e1bd38132161d63467500838753364c68e825df2e2c"}, + {file = "ckzg-1.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b874167de1d6de72890a2ad5bd9aa7adbddc41c3409923b59cf4ef27f83f79da"}, + {file = "ckzg-1.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3d2ccd68b0743e20e853e31a08da490a8d38c7f12b9a0c4ee63ef5afa0dc2427"}, + {file = "ckzg-1.0.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e8d534ddbe785c44cf1cd62ee32d78b4310d66dd70e42851f5468af655b81f5"}, + {file = "ckzg-1.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c732cda00c76b326f39ae97edfc6773dd231b7c77288b38282584a7aee77c3a7"}, + {file = "ckzg-1.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abc5a27284db479ead4c053ff086d6e222914f1b0aa08b80eabfa116dbed4f7a"}, + {file = "ckzg-1.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6bd5006cb3e802744309450183087a6594d50554814eee19065f7064dff7b05"}, + {file = "ckzg-1.0.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3594470134eda7adf2813ad3f1da55ced98c8a393262f47ce3890c5afa05b23e"}, + {file = "ckzg-1.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fea56f39e48b60c1ff6f751c47489e353d1bd95cae65c429cf5f87735d794431"}, + {file = "ckzg-1.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:f769eb2e1056ca396462460079f6849c778f58884bb24b638ff7028dd2120b65"}, + {file = "ckzg-1.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e3cb2f8c767aee57e88944f90848e8689ce43993b9ff21589cfb97a562208fe7"}, + {file = "ckzg-1.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b29889f5bc5db530f766871c0ff4133e7270ecf63aaa3ca756d3b2731980802"}, + {file = "ckzg-1.0.2-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfcc70fb76b3d36125d646110d5001f2aa89c1c09ff5537a4550cdb7951f44d4"}, + {file = "ckzg-1.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ca8a256cdd56d06bc5ef24caac64845240dbabca402c5a1966d519b2514b4ec"}, + {file = "ckzg-1.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ea91b0236384f93ad1df01d530672f09e254bd8c3cf097ebf486aebb97f6c8c"}, + {file = "ckzg-1.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:65311e72780105f239d1d66512629a9f468b7c9f2609b8567fc68963ac638ef9"}, + {file = "ckzg-1.0.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0d7600ce7a73ac41d348712d0c1fe5e4cb6caa329377064cfa3a6fd8fbffb410"}, + {file = "ckzg-1.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:19893ee7bd7da8688382cb134cb9ee7bce5c38e3a9386e3ed99bb010487d2d17"}, + {file = "ckzg-1.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:c3e1a9a72695e777497e95bb2213316a1138f82d1bb5d67b9c029a522d24908e"}, + {file = "ckzg-1.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a2f59da9cb82b6a4be615f2561a255731eededa7ecd6ba4b2f2dedfc918ef137"}, + {file = "ckzg-1.0.2-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c915e1f2ef51657c3255d8b1e2aea6e0b93348ae316b2b79eaadfb17ad8f514e"}, + {file = "ckzg-1.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcc0d2031fcabc4be37e9e602c926ef9347238d2f58c1b07e0c147f60b9e760b"}, + {file = "ckzg-1.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cdaad2745425d7708e76e8e56a52fdaf5c5cc1cfefd5129d24ff8dbe06a012d"}, + {file = "ckzg-1.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:1ec775649daade1b93041aac9c1660c2ad9828b57ccd2eeb5a3074d8f05e544a"}, + {file = "ckzg-1.0.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:02f9cc3e38b3702ec5895a1ebf927fd02b8f5c2f93c7cb9e438581b5b74472c8"}, + {file = "ckzg-1.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0e816af31951b5e94e6bc069f21fe783427c190526e0437e16c4488a34ddcacc"}, + {file = "ckzg-1.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:651ba33ee2d7fefff14ca519a72996b733402f8b043fbfef12d5fe2a442d86d8"}, + {file = "ckzg-1.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:489763ad92e2175fb6ab455411f03ec104c630470d483e11578bf2e00608f283"}, + {file = "ckzg-1.0.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:69e1376284e9a5094d7c4d3e552202d6b32a67c5acc461b0b35718d8ec5c7363"}, + {file = "ckzg-1.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb9d0b09ca1bdb5955b626d6645f811424ae0fcab47699a1a938a3ce0438c25f"}, + {file = "ckzg-1.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d87a121ace8feb6c9386f247e7e36ef55e584fc8a6b1bc2c60757a59c1efe364"}, + {file = "ckzg-1.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:97c27153fab853f017fed159333b27beeb2e0da834c92c9ecdc26d0e5c3983b3"}, + {file = "ckzg-1.0.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b26799907257c39471cb3665f66f7630797140131606085c2c94a7094ab6ddf2"}, + {file = "ckzg-1.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:283a40c625222560fda3dcb912b666f7d50f9502587b73c4358979f519f1c961"}, + {file = "ckzg-1.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:5f029822d27c52b9c3dbe5706408b099da779f10929be0422a09a34aa026a872"}, + {file = "ckzg-1.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:edaea8fb50b01c6c19768d9305ad365639a8cd804754277d5108dcae4808f00b"}, + {file = "ckzg-1.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:27be65c88d5d773a30e6f198719cefede7e25cad807384c3d65a09c11616fc9d"}, + {file = "ckzg-1.0.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9ac729c5c6f3d2c030c0bc8c9e10edc253e36f002cfe227292035009965d349"}, + {file = "ckzg-1.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1528bc2b95aac6d184a90b023602c40d7b11b577235848c1b5593c00cf51d37"}, + {file = "ckzg-1.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:071dc7fc179316ce1bfabaa056156e4e84f312c4560ab7b9529a3b9a84019df3"}, + {file = "ckzg-1.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:895044069de7010be6c7ee703f03fd7548267a0823cf60b9dd26ec50267dd9e8"}, + {file = "ckzg-1.0.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ed8c99cd3d9af596470e0481fd58931007288951719bad026f0dd486dd0ec11"}, + {file = "ckzg-1.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:74d87eafe561d4bfb544a4f3419d26c56ad7de00f39789ef0fdb09515544d12e"}, + {file = "ckzg-1.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:54d71e5ca416bd51c543f9f51e426e6792f8a0280b83aef92faad1b826f401ea"}, + {file = "ckzg-1.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:da2d9988781a09a4577ee7ea8f51fe4a94b4422789a523164f5ba3118566ad41"}, + {file = "ckzg-1.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d9e030af7d6acdcb356fddfb095048bc8e880fe4cd70ff2206c64f33bf384a0d"}, + {file = "ckzg-1.0.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:145ae31c3d499d1950567bd636dc5b24292b600296b9deb5523bc20d8f7b51c3"}, + {file = "ckzg-1.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d81e68e84d80084da298471ad5eaddfcc1cf73545cb24e9453550c8186870982"}, + {file = "ckzg-1.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c67064bbbeba1a6892c9c80b3d0c2a540ff48a5ca5356fdb2a8d998b264e43e6"}, + {file = "ckzg-1.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:99694917eb6decefc0d330d9887a89ea770824b2fa76eb830bab5fe57ea5c20c"}, + {file = "ckzg-1.0.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fca227ce0ce3427254a113fdb3aed5ecd99c1fc670cb0c60cc8a2154793678e4"}, + {file = "ckzg-1.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a66a690d3d1801085d11de6825df47a99b465ff32dbe90be4a3c9f43c577da96"}, + {file = "ckzg-1.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:272adfe471380d10e4a0e1639d877e504555079a60233dd82249c799b15be81e"}, + {file = "ckzg-1.0.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f37be0054ebb4b8ac6e6d5267290b239b09e7ddc611776051b4c3c4032d161ba"}, + {file = "ckzg-1.0.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:611c03a170f0f746180eeb0cc28cdc6f954561b8eb9013605a046de86520ee6b"}, + {file = "ckzg-1.0.2-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75b2f0ab341f3c33702ce64e1c101116c7462a25686d0b1a0193ca654ad4f96e"}, + {file = "ckzg-1.0.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab29fc61fbd32096b82b02e6b18ae0d7423048d3540b7b90805b16ae10bdb769"}, + {file = "ckzg-1.0.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e43741e7453262aa3ba1754623d7864250b33751bd850dd548e3ed6bd1911093"}, + {file = "ckzg-1.0.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:155eacc237cb28c9eafda1c47a89e6e4550f1c2e711f2eee21e0bb2f4df75546"}, + {file = "ckzg-1.0.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d31d7fbe396a51f43375e38c31bc3a96c7996882582f95f3fcfd54acfa7b3ce6"}, + {file = "ckzg-1.0.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d3d049186c9966e9140de39a9979d7adcfe22f8b02d2852c94d3c363235cc18"}, + {file = "ckzg-1.0.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88728fbd410d61bd5d655ac50b842714c38bc34ff717f73592132d28911fc88e"}, + {file = "ckzg-1.0.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:052d302058d72431acc9dd4a9c76854c8dfce10c698deef5252884e32a1ac7bf"}, + {file = "ckzg-1.0.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:633110a9431231664be2ad32baf10971547f18289d33967654581b9ae9c94a7e"}, + {file = "ckzg-1.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f439c9e5297ae29a700f6d55de1525e2e295dbbb7366f0974c8702fca9e536b9"}, + {file = "ckzg-1.0.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:94f7eb080c00c0ccbd4fafad69f0b35b624a6a229a28e11d365b60b58a072832"}, + {file = "ckzg-1.0.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f876783ec654b7b9525503c2a0a1b086e5d4f52ff65cac7e8747769b0c2e5468"}, + {file = "ckzg-1.0.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7e039800e50592580171830e788ef4a1d6bb54300d074ae9f9119e92aefc568"}, + {file = "ckzg-1.0.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13a8cccf0070a29bc01493179db2e61220ee1a6cb17f8ea41c68a2f043ace87f"}, + {file = "ckzg-1.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4f86cef801d7b0838e17b6ee2f2c9e747447d91ad1220a701baccdf7ef11a3c8"}, + {file = "ckzg-1.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2433a89af4158beddebbdd66fae95b34d40f2467bee8dc40df0333de5e616b5f"}, + {file = "ckzg-1.0.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c49d5dc0918ad912777720035f9820bdbb6c7e7d1898e12506d44ab3c938d525"}, + {file = "ckzg-1.0.2-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:331d49bc72430a3f85ea6ecb55a0d0d65f66a21d61af5783b465906a741366d5"}, + {file = "ckzg-1.0.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86627bc33bc63b8de869d7d5bfa9868619a4f3e4e7082103935c52f56c66b5"}, + {file = "ckzg-1.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab6a2ba2706b5eaa1ce6bc7c4e72970bf9587e2e0e482e5fb4df1996bccb7a40"}, + {file = "ckzg-1.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8bca5e7c38d913fabc24ad09545f78ba23cfc13e1ac8250644231729ca908549"}, + {file = "ckzg-1.0.2.tar.gz", hash = "sha256:4295acc380f8d42ebea4a4a0a68c424a322bb335a33bad05c72ead8cbb28d118"}, ] -[package.dependencies] -crashtest = ">=0.4.1,<0.5.0" -rapidfuzz = ">=2.2.0,<3.0.0" - [[package]] name = "click" -version = "8.1.3" +version = "8.1.7" description = "Composable command line interface toolkit" -category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, - {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, ] [package.dependencies] @@ -574,7 +550,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -584,232 +559,179 @@ files = [ [[package]] name = "coverage" -version = "7.2.1" +version = "7.5.3" description = "Code coverage measurement for Python" -category = "dev" optional = false -python-versions = ">=3.7" -files = [ - {file = "coverage-7.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:49567ec91fc5e0b15356da07a2feabb421d62f52a9fff4b1ec40e9e19772f5f8"}, - {file = "coverage-7.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d2ef6cae70168815ed91388948b5f4fcc69681480a0061114db737f957719f03"}, - {file = "coverage-7.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3004765bca3acd9e015794e5c2f0c9a05587f5e698127ff95e9cfba0d3f29339"}, - {file = "coverage-7.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cca7c0b7f5881dfe0291ef09ba7bb1582cb92ab0aeffd8afb00c700bf692415a"}, - {file = "coverage-7.2.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2167d116309f564af56f9aa5e75ef710ef871c5f9b313a83050035097b56820"}, - {file = "coverage-7.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cb5f152fb14857cbe7f3e8c9a5d98979c4c66319a33cad6e617f0067c9accdc4"}, - {file = "coverage-7.2.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:87dc37f16fb5e3a28429e094145bf7c1753e32bb50f662722e378c5851f7fdc6"}, - {file = "coverage-7.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e191a63a05851f8bce77bc875e75457f9b01d42843f8bd7feed2fc26bbe60833"}, - {file = "coverage-7.2.1-cp310-cp310-win32.whl", hash = "sha256:e3ea04b23b114572b98a88c85379e9e9ae031272ba1fb9b532aa934c621626d4"}, - {file = "coverage-7.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:0cf557827be7eca1c38a2480484d706693e7bb1929e129785fe59ec155a59de6"}, - {file = "coverage-7.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:570c21a29493b350f591a4b04c158ce1601e8d18bdcd21db136fbb135d75efa6"}, - {file = "coverage-7.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9e872b082b32065ac2834149dc0adc2a2e6d8203080501e1e3c3c77851b466f9"}, - {file = "coverage-7.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fac6343bae03b176e9b58104a9810df3cdccd5cfed19f99adfa807ffbf43cf9b"}, - {file = "coverage-7.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abacd0a738e71b20e224861bc87e819ef46fedba2fb01bc1af83dfd122e9c319"}, - {file = "coverage-7.2.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9256d4c60c4bbfec92721b51579c50f9e5062c21c12bec56b55292464873508"}, - {file = "coverage-7.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:80559eaf6c15ce3da10edb7977a1548b393db36cbc6cf417633eca05d84dd1ed"}, - {file = "coverage-7.2.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0bd7e628f6c3ec4e7d2d24ec0e50aae4e5ae95ea644e849d92ae4805650b4c4e"}, - {file = "coverage-7.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09643fb0df8e29f7417adc3f40aaf379d071ee8f0350ab290517c7004f05360b"}, - {file = "coverage-7.2.1-cp311-cp311-win32.whl", hash = "sha256:1b7fb13850ecb29b62a447ac3516c777b0e7a09ecb0f4bb6718a8654c87dfc80"}, - {file = "coverage-7.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:617a94ada56bbfe547aa8d1b1a2b8299e2ec1ba14aac1d4b26a9f7d6158e1273"}, - {file = "coverage-7.2.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8649371570551d2fd7dee22cfbf0b61f1747cdfb2b7587bb551e4beaaa44cb97"}, - {file = "coverage-7.2.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d2b9b5e70a21474c105a133ba227c61bc95f2ac3b66861143ce39a5ea4b3f84"}, - {file = "coverage-7.2.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae82c988954722fa07ec5045c57b6d55bc1a0890defb57cf4a712ced65b26ddd"}, - {file = "coverage-7.2.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:861cc85dfbf55a7a768443d90a07e0ac5207704a9f97a8eb753292a7fcbdfcfc"}, - {file = "coverage-7.2.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0339dc3237c0d31c3b574f19c57985fcbe494280153bbcad33f2cdf469f4ac3e"}, - {file = "coverage-7.2.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5928b85416a388dd557ddc006425b0c37e8468bd1c3dc118c1a3de42f59e2a54"}, - {file = "coverage-7.2.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8d3843ca645f62c426c3d272902b9de90558e9886f15ddf5efe757b12dd376f5"}, - {file = "coverage-7.2.1-cp37-cp37m-win32.whl", hash = "sha256:6a034480e9ebd4e83d1aa0453fd78986414b5d237aea89a8fdc35d330aa13bae"}, - {file = "coverage-7.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6fce673f79a0e017a4dc35e18dc7bb90bf6d307c67a11ad5e61ca8d42b87cbff"}, - {file = "coverage-7.2.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7f099da6958ddfa2ed84bddea7515cb248583292e16bb9231d151cd528eab657"}, - {file = "coverage-7.2.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:97a3189e019d27e914ecf5c5247ea9f13261d22c3bb0cfcfd2a9b179bb36f8b1"}, - {file = "coverage-7.2.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a81dbcf6c6c877986083d00b834ac1e84b375220207a059ad45d12f6e518a4e3"}, - {file = "coverage-7.2.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78d2c3dde4c0b9be4b02067185136b7ee4681978228ad5ec1278fa74f5ca3e99"}, - {file = "coverage-7.2.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a209d512d157379cc9ab697cbdbb4cfd18daa3e7eebaa84c3d20b6af0037384"}, - {file = "coverage-7.2.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f3d07edb912a978915576a776756069dede66d012baa503022d3a0adba1b6afa"}, - {file = "coverage-7.2.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8dca3c1706670297851bca1acff9618455122246bdae623be31eca744ade05ec"}, - {file = "coverage-7.2.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b1991a6d64231a3e5bbe3099fb0dd7c9aeaa4275ad0e0aeff4cb9ef885c62ba2"}, - {file = "coverage-7.2.1-cp38-cp38-win32.whl", hash = "sha256:22c308bc508372576ffa3d2dbc4824bb70d28eeb4fcd79d4d1aed663a06630d0"}, - {file = "coverage-7.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:b0c0d46de5dd97f6c2d1b560bf0fcf0215658097b604f1840365296302a9d1fb"}, - {file = "coverage-7.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4dd34a935de268a133e4741827ae951283a28c0125ddcdbcbba41c4b98f2dfef"}, - {file = "coverage-7.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0f8318ed0f3c376cfad8d3520f496946977abde080439d6689d7799791457454"}, - {file = "coverage-7.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:834c2172edff5a08d78e2f53cf5e7164aacabeb66b369f76e7bb367ca4e2d993"}, - {file = "coverage-7.2.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4d70c853f0546855f027890b77854508bdb4d6a81242a9d804482e667fff6e6"}, - {file = "coverage-7.2.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a6450da4c7afc4534305b2b7d8650131e130610cea448ff240b6ab73d7eab63"}, - {file = "coverage-7.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:99f4dd81b2bb8fc67c3da68b1f5ee1650aca06faa585cbc6818dbf67893c6d58"}, - {file = "coverage-7.2.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bdd3f2f285ddcf2e75174248b2406189261a79e7fedee2ceeadc76219b6faa0e"}, - {file = "coverage-7.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f29351393eb05e6326f044a7b45ed8e38cb4dcc38570d12791f271399dc41431"}, - {file = "coverage-7.2.1-cp39-cp39-win32.whl", hash = "sha256:e2b50ebc2b6121edf352336d503357321b9d8738bb7a72d06fc56153fd3f4cd8"}, - {file = "coverage-7.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:bd5a12239c0006252244f94863f1c518ac256160cd316ea5c47fb1a11b25889a"}, - {file = "coverage-7.2.1-pp37.pp38.pp39-none-any.whl", hash = "sha256:436313d129db7cf5b4ac355dd2bd3f7c7e5294af077b090b85de75f8458b8616"}, - {file = "coverage-7.2.1.tar.gz", hash = "sha256:c77f2a9093ccf329dd523a9b2b3c854c20d2a3d968b6def3b820272ca6732242"}, +python-versions = ">=3.8" +files = [ + {file = "coverage-7.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a6519d917abb15e12380406d721e37613e2a67d166f9fb7e5a8ce0375744cd45"}, + {file = "coverage-7.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aea7da970f1feccf48be7335f8b2ca64baf9b589d79e05b9397a06696ce1a1ec"}, + {file = "coverage-7.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:923b7b1c717bd0f0f92d862d1ff51d9b2b55dbbd133e05680204465f454bb286"}, + {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62bda40da1e68898186f274f832ef3e759ce929da9a9fd9fcf265956de269dbc"}, + {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8b7339180d00de83e930358223c617cc343dd08e1aa5ec7b06c3a121aec4e1d"}, + {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:25a5caf742c6195e08002d3b6c2dd6947e50efc5fc2c2205f61ecb47592d2d83"}, + {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:05ac5f60faa0c704c0f7e6a5cbfd6f02101ed05e0aee4d2822637a9e672c998d"}, + {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:239a4e75e09c2b12ea478d28815acf83334d32e722e7433471fbf641c606344c"}, + {file = "coverage-7.5.3-cp310-cp310-win32.whl", hash = "sha256:a5812840d1d00eafae6585aba38021f90a705a25b8216ec7f66aebe5b619fb84"}, + {file = "coverage-7.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:33ca90a0eb29225f195e30684ba4a6db05dbef03c2ccd50b9077714c48153cac"}, + {file = "coverage-7.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f81bc26d609bf0fbc622c7122ba6307993c83c795d2d6f6f6fd8c000a770d974"}, + {file = "coverage-7.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7cec2af81f9e7569280822be68bd57e51b86d42e59ea30d10ebdbb22d2cb7232"}, + {file = "coverage-7.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55f689f846661e3f26efa535071775d0483388a1ccfab899df72924805e9e7cd"}, + {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50084d3516aa263791198913a17354bd1dc627d3c1639209640b9cac3fef5807"}, + {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:341dd8f61c26337c37988345ca5c8ccabeff33093a26953a1ac72e7d0103c4fb"}, + {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ab0b028165eea880af12f66086694768f2c3139b2c31ad5e032c8edbafca6ffc"}, + {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5bc5a8c87714b0c67cfeb4c7caa82b2d71e8864d1a46aa990b5588fa953673b8"}, + {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:38a3b98dae8a7c9057bd91fbf3415c05e700a5114c5f1b5b0ea5f8f429ba6614"}, + {file = "coverage-7.5.3-cp311-cp311-win32.whl", hash = "sha256:fcf7d1d6f5da887ca04302db8e0e0cf56ce9a5e05f202720e49b3e8157ddb9a9"}, + {file = "coverage-7.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:8c836309931839cca658a78a888dab9676b5c988d0dd34ca247f5f3e679f4e7a"}, + {file = "coverage-7.5.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:296a7d9bbc598e8744c00f7a6cecf1da9b30ae9ad51c566291ff1314e6cbbed8"}, + {file = "coverage-7.5.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:34d6d21d8795a97b14d503dcaf74226ae51eb1f2bd41015d3ef332a24d0a17b3"}, + {file = "coverage-7.5.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e317953bb4c074c06c798a11dbdd2cf9979dbcaa8ccc0fa4701d80042d4ebf1"}, + {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:705f3d7c2b098c40f5b81790a5fedb274113373d4d1a69e65f8b68b0cc26f6db"}, + {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1196e13c45e327d6cd0b6e471530a1882f1017eb83c6229fc613cd1a11b53cd"}, + {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:015eddc5ccd5364dcb902eaecf9515636806fa1e0d5bef5769d06d0f31b54523"}, + {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fd27d8b49e574e50caa65196d908f80e4dff64d7e592d0c59788b45aad7e8b35"}, + {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:33fc65740267222fc02975c061eb7167185fef4cc8f2770267ee8bf7d6a42f84"}, + {file = "coverage-7.5.3-cp312-cp312-win32.whl", hash = "sha256:7b2a19e13dfb5c8e145c7a6ea959485ee8e2204699903c88c7d25283584bfc08"}, + {file = "coverage-7.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:0bbddc54bbacfc09b3edaec644d4ac90c08ee8ed4844b0f86227dcda2d428fcb"}, + {file = "coverage-7.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f78300789a708ac1f17e134593f577407d52d0417305435b134805c4fb135adb"}, + {file = "coverage-7.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b368e1aee1b9b75757942d44d7598dcd22a9dbb126affcbba82d15917f0cc155"}, + {file = "coverage-7.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f836c174c3a7f639bded48ec913f348c4761cbf49de4a20a956d3431a7c9cb24"}, + {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:244f509f126dc71369393ce5fea17c0592c40ee44e607b6d855e9c4ac57aac98"}, + {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4c2872b3c91f9baa836147ca33650dc5c172e9273c808c3c3199c75490e709d"}, + {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dd4b3355b01273a56b20c219e74e7549e14370b31a4ffe42706a8cda91f19f6d"}, + {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f542287b1489c7a860d43a7d8883e27ca62ab84ca53c965d11dac1d3a1fab7ce"}, + {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:75e3f4e86804023e991096b29e147e635f5e2568f77883a1e6eed74512659ab0"}, + {file = "coverage-7.5.3-cp38-cp38-win32.whl", hash = "sha256:c59d2ad092dc0551d9f79d9d44d005c945ba95832a6798f98f9216ede3d5f485"}, + {file = "coverage-7.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:fa21a04112c59ad54f69d80e376f7f9d0f5f9123ab87ecd18fbb9ec3a2beed56"}, + {file = "coverage-7.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5102a92855d518b0996eb197772f5ac2a527c0ec617124ad5242a3af5e25f85"}, + {file = "coverage-7.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d1da0a2e3b37b745a2b2a678a4c796462cf753aebf94edcc87dcc6b8641eae31"}, + {file = "coverage-7.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8383a6c8cefba1b7cecc0149415046b6fc38836295bc4c84e820872eb5478b3d"}, + {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9aad68c3f2566dfae84bf46295a79e79d904e1c21ccfc66de88cd446f8686341"}, + {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e079c9ec772fedbade9d7ebc36202a1d9ef7291bc9b3a024ca395c4d52853d7"}, + {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bde997cac85fcac227b27d4fb2c7608a2c5f6558469b0eb704c5726ae49e1c52"}, + {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:990fb20b32990b2ce2c5f974c3e738c9358b2735bc05075d50a6f36721b8f303"}, + {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3d5a67f0da401e105753d474369ab034c7bae51a4c31c77d94030d59e41df5bd"}, + {file = "coverage-7.5.3-cp39-cp39-win32.whl", hash = "sha256:e08c470c2eb01977d221fd87495b44867a56d4d594f43739a8028f8646a51e0d"}, + {file = "coverage-7.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:1d2a830ade66d3563bb61d1e3c77c8def97b30ed91e166c67d0632c018f380f0"}, + {file = "coverage-7.5.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:3538d8fb1ee9bdd2e2692b3b18c22bb1c19ffbefd06880f5ac496e42d7bb3884"}, + {file = "coverage-7.5.3.tar.gz", hash = "sha256:04aefca5190d1dc7a53a4c1a5a7f8568811306d7a8ee231c42fb69215571944f"}, ] [package.extras] toml = ["tomli"] -[[package]] -name = "crashtest" -version = "0.4.1" -description = "Manage Python errors with ease" -category = "main" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "crashtest-0.4.1-py3-none-any.whl", hash = "sha256:8d23eac5fa660409f57472e3851dab7ac18aba459a8d19cbbba86d3d5aecd2a5"}, - {file = "crashtest-0.4.1.tar.gz", hash = "sha256:80d7b1f316ebfbd429f648076d6275c877ba30ba48979de4191714a75266f0ce"}, -] - -[[package]] -name = "cryptography" -version = "39.0.1" -description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "cryptography-39.0.1-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:6687ef6d0a6497e2b58e7c5b852b53f62142cfa7cd1555795758934da363a965"}, - {file = "cryptography-39.0.1-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:706843b48f9a3f9b9911979761c91541e3d90db1ca905fd63fee540a217698bc"}, - {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:5d2d8b87a490bfcd407ed9d49093793d0f75198a35e6eb1a923ce1ee86c62b41"}, - {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83e17b26de248c33f3acffb922748151d71827d6021d98c70e6c1a25ddd78505"}, - {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e124352fd3db36a9d4a21c1aa27fd5d051e621845cb87fb851c08f4f75ce8be6"}, - {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:5aa67414fcdfa22cf052e640cb5ddc461924a045cacf325cd164e65312d99502"}, - {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:35f7c7d015d474f4011e859e93e789c87d21f6f4880ebdc29896a60403328f1f"}, - {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f24077a3b5298a5a06a8e0536e3ea9ec60e4c7ac486755e5fb6e6ea9b3500106"}, - {file = "cryptography-39.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:f0c64d1bd842ca2633e74a1a28033d139368ad959872533b1bab8c80e8240a0c"}, - {file = "cryptography-39.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:0f8da300b5c8af9f98111ffd512910bc792b4c77392a9523624680f7956a99d4"}, - {file = "cryptography-39.0.1-cp36-abi3-win32.whl", hash = "sha256:fe913f20024eb2cb2f323e42a64bdf2911bb9738a15dba7d3cce48151034e3a8"}, - {file = "cryptography-39.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:ced4e447ae29ca194449a3f1ce132ded8fcab06971ef5f618605aacaa612beac"}, - {file = "cryptography-39.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:807ce09d4434881ca3a7594733669bd834f5b2c6d5c7e36f8c00f691887042ad"}, - {file = "cryptography-39.0.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c5caeb8188c24888c90b5108a441c106f7faa4c4c075a2bcae438c6e8ca73cef"}, - {file = "cryptography-39.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4789d1e3e257965e960232345002262ede4d094d1a19f4d3b52e48d4d8f3b885"}, - {file = "cryptography-39.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:96f1157a7c08b5b189b16b47bc9db2332269d6680a196341bf30046330d15388"}, - {file = "cryptography-39.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e422abdec8b5fa8462aa016786680720d78bdce7a30c652b7fadf83a4ba35336"}, - {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:b0afd054cd42f3d213bf82c629efb1ee5f22eba35bf0eec88ea9ea7304f511a2"}, - {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:6f8ba7f0328b79f08bdacc3e4e66fb4d7aab0c3584e0bd41328dce5262e26b2e"}, - {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:ef8b72fa70b348724ff1218267e7f7375b8de4e8194d1636ee60510aae104cd0"}, - {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:aec5a6c9864be7df2240c382740fcf3b96928c46604eaa7f3091f58b878c0bb6"}, - {file = "cryptography-39.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdd188c8a6ef8769f148f88f859884507b954cc64db6b52f66ef199bb9ad660a"}, - {file = "cryptography-39.0.1.tar.gz", hash = "sha256:d1f6198ee6d9148405e49887803907fe8962a23e6c6f83ea7d98f1c0de375695"}, -] - -[package.dependencies] -cffi = ">=1.12" - -[package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] -docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] -pep8test = ["black", "check-manifest", "mypy", "ruff", "types-pytz", "types-requests"] -sdist = ["setuptools-rust (>=0.11.4)"] -ssh = ["bcrypt (>=3.1.5)"] -test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist", "pytz"] -test-randomorder = ["pytest-randomly"] -tox = ["tox"] - [[package]] name = "cytoolz" -version = "0.12.1" +version = "0.12.3" description = "Cython implementation of Toolz: High performance functional utilities" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "cytoolz-0.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c59bb4ca88e1c69931468bf21f91c8f64d8bf1999eb163b7a2df336f60c304a"}, - {file = "cytoolz-0.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4d700e011156ff112966c6d77faaae125fcaf538f4cec2b9ce8957de82858f0f"}, - {file = "cytoolz-0.12.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23c3f57c48eb939d2986eba4aeaeedf930ebf94d58c91a42d4e0fc45ed5427dc"}, - {file = "cytoolz-0.12.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:25ff13c468c06da9ef26651dc389e7e8bb7af548f8c1dfb96305f57f18d398a8"}, - {file = "cytoolz-0.12.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a734511144309ea6e105406633affb74e303a3df07d8a3954f9b01946e27ecb1"}, - {file = "cytoolz-0.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48bc2f30d1b2646d675bb8e7778ab59379bf9edc59fe06fb0e7f85ba1271bf44"}, - {file = "cytoolz-0.12.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30936ae8fa68b6a1ac8ad6c4bacb5a8a00d51bc6c89f9614a1557b0105d09f8a"}, - {file = "cytoolz-0.12.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:efd1b2da3ee577fcfa723a214f73186aef9674dd5b28242d90443c7a82722b0f"}, - {file = "cytoolz-0.12.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6805b007af3557ee6c20dab491b6e55a8177f5b6845d9e6c653374d540366ba7"}, - {file = "cytoolz-0.12.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a6e63fc67b23830947b51e0a488992e3c904fce825ead565f3904dcf621d05f7"}, - {file = "cytoolz-0.12.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:9e324a94856d88ecf10f34c102d0ded67d7c3cf644153d77e34a29720ce6aa47"}, - {file = "cytoolz-0.12.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:02975e2b1e61e47e9afa311f4c1783d155136fad37c54a1cebfe991c5a0798a1"}, - {file = "cytoolz-0.12.1-cp310-cp310-win32.whl", hash = "sha256:b6569f6038133909cd658dbdcc6fc955f791dc47a7f5b55d2066f742253dcbfe"}, - {file = "cytoolz-0.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:1be368623e46ad3c1ce807e7a436acb119c26001507b31f92ceb21b86e08c386"}, - {file = "cytoolz-0.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:849f461bffa1e7700ccfcb5186df29cd4cdcc9efdb7199cb8b5681dc37045d72"}, - {file = "cytoolz-0.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4284120c978fb7039901bf6e66832cb3e82ac1b2a107512e735bdb04fd5533ed"}, - {file = "cytoolz-0.12.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ec296f01c29c809698eaf677211b6255691295c2b35caab2131e1e7eaadfbac"}, - {file = "cytoolz-0.12.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:37c53f456a1c84566a7d911eec57c4c6280b915ab0600e7671582793cc2769fe"}, - {file = "cytoolz-0.12.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1b6761791973b1e839b8309d5853b40eeb413368e31beaf5f2b6ed44c6fc7cf0"}, - {file = "cytoolz-0.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff478682e8ee6dbaa37201bb71bf4a6eee744006ab000e8f5cea05066fc7c845"}, - {file = "cytoolz-0.12.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:867bebe6be30ee36a836f9b835790762a74f46be8cc339ea57b68dcecdbc1133"}, - {file = "cytoolz-0.12.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7e903df991f0957e2b271a37bb25d28e0d260c52825ae67507d15ca55a935961"}, - {file = "cytoolz-0.12.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e797c4afb1b7962d3205b1959e1051f7e6bfbba29da44042a9efc2391f1feb38"}, - {file = "cytoolz-0.12.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b8eceaa12b7f152b046b67cb053ec2b5b00f73593983de69bc5e63a8aca4a7a8"}, - {file = "cytoolz-0.12.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:b575393dd431b8e211de35bd593d831dac870172b16e2b7934f3566b8fc89377"}, - {file = "cytoolz-0.12.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3032c0ba42dee5836d6b57a72a569b65df2c29e8ed266cb900d569003cf933a9"}, - {file = "cytoolz-0.12.1-cp311-cp311-win32.whl", hash = "sha256:c576bd63495150385b8d05eaae775387f378be2fd9805d3ffb4d17c87271fbad"}, - {file = "cytoolz-0.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:421b224dc4157a0d66625acb5798cf50858cfa06a5232d39a8bd6cf1fa88aca3"}, - {file = "cytoolz-0.12.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:be5a454a95797343d0fb1ed02caecae73a023b1393c112951c84f17ec9f4076c"}, - {file = "cytoolz-0.12.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:061387aa39b9c1576c25d0c59142513c09e77a2a07bd5d6211a43c7a758b6f45"}, - {file = "cytoolz-0.12.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:14f4dbc3f0ec8f6fc68865489af21dcf042ff007d2737c27bfd73296f15db544"}, - {file = "cytoolz-0.12.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a816bff6bf424753e1ac2441902ceaf37ae6718b745a53f6aa1a60c617fb4f5f"}, - {file = "cytoolz-0.12.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:633f19d1990b1cf9c67dce9c28bf8b5a18e42785d15548607a100e1236384d5d"}, - {file = "cytoolz-0.12.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fa7009c843667868aa8bdb3d68e5ef3d6356dd418b17ed5ca4e1340e82483a5"}, - {file = "cytoolz-0.12.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:1c29dd04e282ddfd45b457e3551075beec9128aa9271245e58ce924bf6e055f8"}, - {file = "cytoolz-0.12.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:cd35c0be4c46274129dd1678bb911dd4e93d23968b26f4e39cd55bc7cb3b1bac"}, - {file = "cytoolz-0.12.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:5158ae6d8dd112d003f677039a3613ca7d2592bfe35d7accf23684edb961fc26"}, - {file = "cytoolz-0.12.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:7eb9e6fa8a82c3d2f519f7d3942898a97792e3895569e9501b9431048289b82f"}, - {file = "cytoolz-0.12.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ac6784cc43aec51a86cf9058a2a343084f8cf46a9281bea5762bfa608127c53b"}, - {file = "cytoolz-0.12.1-cp36-cp36m-win32.whl", hash = "sha256:794cce219bbcb2f36ca220f27d5afd64eaa854e04901bd6f240be156a578b607"}, - {file = "cytoolz-0.12.1-cp36-cp36m-win_amd64.whl", hash = "sha256:695dd8231e4f1bfb9a2363775a6e4e56ad9d2058058f817203a49614f4bfe33b"}, - {file = "cytoolz-0.12.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1bd8017ef0da935a20106272c5f5ff6b1114add1ccb09cfed1ff7ec5cc01c6d"}, - {file = "cytoolz-0.12.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56e1ebf6eb4438b8c45cbe7e7b22fc65df0c9efa97a70d3bf2f51e08b19756a5"}, - {file = "cytoolz-0.12.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:816c2038008ebf50d81171ddfae377f1af9e71d504ec609469dcb0906bfcf2ae"}, - {file = "cytoolz-0.12.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bebe58f7a160db7838eb70990c704db4bdc2d58bd364290fd69be0587be8bac"}, - {file = "cytoolz-0.12.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a72440305f634604827f96810e4469877b89f5c060d6852267650a49b0e3768c"}, - {file = "cytoolz-0.12.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b46ebc463bb45f278a2b94e630061c26e10077cb68d4c93583d8f4199699a5ef"}, - {file = "cytoolz-0.12.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:e75e287787e6adafed9d8c3d3e7647c0b5eb460221f9f92d7dfe48b45ba77c0d"}, - {file = "cytoolz-0.12.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:03ab22c9aeb1535f8647d23b6520b0c3d41aaa18d04ef42b352dde1931f2e2b1"}, - {file = "cytoolz-0.12.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b2ac288f27a2689d9e39f4cf4df5437a8eb038eaae515169586c77f9f8fb343a"}, - {file = "cytoolz-0.12.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:97a24c0d0806fcf9a6e75fc18aeb95adc37eb0baf6451f10a2de23ffd815329d"}, - {file = "cytoolz-0.12.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:42c9e5cd2a48a257b1f2402334b48122501f249b8dcf77082f569f2680f185eb"}, - {file = "cytoolz-0.12.1-cp37-cp37m-win32.whl", hash = "sha256:35fae4eaa0eaf9072a5fe2d244a79e65baae4e5ddbe9cc629c5037af800213a2"}, - {file = "cytoolz-0.12.1-cp37-cp37m-win_amd64.whl", hash = "sha256:5af43ca7026ead3dd08b261e4f7163cd2cf3ceaa74fa5a81f7b7ea5d445e41d6"}, - {file = "cytoolz-0.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fcc378fa97f02fbcef090b3611305425d72bd1c0afdd13ef4a82dc67d40638b6"}, - {file = "cytoolz-0.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cc3645cf6b9246cb8e179db2803e4f0d148211d2a2cf22d5c9b5219111cd91a0"}, - {file = "cytoolz-0.12.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b245b824f4705aef0e4a03fafef3ad6cb59ef43cc564cdbf683ee28dfc11ad5"}, - {file = "cytoolz-0.12.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c1964dcb5f250fd13fac210944b20810d61ef4094a17fbbe502ab7a7eaeeace7"}, - {file = "cytoolz-0.12.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f7194a22a4a24f3561cb6ad1cca9c9b2f2cf34cc8d4bce6d6a24c80960323fa8"}, - {file = "cytoolz-0.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1c5434db53f3a94a37ad8aedb231901e001995d899af6ed1165f3d27fa04a6a"}, - {file = "cytoolz-0.12.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b30cd083ef8af4ba66d9fe5cc75c653ede3f2655f97a032db1a14cc8a006719c"}, - {file = "cytoolz-0.12.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bef934bd3e024d512c6c0ad1c66eb173f61d9ccb4dbca8d75f727a5604f7c2f6"}, - {file = "cytoolz-0.12.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:37320669c364f7d370392af33cc1034b4563da66c22cd3261e3530f4d30dbe4b"}, - {file = "cytoolz-0.12.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3cb95d23defb2322cddf70efb4af6dac191d95edaa343e8c1f58f1afa4f92ecd"}, - {file = "cytoolz-0.12.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ac5895d5f78dbd8646fe37266655ba4995f9cfec38a86595282fee69e41787da"}, - {file = "cytoolz-0.12.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:499af2aff04f65b4c23de1df08e1d1484a93b23ddaaa0163e44b5070b68356eb"}, - {file = "cytoolz-0.12.1-cp38-cp38-win32.whl", hash = "sha256:aa61e3da751a2dfe95aeca603f3ef510071a136ba9905f61ae6cb5d0696271ad"}, - {file = "cytoolz-0.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:f5b43ce952a5a31441556c55f5f5f5a8e62c28581a0ff2a2c31c04ef992d73bd"}, - {file = "cytoolz-0.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b8b8f88251b84b3877254cdd59c86a1dc6b2b39a03c6c9c067d344ef879562e0"}, - {file = "cytoolz-0.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d72415b0110f7958dd3a5ee98a70166f47bd42ede85e3535669c794d06f57406"}, - {file = "cytoolz-0.12.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8101ab6de5aa0b26a2b5032bc488d430010c91863e701812d65836b03a12f61"}, - {file = "cytoolz-0.12.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2eed428b5e68c28abf2c71195e799850e040d67a27c05f7785319c611665b86a"}, - {file = "cytoolz-0.12.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59641eb1f41cb688b3cb2f98c9003c493a5024325f76b5c02333d08dd972127c"}, - {file = "cytoolz-0.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a48940ff0449ffcf690310bf9228bb57885f7571406ed2fe05c98e299987195"}, - {file = "cytoolz-0.12.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bae431a5985cdb2014be09d37206c288e0d063940cf9539e9769bd2ec26b220"}, - {file = "cytoolz-0.12.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:cb8b10405960a8e6801a4702af98ea640130ec6ecfc1208195762de3f5503ba9"}, - {file = "cytoolz-0.12.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3c9a16a5b4f54d5c0a131f56b0ca65998a9a74958b5b36840c280edba4f8b907"}, - {file = "cytoolz-0.12.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:49911cb533c96d275e31e7eaeb0742ac3f7afe386a1d8c40937814d75039a0f7"}, - {file = "cytoolz-0.12.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:dbae37d48ef5a0ab90cfaf2b9312d96f034b1c828208a9cbe25377a1b19ba129"}, - {file = "cytoolz-0.12.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c34e69be4429633fc614febe3127fa03aa418a1abb9252f29d9ba5b3394573a5"}, - {file = "cytoolz-0.12.1-cp39-cp39-win32.whl", hash = "sha256:0d474dacbafbdbb44c7de986bbf71ff56ae62df0d52ab3b6fa966784dc88737a"}, - {file = "cytoolz-0.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:3d6d0b0075731832343eb88229cea4bf39e96f3fc7acbc449aadbdfec2842703"}, - {file = "cytoolz-0.12.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8506d1863f30d26f577c4ed59d2cfd03d2f39569f9cbaa02a764a9de73d312d5"}, - {file = "cytoolz-0.12.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a1eae39656a1685e8b3f433eecfd72015ce5c1d7519e9c8f9402153c68331bb"}, - {file = "cytoolz-0.12.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a0055943074c6c85b77fcc3f42f7c54010a3478daa2ed9d6243d0411c84a4d3"}, - {file = "cytoolz-0.12.1-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8a7a325b8fe885a6dd91093616c703134f2dacbd869bc519970df3849c2a15b"}, - {file = "cytoolz-0.12.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:7b60caf0fa5f1b49f1062f7dc0f66c7b23e2736bad50fa8296bfb845995e3051"}, - {file = "cytoolz-0.12.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:980e7eb7205e01816a92f3290cfc80507957e64656b9271a0dfebb85fe3718c0"}, - {file = "cytoolz-0.12.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06d38a40fe153f23cda0e823413fe9d9ebee89dd461827285316eff929fb121e"}, - {file = "cytoolz-0.12.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d540e9c34a61b53b6a374ea108794a48388178f7889d772e364cdbd6df37774c"}, - {file = "cytoolz-0.12.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:117871f036926e42d3abcee587eafa9dc7383f1064ac53a806d33e76604de311"}, - {file = "cytoolz-0.12.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:31131b54a0c72efc0eb432dc66df546c6a54f2a7d396c9a34cf65ac1c26b1df8"}, - {file = "cytoolz-0.12.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4534cbfad73cdb1a6dad495530d4186d57d73089c01e9cb0558caab50e46cb3b"}, - {file = "cytoolz-0.12.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50db41e875e36aec11881b8b12bc69c6f4836b7dd9e88a9e5bbf26c2cb3ba6cd"}, - {file = "cytoolz-0.12.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6716855f9c669c9e25a185d88e0f169839bf8553d16496796325acd114607c11"}, - {file = "cytoolz-0.12.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f32452e833f0605b871626e6c61b71b0cba24233aad0e04accc3240497d4995"}, - {file = "cytoolz-0.12.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ba74c239fc6cb6e962eabc420967c7565f3f363b776c89b3df5234caecf1f463"}, - {file = "cytoolz-0.12.1.tar.gz", hash = "sha256:fc33909397481c90de3cec831bfb88d97e220dc91939d996920202f184b4648e"}, + {file = "cytoolz-0.12.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bbe58e26c84b163beba0fbeacf6b065feabc8f75c6d3fe305550d33f24a2d346"}, + {file = "cytoolz-0.12.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c51b66ada9bfdb88cf711bf350fcc46f82b83a4683cf2413e633c31a64df6201"}, + {file = "cytoolz-0.12.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e70d9c615e5c9dc10d279d1e32e846085fe1fd6f08d623ddd059a92861f4e3dd"}, + {file = "cytoolz-0.12.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a83f4532707963ae1a5108e51fdfe1278cc8724e3301fee48b9e73e1316de64f"}, + {file = "cytoolz-0.12.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d028044524ee2e815f36210a793c414551b689d4f4eda28f8bbb0883ad78bf5f"}, + {file = "cytoolz-0.12.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c2875bcd1397d0627a09a4f9172fa513185ad302c63758efc15b8eb33cc2a98"}, + {file = "cytoolz-0.12.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:131ff4820e5d64a25d7ad3c3556f2d8aa65c66b3f021b03f8a8e98e4180dd808"}, + {file = "cytoolz-0.12.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:04afa90d9d9d18394c40d9bed48c51433d08b57c042e0e50c8c0f9799735dcbd"}, + {file = "cytoolz-0.12.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:dc1ca9c610425f9854323669a671fc163300b873731584e258975adf50931164"}, + {file = "cytoolz-0.12.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:bfa3f8e01bc423a933f2e1c510cbb0632c6787865b5242857cc955cae220d1bf"}, + {file = "cytoolz-0.12.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:f702e295dddef5f8af4a456db93f114539b8dc2a7a9bc4de7c7e41d169aa6ec3"}, + {file = "cytoolz-0.12.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0fbad1fb9bb47e827d00e01992a099b0ba79facf5e5aa453be066033232ac4b5"}, + {file = "cytoolz-0.12.3-cp310-cp310-win32.whl", hash = "sha256:8587c3c3dbe78af90c5025288766ac10dc2240c1e76eb0a93a4e244c265ccefd"}, + {file = "cytoolz-0.12.3-cp310-cp310-win_amd64.whl", hash = "sha256:9e45803d9e75ef90a2f859ef8f7f77614730f4a8ce1b9244375734567299d239"}, + {file = "cytoolz-0.12.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3ac4f2fb38bbc67ff1875b7d2f0f162a247f43bd28eb7c9d15e6175a982e558d"}, + {file = "cytoolz-0.12.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0cf1e1e96dd86829a0539baf514a9c8473a58fbb415f92401a68e8e52a34ecd5"}, + {file = "cytoolz-0.12.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08a438701c6141dd34eaf92e9e9a1f66e23a22f7840ef8a371eba274477de85d"}, + {file = "cytoolz-0.12.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6b6f11b0d7ed91be53166aeef2a23a799e636625675bb30818f47f41ad31821"}, + {file = "cytoolz-0.12.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7fde09384d23048a7b4ac889063761e44b89a0b64015393e2d1d21d5c1f534a"}, + {file = "cytoolz-0.12.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d3bfe45173cc8e6c76206be3a916d8bfd2214fb2965563e288088012f1dabfc"}, + {file = "cytoolz-0.12.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27513a5d5b6624372d63313574381d3217a66e7a2626b056c695179623a5cb1a"}, + {file = "cytoolz-0.12.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d294e5e81ff094fe920fd545052ff30838ea49f9e91227a55ecd9f3ca19774a0"}, + {file = "cytoolz-0.12.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:727b01a2004ddb513496507a695e19b5c0cfebcdfcc68349d3efd92a1c297bf4"}, + {file = "cytoolz-0.12.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:fe1e1779a39dbe83f13886d2b4b02f8c4b10755e3c8d9a89b630395f49f4f406"}, + {file = "cytoolz-0.12.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:de74ef266e2679c3bf8b5fc20cee4fc0271ba13ae0d9097b1491c7a9bcadb389"}, + {file = "cytoolz-0.12.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e04d22049233394e0b08193aca9737200b4a2afa28659d957327aa780ddddf2"}, + {file = "cytoolz-0.12.3-cp311-cp311-win32.whl", hash = "sha256:20d36430d8ac809186736fda735ee7d595b6242bdb35f69b598ef809ebfa5605"}, + {file = "cytoolz-0.12.3-cp311-cp311-win_amd64.whl", hash = "sha256:780c06110f383344d537f48d9010d79fa4f75070d214fc47f389357dd4f010b6"}, + {file = "cytoolz-0.12.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:86923d823bd19ce35805953b018d436f6b862edd6a7c8b747a13d52b39ed5716"}, + {file = "cytoolz-0.12.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3e61acfd029bfb81c2c596249b508dfd2b4f72e31b7b53b62e5fb0507dd7293"}, + {file = "cytoolz-0.12.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd728f4e6051af6af234651df49319da1d813f47894d4c3c8ab7455e01703a37"}, + {file = "cytoolz-0.12.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe8c6267caa7ec67bcc37e360f0d8a26bc3bdce510b15b97f2f2e0143bdd3673"}, + {file = "cytoolz-0.12.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99462abd8323c52204a2a0ce62454ce8fa0f4e94b9af397945c12830de73f27e"}, + {file = "cytoolz-0.12.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da125221b1fa25c690fcd030a54344cecec80074df018d906fc6a99f46c1e3a6"}, + {file = "cytoolz-0.12.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c18e351956f70db9e2d04ff02f28e9a41839250d3f936a4c8a1eabd1c3094d2"}, + {file = "cytoolz-0.12.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:921e6d2440ac758c4945c587b1d1d9b781b72737ac0c0ca5d5e02ca1db8bded2"}, + {file = "cytoolz-0.12.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1651a9bd591a8326329ce1d6336f3129161a36d7061a4d5ea9e5377e033364cf"}, + {file = "cytoolz-0.12.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:8893223b87c2782bd59f9c4bd5c7bf733edd8728b523c93efb91d7468b486528"}, + {file = "cytoolz-0.12.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:e4d2961644153c5ae186db964aa9f6109da81b12df0f1d3494b4e5cf2c332ee2"}, + {file = "cytoolz-0.12.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:71b6eb97f6695f7ba8ce69c49b707a351c5f46fd97f5aeb5f6f2fb0d6e72b887"}, + {file = "cytoolz-0.12.3-cp312-cp312-win32.whl", hash = "sha256:cee3de65584e915053412cd178729ff510ad5f8f585c21c5890e91028283518f"}, + {file = "cytoolz-0.12.3-cp312-cp312-win_amd64.whl", hash = "sha256:9eef0d23035fa4dcfa21e570961e86c375153a7ee605cdd11a8b088c24f707f6"}, + {file = "cytoolz-0.12.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9a38332cfad2a91e89405b7c18b3f00e2edc951c225accbc217597d3e4e9fde"}, + {file = "cytoolz-0.12.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f501ae1353071fa5d6677437bbeb1aeb5622067dce0977cedc2c5ec5843b202"}, + {file = "cytoolz-0.12.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:56f899758146a52e2f8cfb3fb6f4ca19c1e5814178c3d584de35f9e4d7166d91"}, + {file = "cytoolz-0.12.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:800f0526adf9e53d3c6acda748f4def1f048adaa780752f154da5cf22aa488a2"}, + {file = "cytoolz-0.12.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0976a3fcb81d065473173e9005848218ce03ddb2ec7d40dd6a8d2dba7f1c3ae"}, + {file = "cytoolz-0.12.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c835eab01466cb67d0ce6290601ebef2d82d8d0d0a285ed0d6e46989e4a7a71a"}, + {file = "cytoolz-0.12.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:4fba0616fcd487e34b8beec1ad9911d192c62e758baa12fcb44448b9b6feae22"}, + {file = "cytoolz-0.12.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6f6e8207d732651e0204779e1ba5a4925c93081834570411f959b80681f8d333"}, + {file = "cytoolz-0.12.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:8119bf5961091cfe644784d0bae214e273b3b3a479f93ee3baab97bbd995ccfe"}, + {file = "cytoolz-0.12.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:7ad1331cb68afeec58469c31d944a2100cee14eac221553f0d5218ace1a0b25d"}, + {file = "cytoolz-0.12.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:92c53d508fb8a4463acc85b322fa24734efdc66933a5c8661bdc862103a3373d"}, + {file = "cytoolz-0.12.3-cp37-cp37m-win32.whl", hash = "sha256:2c6dd75dae3d84fa8988861ab8b1189d2488cb8a9b8653828f9cd6126b5e7abd"}, + {file = "cytoolz-0.12.3-cp37-cp37m-win_amd64.whl", hash = "sha256:caf07a97b5220e6334dd32c8b6d8b2bd255ca694eca5dfe914bb5b880ee66cdb"}, + {file = "cytoolz-0.12.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ed0cfb9326747759e2ad81cb6e45f20086a273b67ac3a4c00b19efcbab007c60"}, + {file = "cytoolz-0.12.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:96a5a0292575c3697121f97cc605baf2fd125120c7dcdf39edd1a135798482ca"}, + {file = "cytoolz-0.12.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b76f2f50a789c44d6fd7f773ec43d2a8686781cd52236da03f7f7d7998989bee"}, + {file = "cytoolz-0.12.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2905fdccacc64b4beba37f95cab9d792289c80f4d70830b70de2fc66c007ec01"}, + {file = "cytoolz-0.12.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ebe23028eac51251f22ba01dba6587d30aa9c320372ca0c14eeab67118ec3f"}, + {file = "cytoolz-0.12.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96c715404a3825e37fe3966fe84c5f8a1f036e7640b2a02dbed96cac0c933451"}, + {file = "cytoolz-0.12.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bac0adffc1b6b6a4c5f1fd1dd2161afb720bcc771a91016dc6bdba59af0a5d3"}, + {file = "cytoolz-0.12.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:37441bf4a2a4e2e0fe9c3b0ea5e72db352f5cca03903977ffc42f6f6c5467be9"}, + {file = "cytoolz-0.12.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f04037302049cb30033f7fa4e1d0e44afe35ed6bfcf9b380fc11f2a27d3ed697"}, + {file = "cytoolz-0.12.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f37b60e66378e7a116931d7220f5352186abfcc950d64856038aa2c01944929c"}, + {file = "cytoolz-0.12.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ec9be3e4b6f86ea8b294d34c990c99d2ba6c526ef1e8f46f1d52c263d4f32cd7"}, + {file = "cytoolz-0.12.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0e9199c9e3fbf380a92b8042c677eb9e7ed4bccb126de5e9c0d26f5888d96788"}, + {file = "cytoolz-0.12.3-cp38-cp38-win32.whl", hash = "sha256:18cd61e078bd6bffe088e40f1ed02001387c29174750abce79499d26fa57f5eb"}, + {file = "cytoolz-0.12.3-cp38-cp38-win_amd64.whl", hash = "sha256:765b8381d4003ceb1a07896a854eee2c31ebc950a4ae17d1e7a17c2a8feb2a68"}, + {file = "cytoolz-0.12.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b4a52dd2a36b0a91f7aa50ca6c8509057acc481a24255f6cb07b15d339a34e0f"}, + {file = "cytoolz-0.12.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:581f1ce479769fe7eeb9ae6d87eadb230df8c7c5fff32138162cdd99d7fb8fc3"}, + {file = "cytoolz-0.12.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46f505d4c6eb79585c8ad0b9dc140ef30a138c880e4e3b40230d642690e36366"}, + {file = "cytoolz-0.12.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59276021619b432a5c21c01cda8320b9cc7dbc40351ffc478b440bfccd5bbdd3"}, + {file = "cytoolz-0.12.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e44f4c25e1e7cf6149b499c74945a14649c8866d36371a2c2d2164e4649e7755"}, + {file = "cytoolz-0.12.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c64f8e60c1dd69e4d5e615481f2d57937746f4a6be2d0f86e9e7e3b9e2243b5e"}, + {file = "cytoolz-0.12.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33c63186f3bf9d7ef1347bc0537bb9a0b4111a0d7d6e619623cabc18fef0dc3b"}, + {file = "cytoolz-0.12.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fdddb9d988405f24035234f1e8d1653ab2e48cc2404226d21b49a129aefd1d25"}, + {file = "cytoolz-0.12.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6986632d8a969ea1e720990c818dace1a24c11015fd7c59b9fea0b65ef71f726"}, + {file = "cytoolz-0.12.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0ba1cbc4d9cd7571c917f88f4a069568e5121646eb5d82b2393b2cf84712cf2a"}, + {file = "cytoolz-0.12.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7d267ffc9a36c0a9a58c7e0adc9fa82620f22e4a72533e15dd1361f57fc9accf"}, + {file = "cytoolz-0.12.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:95e878868a172a41fbf6c505a4b967309e6870e22adc7b1c3b19653d062711fa"}, + {file = "cytoolz-0.12.3-cp39-cp39-win32.whl", hash = "sha256:8e21932d6d260996f7109f2a40b2586070cb0a0cf1d65781e156326d5ebcc329"}, + {file = "cytoolz-0.12.3-cp39-cp39-win_amd64.whl", hash = "sha256:0d8edfbc694af6c9bda4db56643fb8ed3d14e47bec358c2f1417de9a12d6d1fb"}, + {file = "cytoolz-0.12.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:55f9bd1ae6c2a27eda5abe2a0b65a83029d2385c5a1da7b8ef47af5905d7e905"}, + {file = "cytoolz-0.12.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2d271393c378282727f1231d40391ae93b93ddc0997448acc21dd0cb6a1e56d"}, + {file = "cytoolz-0.12.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee98968d6a66ee83a8ceabf31182189ab5d8598998c8ce69b6d5843daeb2db60"}, + {file = "cytoolz-0.12.3-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01cfb8518828c1189200c02a5010ea404407fb18fd5589e29c126e84bbeadd36"}, + {file = "cytoolz-0.12.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:456395d7aec01db32bf9e6db191d667347c78d8d48e77234521fa1078f60dabb"}, + {file = "cytoolz-0.12.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:cd88028bb897fba99ddd84f253ca6bef73ecb7bdf3f3cf25bc493f8f97d3c7c5"}, + {file = "cytoolz-0.12.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59b19223e7f7bd7a73ec3aa6fdfb73b579ff09c2bc0b7d26857eec2d01a58c76"}, + {file = "cytoolz-0.12.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a79d72b08048a0980a59457c239555f111ac0c8bdc140c91a025f124104dbb4"}, + {file = "cytoolz-0.12.3-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1dd70141b32b717696a72b8876e86bc9c6f8eff995c1808e299db3541213ff82"}, + {file = "cytoolz-0.12.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:a1445c91009eb775d479e88954c51d0b4cf9a1e8ce3c503c2672d17252882647"}, + {file = "cytoolz-0.12.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ca6a9a9300d5bda417d9090107c6d2b007683efc59d63cc09aca0e7930a08a85"}, + {file = "cytoolz-0.12.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be6feb903d2a08a4ba2e70e950e862fd3be9be9a588b7c38cee4728150a52918"}, + {file = "cytoolz-0.12.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92b6f43f086e5a965d33d62a145ae121b4ccb6e0789ac0acc895ce084fec8c65"}, + {file = "cytoolz-0.12.3-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:534fa66db8564d9b13872d81d54b6b09ae592c585eb826aac235bd6f1830f8ad"}, + {file = "cytoolz-0.12.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:fea649f979def23150680de1bd1d09682da3b54932800a0f90f29fc2a6c98ba8"}, + {file = "cytoolz-0.12.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a447247ed312dd64e3a8d9483841ecc5338ee26d6e6fbd29cd373ed030db0240"}, + {file = "cytoolz-0.12.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba3f843aa89f35467b38c398ae5b980a824fdbdb94065adc6ec7c47a0a22f4c7"}, + {file = "cytoolz-0.12.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:582c22f97a380211fb36a7b65b1beeb84ea11d82015fa84b054be78580390082"}, + {file = "cytoolz-0.12.3-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47feb089506fc66e1593cd9ade3945693a9d089a445fbe9a11385cab200b9f22"}, + {file = "cytoolz-0.12.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ba9002d2f043943744a9dc8e50a47362bcb6e6f360dc0a1abcb19642584d87bb"}, + {file = "cytoolz-0.12.3.tar.gz", hash = "sha256:4503dc59f4ced53a54643272c61dc305d1dbbfbd7d6bdf296948de9f34c3a282"}, ] [package.dependencies] @@ -820,285 +742,180 @@ cython = ["cython"] [[package]] name = "dill" -version = "0.3.6" -description = "serialize all of python" -category = "dev" +version = "0.3.8" +description = "serialize all of Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"}, - {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, + {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"}, + {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"}, ] [package.extras] graph = ["objgraph (>=1.7.2)"] - -[[package]] -name = "distlib" -version = "0.3.6" -description = "Distribution utilities" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, - {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, -] - -[[package]] -name = "dulwich" -version = "0.20.50" -description = "Python Git Library" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "dulwich-0.20.50-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:97f02f8d500d4af08dc022d697c56e8539171acc3f575c2fe9acf3b078e5c8c9"}, - {file = "dulwich-0.20.50-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7301773e5cc16d521bc6490e73772a86a4d1d0263de506f08b54678cc4e2f061"}, - {file = "dulwich-0.20.50-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b70106580ed11f45f4c32d2831d0c9c9f359bc2415fff4a6be443e3a36811398"}, - {file = "dulwich-0.20.50-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f9c4f2455f966cad94648278fa9972e4695b35d04f82792fa58e1ea15dd83f0"}, - {file = "dulwich-0.20.50-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9163fbb021a8ad9c35a0814a5eedf45a8eb3a0b764b865d7016d901fc5a947fc"}, - {file = "dulwich-0.20.50-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:322ff8ff6aa4d6d36294cd36de1c84767eb1903c7db3e7b4475ad091febf5363"}, - {file = "dulwich-0.20.50-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5d3290a45651c8e534f8e83ae2e30322aefdd162f0f338bae2e79a6ee5a87513"}, - {file = "dulwich-0.20.50-cp310-cp310-win32.whl", hash = "sha256:80ab07131a6e68594441f5c4767e9e44e87fceafc3e347e541c928a18c679bd8"}, - {file = "dulwich-0.20.50-cp310-cp310-win_amd64.whl", hash = "sha256:eefe786a6010f8546baac4912113eeed4e397ddb8c433a345b548a04d4176496"}, - {file = "dulwich-0.20.50-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:df3562dde3079d57287c233d45b790bc967c5aae975c9a7b07ca30e60e055512"}, - {file = "dulwich-0.20.50-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e1ae18d5805f0c0c5dac65795f8d48660437166b12ee2c0ffea95bfdbf9c1051"}, - {file = "dulwich-0.20.50-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d2f7df39bd1378d3b0bfb3e7fc930fd0191924af1f0ef587bcd9946afe076c06"}, - {file = "dulwich-0.20.50-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:731e7f319b34251fadeb362ada1d52cc932369d9cdfa25c0e41150cda28773d0"}, - {file = "dulwich-0.20.50-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4d11d44176e5d2fa8271fc86ad1e0a8731b9ad8f77df64c12846b30e16135eb"}, - {file = "dulwich-0.20.50-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7aaabb8e4beadd53f75f853a981caaadef3ef130e5645c902705704eaf136daa"}, - {file = "dulwich-0.20.50-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c3dc9f97ec8d3db08d9723b9fd06f3e52c15b84c800d153cfb59b0a3dc8b8d40"}, - {file = "dulwich-0.20.50-cp311-cp311-win32.whl", hash = "sha256:3b1964fa80cafd5a1fd71615b0313daf6f3295c6ab05656ea0c1d2423539904a"}, - {file = "dulwich-0.20.50-cp311-cp311-win_amd64.whl", hash = "sha256:a24a3893108f3b97beb958670d5f3f2a3bec73a1fe18637a572a85abd949a1c4"}, - {file = "dulwich-0.20.50-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6d409a282f8848fd6c8d7c7545ad2f75c16de5d5977de202642f1d50fdaac554"}, - {file = "dulwich-0.20.50-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5411d0f1092152e1c0bb916ae490fe181953ae1b8d13f4e68661253e10b78dbb"}, - {file = "dulwich-0.20.50-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6343569f998ce429e2a5d813c56768ac51b496522401db950f0aa44240bfa901"}, - {file = "dulwich-0.20.50-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a405cd236766060894411614a272cfb86fe86cde5ca73ef264fc4fa5a715fff4"}, - {file = "dulwich-0.20.50-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ee0f9b02019c0ea84cdd31c00a0c283669b771c85612997a911715cf84e33d99"}, - {file = "dulwich-0.20.50-cp36-cp36m-win32.whl", hash = "sha256:2644466270267270f2157ea6f1c0aa224f6f3bf06a307fc39954e6b4b3d82bae"}, - {file = "dulwich-0.20.50-cp36-cp36m-win_amd64.whl", hash = "sha256:d4629635a97e3af1b5da48071e00c8e70fad85f3266fadabe1f5a8f49172c507"}, - {file = "dulwich-0.20.50-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0e4862f318d99cc8a500e3622a89613a88c07d957a0f628cdc2ed86addff790f"}, - {file = "dulwich-0.20.50-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96e3fb9d48c0454dc242c7accc7819780c9a7f29e441a9eff12361ed0fa35f9"}, - {file = "dulwich-0.20.50-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cc6092a4f0bbbff2e553e87a9c6325955b64ea43fca21297c8182e19ae8a43c"}, - {file = "dulwich-0.20.50-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:519b627d49d273e2fd01c79d09e578675ca6cd05193c1787e9ef165c9a1d66ea"}, - {file = "dulwich-0.20.50-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a75cab01b909c4c683c2083e060e378bc01701b7366b5a7d9846ef6d3b9e3d5"}, - {file = "dulwich-0.20.50-cp37-cp37m-win32.whl", hash = "sha256:ea8ffe26d91dbcd5580dbd5a07270a12ea57b091604d77184da0a0d9fad50ed3"}, - {file = "dulwich-0.20.50-cp37-cp37m-win_amd64.whl", hash = "sha256:8f3af857f94021cae1322d86925bfc0dd31e501e885ab5db275473bfac0bb39d"}, - {file = "dulwich-0.20.50-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3fb35cedb1243bc420d885ef5b4afd642c6ac8f07ddfc7fdbca1becf9948bf7e"}, - {file = "dulwich-0.20.50-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4bb23a9cec63e16c0e432335f068169b73dd44fa9318dd7cd7a4ca83607ff367"}, - {file = "dulwich-0.20.50-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5267619b34ddaf8d9a6b841492cd17a971fd25bf9a5657f2de928385c3a08b94"}, - {file = "dulwich-0.20.50-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9091f1d53a3c0747cbf0bd127c64e7f09b770264d8fb53e284383fcdf69154e7"}, - {file = "dulwich-0.20.50-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6ec7c8fea2b44187a3b545e6c11ab9947ffb122647b07abcdb7cc3aaa770c0e"}, - {file = "dulwich-0.20.50-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:11b180b80363b4fc70664197028181a17ae4c52df9965a29b62a6c52e40c2dbe"}, - {file = "dulwich-0.20.50-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c83e7840d9d0a94d7033bc109efe0c22dfcdcd816bcd4469085e42809e3bf5ba"}, - {file = "dulwich-0.20.50-cp38-cp38-win32.whl", hash = "sha256:c075f69c2de19d9fd97e3b70832d2b42c6a4a5d909b3ffd1963b67d86029f95f"}, - {file = "dulwich-0.20.50-cp38-cp38-win_amd64.whl", hash = "sha256:06775c5713cfeda778c7c67d4422b5e7554d3a7f644f1dde646cdf486a30285a"}, - {file = "dulwich-0.20.50-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:49f66f1c057c18d7d60363f461f4ab8329320fbe1f02a7a33c255864a7d3c942"}, - {file = "dulwich-0.20.50-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4e541cd690a5e3d55082ed51732d755917e933cddeb4b0204f2a5ec5d5d7b60b"}, - {file = "dulwich-0.20.50-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:80e8750ee2fa0ab2784a095956077758e5f6107de27f637c4b9d18406652c22c"}, - {file = "dulwich-0.20.50-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fbb6368f18451dc44c95c55e1a609d1a01d3821f7ed480b22b2aea1baca0f4a7"}, - {file = "dulwich-0.20.50-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3ee45001411b638641819b7b3b33f31f13467c84066e432256580fcab7d8815"}, - {file = "dulwich-0.20.50-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4842e22ed863a776b36ef8ffe9ed7b772eb452b42c8d02975c29d27e3bc50ab4"}, - {file = "dulwich-0.20.50-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:790e4a641284a7fb4d56ebdaf8b324a5826fbbb9c54307c06f586f9f6a5e56db"}, - {file = "dulwich-0.20.50-cp39-cp39-win32.whl", hash = "sha256:f08406b6b789dea5c95ba1130a0801d8748a67f18be940fe7486a8b481fde875"}, - {file = "dulwich-0.20.50-cp39-cp39-win_amd64.whl", hash = "sha256:78c388ad421199000fb7b5ed5f0c7b509b3e31bd7cad303786a4d0bf89b82f60"}, - {file = "dulwich-0.20.50-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:cb194c53109131bcbcd1ca430fcd437cdaf2d33e204e45fbe121c47eaa43e9af"}, - {file = "dulwich-0.20.50-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7542a72c5640dd0620862d6df8688f02a6c336359b5af9b3fcfe11b7fa6652f"}, - {file = "dulwich-0.20.50-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4aa1d0861517ebbbe0e0084cc9ab4f7ab720624a3eda2bd10e45f774ab858db8"}, - {file = "dulwich-0.20.50-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:583c6bbc27f13fe2e41a19f6987a42681c6e4f6959beae0a6e5bb033b8b081a8"}, - {file = "dulwich-0.20.50-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0c61c193d02c0e1e0d758cdd57ae76685c368d09a01f00d704ba88bd96767cfe"}, - {file = "dulwich-0.20.50-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2edbff3053251985f10702adfafbee118298d383ef5b5b432a5f22d1f1915df"}, - {file = "dulwich-0.20.50-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a344230cadfc5d315752add6ce9d4cfcfc6c85e36bbf57fce9444bcc7c6ea8fb"}, - {file = "dulwich-0.20.50-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:57bff9bde0b6b05b00c6acbb1a94357caddb2908ed7026a48c715ff50d220335"}, - {file = "dulwich-0.20.50-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e29a3c2037761fa816aa556e78364dfc8e3f44b873db2d17aed96f9b06ac83a3"}, - {file = "dulwich-0.20.50-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2aa2a4a84029625bf9c63771f8a628db1f3be2d2ea3cb8b17942cd4317797152"}, - {file = "dulwich-0.20.50-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd9fa00971ecf059bb358085a942ecac5be4ff71acdf299f44c8cbc45c18659f"}, - {file = "dulwich-0.20.50-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:af4adac92fb95671ea3a24f2f8e5e5e8f638711ce9c33a3ca6cd68bf1ff7d99f"}, - {file = "dulwich-0.20.50.tar.gz", hash = "sha256:50a941796b2c675be39be728d540c16b5b7ce77eb9e1b3f855650ece6832d2be"}, -] - -[package.dependencies] -urllib3 = ">=1.25" - -[package.extras] -fastimport = ["fastimport"] -https = ["urllib3 (>=1.24.1)"] -paramiko = ["paramiko"] -pgp = ["gpg"] +profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "eth-abi" -version = "4.0.0b2" +version = "5.1.0" description = "eth_abi: Python utilities for working with Ethereum ABI definitions, especially encoding and decoding" -category = "main" optional = false -python-versions = ">=3.7, <4" +python-versions = "<4,>=3.8" files = [ - {file = "eth_abi-4.0.0b2-py3-none-any.whl", hash = "sha256:9c81da53b0b48f72c539eb5744b7596ccb97e626e585eb4f1354b1670ea51ae2"}, - {file = "eth_abi-4.0.0b2.tar.gz", hash = "sha256:0cbd5a854acf101843d3f009b10a8b63050125981211ea4d074a80eb953f97ab"}, + {file = "eth_abi-5.1.0-py3-none-any.whl", hash = "sha256:84cac2626a7db8b7d9ebe62b0fdca676ab1014cc7f777189e3c0cd721a4c16d8"}, + {file = "eth_abi-5.1.0.tar.gz", hash = "sha256:33ddd756206e90f7ddff1330cc8cac4aa411a824fe779314a0a52abea2c8fc14"}, ] [package.dependencies] eth-typing = ">=3.0.0" eth-utils = ">=2.0.0" -parsimonious = ">=0.8.0,<0.10.0" +parsimonious = ">=0.10.0,<0.11.0" [package.extras] -dev = ["black", "bumpversion (>=0.5.3,<1)", "eth-hash[pycryptodome]", "flake8 (==4.0.1)", "hypothesis (>=4.18.2,<5.0.0)", "ipython", "isort (>=4.2.15,<5)", "jinja2 (>=3.0.0,<3.1.0)", "mypy (==0.910)", "pydocstyle (>=6.0.0,<7)", "pytest (>=6.2.5,<7)", "pytest-pythonpath (>=0.7.1)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist (>=2.5.0,<3)", "sphinx (>=4.5.0,<5)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (==18.5.0)", "tox (>=2.9.1,<3)", "twine", "wheel"] -doc = ["jinja2 (>=3.0.0,<3.1.0)", "sphinx (>=4.5.0,<5)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (==18.5.0)"] -lint = ["black", "flake8 (==4.0.1)", "isort (>=4.2.15,<5)", "mypy (==0.910)", "pydocstyle (>=6.0.0,<7)"] -test = ["eth-hash[pycryptodome]", "hypothesis (>=4.18.2,<5.0.0)", "pytest (>=6.2.5,<7)", "pytest-pythonpath (>=0.7.1)", "pytest-xdist (>=2.5.0,<3)", "tox (>=2.9.1,<3)"] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "eth-hash[pycryptodome]", "hypothesis (>=4.18.2,<5.0.0)", "ipython", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-pythonpath (>=0.7.1)", "pytest-timeout (>=2.0.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +test = ["eth-hash[pycryptodome]", "hypothesis (>=4.18.2,<5.0.0)", "pytest (>=7.0.0)", "pytest-pythonpath (>=0.7.1)", "pytest-timeout (>=2.0.0)", "pytest-xdist (>=2.4.0)"] tools = ["hypothesis (>=4.18.2,<5.0.0)"] [[package]] name = "eth-account" -version = "0.8.0" +version = "0.11.2" description = "eth-account: Sign Ethereum transactions and messages with local private keys" -category = "main" optional = false -python-versions = ">=3.6, <4" +python-versions = "<4,>=3.8" files = [ - {file = "eth-account-0.8.0.tar.gz", hash = "sha256:ccb2d90a16c81c8ea4ca4dc76a70b50f1d63cea6aff3c5a5eddedf9e45143eca"}, - {file = "eth_account-0.8.0-py3-none-any.whl", hash = "sha256:0ccc0edbb17021004356ae6e37887528b6e59e6ae6283f3917b9759a5887203b"}, + {file = "eth-account-0.11.2.tar.gz", hash = "sha256:b43daf2c0ae43f2a24ba754d66889f043fae4d3511559cb26eb0122bae9afbbd"}, + {file = "eth_account-0.11.2-py3-none-any.whl", hash = "sha256:95157c262a9823c1e08be826d4bc304bf32f0c32e80afb38c126a325a64f651a"}, ] [package.dependencies] -bitarray = ">=2.4.0,<3" -eth-abi = ">=3.0.1" -eth-keyfile = ">=0.6.0,<0.7.0" -eth-keys = ">=0.4.0,<0.5" -eth-rlp = ">=0.3.0,<1" -eth-utils = ">=2.0.0,<3" -hexbytes = ">=0.1.0,<1" -rlp = ">=1.0.0,<4" +bitarray = ">=2.4.0" +ckzg = ">=0.4.3" +eth-abi = ">=4.0.0-b.2" +eth-keyfile = ">=0.6.0" +eth-keys = ">=0.4.0" +eth-rlp = ">=0.3.0" +eth-utils = ">=2.0.0" +hexbytes = ">=0.1.0,<0.4.0" +rlp = ">=1.0.0" [package.extras] -dev = ["Sphinx (>=1.6.5,<5)", "black (>=22,<23)", "bumpversion (>=0.5.3,<1)", "coverage", "flake8 (==3.7.9)", "hypothesis (>=4.18.0,<5)", "ipython", "isort (>=4.2.15,<5)", "jinja2 (>=3.0.0,<3.1.0)", "mypy (==0.910)", "pydocstyle (>=5.0.0,<6)", "pytest (>=6.2.5,<7)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=21,<22)", "tox (==3.25.0)", "twine", "wheel"] -doc = ["Sphinx (>=1.6.5,<5)", "jinja2 (>=3.0.0,<3.1.0)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=21,<22)"] -lint = ["black (>=22,<23)", "flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.910)", "pydocstyle (>=5.0.0,<6)"] -test = ["coverage", "hypothesis (>=4.18.0,<5)", "pytest (>=6.2.5,<7)", "pytest-xdist", "tox (==3.25.0)"] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "coverage", "hypothesis (>=4.18.0,<5)", "ipython", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +test = ["coverage", "hypothesis (>=4.18.0,<5)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "eth-hash" -version = "0.5.1" +version = "0.7.0" description = "eth-hash: The Ethereum hashing function, keccak256, sometimes (erroneously) called sha3" -category = "main" optional = false -python-versions = ">=3.7, <4" +python-versions = ">=3.8, <4" files = [ - {file = "eth-hash-0.5.1.tar.gz", hash = "sha256:9805075f653e114a31a99678e93b257fb4082337696f4eff7b4371fe65158409"}, - {file = "eth_hash-0.5.1-py3-none-any.whl", hash = "sha256:4d992e885f3ae3901abbe98bd776ba62d0f6335f98c6e9fc60a39b9d114dfb5a"}, + {file = "eth-hash-0.7.0.tar.gz", hash = "sha256:bacdc705bfd85dadd055ecd35fd1b4f846b671add101427e089a4ca2e8db310a"}, + {file = "eth_hash-0.7.0-py3-none-any.whl", hash = "sha256:b8d5a230a2b251f4a291e3164a23a14057c4a6de4b0aa4a16fa4dc9161b57e2f"}, ] [package.dependencies] pycryptodome = {version = ">=3.6.6,<4", optional = true, markers = "extra == \"pycryptodome\""} [package.extras] -dev = ["Sphinx (>=5.0.0,<6)", "black (>=22.0,<23)", "bumpversion (>=0.5.3,<1)", "flake8 (==3.7.9)", "ipython", "isort (>=4.2.15,<5)", "jinja2 (>=3.0.0,<3.1.0)", "mypy (==0.961)", "pydocstyle (>=5.0.0,<6)", "pytest (>=6.2.5,<7)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist (>=2.4.0,<3)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=21,<22)", "tox (>=3.14.6,<4)", "twine", "wheel"] -doc = ["Sphinx (>=5.0.0,<6)", "jinja2 (>=3.0.0,<3.1.0)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=21,<22)"] -lint = ["black (>=22.0,<23)", "flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.961)", "pydocstyle (>=5.0.0,<6)"] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "ipython", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] pycryptodome = ["pycryptodome (>=3.6.6,<4)"] pysha3 = ["pysha3 (>=1.0.0,<2.0.0)", "safe-pysha3 (>=1.0.0)"] -test = ["pytest (>=6.2.5,<7)", "pytest-xdist (>=2.4.0,<3)", "tox (>=3.14.6,<4)"] +test = ["pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "eth-keyfile" -version = "0.6.1" -description = "A library for handling the encrypted keyfiles used to store ethereum private keys." -category = "main" +version = "0.8.1" +description = "eth-keyfile: A library for handling the encrypted keyfiles used to store ethereum private keys" optional = false -python-versions = "*" +python-versions = "<4,>=3.8" files = [ - {file = "eth-keyfile-0.6.1.tar.gz", hash = "sha256:471be6e5386fce7b22556b3d4bde5558dbce46d2674f00848027cb0a20abdc8c"}, - {file = "eth_keyfile-0.6.1-py3-none-any.whl", hash = "sha256:609773a1ad5956944a33348413cad366ec6986c53357a806528c8f61c4961560"}, + {file = "eth_keyfile-0.8.1-py3-none-any.whl", hash = "sha256:65387378b82fe7e86d7cb9f8d98e6d639142661b2f6f490629da09fddbef6d64"}, + {file = "eth_keyfile-0.8.1.tar.gz", hash = "sha256:9708bc31f386b52cca0969238ff35b1ac72bd7a7186f2a84b86110d3c973bec1"}, ] [package.dependencies] -eth-keys = ">=0.4.0,<0.5.0" -eth-utils = ">=2,<3" +eth-keys = ">=0.4.0" +eth-utils = ">=2" pycryptodome = ">=3.6.6,<4" [package.extras] -dev = ["bumpversion (>=0.5.3,<1)", "eth-keys (>=0.4.0,<0.5.0)", "eth-utils (>=2,<3)", "flake8 (==4.0.1)", "idna (==2.7)", "pluggy (>=1.0.0,<2)", "pycryptodome (>=3.6.6,<4)", "pytest (>=6.2.5,<7)", "requests (>=2.20,<3)", "setuptools (>=38.6.0)", "tox (>=2.7.0)", "twine", "wheel"] -keyfile = ["eth-keys (>=0.4.0,<0.5.0)", "eth-utils (>=2,<3)", "pycryptodome (>=3.6.6,<4)"] -lint = ["flake8 (==4.0.1)"] -test = ["pytest (>=6.2.5,<7)"] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "ipython", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["towncrier (>=21,<22)"] +test = ["pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "eth-keys" -version = "0.4.0" -description = "Common API for Ethereum key operations." -category = "main" +version = "0.5.1" +description = "eth-keys: Common API for Ethereum key operations" optional = false -python-versions = "*" +python-versions = "<4,>=3.8" files = [ - {file = "eth-keys-0.4.0.tar.gz", hash = "sha256:7d18887483bc9b8a3fdd8e32ddcb30044b9f08fcb24a380d93b6eee3a5bb3216"}, - {file = "eth_keys-0.4.0-py3-none-any.whl", hash = "sha256:e07915ffb91277803a28a379418bdd1fad1f390c38ad9353a0f189789a440d5d"}, + {file = "eth_keys-0.5.1-py3-none-any.whl", hash = "sha256:ad13d920a2217a49bed3a1a7f54fb0980f53caf86d3bbab2139fd3330a17b97e"}, + {file = "eth_keys-0.5.1.tar.gz", hash = "sha256:2b587e4bbb9ac2195215a7ab0c0fb16042b17d4ec50240ed670bbb8f53da7a48"}, ] [package.dependencies] -eth-typing = ">=3.0.0,<4" -eth-utils = ">=2.0.0,<3.0.0" +eth-typing = ">=3" +eth-utils = ">=2" [package.extras] -coincurve = ["coincurve (>=7.0.0,<16.0.0)"] -dev = ["asn1tools (>=0.146.2,<0.147)", "bumpversion (==0.5.3)", "eth-hash[pycryptodome]", "eth-hash[pysha3]", "eth-typing (>=3.0.0,<4)", "eth-utils (>=2.0.0,<3.0.0)", "factory-boy (>=3.0.1,<3.1)", "flake8 (==3.0.4)", "hypothesis (>=5.10.3,<6.0.0)", "mypy (==0.782)", "pyasn1 (>=0.4.5,<0.5)", "pytest (==6.2.5)", "tox (==3.20.0)", "twine"] -eth-keys = ["eth-typing (>=3.0.0,<4)", "eth-utils (>=2.0.0,<3.0.0)"] -lint = ["flake8 (==3.0.4)", "mypy (==0.782)"] -test = ["asn1tools (>=0.146.2,<0.147)", "eth-hash[pycryptodome]", "eth-hash[pysha3]", "factory-boy (>=3.0.1,<3.1)", "hypothesis (>=5.10.3,<6.0.0)", "pyasn1 (>=0.4.5,<0.5)", "pytest (==6.2.5)"] +coincurve = ["coincurve (>=12.0.0)"] +dev = ["asn1tools (>=0.146.2)", "build (>=0.9.0)", "bumpversion (>=0.5.3)", "coincurve (>=12.0.0)", "eth-hash[pysha3]", "factory-boy (>=3.0.1)", "hypothesis (>=5.10.3)", "ipython", "pre-commit (>=3.4.0)", "pyasn1 (>=0.4.5)", "pytest (>=7.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["towncrier (>=21,<22)"] +test = ["asn1tools (>=0.146.2)", "eth-hash[pysha3]", "factory-boy (>=3.0.1)", "hypothesis (>=5.10.3)", "pyasn1 (>=0.4.5)", "pytest (>=7.0.0)"] [[package]] name = "eth-rlp" -version = "0.3.0" +version = "1.0.1" description = "eth-rlp: RLP definitions for common Ethereum objects in Python" -category = "main" optional = false -python-versions = ">=3.7, <4" +python-versions = ">=3.8, <4" files = [ - {file = "eth-rlp-0.3.0.tar.gz", hash = "sha256:f3263b548df718855d9a8dbd754473f383c0efc82914b0b849572ce3e06e71a6"}, - {file = "eth_rlp-0.3.0-py3-none-any.whl", hash = "sha256:e88e949a533def85c69fa94224618bbbd6de00061f4cff645c44621dab11cf33"}, + {file = "eth-rlp-1.0.1.tar.gz", hash = "sha256:d61dbda892ee1220f28fb3663c08f6383c305db9f1f5624dc585c9cd05115027"}, + {file = "eth_rlp-1.0.1-py3-none-any.whl", hash = "sha256:dd76515d71654277377d48876b88e839d61553aaf56952e580bb7cebef2b1517"}, ] [package.dependencies] -eth-utils = ">=2.0.0,<3" +eth-utils = ">=2.0.0" hexbytes = ">=0.1.0,<1" -rlp = ">=0.6.0,<4" +rlp = ">=0.6.0" [package.extras] -dev = ["Sphinx (>=1.6.5,<2)", "bumpversion (>=0.5.3,<1)", "eth-hash[pycryptodome]", "flake8 (==3.7.9)", "ipython", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=3.0.0,<4)", "pytest (>=6.2.5,<7)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist", "sphinx-rtd-theme (>=0.1.9)", "towncrier (>=19.2.0,<20)", "tox (==3.14.6)", "twine", "wheel"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9)", "towncrier (>=19.2.0,<20)"] -lint = ["flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.770)", "pydocstyle (>=3.0.0,<4)"] -test = ["eth-hash[pycryptodome]", "pytest (>=6.2.5,<7)", "pytest-xdist", "tox (==3.14.6)"] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "eth-hash[pycryptodome]", "ipython", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +test = ["eth-hash[pycryptodome]", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "eth-typing" -version = "3.2.0" +version = "4.3.0" description = "eth-typing: Common type annotations for ethereum python packages" -category = "main" optional = false -python-versions = ">=3.6, <4" +python-versions = "<4,>=3.8" files = [ - {file = "eth-typing-3.2.0.tar.gz", hash = "sha256:177e2070da9bf557fe0fd46ee467a7be2d0b6476aa4dc18680603e7da1fc5690"}, - {file = "eth_typing-3.2.0-py3-none-any.whl", hash = "sha256:2d7540c1c65c0e686c1dc357b8376a53caf4e1693724a90191ad133be568841d"}, + {file = "eth_typing-4.3.0-py3-none-any.whl", hash = "sha256:718f8ef8180ac1a15e476f072e4522e7bd4429bdabc71499e3ca79e2219d775c"}, + {file = "eth_typing-4.3.0.tar.gz", hash = "sha256:3f4eface387eefa68761b23743baab8d413d609b4201c4086c64a006be5dbf53"}, ] +[package.dependencies] +typing-extensions = ">=4.0.0" + [package.extras] -dev = ["bumpversion (>=0.5.3,<1)", "flake8 (==3.8.3)", "ipython", "isort (>=4.2.15,<5)", "mypy (==0.782)", "pydocstyle (>=3.0.0,<4)", "pytest (>=6.2.5,<7)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist", "sphinx (>=4.2.0,<5)", "sphinx-rtd-theme (>=0.1.9)", "towncrier (>=21,<22)", "tox (>=2.9.1,<3)", "twine", "wheel"] -doc = ["sphinx (>=4.2.0,<5)", "sphinx-rtd-theme (>=0.1.9)", "towncrier (>=21,<22)"] -lint = ["flake8 (==3.8.3)", "isort (>=4.2.15,<5)", "mypy (==0.782)", "pydocstyle (>=3.0.0,<4)"] -test = ["pytest (>=6.2.5,<7)", "pytest-xdist", "tox (>=2.9.1,<3)"] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "ipython", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["sphinx (>=6.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +test = ["pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "eth-utils" -version = "2.1.0" +version = "4.1.1" description = "eth-utils: Common utility functions for python code that interacts with Ethereum" -category = "main" optional = false -python-versions = ">=3.7,<4" +python-versions = "<4,>=3.8" files = [ - {file = "eth-utils-2.1.0.tar.gz", hash = "sha256:fcb4c3c1b32947ba92970963f9aaf40da73b04ea1034964ff8c0e70595127138"}, - {file = "eth_utils-2.1.0-py3-none-any.whl", hash = "sha256:63901e54ec9e4ac16ae0a0d28e1dc48b968c20184d22f2727e5f3ca24b6250bc"}, + {file = "eth_utils-4.1.1-py3-none-any.whl", hash = "sha256:ccbbac68a6d65cb6e294c5bcb6c6a5cec79a241c56dc5d9c345ed788c30f8534"}, + {file = "eth_utils-4.1.1.tar.gz", hash = "sha256:71c8d10dec7494aeed20fa7a4d52ec2ce4a2e52fdce80aab4f5c3c19f3648b25"}, ] [package.dependencies] @@ -1108,250 +925,188 @@ eth-typing = ">=3.0.0" toolz = {version = ">0.8.2", markers = "implementation_name == \"pypy\""} [package.extras] -dev = ["Sphinx (>=1.6.5,<2)", "black (>=22)", "bumpversion (>=0.5.3,<1)", "flake8 (==3.7.9)", "hypothesis (>=4.43.0,<5.0.0)", "ipython", "isort (>=4.2.15,<5)", "jinja2 (>=3.0.0,<3.0.1)", "mypy (==0.910)", "pydocstyle (>=5.0.0,<6)", "pytest (>=6.2.5,<7)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist", "sphinx-rtd-theme (>=0.1.9,<2)", "towncrier (>=21,<22)", "tox (==3.14.6)", "twine (>=1.13,<2)", "types-setuptools", "wheel (>=0.30.0,<1.0.0)"] -doc = ["Sphinx (>=1.6.5,<2)", "jinja2 (>=3.0.0,<3.0.1)", "sphinx-rtd-theme (>=0.1.9,<2)", "towncrier (>=21,<22)"] -lint = ["black (>=22)", "flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.910)", "pydocstyle (>=5.0.0,<6)", "pytest (>=6.2.5,<7)", "types-setuptools"] -test = ["hypothesis (>=4.43.0,<5.0.0)", "pytest (>=6.2.5,<7)", "pytest-xdist", "tox (==3.14.6)", "types-setuptools"] +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "eth-hash[pycryptodome]", "hypothesis (>=4.43.0)", "ipython", "mypy (==1.5.1)", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=6.0.0)", "sphinx-autobuild (>=2021.3.14)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["sphinx (>=6.0.0)", "sphinx-autobuild (>=2021.3.14)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +test = ["hypothesis (>=4.43.0)", "mypy (==1.5.1)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "execnet" -version = "1.9.0" +version = "2.1.1" description = "execnet: rapid multi-Python deployment" -category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.8" files = [ - {file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"}, - {file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"}, + {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"}, + {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"}, ] [package.extras] -testing = ["pre-commit"] +testing = ["hatch", "pre-commit", "pytest", "tox"] [[package]] name = "faker" -version = "17.6.0" +version = "25.8.0" description = "Faker is a Python package that generates fake data for you." -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "Faker-17.6.0-py3-none-any.whl", hash = "sha256:5aaa16fa9cfde7d117eef70b6b293a705021e57158f3fa6b44ed1b70202d2065"}, - {file = "Faker-17.6.0.tar.gz", hash = "sha256:51f37ff9df710159d6d736d0ba1c75e063430a8c806b91334d7794305b5a6114"}, + {file = "Faker-25.8.0-py3-none-any.whl", hash = "sha256:4c40b34a9c569018d4f9d6366d71a4da8a883d5ddf2b23197be5370f29b7e1b6"}, + {file = "Faker-25.8.0.tar.gz", hash = "sha256:bdec5f2fb057d244ebef6e0ed318fea4dcbdf32c3a1a010766fc45f5d68fc68d"}, ] [package.dependencies] python-dateutil = ">=2.4" -[[package]] -name = "filelock" -version = "3.9.0" -description = "A platform independent file lock." -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "filelock-3.9.0-py3-none-any.whl", hash = "sha256:f58d535af89bb9ad5cd4df046f741f8553a418c01a7856bf0d173bbc9f6bd16d"}, - {file = "filelock-3.9.0.tar.gz", hash = "sha256:7b319f24340b51f55a2bf7a12ac0755a9b03e718311dac567a0f4f7fabd2f5de"}, -] - -[package.extras] -docs = ["furo (>=2022.12.7)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] -testing = ["covdefaults (>=2.2.2)", "coverage (>=7.0.1)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-timeout (>=2.1)"] - [[package]] name = "frozenlist" -version = "1.3.3" +version = "1.4.1" description = "A list-like structure which implements collections.abc.MutableSequence" -category = "main" optional = false -python-versions = ">=3.7" -files = [ - {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff8bf625fe85e119553b5383ba0fb6aa3d0ec2ae980295aaefa552374926b3f4"}, - {file = "frozenlist-1.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dfbac4c2dfcc082fcf8d942d1e49b6aa0766c19d3358bd86e2000bf0fa4a9cf0"}, - {file = "frozenlist-1.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b1c63e8d377d039ac769cd0926558bb7068a1f7abb0f003e3717ee003ad85530"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fdfc24dcfce5b48109867c13b4cb15e4660e7bd7661741a391f821f23dfdca7"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2c926450857408e42f0bbc295e84395722ce74bae69a3b2aa2a65fe22cb14b99"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1841e200fdafc3d51f974d9d377c079a0694a8f06de2e67b48150328d66d5483"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f470c92737afa7d4c3aacc001e335062d582053d4dbe73cda126f2d7031068dd"}, - {file = "frozenlist-1.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:783263a4eaad7c49983fe4b2e7b53fa9770c136c270d2d4bbb6d2192bf4d9caf"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:924620eef691990dfb56dc4709f280f40baee568c794b5c1885800c3ecc69816"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ae4dc05c465a08a866b7a1baf360747078b362e6a6dbeb0c57f234db0ef88ae0"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:bed331fe18f58d844d39ceb398b77d6ac0b010d571cba8267c2e7165806b00ce"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:02c9ac843e3390826a265e331105efeab489ffaf4dd86384595ee8ce6d35ae7f"}, - {file = "frozenlist-1.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9545a33965d0d377b0bc823dcabf26980e77f1b6a7caa368a365a9497fb09420"}, - {file = "frozenlist-1.3.3-cp310-cp310-win32.whl", hash = "sha256:d5cd3ab21acbdb414bb6c31958d7b06b85eeb40f66463c264a9b343a4e238642"}, - {file = "frozenlist-1.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:b756072364347cb6aa5b60f9bc18e94b2f79632de3b0190253ad770c5df17db1"}, - {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b4395e2f8d83fbe0c627b2b696acce67868793d7d9750e90e39592b3626691b7"}, - {file = "frozenlist-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14143ae966a6229350021384870458e4777d1eae4c28d1a7aa47f24d030e6678"}, - {file = "frozenlist-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5d8860749e813a6f65bad8285a0520607c9500caa23fea6ee407e63debcdbef6"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23d16d9f477bb55b6154654e0e74557040575d9d19fe78a161bd33d7d76808e8"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb82dbba47a8318e75f679690190c10a5e1f447fbf9df41cbc4c3afd726d88cb"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9309869032abb23d196cb4e4db574232abe8b8be1339026f489eeb34a4acfd91"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a97b4fe50b5890d36300820abd305694cb865ddb7885049587a5678215782a6b"}, - {file = "frozenlist-1.3.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c188512b43542b1e91cadc3c6c915a82a5eb95929134faf7fd109f14f9892ce4"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:303e04d422e9b911a09ad499b0368dc551e8c3cd15293c99160c7f1f07b59a48"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0771aed7f596c7d73444c847a1c16288937ef988dc04fb9f7be4b2aa91db609d"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:66080ec69883597e4d026f2f71a231a1ee9887835902dbe6b6467d5a89216cf6"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:41fe21dc74ad3a779c3d73a2786bdf622ea81234bdd4faf90b8b03cad0c2c0b4"}, - {file = "frozenlist-1.3.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f20380df709d91525e4bee04746ba612a4df0972c1b8f8e1e8af997e678c7b81"}, - {file = "frozenlist-1.3.3-cp311-cp311-win32.whl", hash = "sha256:f30f1928162e189091cf4d9da2eac617bfe78ef907a761614ff577ef4edfb3c8"}, - {file = "frozenlist-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:a6394d7dadd3cfe3f4b3b186e54d5d8504d44f2d58dcc89d693698e8b7132b32"}, - {file = "frozenlist-1.3.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8df3de3a9ab8325f94f646609a66cbeeede263910c5c0de0101079ad541af332"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0693c609e9742c66ba4870bcee1ad5ff35462d5ffec18710b4ac89337ff16e27"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd4210baef299717db0a600d7a3cac81d46ef0e007f88c9335db79f8979c0d3d"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:394c9c242113bfb4b9aa36e2b80a05ffa163a30691c7b5a29eba82e937895d5e"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6327eb8e419f7d9c38f333cde41b9ae348bec26d840927332f17e887a8dcb70d"}, - {file = "frozenlist-1.3.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e24900aa13212e75e5b366cb9065e78bbf3893d4baab6052d1aca10d46d944c"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3843f84a6c465a36559161e6c59dce2f2ac10943040c2fd021cfb70d58c4ad56"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:84610c1502b2461255b4c9b7d5e9c48052601a8957cd0aea6ec7a7a1e1fb9420"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:c21b9aa40e08e4f63a2f92ff3748e6b6c84d717d033c7b3438dd3123ee18f70e"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:efce6ae830831ab6a22b9b4091d411698145cb9b8fc869e1397ccf4b4b6455cb"}, - {file = "frozenlist-1.3.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:40de71985e9042ca00b7953c4f41eabc3dc514a2d1ff534027f091bc74416401"}, - {file = "frozenlist-1.3.3-cp37-cp37m-win32.whl", hash = "sha256:180c00c66bde6146a860cbb81b54ee0df350d2daf13ca85b275123bbf85de18a"}, - {file = "frozenlist-1.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9bbbcedd75acdfecf2159663b87f1bb5cfc80e7cd99f7ddd9d66eb98b14a8411"}, - {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:034a5c08d36649591be1cbb10e09da9f531034acfe29275fc5454a3b101ce41a"}, - {file = "frozenlist-1.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba64dc2b3b7b158c6660d49cdb1d872d1d0bf4e42043ad8d5006099479a194e5"}, - {file = "frozenlist-1.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:47df36a9fe24054b950bbc2db630d508cca3aa27ed0566c0baf661225e52c18e"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:008a054b75d77c995ea26629ab3a0c0d7281341f2fa7e1e85fa6153ae29ae99c"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:841ea19b43d438a80b4de62ac6ab21cfe6827bb8a9dc62b896acc88eaf9cecba"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e235688f42b36be2b6b06fc37ac2126a73b75fb8d6bc66dd632aa35286238703"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca713d4af15bae6e5d79b15c10c8522859a9a89d3b361a50b817c98c2fb402a2"}, - {file = "frozenlist-1.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ac5995f2b408017b0be26d4a1d7c61bce106ff3d9e3324374d66b5964325448"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4ae8135b11652b08a8baf07631d3ebfe65a4c87909dbef5fa0cdde440444ee4"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4ea42116ceb6bb16dbb7d526e242cb6747b08b7710d9782aa3d6732bd8d27649"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:810860bb4bdce7557bc0febb84bbd88198b9dbc2022d8eebe5b3590b2ad6c842"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ee78feb9d293c323b59a6f2dd441b63339a30edf35abcb51187d2fc26e696d13"}, - {file = "frozenlist-1.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0af2e7c87d35b38732e810befb9d797a99279cbb85374d42ea61c1e9d23094b3"}, - {file = "frozenlist-1.3.3-cp38-cp38-win32.whl", hash = "sha256:899c5e1928eec13fd6f6d8dc51be23f0d09c5281e40d9cf4273d188d9feeaf9b"}, - {file = "frozenlist-1.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:7f44e24fa70f6fbc74aeec3e971f60a14dde85da364aa87f15d1be94ae75aeef"}, - {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2b07ae0c1edaa0a36339ec6cce700f51b14a3fc6545fdd32930d2c83917332cf"}, - {file = "frozenlist-1.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ebb86518203e12e96af765ee89034a1dbb0c3c65052d1b0c19bbbd6af8a145e1"}, - {file = "frozenlist-1.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5cf820485f1b4c91e0417ea0afd41ce5cf5965011b3c22c400f6d144296ccbc0"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c11e43016b9024240212d2a65043b70ed8dfd3b52678a1271972702d990ac6d"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8fa3c6e3305aa1146b59a09b32b2e04074945ffcfb2f0931836d103a2c38f936"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:352bd4c8c72d508778cf05ab491f6ef36149f4d0cb3c56b1b4302852255d05d5"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65a5e4d3aa679610ac6e3569e865425b23b372277f89b5ef06cf2cdaf1ebf22b"}, - {file = "frozenlist-1.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e2c1185858d7e10ff045c496bbf90ae752c28b365fef2c09cf0fa309291669"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f163d2fd041c630fed01bc48d28c3ed4a3b003c00acd396900e11ee5316b56bb"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:05cdb16d09a0832eedf770cb7bd1fe57d8cf4eaf5aced29c4e41e3f20b30a784"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:8bae29d60768bfa8fb92244b74502b18fae55a80eac13c88eb0b496d4268fd2d"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:eedab4c310c0299961ac285591acd53dc6723a1ebd90a57207c71f6e0c2153ab"}, - {file = "frozenlist-1.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3bbdf44855ed8f0fbcd102ef05ec3012d6a4fd7c7562403f76ce6a52aeffb2b1"}, - {file = "frozenlist-1.3.3-cp39-cp39-win32.whl", hash = "sha256:efa568b885bca461f7c7b9e032655c0c143d305bf01c30caf6db2854a4532b38"}, - {file = "frozenlist-1.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfe33efc9cb900a4c46f91a5ceba26d6df370ffddd9ca386eb1d4f0ad97b9ea9"}, - {file = "frozenlist-1.3.3.tar.gz", hash = "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a"}, +python-versions = ">=3.8" +files = [ + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"}, + {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"}, + {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"}, + {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"}, + {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"}, + {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"}, + {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7"}, + {file = "frozenlist-1.4.1-cp38-cp38-win32.whl", hash = "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497"}, + {file = "frozenlist-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6"}, + {file = "frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932"}, + {file = "frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0"}, + {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"}, + {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, ] [[package]] name = "hexbytes" -version = "0.3.0" +version = "0.3.1" description = "hexbytes: Python `bytes` subclass that decodes hex, with a readable console output" -category = "main" optional = false python-versions = ">=3.7, <4" files = [ - {file = "hexbytes-0.3.0-py3-none-any.whl", hash = "sha256:21c3a5bd00a383097f0369c387174e79839d75c4ccc3a7edda315c9644f4458a"}, - {file = "hexbytes-0.3.0.tar.gz", hash = "sha256:afeebfb800f5f15a3ca5bab52e49eabcb4b6dac06ec8ff01a94fdb890c6c0712"}, + {file = "hexbytes-0.3.1-py3-none-any.whl", hash = "sha256:383595ad75026cf00abd570f44b368c6cdac0c6becfae5c39ff88829877f8a59"}, + {file = "hexbytes-0.3.1.tar.gz", hash = "sha256:a3fe35c6831ee8fafd048c4c086b986075fc14fd46258fa24ecb8d65745f9a9d"}, ] [package.extras] -dev = ["Sphinx (>=4.0.0,<5)", "black (>=22,<23)", "bumpversion (>=0.5.3,<1)", "eth-utils (>=1.0.1,<3)", "flake8 (==3.7.9)", "hypothesis (>=3.44.24,<=6.31.6)", "ipython", "isort (>=4.2.15,<5)", "mypy (==0.971)", "pydocstyle (>=5.0.0,<6)", "pytest (>=7,<8)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=21,<22)", "tox (>=3.25.1,<4)", "twine", "wheel"] -doc = ["Sphinx (>=4.0.0,<5)", "sphinx-rtd-theme (>=0.1.9,<1)", "towncrier (>=21,<22)"] -lint = ["black (>=22,<23)", "flake8 (==3.7.9)", "isort (>=4.2.15,<5)", "mypy (==0.971)", "pydocstyle (>=5.0.0,<6)"] -test = ["eth-utils (>=1.0.1,<3)", "hypothesis (>=3.44.24,<=6.31.6)", "pytest (>=7,<8)", "pytest-xdist", "tox (>=3.25.1,<4)"] - -[[package]] -name = "html5lib" -version = "1.1" -description = "HTML parser based on the WHATWG HTML specification" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"}, - {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"}, -] - -[package.dependencies] -six = ">=1.9" -webencodings = "*" - -[package.extras] -all = ["chardet (>=2.2)", "genshi", "lxml"] -chardet = ["chardet (>=2.2)"] -genshi = ["genshi"] -lxml = ["lxml"] +dev = ["black (>=22)", "bumpversion (>=0.5.3)", "eth-utils (>=1.0.1,<3)", "flake8 (==6.0.0)", "flake8-bugbear (==23.3.23)", "hypothesis (>=3.44.24,<=6.31.6)", "ipython", "isort (>=5.10.1)", "mypy (==0.971)", "pydocstyle (>=5.0.0)", "pytest (>=7.0.0)", "pytest-watch (>=4.1.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=5.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +doc = ["sphinx (>=5.0.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +lint = ["black (>=22)", "flake8 (==6.0.0)", "flake8-bugbear (==23.3.23)", "isort (>=5.10.1)", "mypy (==0.971)", "pydocstyle (>=5.0.0)"] +test = ["eth-utils (>=1.0.1,<3)", "hypothesis (>=3.44.24,<=6.31.6)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] [[package]] name = "hypothesis" -version = "6.68.2" +version = "6.103.1" description = "A library for property-based testing" -category = "dev" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "hypothesis-6.68.2-py3-none-any.whl", hash = "sha256:2a41cc766cde52705895e54547374af89c617e8ec7bc4186cb7f03884a667d4e"}, - {file = "hypothesis-6.68.2.tar.gz", hash = "sha256:a7eb2b0c9a18560d8197fe35047ceb58e7e8ab7623a3e5a82613f6a2cd71cffa"}, + {file = "hypothesis-6.103.1-py3-none-any.whl", hash = "sha256:d3c959fab6233e78867499e2117ae9db8dc40eeed936d71a2cfc7b6094972e74"}, + {file = "hypothesis-6.103.1.tar.gz", hash = "sha256:d299d5c21d6408eab3be670c94c974f3acf0b511c61fe81804b09091e393ee1f"}, ] [package.dependencies] -attrs = ">=19.2.0" +attrs = ">=22.2.0" sortedcontainers = ">=2.1.0,<3.0.0" [package.extras] -all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "django (>=3.2)", "dpcontracts (>=0.4)", "importlib-metadata (>=3.6)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.9.0)", "pandas (>=1.0)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2022.7)"] +all = ["backports.zoneinfo (>=0.2.1)", "black (>=19.10b0)", "click (>=7.0)", "crosshair-tool (>=0.0.54)", "django (>=3.2)", "dpcontracts (>=0.4)", "hypothesis-crosshair (>=0.0.4)", "lark (>=0.10.1)", "libcst (>=0.3.16)", "numpy (>=1.17.3)", "pandas (>=1.1)", "pytest (>=4.6)", "python-dateutil (>=1.4)", "pytz (>=2014.1)", "redis (>=3.0.0)", "rich (>=9.0.0)", "tzdata (>=2024.1)"] cli = ["black (>=19.10b0)", "click (>=7.0)", "rich (>=9.0.0)"] codemods = ["libcst (>=0.3.16)"] +crosshair = ["crosshair-tool (>=0.0.54)", "hypothesis-crosshair (>=0.0.4)"] dateutil = ["python-dateutil (>=1.4)"] django = ["django (>=3.2)"] dpcontracts = ["dpcontracts (>=0.4)"] ghostwriter = ["black (>=19.10b0)"] lark = ["lark (>=0.10.1)"] -numpy = ["numpy (>=1.9.0)"] -pandas = ["pandas (>=1.0)"] +numpy = ["numpy (>=1.17.3)"] +pandas = ["pandas (>=1.1)"] pytest = ["pytest (>=4.6)"] pytz = ["pytz (>=2014.1)"] redis = ["redis (>=3.0.0)"] -zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2022.7)"] +zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2024.1)"] [[package]] name = "idna" -version = "3.4" +version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] -[[package]] -name = "importlib-metadata" -version = "6.0.0" -description = "Read metadata from Python packages" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "importlib_metadata-6.0.0-py3-none-any.whl", hash = "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad"}, - {file = "importlib_metadata-6.0.0.tar.gz", hash = "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d"}, -] - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] - [[package]] name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1363,7 +1118,6 @@ files = [ name = "ipfshttpclient" version = "0.7.0" description = "Python IPFS HTTP CLIENT library" -category = "dev" optional = false python-versions = ">=3.5.4,!=3.6.0,!=3.6.1,!=3.7.0,!=3.7.1" files = [ @@ -1377,215 +1131,287 @@ requests = ">=2.11" [[package]] name = "isort" -version = "5.12.0" +version = "5.13.2" description = "A Python utility / library to sort Python imports." -category = "dev" optional = false python-versions = ">=3.8.0" files = [ - {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, - {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, ] [package.extras] -colors = ["colorama (>=0.4.3)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] +colors = ["colorama (>=0.4.6)"] [[package]] -name = "jaraco-classes" -version = "3.2.3" -description = "Utility functions for Python class constructs" -category = "main" +name = "json-stream" +version = "2.3.2" +description = "Streaming JSON encoder and decoder" optional = false -python-versions = ">=3.7" +python-versions = "<4,>=3.5" files = [ - {file = "jaraco.classes-3.2.3-py3-none-any.whl", hash = "sha256:2353de3288bc6b82120752201c6b1c1a14b058267fa424ed5ce5984e3b922158"}, - {file = "jaraco.classes-3.2.3.tar.gz", hash = "sha256:89559fa5c1d3c34eff6f631ad80bb21f378dbcbb35dd161fd2c6b93f5be2f98a"}, + {file = "json-stream-2.3.2.tar.gz", hash = "sha256:b8b450ea8e8e3c239e9e7e38d12fed934e77a353c14b297f8ee345a5ceb25b91"}, + {file = "json_stream-2.3.2-py3-none-any.whl", hash = "sha256:236b8e08e2761b209816452a3527355e757913d833e6802b68a034a13b8bd3ac"}, ] [package.dependencies] -more-itertools = "*" +json-stream-rs-tokenizer = ">=0.4.17" [package.extras] -docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +httpx = ["httpx"] +requests = ["requests"] [[package]] -name = "jeepney" -version = "0.8.0" -description = "Low-level, pure Python DBus protocol wrapper." -category = "main" +name = "json-stream-rs-tokenizer" +version = "0.4.26" +description = "A faster tokenizer for the json-stream Python library" optional = false -python-versions = ">=3.7" +python-versions = ">=3.7,<4" files = [ - {file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"}, - {file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"}, + {file = "json-stream-rs-tokenizer-0.4.26.tar.gz", hash = "sha256:19333ccda9121b1224598d67178665f77e142862800cb1edd7797a62936f7a1c"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:386089a087b7ed950546557676f72f7f698bc3d10f31f50ad9cffbd7fab506bc"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d81cd53d2367d03417b6a1e83f248f7a6ff8aed62d5b4ca095f1a71cbd41fa19"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b9e12f234993b2759dd20fb1f1792c7276cb599c0f43f65616b2d51c3d13206"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b33140892507ee6bbba33b67db27a2f4f587c4a0d0aefc94e32c8e87ae640303"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9799cc5d955791d999e660929d01f9a22d174025a2be2df50ddfe453a685ad5"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:525e2ea12fc1a8522a5dd4c98d6784e758cba46861de689acf160f650248624e"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp310-cp310-win32.whl", hash = "sha256:b7857ca3d7efba0a43be1164b8fc330db8727683d64010700686f985b63f5d33"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp310-cp310-win_amd64.whl", hash = "sha256:48824ee03c7fd569c076154a70c910aa986bb583870ef01b6defa82a60493bab"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:42e3a6fa214ea21e30b7eabe78ab694ac1452f1ed8ee806d7ede56bb8eb4e364"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:49cbdbe008aa79da7a3bcb0d5d2a7c85dc76842c7d2988dcdb68c760416a6fa2"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4436e1d6a90906afb510358b60eb15391897edf24afe2dab3934deb701aadaf0"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05992fa1d5d9bcf247f42112c52f399a507a03d307fa73b2146ba6b0532bffab"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c38dfea5e5d495f8cf70d7dedd1c354ca53d400f3792ebe040d9fdd2d492d38"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:468eec40d407c031b6468d8602c4a467bd302b61cd3603fd94bf20445ed822de"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp311-cp311-win32.whl", hash = "sha256:3ad1c8f4fa4856a921d12ee3c3d338b8ad8409dbca8f47fb5a9f95515bfd8b71"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp311-cp311-win_amd64.whl", hash = "sha256:52ae28491500b730664caff2c0ef8acd6c902913019109e528a88661b22fd3f7"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5b9f1f61ad4cc1f8a7c0715d5ab095555699734082231d907f3acb7d1bb6bfaf"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:79d20bf715ce506b174596a5d9a50682f2c0cc93ec9acec06872860820de6918"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de36a262305dcf1dca0786047369720b3b628b3484d98428a89cbcc8fe6a88f6"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bf3fd93d9e26906436ad5df4197d5a6ea3bdf36b3917c8507a80e4430e4c768"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9af9f62d2f765be4cd02973390e604cf8ef64527b6123f0dde22f2b760f35b4b"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9c3e35c1ab59461d338b18dbc24ecec477a3b2b16380d738ad8b6566da57fa91"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp312-cp312-win32.whl", hash = "sha256:0413f8cdffdb00f58dede2488daf9b7b6e388aff9204c16aaacdf45cf857d839"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp312-cp312-win_amd64.whl", hash = "sha256:9d946e880ef7d8963ecf54077fb1606fda51a631b69b6613cfb01487930781d2"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a2277c85bb06775aa53fb3918282551c286e5ee76280bdec007eeae62d347ff6"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fb08227eee13e876029a65ba37e9d69e466cd99617de0884ced581674aebdb"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e7f0dae17f133385f34ded101c228e46cecdbf5edad3227cfcf686a8f2cecbe"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e18fad1ae8a7849e2e8425d4a8ebacb59ea3dbe557da4b2e4e508b33cf4bfb32"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0978c6d165e5b4e26d6246abf1e5d0047dceb764e5d06087649ae4d68508dc5e"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp37-cp37m-win32.whl", hash = "sha256:7bd2e5bd6ed803a93f2e29bb11a65f79ccf050254763991748d39f0268e73d59"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp37-cp37m-win_amd64.whl", hash = "sha256:1cacf8782de679528ee6e070fcb72e51cbe037ecdad59dc98481d0bf8cb5af67"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a148c60ccd384c4eae404068ab3ba77a13d06270a973b69d6e78da32a4990096"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9e683513caf2a2862f0b064accff11d91a18849f9fc8c18c11baf8b1b63c2ab9"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03a48f0eea1b84e23924da7d3d19e83d5b84ba02ba7c9e5246a05ba97051d48"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c79ffffaa6101ebaa1586812746b5f4bbf64799ecf218ec23140d97cf6507392"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca475303513e4b3650ce0471a964ac5bd9010ea0aae681bb9be23927ce76344b"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:594c8b727fc399214adce14a77242f481790a2fcc1c001b7cf34aea7a6fa8ad3"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp38-cp38-win32.whl", hash = "sha256:24c004415764d58b121fcd8249fed55fe189415f0e3e917b235a729c0e226989"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp38-cp38-win_amd64.whl", hash = "sha256:56f1816a51a4f645d9f58632cde99a0c7b601867de5c34f2a63a9bea6b9656b1"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e1a4bfa55013e60c7164ec0f005af28e109581a2549ea266aea6d0c7c066a13"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:14b1d2eed8f5127f26f7247865414dea0e35536fdfb61203aefe48a1a7930b99"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2bc6fd4f978407bff1ad85a66b51eb107940232b5cfa3376bfe1568ce575bb5"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:393d6fca34a0df7318c845f90dbd4e23dd3b869dd3d5017ad49f0c313819708a"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:31aaebd4348191cc41d14e8d446f93fd3cf74da7d97458b8a5e00b1109e5f385"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6721c5011d362e9460f8b4cd319d1ac9a1c41d96ffd6891a6a21fa56649c263f"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp39-cp39-win32.whl", hash = "sha256:f048722719bcb28d9cefabb9c612abdc18c619bc833a793335dcec69e9bab17e"}, + {file = "json_stream_rs_tokenizer-0.4.26-cp39-cp39-win_amd64.whl", hash = "sha256:573fc21370b3fa36ea65b3e0df5a0509d2cf797f402a3d3a643fd9f734c31f24"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:eab3f142d6483d822a732ad7905931d33225b5027c7cde15e66e95ff261b1c9a"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4aa60ff6a73121769370ed27b9b06a2f8995864b4ca7e809fd9b3231e383b"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b6f296f6cf8c0f2968633d626cf0caa7c0e09321dada8b830b4b3e08e938445"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70eae6687530e26fa88a733fd154cff364d1073b9d4643dad89232f0bf2f5e67"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:751fbcc0b9037144a552ca3d3943d7ede4447d85a8cf9e57479f6c55aefd010f"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:236f0354787a89c64e64d54166287fb602d2ad09e66e6c216a3fa931fee57491"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:374b96309943543f277f1cd57c93d9ce8eb641a3aa0c40cf422f911561080eec"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7e1409578e9c0a08528b3ab3988ce73be13aa5acea09553699471218ae43446"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d698c8cd29e99a41866710f738fe29d3a1d0700596939917365566352ecf590"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:45cddce2b803289a21bb52e877b31ef98d8b9d7e0845d1c8ca61b4b5ed57616d"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c87343153e7c588f66a4de5f890bcfb846738832c6b0702e30295080b0afb976"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a82439118ed6fedd8f10f7f0a68c926e729d7166ceb3678267ea9170f7353b2d"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:878d9e646ea690344cdf69a3bea19b75b9db3c6218614abb99994580dec85053"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:77b37b1d4084b14e04f186d5b0197677848846b3bba7c61e8615fbcb4ba99e4b"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:37c002dd7a1ec620ff0ae25b551dea1dead991c0c7d9c8355ad689612b1bf5a7"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9db149d818f958317a118e8c20e1d98d551801c6cfe332183fa8dcd06935c4cd"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd1378815e45613e3a815a3d57a055588ff9b96f464d418f5f32c867c2cddf3a"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f760a45099d6674e8c2c773f67c6c0364795a082f418046ef257c47d68c5c663"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:709974e142f97df5a725616b844d1c7611fcb1b64f70d5076662caf1e7f99f7a"}, + {file = "json_stream_rs_tokenizer-0.4.26-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d130d7d5a343719e5eb236d7037b93083c083a99a154657c567bca4e41bfef86"}, ] [package.extras] -test = ["async-timeout", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] -trio = ["async_generator", "trio"] +benchmark = ["contexttimer (>=0.3,<0.4)", "json-stream-to-standard-types (>=0.1,<0.2)", "si-prefix (>=1.2,<2)", "tqdm (>=4.64,<5)", "typer (>=0.6,<0.7)"] +test = ["json-stream (==2.3.2)", "json-stream-rs-tokenizer[benchmark]", "pytest (>7.1,<8)"] [[package]] name = "jsonschema" -version = "4.17.3" +version = "4.22.0" description = "An implementation of JSON Schema validation for Python" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, - {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, + {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"}, + {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"}, ] [package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] [[package]] -name = "keyring" -version = "23.13.1" -description = "Store and access your passwords safely." -category = "main" +name = "jsonschema-specifications" +version = "2023.12.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "keyring-23.13.1-py3-none-any.whl", hash = "sha256:771ed2a91909389ed6148631de678f82ddc73737d85a927f382a8a1b157898cd"}, - {file = "keyring-23.13.1.tar.gz", hash = "sha256:ba2e15a9b35e21908d0aaf4e0a47acc52d6ae33444df0da2b49d41a46ef6d678"}, + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, ] [package.dependencies] -importlib-metadata = {version = ">=4.11.4", markers = "python_version < \"3.12\""} -"jaraco.classes" = "*" -jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} -pywin32-ctypes = {version = ">=0.2.0", markers = "sys_platform == \"win32\""} -SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} - -[package.extras] -completion = ["shtab"] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +referencing = ">=0.31.0" [[package]] name = "lazy-object-proxy" -version = "1.9.0" +version = "1.10.0" description = "A fast and thorough lazy object proxy." -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, - {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, - {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, - {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, - {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, - {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, -] - -[[package]] -name = "lockfile" -version = "0.12.2" -description = "Platform-independent file locking module" -category = "main" optional = false -python-versions = "*" -files = [ - {file = "lockfile-0.12.2-py2.py3-none-any.whl", hash = "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa"}, - {file = "lockfile-0.12.2.tar.gz", hash = "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799"}, +python-versions = ">=3.8" +files = [ + {file = "lazy-object-proxy-1.10.0.tar.gz", hash = "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win32.whl", hash = "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9"}, + {file = "lazy_object_proxy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win32.whl", hash = "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03"}, + {file = "lazy_object_proxy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win32.whl", hash = "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074"}, + {file = "lazy_object_proxy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win32.whl", hash = "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4"}, + {file = "lazy_object_proxy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win32.whl", hash = "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70"}, + {file = "lazy_object_proxy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd"}, + {file = "lazy_object_proxy-1.10.0-pp310.pp311.pp312.pp38.pp39-none-any.whl", hash = "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d"}, ] [[package]] name = "lru-dict" -version = "1.1.8" +version = "1.2.0" description = "An Dict like LRU container." -category = "main" optional = false python-versions = "*" files = [ - {file = "lru-dict-1.1.8.tar.gz", hash = "sha256:878bc8ef4073e5cfb953dfc1cf4585db41e8b814c0106abde34d00ee0d0b3115"}, - {file = "lru_dict-1.1.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f9d5815c0e85922cd0fb8344ca8b1c7cf020bf9fc45e670d34d51932c91fd7ec"}, - {file = "lru_dict-1.1.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f877f53249c3e49bbd7612f9083127290bede6c7d6501513567ab1bf9c581381"}, - {file = "lru_dict-1.1.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fef595c4f573141d54a38bda9221b9ee3cbe0acc73d67304a1a6d5972eb2a02"}, - {file = "lru_dict-1.1.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:db20597c4e67b4095b376ce2e83930c560f4ce481e8d05737885307ed02ba7c1"}, - {file = "lru_dict-1.1.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5b09dbe47bc4b4d45ffe56067aff190bc3c0049575da6e52127e114236e0a6a7"}, - {file = "lru_dict-1.1.8-cp310-cp310-win32.whl", hash = "sha256:3b1692755fef288b67af5cd8a973eb331d1f44cb02cbdc13660040809c2bfec6"}, - {file = "lru_dict-1.1.8-cp310-cp310-win_amd64.whl", hash = "sha256:8f6561f9cd5a452cb84905c6a87aa944fdfdc0f41cc057d03b71f9b29b2cc4bd"}, - {file = "lru_dict-1.1.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ca8f89361e0e7aad0bf93ae03a31502e96280faeb7fb92267f4998fb230d36b2"}, - {file = "lru_dict-1.1.8-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c50ab9edaa5da5838426816a2b7bcde9d576b4fc50e6a8c062073dbc4969d78"}, - {file = "lru_dict-1.1.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fe16ade5fd0a57e9a335f69b8055aaa6fb278fbfa250458e4f6b8255115578f"}, - {file = "lru_dict-1.1.8-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:de972c7f4bc7b6002acff2a8de984c55fbd7f2289dba659cfd90f7a0f5d8f5d1"}, - {file = "lru_dict-1.1.8-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:3d003a864899c29b0379e412709a6e516cbd6a72ee10b09d0b33226343617412"}, - {file = "lru_dict-1.1.8-cp36-cp36m-win32.whl", hash = "sha256:6e2a7aa9e36626fb48fdc341c7e3685a31a7b50ea4918677ea436271ad0d904d"}, - {file = "lru_dict-1.1.8-cp36-cp36m-win_amd64.whl", hash = "sha256:d2ed4151445c3f30423c2698f72197d64b27b1cd61d8d56702ffe235584e47c2"}, - {file = "lru_dict-1.1.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:075b9dd46d7022b675419bc6e3631748ae184bc8af195d20365a98b4f3bb2914"}, - {file = "lru_dict-1.1.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70364e3cbef536adab8762b4835e18f5ca8e3fddd8bd0ec9258c42bbebd0ee77"}, - {file = "lru_dict-1.1.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:720f5728e537f11a311e8b720793a224e985d20e6b7c3d34a891a391865af1a2"}, - {file = "lru_dict-1.1.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c2fe692332c2f1d81fd27457db4b35143801475bfc2e57173a2403588dd82a42"}, - {file = "lru_dict-1.1.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:86d32a4498b74a75340497890a260d37bf1560ad2683969393032977dd36b088"}, - {file = "lru_dict-1.1.8-cp37-cp37m-win32.whl", hash = "sha256:348167f110494cfafae70c066470a6f4e4d43523933edf16ccdb8947f3b5fae0"}, - {file = "lru_dict-1.1.8-cp37-cp37m-win_amd64.whl", hash = "sha256:9be6c4039ef328676b868acea619cd100e3de1a35b3be211cf0eaf9775563b65"}, - {file = "lru_dict-1.1.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a777d48319d293b1b6a933d606c0e4899690a139b4c81173451913bbcab6f44f"}, - {file = "lru_dict-1.1.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99f6cfb3e28490357a0805b409caf693e46c61f8dbb789c51355adb693c568d3"}, - {file = "lru_dict-1.1.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:163079dbda54c3e6422b23da39fb3ecc561035d65e8496ff1950cbdb376018e1"}, - {file = "lru_dict-1.1.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0972d669e9e207617e06416166718b073a49bf449abbd23940d9545c0847a4d9"}, - {file = "lru_dict-1.1.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:97c24ffc55de6013075979f440acd174e88819f30387074639fb7d7178ca253e"}, - {file = "lru_dict-1.1.8-cp38-cp38-win32.whl", hash = "sha256:0f83cd70a6d32f9018d471be609f3af73058f700691657db4a3d3dd78d3f96dd"}, - {file = "lru_dict-1.1.8-cp38-cp38-win_amd64.whl", hash = "sha256:add762163f4af7f4173fafa4092eb7c7f023cf139ef6d2015cfea867e1440d82"}, - {file = "lru_dict-1.1.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484ac524e4615f06dc72ffbfd83f26e073c9ec256de5413634fbd024c010a8bc"}, - {file = "lru_dict-1.1.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7284bdbc5579bbdc3fc8f869ed4c169f403835566ab0f84567cdbfdd05241847"}, - {file = "lru_dict-1.1.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ca497cb25f19f24171f9172805f3ff135b911aeb91960bd4af8e230421ccb51"}, - {file = "lru_dict-1.1.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1df1da204a9f0b5eb8393a46070f1d984fa8559435ee790d7f8f5602038fc00"}, - {file = "lru_dict-1.1.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f4d0a6d733a23865019b1c97ed6fb1fdb739be923192abf4dbb644f697a26a69"}, - {file = "lru_dict-1.1.8-cp39-cp39-win32.whl", hash = "sha256:7be1b66926277993cecdc174c15a20c8ce785c1f8b39aa560714a513eef06473"}, - {file = "lru_dict-1.1.8-cp39-cp39-win_amd64.whl", hash = "sha256:881104711900af45967c2e5ce3e62291dd57d5b2a224d58b7c9f60bf4ad41b8c"}, - {file = "lru_dict-1.1.8-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:beb089c46bd95243d1ac5b2bd13627317b08bf40dd8dc16d4b7ee7ecb3cf65ca"}, - {file = "lru_dict-1.1.8-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10fe823ff90b655f0b6ba124e2b576ecda8c61b8ead76b456db67831942d22f2"}, - {file = "lru_dict-1.1.8-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c07163c9dcbb2eca377f366b1331f46302fd8b6b72ab4d603087feca00044bb0"}, - {file = "lru_dict-1.1.8-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:93336911544ebc0e466272043adab9fb9f6e9dcba6024b639c32553a3790e089"}, - {file = "lru_dict-1.1.8-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:55aeda6b6789b2d030066b4f5f6fc3596560ba2a69028f35f3682a795701b5b1"}, - {file = "lru_dict-1.1.8-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:262a4e622010ceb960a6a5222ed011090e50954d45070fd369c0fa4d2ed7d9a9"}, - {file = "lru_dict-1.1.8-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6f64005ede008b7a866be8f3f6274dbf74e656e15e4004e9d99ad65efb01809"}, - {file = "lru_dict-1.1.8-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:9d70257246b8207e8ef3d8b18457089f5ff0dfb087bd36eb33bce6584f2e0b3a"}, - {file = "lru_dict-1.1.8-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f874e9c2209dada1a080545331aa1277ec060a13f61684a8642788bf44b2325f"}, - {file = "lru_dict-1.1.8-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a592363c93d6fc6472d5affe2819e1c7590746aecb464774a4f67e09fbefdfc"}, - {file = "lru_dict-1.1.8-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f340b61f3cdfee71f66da7dbfd9a5ea2db6974502ccff2065cdb76619840dca"}, - {file = "lru_dict-1.1.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:9447214e4857e16d14158794ef01e4501d8fad07d298d03308d9f90512df02fa"}, + {file = "lru-dict-1.2.0.tar.gz", hash = "sha256:13c56782f19d68ddf4d8db0170041192859616514c706b126d0df2ec72a11bd7"}, + {file = "lru_dict-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:de906e5486b5c053d15b7731583c25e3c9147c288ac8152a6d1f9bccdec72641"}, + {file = "lru_dict-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604d07c7604b20b3130405d137cae61579578b0e8377daae4125098feebcb970"}, + {file = "lru_dict-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:203b3e78d03d88f491fa134f85a42919020686b6e6f2d09759b2f5517260c651"}, + {file = "lru_dict-1.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:020b93870f8c7195774cbd94f033b96c14f51c57537969965c3af300331724fe"}, + {file = "lru_dict-1.2.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1184d91cfebd5d1e659d47f17a60185bbf621635ca56dcdc46c6a1745d25df5c"}, + {file = "lru_dict-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fc42882b554a86e564e0b662da47b8a4b32fa966920bd165e27bb8079a323bc1"}, + {file = "lru_dict-1.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:18ee88ada65bd2ffd483023be0fa1c0a6a051ef666d1cd89e921dcce134149f2"}, + {file = "lru_dict-1.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:756230c22257597b7557eaef7f90484c489e9ba78e5bb6ab5a5bcfb6b03cb075"}, + {file = "lru_dict-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c4da599af36618881748b5db457d937955bb2b4800db891647d46767d636c408"}, + {file = "lru_dict-1.2.0-cp310-cp310-win32.whl", hash = "sha256:35a142a7d1a4fd5d5799cc4f8ab2fff50a598d8cee1d1c611f50722b3e27874f"}, + {file = "lru_dict-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:6da5b8099766c4da3bf1ed6e7d7f5eff1681aff6b5987d1258a13bd2ed54f0c9"}, + {file = "lru_dict-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b20b7c9beb481e92e07368ebfaa363ed7ef61e65ffe6e0edbdbaceb33e134124"}, + {file = "lru_dict-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22147367b296be31cc858bf167c448af02435cac44806b228c9be8117f1bfce4"}, + {file = "lru_dict-1.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34a3091abeb95e707f381a8b5b7dc8e4ee016316c659c49b726857b0d6d1bd7a"}, + {file = "lru_dict-1.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:877801a20f05c467126b55338a4e9fa30e2a141eb7b0b740794571b7d619ee11"}, + {file = "lru_dict-1.2.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d3336e901acec897bcd318c42c2b93d5f1d038e67688f497045fc6bad2c0be7"}, + {file = "lru_dict-1.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8dafc481d2defb381f19b22cc51837e8a42631e98e34b9e0892245cc96593deb"}, + {file = "lru_dict-1.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:87bbad3f5c3de8897b8c1263a9af73bbb6469fb90e7b57225dad89b8ef62cd8d"}, + {file = "lru_dict-1.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:25f9e0bc2fe8f41c2711ccefd2871f8a5f50a39e6293b68c3dec576112937aad"}, + {file = "lru_dict-1.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ae301c282a499dc1968dd633cfef8771dd84228ae9d40002a3ea990e4ff0c469"}, + {file = "lru_dict-1.2.0-cp311-cp311-win32.whl", hash = "sha256:c9617583173a29048e11397f165501edc5ae223504a404b2532a212a71ecc9ed"}, + {file = "lru_dict-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6b7a031e47421d4b7aa626b8c91c180a9f037f89e5d0a71c4bb7afcf4036c774"}, + {file = "lru_dict-1.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ea2ac3f7a7a2f32f194c84d82a034e66780057fd908b421becd2f173504d040e"}, + {file = "lru_dict-1.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd46c94966f631a81ffe33eee928db58e9fbee15baba5923d284aeadc0e0fa76"}, + {file = "lru_dict-1.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:086ce993414f0b28530ded7e004c77dc57c5748fa6da488602aa6e7f79e6210e"}, + {file = "lru_dict-1.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df25a426446197488a6702954dcc1de511deee20c9db730499a2aa83fddf0df1"}, + {file = "lru_dict-1.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c53b12b89bd7a6c79f0536ff0d0a84fdf4ab5f6252d94b24b9b753bd9ada2ddf"}, + {file = "lru_dict-1.2.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:f9484016e6765bd295708cccc9def49f708ce07ac003808f69efa386633affb9"}, + {file = "lru_dict-1.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d0f7ec902a0097ac39f1922c89be9eaccf00eb87751e28915320b4f72912d057"}, + {file = "lru_dict-1.2.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:981ef3edc82da38d39eb60eae225b88a538d47b90cce2e5808846fd2cf64384b"}, + {file = "lru_dict-1.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e25b2e90a032dc248213af7f3f3e975e1934b204f3b16aeeaeaff27a3b65e128"}, + {file = "lru_dict-1.2.0-cp36-cp36m-win32.whl", hash = "sha256:59f3df78e94e07959f17764e7fa7ca6b54e9296953d2626a112eab08e1beb2db"}, + {file = "lru_dict-1.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:de24b47159e07833aeab517d9cb1c3c5c2d6445cc378b1c2f1d8d15fb4841d63"}, + {file = "lru_dict-1.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d0dd4cd58220351233002f910e35cc01d30337696b55c6578f71318b137770f9"}, + {file = "lru_dict-1.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a87bdc291718bbdf9ea4be12ae7af26cbf0706fa62c2ac332748e3116c5510a7"}, + {file = "lru_dict-1.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05fb8744f91f58479cbe07ed80ada6696ec7df21ea1740891d4107a8dd99a970"}, + {file = "lru_dict-1.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00f6e8a3fc91481b40395316a14c94daa0f0a5de62e7e01a7d589f8d29224052"}, + {file = "lru_dict-1.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b172fce0a0ffc0fa6d282c14256d5a68b5db1e64719c2915e69084c4b6bf555"}, + {file = "lru_dict-1.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:e707d93bae8f0a14e6df1ae8b0f076532b35f00e691995f33132d806a88e5c18"}, + {file = "lru_dict-1.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b9ec7a4a0d6b8297102aa56758434fb1fca276a82ed7362e37817407185c3abb"}, + {file = "lru_dict-1.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:f404dcc8172da1f28da9b1f0087009578e608a4899b96d244925c4f463201f2a"}, + {file = "lru_dict-1.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1171ad3bff32aa8086778be4a3bdff595cc2692e78685bcce9cb06b96b22dcc2"}, + {file = "lru_dict-1.2.0-cp37-cp37m-win32.whl", hash = "sha256:0c316dfa3897fabaa1fe08aae89352a3b109e5f88b25529bc01e98ac029bf878"}, + {file = "lru_dict-1.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:5919dd04446bc1ee8d6ecda2187deeebfff5903538ae71083e069bc678599446"}, + {file = "lru_dict-1.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fbf36c5a220a85187cacc1fcb7dd87070e04b5fc28df7a43f6842f7c8224a388"}, + {file = "lru_dict-1.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:712e71b64da181e1c0a2eaa76cd860265980cd15cb0e0498602b8aa35d5db9f8"}, + {file = "lru_dict-1.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f54908bf91280a9b8fa6a8c8f3c2f65850ce6acae2852bbe292391628ebca42f"}, + {file = "lru_dict-1.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3838e33710935da2ade1dd404a8b936d571e29268a70ff4ca5ba758abb3850df"}, + {file = "lru_dict-1.2.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5d5a5f976b39af73324f2b793862859902ccb9542621856d51a5993064f25e4"}, + {file = "lru_dict-1.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8bda3a9afd241ee0181661decaae25e5336ce513ac268ab57da737eacaa7871f"}, + {file = "lru_dict-1.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:bd2cd1b998ea4c8c1dad829fc4fa88aeed4dee555b5e03c132fc618e6123f168"}, + {file = "lru_dict-1.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:b55753ee23028ba8644fd22e50de7b8f85fa60b562a0fafaad788701d6131ff8"}, + {file = "lru_dict-1.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7e51fa6a203fa91d415f3b2900e5748ec8e06ad75777c98cc3aeb3983ca416d7"}, + {file = "lru_dict-1.2.0-cp38-cp38-win32.whl", hash = "sha256:cd6806313606559e6c7adfa0dbeb30fc5ab625f00958c3d93f84831e7a32b71e"}, + {file = "lru_dict-1.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:5d90a70c53b0566084447c3ef9374cc5a9be886e867b36f89495f211baabd322"}, + {file = "lru_dict-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a3ea7571b6bf2090a85ff037e6593bbafe1a8598d5c3b4560eb56187bcccb4dc"}, + {file = "lru_dict-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:287c2115a59c1c9ed0d5d8ae7671e594b1206c36ea9df2fca6b17b86c468ff99"}, + {file = "lru_dict-1.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b5ccfd2291c93746a286c87c3f895165b697399969d24c54804ec3ec559d4e43"}, + {file = "lru_dict-1.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b710f0f4d7ec4f9fa89dfde7002f80bcd77de8024017e70706b0911ea086e2ef"}, + {file = "lru_dict-1.2.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5345bf50e127bd2767e9fd42393635bbc0146eac01f6baf6ef12c332d1a6a329"}, + {file = "lru_dict-1.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:291d13f85224551913a78fe695cde04cbca9dcb1d84c540167c443eb913603c9"}, + {file = "lru_dict-1.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d5bb41bc74b321789803d45b124fc2145c1b3353b4ad43296d9d1d242574969b"}, + {file = "lru_dict-1.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0facf49b053bf4926d92d8d5a46fe07eecd2af0441add0182c7432d53d6da667"}, + {file = "lru_dict-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:987b73a06bcf5a95d7dc296241c6b1f9bc6cda42586948c9dabf386dc2bef1cd"}, + {file = "lru_dict-1.2.0-cp39-cp39-win32.whl", hash = "sha256:231d7608f029dda42f9610e5723614a35b1fff035a8060cf7d2be19f1711ace8"}, + {file = "lru_dict-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:71da89e134747e20ed5b8ad5b4ee93fc5b31022c2b71e8176e73c5a44699061b"}, + {file = "lru_dict-1.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:21b3090928c7b6cec509e755cc3ab742154b33660a9b433923bd12c37c448e3e"}, + {file = "lru_dict-1.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaecd7085212d0aa4cd855f38b9d61803d6509731138bf798a9594745953245b"}, + {file = "lru_dict-1.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ead83ac59a29d6439ddff46e205ce32f8b7f71a6bd8062347f77e232825e3d0a"}, + {file = "lru_dict-1.2.0-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:312b6b2a30188586fe71358f0f33e4bac882d33f5e5019b26f084363f42f986f"}, + {file = "lru_dict-1.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:b30122e098c80e36d0117810d46459a46313421ce3298709170b687dc1240b02"}, + {file = "lru_dict-1.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f010cfad3ab10676e44dc72a813c968cd586f37b466d27cde73d1f7f1ba158c2"}, + {file = "lru_dict-1.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20f5f411f7751ad9a2c02e80287cedf69ae032edd321fe696e310d32dd30a1f8"}, + {file = "lru_dict-1.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:afdadd73304c9befaed02eb42f5f09fdc16288de0a08b32b8080f0f0f6350aa6"}, + {file = "lru_dict-1.2.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7ab0c10c4fa99dc9e26b04e6b62ac32d2bcaea3aad9b81ec8ce9a7aa32b7b1b"}, + {file = "lru_dict-1.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:edad398d5d402c43d2adada390dd83c74e46e020945ff4df801166047013617e"}, + {file = "lru_dict-1.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:91d577a11b84387013815b1ad0bb6e604558d646003b44c92b3ddf886ad0f879"}, + {file = "lru_dict-1.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb12f19cdf9c4f2d9aa259562e19b188ff34afab28dd9509ff32a3f1c2c29326"}, + {file = "lru_dict-1.2.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e4c85aa8844bdca3c8abac3b7f78da1531c74e9f8b3e4890c6e6d86a5a3f6c0"}, + {file = "lru_dict-1.2.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c6acbd097b15bead4de8e83e8a1030bb4d8257723669097eac643a301a952f0"}, + {file = "lru_dict-1.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b6613daa851745dd22b860651de930275be9d3e9373283a2164992abacb75b62"}, ] [package.extras] @@ -1595,7 +1421,6 @@ test = ["pytest"] name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1605,83 +1430,19 @@ files = [ [[package]] name = "more-itertools" -version = "9.0.0" +version = "10.3.0" description = "More routines for operating on iterables, beyond itertools" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "more-itertools-9.0.0.tar.gz", hash = "sha256:5a6257e40878ef0520b1803990e3e22303a41b5714006c32a3fd8304b26ea1ab"}, - {file = "more_itertools-9.0.0-py3-none-any.whl", hash = "sha256:250e83d7e81d0c87ca6bd942e6aeab8cc9daa6096d12c5308f3f92fa5e5c1f41"}, -] - -[[package]] -name = "msgpack" -version = "1.0.4" -description = "MessagePack serializer" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "msgpack-1.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4ab251d229d10498e9a2f3b1e68ef64cb393394ec477e3370c457f9430ce9250"}, - {file = "msgpack-1.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:112b0f93202d7c0fef0b7810d465fde23c746a2d482e1e2de2aafd2ce1492c88"}, - {file = "msgpack-1.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:002b5c72b6cd9b4bafd790f364b8480e859b4712e91f43014fe01e4f957b8467"}, - {file = "msgpack-1.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35bc0faa494b0f1d851fd29129b2575b2e26d41d177caacd4206d81502d4c6a6"}, - {file = "msgpack-1.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4733359808c56d5d7756628736061c432ded018e7a1dff2d35a02439043321aa"}, - {file = "msgpack-1.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb514ad14edf07a1dbe63761fd30f89ae79b42625731e1ccf5e1f1092950eaa6"}, - {file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c23080fdeec4716aede32b4e0ef7e213c7b1093eede9ee010949f2a418ced6ba"}, - {file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:49565b0e3d7896d9ea71d9095df15b7f75a035c49be733051c34762ca95bbf7e"}, - {file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:aca0f1644d6b5a73eb3e74d4d64d5d8c6c3d577e753a04c9e9c87d07692c58db"}, - {file = "msgpack-1.0.4-cp310-cp310-win32.whl", hash = "sha256:0dfe3947db5fb9ce52aaea6ca28112a170db9eae75adf9339a1aec434dc954ef"}, - {file = "msgpack-1.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dea20515f660aa6b7e964433b1808d098dcfcabbebeaaad240d11f909298075"}, - {file = "msgpack-1.0.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e83f80a7fec1a62cf4e6c9a660e39c7f878f603737a0cdac8c13131d11d97f52"}, - {file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c11a48cf5e59026ad7cb0dc29e29a01b5a66a3e333dc11c04f7e991fc5510a9"}, - {file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1276e8f34e139aeff1c77a3cefb295598b504ac5314d32c8c3d54d24fadb94c9"}, - {file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c9566f2c39ccced0a38d37c26cc3570983b97833c365a6044edef3574a00c08"}, - {file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:fcb8a47f43acc113e24e910399376f7277cf8508b27e5b88499f053de6b115a8"}, - {file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:76ee788122de3a68a02ed6f3a16bbcd97bc7c2e39bd4d94be2f1821e7c4a64e6"}, - {file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0a68d3ac0104e2d3510de90a1091720157c319ceeb90d74f7b5295a6bee51bae"}, - {file = "msgpack-1.0.4-cp36-cp36m-win32.whl", hash = "sha256:85f279d88d8e833ec015650fd15ae5eddce0791e1e8a59165318f371158efec6"}, - {file = "msgpack-1.0.4-cp36-cp36m-win_amd64.whl", hash = "sha256:c1683841cd4fa45ac427c18854c3ec3cd9b681694caf5bff04edb9387602d661"}, - {file = "msgpack-1.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a75dfb03f8b06f4ab093dafe3ddcc2d633259e6c3f74bb1b01996f5d8aa5868c"}, - {file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9667bdfdf523c40d2511f0e98a6c9d3603be6b371ae9a238b7ef2dc4e7a427b0"}, - {file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11184bc7e56fd74c00ead4f9cc9a3091d62ecb96e97653add7a879a14b003227"}, - {file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac5bd7901487c4a1dd51a8c58f2632b15d838d07ceedaa5e4c080f7190925bff"}, - {file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1e91d641d2bfe91ba4c52039adc5bccf27c335356055825c7f88742c8bb900dd"}, - {file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2a2df1b55a78eb5f5b7d2a4bb221cd8363913830145fad05374a80bf0877cb1e"}, - {file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:545e3cf0cf74f3e48b470f68ed19551ae6f9722814ea969305794645da091236"}, - {file = "msgpack-1.0.4-cp37-cp37m-win32.whl", hash = "sha256:2cc5ca2712ac0003bcb625c96368fd08a0f86bbc1a5578802512d87bc592fe44"}, - {file = "msgpack-1.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:eba96145051ccec0ec86611fe9cf693ce55f2a3ce89c06ed307de0e085730ec1"}, - {file = "msgpack-1.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7760f85956c415578c17edb39eed99f9181a48375b0d4a94076d84148cf67b2d"}, - {file = "msgpack-1.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:449e57cc1ff18d3b444eb554e44613cffcccb32805d16726a5494038c3b93dab"}, - {file = "msgpack-1.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d603de2b8d2ea3f3bcb2efe286849aa7a81531abc52d8454da12f46235092bcb"}, - {file = "msgpack-1.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f5d88c99f64c456413d74a975bd605a9b0526293218a3b77220a2c15458ba9"}, - {file = "msgpack-1.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6916c78f33602ecf0509cc40379271ba0f9ab572b066bd4bdafd7434dee4bc6e"}, - {file = "msgpack-1.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81fc7ba725464651190b196f3cd848e8553d4d510114a954681fd0b9c479d7e1"}, - {file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d5b5b962221fa2c5d3a7f8133f9abffc114fe218eb4365e40f17732ade576c8e"}, - {file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:77ccd2af37f3db0ea59fb280fa2165bf1b096510ba9fe0cc2bf8fa92a22fdb43"}, - {file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b17be2478b622939e39b816e0aa8242611cc8d3583d1cd8ec31b249f04623243"}, - {file = "msgpack-1.0.4-cp38-cp38-win32.whl", hash = "sha256:2bb8cdf50dd623392fa75525cce44a65a12a00c98e1e37bf0fb08ddce2ff60d2"}, - {file = "msgpack-1.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:26b8feaca40a90cbe031b03d82b2898bf560027160d3eae1423f4a67654ec5d6"}, - {file = "msgpack-1.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:462497af5fd4e0edbb1559c352ad84f6c577ffbbb708566a0abaaa84acd9f3ae"}, - {file = "msgpack-1.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2999623886c5c02deefe156e8f869c3b0aaeba14bfc50aa2486a0415178fce55"}, - {file = "msgpack-1.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f0029245c51fd9473dc1aede1160b0a29f4a912e6b1dd353fa6d317085b219da"}, - {file = "msgpack-1.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed6f7b854a823ea44cf94919ba3f727e230da29feb4a99711433f25800cf747f"}, - {file = "msgpack-1.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0df96d6eaf45ceca04b3f3b4b111b86b33785683d682c655063ef8057d61fd92"}, - {file = "msgpack-1.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a4192b1ab40f8dca3f2877b70e63799d95c62c068c84dc028b40a6cb03ccd0f"}, - {file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e3590f9fb9f7fbc36df366267870e77269c03172d086fa76bb4eba8b2b46624"}, - {file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1576bd97527a93c44fa856770197dec00d223b0b9f36ef03f65bac60197cedf8"}, - {file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:63e29d6e8c9ca22b21846234913c3466b7e4ee6e422f205a2988083de3b08cae"}, - {file = "msgpack-1.0.4-cp39-cp39-win32.whl", hash = "sha256:fb62ea4b62bfcb0b380d5680f9a4b3f9a2d166d9394e9bbd9666c0ee09a3645c"}, - {file = "msgpack-1.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:4d5834a2a48965a349da1c5a79760d94a1a0172fbb5ab6b5b33cbf8447e109ce"}, - {file = "msgpack-1.0.4.tar.gz", hash = "sha256:f5d869c18f030202eb412f08b28d2afeea553d6613aee89e200d7aca7ef01f5f"}, + {file = "more-itertools-10.3.0.tar.gz", hash = "sha256:e5d93ef411224fbcef366a6e8ddc4c5781bc6359d43412a65dd5964e46111463"}, + {file = "more_itertools-10.3.0-py3-none-any.whl", hash = "sha256:ea6a02e24a9161e51faad17a8782b92a0df82c12c1c8886fec7f0c3fa1a1b320"}, ] [[package]] name = "multiaddr" version = "0.0.9" description = "Python implementation of jbenet's multiaddr" -category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" files = [ @@ -1697,139 +1458,153 @@ varint = "*" [[package]] name = "multidict" -version = "6.0.4" +version = "6.0.5" description = "multidict implementation" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"}, - {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"}, - {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"}, - {file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"}, - {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"}, - {file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"}, - {file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"}, - {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"}, - {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"}, - {file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"}, - {file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"}, - {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"}, - {file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"}, - {file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"}, - {file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"}, - {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"}, - {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"}, - {file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"}, - {file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"}, - {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"}, - {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"}, - {file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"}, - {file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"}, - {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"}, - {file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"}, - {file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"}, - {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"}, - {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"}, - {file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"}, - {file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"}, - {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"}, - {file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"}, - {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"}, - {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc"}, + {file = "multidict-6.0.5-cp310-cp310-win32.whl", hash = "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319"}, + {file = "multidict-6.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e"}, + {file = "multidict-6.0.5-cp311-cp311-win32.whl", hash = "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c"}, + {file = "multidict-6.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda"}, + {file = "multidict-6.0.5-cp312-cp312-win32.whl", hash = "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5"}, + {file = "multidict-6.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556"}, + {file = "multidict-6.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc"}, + {file = "multidict-6.0.5-cp37-cp37m-win32.whl", hash = "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee"}, + {file = "multidict-6.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44"}, + {file = "multidict-6.0.5-cp38-cp38-win32.whl", hash = "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241"}, + {file = "multidict-6.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c"}, + {file = "multidict-6.0.5-cp39-cp39-win32.whl", hash = "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b"}, + {file = "multidict-6.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755"}, + {file = "multidict-6.0.5-py3-none-any.whl", hash = "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7"}, + {file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"}, ] [[package]] name = "mypy" -version = "1.0.1" +version = "1.10.0" description = "Optional static typing for Python" -category = "dev" optional = false -python-versions = ">=3.7" -files = [ - {file = "mypy-1.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:71a808334d3f41ef011faa5a5cd8153606df5fc0b56de5b2e89566c8093a0c9a"}, - {file = "mypy-1.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:920169f0184215eef19294fa86ea49ffd4635dedfdea2b57e45cb4ee85d5ccaf"}, - {file = "mypy-1.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27a0f74a298769d9fdc8498fcb4f2beb86f0564bcdb1a37b58cbbe78e55cf8c0"}, - {file = "mypy-1.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:65b122a993d9c81ea0bfde7689b3365318a88bde952e4dfa1b3a8b4ac05d168b"}, - {file = "mypy-1.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:5deb252fd42a77add936b463033a59b8e48eb2eaec2976d76b6878d031933fe4"}, - {file = "mypy-1.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2013226d17f20468f34feddd6aae4635a55f79626549099354ce641bc7d40262"}, - {file = "mypy-1.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:48525aec92b47baed9b3380371ab8ab6e63a5aab317347dfe9e55e02aaad22e8"}, - {file = "mypy-1.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c96b8a0c019fe29040d520d9257d8c8f122a7343a8307bf8d6d4a43f5c5bfcc8"}, - {file = "mypy-1.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:448de661536d270ce04f2d7dddaa49b2fdba6e3bd8a83212164d4174ff43aa65"}, - {file = "mypy-1.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:d42a98e76070a365a1d1c220fcac8aa4ada12ae0db679cb4d910fabefc88b994"}, - {file = "mypy-1.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e64f48c6176e243ad015e995de05af7f22bbe370dbb5b32bd6988438ec873919"}, - {file = "mypy-1.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fdd63e4f50e3538617887e9aee91855368d9fc1dea30da743837b0df7373bc4"}, - {file = "mypy-1.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dbeb24514c4acbc78d205f85dd0e800f34062efcc1f4a4857c57e4b4b8712bff"}, - {file = "mypy-1.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a2948c40a7dd46c1c33765718936669dc1f628f134013b02ff5ac6c7ef6942bf"}, - {file = "mypy-1.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5bc8d6bd3b274dd3846597855d96d38d947aedba18776aa998a8d46fabdaed76"}, - {file = "mypy-1.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:17455cda53eeee0a4adb6371a21dd3dbf465897de82843751cf822605d152c8c"}, - {file = "mypy-1.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e831662208055b006eef68392a768ff83596035ffd6d846786578ba1714ba8f6"}, - {file = "mypy-1.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e60d0b09f62ae97a94605c3f73fd952395286cf3e3b9e7b97f60b01ddfbbda88"}, - {file = "mypy-1.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:0af4f0e20706aadf4e6f8f8dc5ab739089146b83fd53cb4a7e0e850ef3de0bb6"}, - {file = "mypy-1.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:24189f23dc66f83b839bd1cce2dfc356020dfc9a8bae03978477b15be61b062e"}, - {file = "mypy-1.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93a85495fb13dc484251b4c1fd7a5ac370cd0d812bbfc3b39c1bafefe95275d5"}, - {file = "mypy-1.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f546ac34093c6ce33f6278f7c88f0f147a4849386d3bf3ae193702f4fe31407"}, - {file = "mypy-1.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c6c2ccb7af7154673c591189c3687b013122c5a891bb5651eca3db8e6c6c55bd"}, - {file = "mypy-1.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:15b5a824b58c7c822c51bc66308e759243c32631896743f030daf449fe3677f3"}, - {file = "mypy-1.0.1-py3-none-any.whl", hash = "sha256:eda5c8b9949ed411ff752b9a01adda31afe7eae1e53e946dbdf9db23865e66c4"}, - {file = "mypy-1.0.1.tar.gz", hash = "sha256:28cea5a6392bb43d266782983b5a4216c25544cd7d80be681a155ddcdafd152d"}, +python-versions = ">=3.8" +files = [ + {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, + {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, + {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, + {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, + {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, + {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, + {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, + {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, + {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, + {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, + {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, + {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, + {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, + {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, + {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, + {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, + {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, + {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, + {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, ] [package.dependencies] -mypy-extensions = ">=0.4.3" -typing-extensions = ">=3.10" +mypy-extensions = ">=1.0.0" +typing-extensions = ">=4.1.0" [package.extras] dmypy = ["psutil (>=4.0)"] install-types = ["pip"] -python2 = ["typed-ast (>=1.4.0,<2)"] +mypyc = ["setuptools (>=50)"] reports = ["lxml"] [[package]] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -1839,37 +1614,57 @@ files = [ [[package]] name = "netaddr" -version = "0.8.0" +version = "1.3.0" description = "A network address manipulation library for Python" -category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "netaddr-0.8.0-py2.py3-none-any.whl", hash = "sha256:9666d0232c32d2656e5e5f8d735f58fd6c7457ce52fc21c98d45f2af78f990ac"}, - {file = "netaddr-0.8.0.tar.gz", hash = "sha256:d6cc57c7a07b1d9d2e917aa8b36ae8ce61c35ba3fcd1b83ca31c5a0ee2b5a243"}, + {file = "netaddr-1.3.0-py3-none-any.whl", hash = "sha256:c2c6a8ebe5554ce33b7d5b3a306b71bbb373e000bbbf2350dd5213cc56e3dbbe"}, + {file = "netaddr-1.3.0.tar.gz", hash = "sha256:5c3c3d9895b551b763779ba7db7a03487dc1f8e3b385af819af341ae9ef6e48a"}, ] +[package.extras] +nicer-shell = ["ipython"] + +[[package]] +name = "oz-merkle-tree" +version = "0.1.0" +description = "A Python library to generate merkle trees and merkle proofs." +optional = false +python-versions = "^3.11" +files = [] +develop = false + +[package.dependencies] +eth-abi = "^5.1.0" +eth-hash = {version = "^0.7.0", extras = ["pycryptodome"]} + +[package.source] +type = "git" +url = "https://github.com/lidofinance/oz-merkle-tree" +reference = "HEAD" +resolved_reference = "f4ad6e006b8daf05ce2ce255e123eb9f923d8ef8" + [[package]] name = "packaging" -version = "23.0" +version = "24.1" description = "Core utilities for Python packages" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, - {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] name = "parsimonious" -version = "0.9.0" +version = "0.10.0" description = "(Soon to be) the fastest pure-Python PEG parser I could muster" -category = "main" optional = false python-versions = "*" files = [ - {file = "parsimonious-0.9.0.tar.gz", hash = "sha256:b2ad1ae63a2f65bd78f5e0a8ac510a98f3607a43f1db2a8d46636a5d9e4a30c1"}, + {file = "parsimonious-0.10.0-py3-none-any.whl", hash = "sha256:982ab435fabe86519b57f6b35610aa4e4e977e9f02a14353edf4bbc75369fc0f"}, + {file = "parsimonious-0.10.0.tar.gz", hash = "sha256:8281600da180ec8ae35427a4ab4f7b82bfec1e3d1e52f80cb60ea82b9512501c"}, ] [package.dependencies] @@ -1877,148 +1672,50 @@ regex = ">=2022.3.15" [[package]] name = "pathspec" -version = "0.11.1" +version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false -python-versions = ">=3.7" -files = [ - {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, - {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, -] - -[[package]] -name = "pexpect" -version = "4.8.0" -description = "Pexpect allows easy control of interactive console applications." -category = "main" -optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, - {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] -[package.dependencies] -ptyprocess = ">=0.5" - -[[package]] -name = "pkginfo" -version = "1.9.6" -description = "Query metadata from sdists / bdists / installed packages." -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pkginfo-1.9.6-py3-none-any.whl", hash = "sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546"}, - {file = "pkginfo-1.9.6.tar.gz", hash = "sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046"}, -] - -[package.extras] -testing = ["pytest", "pytest-cov"] - [[package]] name = "platformdirs" -version = "2.6.2" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"}, - {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"}, + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, ] [package.extras] -docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] [[package]] name = "pluggy" -version = "1.0.0" +version = "1.5.0" description = "plugin and hook calling mechanisms for python" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] -[[package]] -name = "poetry" -version = "1.3.2" -description = "Python dependency management and packaging made easy." -category = "main" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "poetry-1.3.2-py3-none-any.whl", hash = "sha256:41980d557954b1418fa503de7a8fb25f19c03c0223a171666b305f05a45fc206"}, - {file = "poetry-1.3.2.tar.gz", hash = "sha256:26ded25f0cf67943243ca4f0aafd47ec4668bdb62845dbb8c2b0e3d9cd280bf4"}, -] - -[package.dependencies] -cachecontrol = {version = ">=0.12.9,<0.13.0", extras = ["filecache"]} -cleo = ">=2.0.0,<3.0.0" -crashtest = ">=0.4.1,<0.5.0" -dulwich = ">=0.20.46,<0.21.0" -filelock = ">=3.8.0,<4.0.0" -html5lib = ">=1.0,<2.0" -jsonschema = ">=4.10.0,<5.0.0" -keyring = ">=23.9.0,<24.0.0" -lockfile = ">=0.12.2,<0.13.0" -packaging = ">=20.4" -pexpect = ">=4.7.0,<5.0.0" -pkginfo = ">=1.5,<2.0" -platformdirs = ">=2.5.2,<3.0.0" -poetry-core = "1.4.0" -poetry-plugin-export = ">=1.2.0,<2.0.0" -requests = ">=2.18,<3.0" -requests-toolbelt = ">=0.9.1,<0.11.0" -shellingham = ">=1.5,<2.0" -tomlkit = ">=0.11.1,<0.11.2 || >0.11.2,<0.11.3 || >0.11.3,<1.0.0" -trove-classifiers = ">=2022.5.19" -urllib3 = ">=1.26.0,<2.0.0" -virtualenv = {version = ">=20.4.3,<20.4.5 || >20.4.5,<20.4.6 || >20.4.6,<21.0.0", markers = "sys_platform != \"win32\" or python_version != \"3.9\""} -xattr = {version = ">=0.10.0,<0.11.0", markers = "sys_platform == \"darwin\""} - -[[package]] -name = "poetry-core" -version = "1.4.0" -description = "Poetry PEP 517 Build Backend" -category = "main" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "poetry_core-1.4.0-py3-none-any.whl", hash = "sha256:5559ab80384ac021db329ef317086417e140ee1176bcfcb3a3838b544e213c8e"}, - {file = "poetry_core-1.4.0.tar.gz", hash = "sha256:514bd33c30e0bf56b0ed44ee15e120d7e47b61ad908b2b1011da68c48a84ada9"}, -] - -[[package]] -name = "poetry-plugin-export" -version = "1.3.0" -description = "Poetry plugin to export the dependencies to various formats" -category = "main" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "poetry_plugin_export-1.3.0-py3-none-any.whl", hash = "sha256:6e5919bf84afcb08cdd419a03f909f490d8671f00633a3c6df8ba09b0820dc2f"}, - {file = "poetry_plugin_export-1.3.0.tar.gz", hash = "sha256:61ae5ec1db233aba947a48e1ce54c6ff66afd0e1c87195d6bce64c73a5ae658c"}, -] - -[package.dependencies] -poetry = ">=1.3.0,<2.0.0" -poetry-core = ">=1.3.0,<2.0.0" - [[package]] name = "prometheus-client" version = "0.16.0" description = "Python client for the Prometheus monitoring system." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2031,99 +1728,69 @@ twisted = ["twisted"] [[package]] name = "protobuf" -version = "4.22.0" +version = "5.27.1" description = "" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "protobuf-4.22.0-cp310-abi3-win32.whl", hash = "sha256:b2fea9dc8e3c0f32c38124790ef16cba2ee0628fe2022a52e435e1117bfef9b1"}, - {file = "protobuf-4.22.0-cp310-abi3-win_amd64.whl", hash = "sha256:a33a273d21852f911b8bda47f39f4383fe7c061eb1814db2c76c9875c89c2491"}, - {file = "protobuf-4.22.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:e894e9ae603e963f0842498c4cd5d39c6a60f0d7e4c103df50ee939564298658"}, - {file = "protobuf-4.22.0-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:7c535d126e7dcc714105ab20b418c4fedbd28f8b8afc42b7350b1e317bbbcc71"}, - {file = "protobuf-4.22.0-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:86c3d20428b007537ba6792b475c0853bba7f66b1f60e610d913b77d94b486e4"}, - {file = "protobuf-4.22.0-cp37-cp37m-win32.whl", hash = "sha256:1669cb7524221a8e2d9008d0842453dbefdd0fcdd64d67672f657244867635fb"}, - {file = "protobuf-4.22.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ab4d043865dd04e6b09386981fe8f80b39a1e46139fb4a3c206229d6b9f36ff6"}, - {file = "protobuf-4.22.0-cp38-cp38-win32.whl", hash = "sha256:29288813aacaa302afa2381db1d6e0482165737b0afdf2811df5fa99185c457b"}, - {file = "protobuf-4.22.0-cp38-cp38-win_amd64.whl", hash = "sha256:e474b63bab0a2ea32a7b26a4d8eec59e33e709321e5e16fb66e766b61b82a95e"}, - {file = "protobuf-4.22.0-cp39-cp39-win32.whl", hash = "sha256:47d31bdf58222dd296976aa1646c68c6ee80b96d22e0a3c336c9174e253fd35e"}, - {file = "protobuf-4.22.0-cp39-cp39-win_amd64.whl", hash = "sha256:c27f371f0159feb70e6ea52ed7e768b3f3a4c5676c1900a7e51a24740381650e"}, - {file = "protobuf-4.22.0-py3-none-any.whl", hash = "sha256:c3325803095fb4c2a48649c321d2fbde59f8fbfcb9bfc7a86df27d112831c571"}, - {file = "protobuf-4.22.0.tar.gz", hash = "sha256:652d8dfece122a24d98eebfef30e31e455d300efa41999d1182e015984ac5930"}, -] - -[[package]] -name = "ptyprocess" -version = "0.7.0" -description = "Run a subprocess in a pseudo terminal" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, - {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, -] - -[[package]] -name = "pycparser" -version = "2.21" -description = "C parser in Python" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, - {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, + {file = "protobuf-5.27.1-cp310-abi3-win32.whl", hash = "sha256:3adc15ec0ff35c5b2d0992f9345b04a540c1e73bfee3ff1643db43cc1d734333"}, + {file = "protobuf-5.27.1-cp310-abi3-win_amd64.whl", hash = "sha256:25236b69ab4ce1bec413fd4b68a15ef8141794427e0b4dc173e9d5d9dffc3bcd"}, + {file = "protobuf-5.27.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:4e38fc29d7df32e01a41cf118b5a968b1efd46b9c41ff515234e794011c78b17"}, + {file = "protobuf-5.27.1-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:917ed03c3eb8a2d51c3496359f5b53b4e4b7e40edfbdd3d3f34336e0eef6825a"}, + {file = "protobuf-5.27.1-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:ee52874a9e69a30271649be88ecbe69d374232e8fd0b4e4b0aaaa87f429f1631"}, + {file = "protobuf-5.27.1-cp38-cp38-win32.whl", hash = "sha256:7a97b9c5aed86b9ca289eb5148df6c208ab5bb6906930590961e08f097258107"}, + {file = "protobuf-5.27.1-cp38-cp38-win_amd64.whl", hash = "sha256:f6abd0f69968792da7460d3c2cfa7d94fd74e1c21df321eb6345b963f9ec3d8d"}, + {file = "protobuf-5.27.1-cp39-cp39-win32.whl", hash = "sha256:dfddb7537f789002cc4eb00752c92e67885badcc7005566f2c5de9d969d3282d"}, + {file = "protobuf-5.27.1-cp39-cp39-win_amd64.whl", hash = "sha256:39309898b912ca6febb0084ea912e976482834f401be35840a008da12d189340"}, + {file = "protobuf-5.27.1-py3-none-any.whl", hash = "sha256:4ac7249a1530a2ed50e24201d6630125ced04b30619262f06224616e0030b6cf"}, + {file = "protobuf-5.27.1.tar.gz", hash = "sha256:df5e5b8e39b7d1c25b186ffdf9f44f40f810bbcc9d2b71d9d3156fee5a9adf15"}, ] [[package]] name = "pycryptodome" -version = "3.17" +version = "3.20.0" description = "Cryptographic library for Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ - {file = "pycryptodome-3.17-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:2c5631204ebcc7ae33d11c43037b2dafe25e2ab9c1de6448eb6502ac69c19a56"}, - {file = "pycryptodome-3.17-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:04779cc588ad8f13c80a060b0b1c9d1c203d051d8a43879117fe6b8aaf1cd3fa"}, - {file = "pycryptodome-3.17-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:f812d58c5af06d939b2baccdda614a3ffd80531a26e5faca2c9f8b1770b2b7af"}, - {file = "pycryptodome-3.17-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:9453b4e21e752df8737fdffac619e93c9f0ec55ead9a45df782055eb95ef37d9"}, - {file = "pycryptodome-3.17-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:121d61663267f73692e8bde5ec0d23c9146465a0d75cad75c34f75c752527b01"}, - {file = "pycryptodome-3.17-cp27-cp27m-win32.whl", hash = "sha256:ba2d4fcb844c6ba5df4bbfee9352ad5352c5ae939ac450e06cdceff653280450"}, - {file = "pycryptodome-3.17-cp27-cp27m-win_amd64.whl", hash = "sha256:87e2ca3aa557781447428c4b6c8c937f10ff215202ab40ece5c13a82555c10d6"}, - {file = "pycryptodome-3.17-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f44c0d28716d950135ff21505f2c764498eda9d8806b7c78764165848aa419bc"}, - {file = "pycryptodome-3.17-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:5a790bc045003d89d42e3b9cb3cc938c8561a57a88aaa5691512e8540d1ae79c"}, - {file = "pycryptodome-3.17-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:d086d46774e27b280e4cece8ab3d87299cf0d39063f00f1e9290d096adc5662a"}, - {file = "pycryptodome-3.17-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:5587803d5b66dfd99e7caa31ed91fba0fdee3661c5d93684028ad6653fce725f"}, - {file = "pycryptodome-3.17-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:e7debd9c439e7b84f53be3cf4ba8b75b3d0b6e6015212355d6daf44ac672e210"}, - {file = "pycryptodome-3.17-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ca1ceb6303be1282148f04ac21cebeebdb4152590842159877778f9cf1634f09"}, - {file = "pycryptodome-3.17-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:dc22cc00f804485a3c2a7e2010d9f14a705555f67020eb083e833cabd5bd82e4"}, - {file = "pycryptodome-3.17-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80ea8333b6a5f2d9e856ff2293dba2e3e661197f90bf0f4d5a82a0a6bc83a626"}, - {file = "pycryptodome-3.17-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c133f6721fba313722a018392a91e3c69d3706ae723484841752559e71d69dc6"}, - {file = "pycryptodome-3.17-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:333306eaea01fde50a73c4619e25631e56c4c61bd0fb0a2346479e67e3d3a820"}, - {file = "pycryptodome-3.17-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:1a30f51b990994491cec2d7d237924e5b6bd0d445da9337d77de384ad7f254f9"}, - {file = "pycryptodome-3.17-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:909e36a43fe4a8a3163e9c7fc103867825d14a2ecb852a63d3905250b308a4e5"}, - {file = "pycryptodome-3.17-cp35-abi3-win32.whl", hash = "sha256:a3228728a3808bc9f18c1797ec1179a0efb5068c817b2ffcf6bcd012494dffb2"}, - {file = "pycryptodome-3.17-cp35-abi3-win_amd64.whl", hash = "sha256:9ec565e89a6b400eca814f28d78a9ef3f15aea1df74d95b28b7720739b28f37f"}, - {file = "pycryptodome-3.17-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:e1819b67bcf6ca48341e9b03c2e45b1c891fa8eb1a8458482d14c2805c9616f2"}, - {file = "pycryptodome-3.17-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:f8e550caf52472ae9126953415e4fc554ab53049a5691c45b8816895c632e4d7"}, - {file = "pycryptodome-3.17-pp27-pypy_73-win32.whl", hash = "sha256:afbcdb0eda20a0e1d44e3a1ad6d4ec3c959210f4b48cabc0e387a282f4c7deb8"}, - {file = "pycryptodome-3.17-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a74f45aee8c5cc4d533e585e0e596e9f78521e1543a302870a27b0ae2106381e"}, - {file = "pycryptodome-3.17-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38bbd6717eac084408b4094174c0805bdbaba1f57fc250fd0309ae5ec9ed7e09"}, - {file = "pycryptodome-3.17-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f68d6c8ea2974a571cacb7014dbaada21063a0375318d88ac1f9300bc81e93c3"}, - {file = "pycryptodome-3.17-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8198f2b04c39d817b206ebe0db25a6653bb5f463c2319d6f6d9a80d012ac1e37"}, - {file = "pycryptodome-3.17-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3a232474cd89d3f51e4295abe248a8b95d0332d153bf46444e415409070aae1e"}, - {file = "pycryptodome-3.17-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4992ec965606054e8326e83db1c8654f0549cdb26fce1898dc1a20bc7684ec1c"}, - {file = "pycryptodome-3.17-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53068e33c74f3b93a8158dacaa5d0f82d254a81b1002e0cd342be89fcb3433eb"}, - {file = "pycryptodome-3.17-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:74794a2e2896cd0cf56fdc9db61ef755fa812b4a4900fa46c49045663a92b8d0"}, - {file = "pycryptodome-3.17.tar.gz", hash = "sha256:bce2e2d8e82fcf972005652371a3e8731956a0c1fbb719cc897943b3695ad91b"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:f0e6d631bae3f231d3634f91ae4da7a960f7ff87f2865b2d2b831af1dfb04e9a"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:baee115a9ba6c5d2709a1e88ffe62b73ecc044852a925dcb67713a288c4ec70f"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:417a276aaa9cb3be91f9014e9d18d10e840a7a9b9a9be64a42f553c5b50b4d1d"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a1250b7ea809f752b68e3e6f3fd946b5939a52eaeea18c73bdab53e9ba3c2dd"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:d5954acfe9e00bc83ed9f5cb082ed22c592fbbef86dc48b907238be64ead5c33"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-win32.whl", hash = "sha256:06d6de87c19f967f03b4cf9b34e538ef46e99a337e9a61a77dbe44b2cbcf0690"}, + {file = "pycryptodome-3.20.0-cp27-cp27m-win_amd64.whl", hash = "sha256:ec0bb1188c1d13426039af8ffcb4dbe3aad1d7680c35a62d8eaf2a529b5d3d4f"}, + {file = "pycryptodome-3.20.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5601c934c498cd267640b57569e73793cb9a83506f7c73a8ec57a516f5b0b091"}, + {file = "pycryptodome-3.20.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d29daa681517f4bc318cd8a23af87e1f2a7bad2fe361e8aa29c77d652a065de4"}, + {file = "pycryptodome-3.20.0-cp27-cp27mu-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3427d9e5310af6680678f4cce149f54e0bb4af60101c7f2c16fdf878b39ccccc"}, + {file = "pycryptodome-3.20.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:3cd3ef3aee1079ae44afaeee13393cf68b1058f70576b11439483e34f93cf818"}, + {file = "pycryptodome-3.20.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac1c7c0624a862f2e53438a15c9259d1655325fc2ec4392e66dc46cdae24d044"}, + {file = "pycryptodome-3.20.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:76658f0d942051d12a9bd08ca1b6b34fd762a8ee4240984f7c06ddfb55eaf15a"}, + {file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f35d6cee81fa145333137009d9c8ba90951d7d77b67c79cbe5f03c7eb74d8fe2"}, + {file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76cb39afede7055127e35a444c1c041d2e8d2f1f9c121ecef573757ba4cd2c3c"}, + {file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a4c4dc60b78ec41d2afa392491d788c2e06edf48580fbfb0dd0f828af49d25"}, + {file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fb3b87461fa35afa19c971b0a2b7456a7b1db7b4eba9a8424666104925b78128"}, + {file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:acc2614e2e5346a4a4eab6e199203034924313626f9620b7b4b38e9ad74b7e0c"}, + {file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:210ba1b647837bfc42dd5a813cdecb5b86193ae11a3f5d972b9a0ae2c7e9e4b4"}, + {file = "pycryptodome-3.20.0-cp35-abi3-win32.whl", hash = "sha256:8d6b98d0d83d21fb757a182d52940d028564efe8147baa9ce0f38d057104ae72"}, + {file = "pycryptodome-3.20.0-cp35-abi3-win_amd64.whl", hash = "sha256:9b3ae153c89a480a0ec402e23db8d8d84a3833b65fa4b15b81b83be9d637aab9"}, + {file = "pycryptodome-3.20.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:4401564ebf37dfde45d096974c7a159b52eeabd9969135f0426907db367a652a"}, + {file = "pycryptodome-3.20.0-pp27-pypy_73-win32.whl", hash = "sha256:ec1f93feb3bb93380ab0ebf8b859e8e5678c0f010d2d78367cf6bc30bfeb148e"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:acae12b9ede49f38eb0ef76fdec2df2e94aad85ae46ec85be3648a57f0a7db04"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f47888542a0633baff535a04726948e876bf1ed880fddb7c10a736fa99146ab3"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e0e4a987d38cfc2e71b4a1b591bae4891eeabe5fa0f56154f576e26287bfdea"}, + {file = "pycryptodome-3.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c18b381553638414b38705f07d1ef0a7cf301bc78a5f9bc17a957eb19446834b"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a60fedd2b37b4cb11ccb5d0399efe26db9e0dd149016c1cc6c8161974ceac2d6"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:405002eafad114a2f9a930f5db65feef7b53c4784495dd8758069b89baf68eab"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ab6ab0cb755154ad14e507d1df72de9897e99fd2d4922851a276ccc14f4f1a5"}, + {file = "pycryptodome-3.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:acf6e43fa75aca2d33e93409f2dafe386fe051818ee79ee8a3e21de9caa2ac9e"}, + {file = "pycryptodome-3.20.0.tar.gz", hash = "sha256:09609209ed7de61c2b560cc5c8c4fbf892f8b15b1faf7e4cbffac97db1fffda7"}, ] [[package]] name = "pydantic" version = "1.10.6" description = "Data validation and settings management using python type hints" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2174,14 +1841,13 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pydantic-factories" -version = "1.17.2" +version = "1.17.3" description = "Mock data generation for pydantic based models and python dataclasses" -category = "dev" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "pydantic_factories-1.17.2-py3-none-any.whl", hash = "sha256:e1378700a9e963b368b602e46e8ccc3331027f10233e617eb47b3a3dd052ee25"}, - {file = "pydantic_factories-1.17.2.tar.gz", hash = "sha256:a1ea1d3a595235a65f954d6e182ec4bfe94645f2c4d986fd43ae19a62ffb90b0"}, + {file = "pydantic_factories-1.17.3-py3-none-any.whl", hash = "sha256:5a1522a31d27e1af414719c510a4a934365292f3ea6fdc843ed65d0564242636"}, + {file = "pydantic_factories-1.17.3.tar.gz", hash = "sha256:de36e0db7108af5f4328308da9a4049311c4d5e0814553d2f39078b08b05e48d"}, ] [package.dependencies] @@ -2191,21 +1857,20 @@ typing-extensions = "*" [[package]] name = "pylint" -version = "2.16.2" +version = "3.2.3" description = "python code static checker" -category = "dev" optional = false -python-versions = ">=3.7.2" +python-versions = ">=3.8.0" files = [ - {file = "pylint-2.16.2-py3-none-any.whl", hash = "sha256:ff22dde9c2128cd257c145cfd51adeff0be7df4d80d669055f24a962b351bbe4"}, - {file = "pylint-2.16.2.tar.gz", hash = "sha256:13b2c805a404a9bf57d002cd5f054ca4d40b0b87542bdaba5e05321ae8262c84"}, + {file = "pylint-3.2.3-py3-none-any.whl", hash = "sha256:b3d7d2708a3e04b4679e02d99e72329a8b7ee8afb8d04110682278781f889fa8"}, + {file = "pylint-3.2.3.tar.gz", hash = "sha256:02f6c562b215582386068d52a30f520d84fdbcf2a95fc7e855b816060d048b60"}, ] [package.dependencies] -astroid = ">=2.14.2,<=2.16.0-dev0" +astroid = ">=3.2.2,<=3.3.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -dill = {version = ">=0.3.6", markers = "python_version >= \"3.11\""} -isort = ">=4.2.5,<6" +dill = {version = ">=0.3.7", markers = "python_version >= \"3.12\""} +isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" tomlkit = ">=0.10.1" @@ -2214,75 +1879,35 @@ tomlkit = ">=0.10.1" spelling = ["pyenchant (>=3.2,<4.0)"] testutils = ["gitpython (>3)"] -[[package]] -name = "pyrsistent" -version = "0.19.3" -description = "Persistent/Functional/Immutable data structures" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"}, - {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"}, - {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"}, - {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"}, - {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, - {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, -] - [[package]] name = "pytest" -version = "7.2.1" +version = "7.4.4" description = "pytest: simple powerful testing with Python" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.2.1-py3-none-any.whl", hash = "sha256:c7c6ca206e93355074ae32f7403e8ea12163b1163c976fee7d4d84027c162be5"}, - {file = "pytest-7.2.1.tar.gz", hash = "sha256:d45e0952f3727241918b8fd0f376f5ff6b301cc0777c6f9a556935c92d8a7d42"}, + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, ] [package.dependencies] -attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-cov" -version = "4.0.0" +version = "4.1.0" description = "Pytest plugin for measuring coverage." -category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, - {file = "pytest_cov-4.0.0-py3-none-any.whl", hash = "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b"}, + {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, + {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, ] [package.dependencies] @@ -2294,19 +1919,18 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale [[package]] name = "pytest-xdist" -version = "3.2.1" +version = "3.6.1" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-xdist-3.2.1.tar.gz", hash = "sha256:1849bd98d8b242b948e472db7478e090bf3361912a8fed87992ed94085f54727"}, - {file = "pytest_xdist-3.2.1-py3-none-any.whl", hash = "sha256:37290d161638a20b672401deef1cba812d110ac27e35d213f091d15b8beb40c9"}, + {file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"}, + {file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"}, ] [package.dependencies] -execnet = ">=1.1" -pytest = ">=6.2.0" +execnet = ">=2.1" +pytest = ">=7.0.0" [package.extras] psutil = ["psutil (>=3.0)"] @@ -2315,347 +1939,307 @@ testing = ["filelock"] [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] six = ">=1.5" [[package]] -name = "pywin32" -version = "305" -description = "Python for Window Extensions" -category = "main" +name = "pyunormalize" +version = "15.1.0" +description = "Unicode normalization forms (NFC, NFKC, NFD, NFKD). A library independent from the Python core Unicode database." optional = false -python-versions = "*" +python-versions = ">=3.6" files = [ - {file = "pywin32-305-cp310-cp310-win32.whl", hash = "sha256:421f6cd86e84bbb696d54563c48014b12a23ef95a14e0bdba526be756d89f116"}, - {file = "pywin32-305-cp310-cp310-win_amd64.whl", hash = "sha256:73e819c6bed89f44ff1d690498c0a811948f73777e5f97c494c152b850fad478"}, - {file = "pywin32-305-cp310-cp310-win_arm64.whl", hash = "sha256:742eb905ce2187133a29365b428e6c3b9001d79accdc30aa8969afba1d8470f4"}, - {file = "pywin32-305-cp311-cp311-win32.whl", hash = "sha256:19ca459cd2e66c0e2cc9a09d589f71d827f26d47fe4a9d09175f6aa0256b51c2"}, - {file = "pywin32-305-cp311-cp311-win_amd64.whl", hash = "sha256:326f42ab4cfff56e77e3e595aeaf6c216712bbdd91e464d167c6434b28d65990"}, - {file = "pywin32-305-cp311-cp311-win_arm64.whl", hash = "sha256:4ecd404b2c6eceaca52f8b2e3e91b2187850a1ad3f8b746d0796a98b4cea04db"}, - {file = "pywin32-305-cp36-cp36m-win32.whl", hash = "sha256:48d8b1659284f3c17b68587af047d110d8c44837736b8932c034091683e05863"}, - {file = "pywin32-305-cp36-cp36m-win_amd64.whl", hash = "sha256:13362cc5aa93c2beaf489c9c9017c793722aeb56d3e5166dadd5ef82da021fe1"}, - {file = "pywin32-305-cp37-cp37m-win32.whl", hash = "sha256:a55db448124d1c1484df22fa8bbcbc45c64da5e6eae74ab095b9ea62e6d00496"}, - {file = "pywin32-305-cp37-cp37m-win_amd64.whl", hash = "sha256:109f98980bfb27e78f4df8a51a8198e10b0f347257d1e265bb1a32993d0c973d"}, - {file = "pywin32-305-cp38-cp38-win32.whl", hash = "sha256:9dd98384da775afa009bc04863426cb30596fd78c6f8e4e2e5bbf4edf8029504"}, - {file = "pywin32-305-cp38-cp38-win_amd64.whl", hash = "sha256:56d7a9c6e1a6835f521788f53b5af7912090674bb84ef5611663ee1595860fc7"}, - {file = "pywin32-305-cp39-cp39-win32.whl", hash = "sha256:9d968c677ac4d5cbdaa62fd3014ab241718e619d8e36ef8e11fb930515a1e918"}, - {file = "pywin32-305-cp39-cp39-win_amd64.whl", hash = "sha256:50768c6b7c3f0b38b7fb14dd4104da93ebced5f1a50dc0e834594bff6fbe1271"}, -] - -[[package]] -name = "pywin32-ctypes" -version = "0.2.0" -description = "" -category = "main" + {file = "pyunormalize-15.1.0.tar.gz", hash = "sha256:cf4a87451a0f1cb76911aa97f432f4579e1f564a2f0c84ce488c73a73901b6c1"}, +] + +[[package]] +name = "pywin32" +version = "306" +description = "Python for Window Extensions" optional = false python-versions = "*" files = [ - {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, - {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, ] [[package]] -name = "rapidfuzz" -version = "2.13.7" -description = "rapid fuzzy string matching" -category = "main" +name = "referencing" +version = "0.35.1" +description = "JSON Referencing + Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "rapidfuzz-2.13.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b75dd0928ce8e216f88660ab3d5c5ffe990f4dd682fd1709dba29d5dafdde6de"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24d3fea10680d085fd0a4d76e581bfb2b1074e66e78fd5964d4559e1fcd2a2d4"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8109e0324d21993d5b2d111742bf5958f3516bf8c59f297c5d1cc25a2342eb66"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5f705652360d520c2de52bee11100c92f59b3e3daca308ebb150cbc58aecdad"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7496e8779905b02abc0ab4ba2a848e802ab99a6e20756ffc967a0de4900bd3da"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:24eb6b843492bdc63c79ee4b2f104059b7a2201fef17f25177f585d3be03405a"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:467c1505362823a5af12b10234cb1c4771ccf124c00e3fc9a43696512bd52293"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53dcae85956853b787c27c1cb06f18bb450e22cf57a4ad3444cf03b8ff31724a"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:46b9b8aa09998bc48dd800854e8d9b74bc534d7922c1d6e1bbf783e7fa6ac29c"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1fbad8fb28d98980f5bff33c7842efef0315d42f0cd59082108482a7e6b61410"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:43fb8cb030f888c3f076d40d428ed5eb4331f5dd6cf1796cfa39c67bf0f0fc1e"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:b6bad92de071cbffa2acd4239c1779f66851b60ffbbda0e4f4e8a2e9b17e7eef"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d00df2e4a81ffa56a6b1ec4d2bc29afdcb7f565e0b8cd3092fece2290c4c7a79"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-win32.whl", hash = "sha256:2c836f0f2d33d4614c3fbaf9a1eb5407c0fe23f8876f47fd15b90f78daa64c34"}, - {file = "rapidfuzz-2.13.7-cp310-cp310-win_amd64.whl", hash = "sha256:c36fd260084bb636b9400bb92016c6bd81fd80e59ed47f2466f85eda1fc9f782"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b34e8c0e492949ecdd5da46a1cfc856a342e2f0389b379b1a45a3cdcd3176a6e"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:875d51b3497439a72e2d76183e1cb5468f3f979ab2ddfc1d1f7dde3b1ecfb42f"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ae33a72336059213996fe4baca4e0e4860913905c2efb7c991eab33b95a98a0a"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5585189b3d90d81ccd62d4f18530d5ac8972021f0aaaa1ffc6af387ff1dce75"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42085d4b154a8232767de8296ac39c8af5bccee6b823b0507de35f51c9cbc2d7"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:585206112c294e335d84de5d5f179c0f932837752d7420e3de21db7fdc476278"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f891b98f8bc6c9d521785816085e9657212621e93f223917fb8e32f318b2957e"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08590905a95ccfa43f4df353dcc5d28c15d70664299c64abcad8721d89adce4f"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b5dd713a1734574c2850c566ac4286594bacbc2d60b9170b795bee4b68656625"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:988f8f6abfba7ee79449f8b50687c174733b079521c3cc121d65ad2d38831846"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b3210869161a864f3831635bb13d24f4708c0aa7208ef5baac1ac4d46e9b4208"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f6fe570e20e293eb50491ae14ddeef71a6a7e5f59d7e791393ffa99b13f1f8c2"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6120f2995f5154057454c5de99d86b4ef3b38397899b5da1265467e8980b2f60"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-win32.whl", hash = "sha256:b20141fa6cee041917801de0bab503447196d372d4c7ee9a03721b0a8edf5337"}, - {file = "rapidfuzz-2.13.7-cp311-cp311-win_amd64.whl", hash = "sha256:ec55a81ac2b0f41b8d6fb29aad16e55417036c7563bad5568686931aa4ff08f7"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7d005e058d86f2a968a8d28ca6f2052fab1f124a39035aa0523261d6baf21e1f"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe59a0c21a032024edb0c8e43f5dee5623fef0b65a1e3c1281836d9ce199af3b"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfc04f7647c29fb48da7a04082c34cdb16f878d3c6d098d62d5715c0ad3000c"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:68a89bb06d5a331511961f4d3fa7606f8e21237467ba9997cae6f67a1c2c2b9e"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:effe182767d102cb65dfbbf74192237dbd22d4191928d59415aa7d7c861d8c88"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25b4cedf2aa19fb7212894ce5f5219010cce611b60350e9a0a4d492122e7b351"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3a9bd02e1679c0fd2ecf69b72d0652dbe2a9844eaf04a36ddf4adfbd70010e95"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5e2b3d020219baa75f82a4e24b7c8adcb598c62f0e54e763c39361a9e5bad510"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:cf62dacb3f9234f3fddd74e178e6d25c68f2067fde765f1d95f87b1381248f58"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:fa263135b892686e11d5b84f6a1892523123a00b7e5882eff4fbdabb38667347"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:fa4c598ed77f74ec973247ca776341200b0f93ec3883e34c222907ce72cb92a4"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-win32.whl", hash = "sha256:c2523f8180ebd9796c18d809e9a19075a1060b1a170fde3799e83db940c1b6d5"}, - {file = "rapidfuzz-2.13.7-cp37-cp37m-win_amd64.whl", hash = "sha256:5ada0a14c67452358c1ee52ad14b80517a87b944897aaec3e875279371a9cb96"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ca8a23097c1f50e0fdb4de9e427537ca122a18df2eead06ed39c3a0bef6d9d3a"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9be02162af0376d64b840f2fc8ee3366794fc149f1e06d095a6a1d42447d97c5"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af4f7c3c904ca709493eb66ca9080b44190c38e9ecb3b48b96d38825d5672559"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f50d1227e6e2a0e3ae1fb1c9a2e1c59577d3051af72c7cab2bcc430cb5e18da"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c71d9d512b76f05fa00282227c2ae884abb60e09f08b5ca3132b7e7431ac7f0d"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b52ac2626945cd21a2487aeefed794c14ee31514c8ae69b7599170418211e6f6"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca00fafd2756bc9649bf80f1cf72c647dce38635f0695d7ce804bc0f759aa756"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d248a109699ce9992304e79c1f8735c82cc4c1386cd8e27027329c0549f248a2"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c88adbcb933f6b8612f6c593384bf824e562bb35fc8a0f55fac690ab5b3486e5"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c8601a66fbfc0052bb7860d2eacd303fcde3c14e87fdde409eceff516d659e77"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:27be9c63215d302ede7d654142a2e21f0d34ea6acba512a4ae4cfd52bbaa5b59"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3dcffe1f3cbda0dc32133a2ae2255526561ca594f15f9644384549037b355245"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8450d15f7765482e86ef9be2ad1a05683cd826f59ad236ef7b9fb606464a56aa"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-win32.whl", hash = "sha256:460853983ab88f873173e27cc601c5276d469388e6ad6e08c4fd57b2a86f1064"}, - {file = "rapidfuzz-2.13.7-cp38-cp38-win_amd64.whl", hash = "sha256:424f82c35dbe4f83bdc3b490d7d696a1dc6423b3d911460f5493b7ffae999fd2"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c3fbe449d869ea4d0909fc9d862007fb39a584fb0b73349a6aab336f0d90eaed"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:16080c05a63d6042643ae9b6cfec1aefd3e61cef53d0abe0df3069b9d4b72077"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dbcf5371ea704759fcce772c66a07647751d1f5dbdec7818331c9b31ae996c77"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:114810491efb25464016fd554fdf1e20d390309cecef62587494fc474d4b926f"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99a84ab9ac9a823e7e93b4414f86344052a5f3e23b23aa365cda01393ad895bd"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81642a24798851b118f82884205fc1bd9ff70b655c04018c467824b6ecc1fabc"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3741cb0bf9794783028e8b0cf23dab917fa5e37a6093b94c4c2f805f8e36b9f"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:759a3361711586a29bc753d3d1bdb862983bd9b9f37fbd7f6216c24f7c972554"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1333fb3d603d6b1040e365dca4892ba72c7e896df77a54eae27dc07db90906e3"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:916bc2e6cf492c77ad6deb7bcd088f0ce9c607aaeabc543edeb703e1fbc43e31"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:23524635840500ce6f4d25005c9529a97621689c85d2f727c52eed1782839a6a"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:ebe303cd9839af69dd1f7942acaa80b1ba90bacef2e7ded9347fbed4f1654672"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fe56659ccadbee97908132135de4b875543353351e0c92e736b7c57aee298b5a"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-win32.whl", hash = "sha256:3f11a7eff7bc6301cd6a5d43f309e22a815af07e1f08eeb2182892fca04c86cb"}, - {file = "rapidfuzz-2.13.7-cp39-cp39-win_amd64.whl", hash = "sha256:e8914dad106dacb0775718e54bf15e528055c4e92fb2677842996f2d52da5069"}, - {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7f7930adf84301797c3f09c94b9c5a9ed90a9e8b8ed19b41d2384937e0f9f5bd"}, - {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c31022d9970177f6affc6d5dd757ed22e44a10890212032fabab903fdee3bfe7"}, - {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f42b82f268689f429def9ecfb86fa65ceea0eaf3fed408b570fe113311bf5ce7"}, - {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b477b43ced896301665183a5e0faec0f5aea2373005648da8bdcb3c4b73f280"}, - {file = "rapidfuzz-2.13.7-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d63def9bbc6b35aef4d76dc740301a4185867e8870cbb8719ec9de672212fca8"}, - {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c66546e30addb04a16cd864f10f5821272a1bfe6462ee5605613b4f1cb6f7b48"}, - {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f799d1d6c33d81e983d3682571cc7d993ae7ff772c19b3aabb767039c33f6d1e"}, - {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d82f20c0060ffdaadaf642b88ab0aa52365b56dffae812e188e5bdb998043588"}, - {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:042644133244bfa7b20de635d500eb9f46af7097f3d90b1724f94866f17cb55e"}, - {file = "rapidfuzz-2.13.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:75c45dcd595f8178412367e302fd022860ea025dc4a78b197b35428081ed33d5"}, - {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3d8b081988d0a49c486e4e845a547565fee7c6e7ad8be57ff29c3d7c14c6894c"}, - {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16ffad751f43ab61001187b3fb4a9447ec2d1aedeff7c5bac86d3b95f9980cc3"}, - {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:020858dd89b60ce38811cd6e37875c4c3c8d7fcd8bc20a0ad2ed1f464b34dc4e"}, - {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cda1e2f66bb4ba7261a0f4c2d052d5d909798fca557cbff68f8a79a87d66a18f"}, - {file = "rapidfuzz-2.13.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b6389c50d8d214c9cd11a77f6d501529cb23279a9c9cafe519a3a4b503b5f72a"}, - {file = "rapidfuzz-2.13.7.tar.gz", hash = "sha256:8d3e252d4127c79b4d7c2ae47271636cbaca905c8bb46d80c7930ab906cf4b5c"}, + {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, + {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, ] -[package.extras] -full = ["numpy"] +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" [[package]] name = "regex" -version = "2022.10.31" +version = "2024.5.15" description = "Alternative regular expression module, to replace re." -category = "main" optional = false -python-versions = ">=3.6" -files = [ - {file = "regex-2022.10.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8ff454ef0bb061e37df03557afda9d785c905dab15584860f982e88be73015f"}, - {file = "regex-2022.10.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1eba476b1b242620c266edf6325b443a2e22b633217a9835a52d8da2b5c051f9"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0e5af9a9effb88535a472e19169e09ce750c3d442fb222254a276d77808620b"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d03fe67b2325cb3f09be029fd5da8df9e6974f0cde2c2ac6a79d2634e791dd57"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9d0b68ac1743964755ae2d89772c7e6fb0118acd4d0b7464eaf3921c6b49dd4"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a45b6514861916c429e6059a55cf7db74670eaed2052a648e3e4d04f070e001"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b0886885f7323beea6f552c28bff62cbe0983b9fbb94126531693ea6c5ebb90"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5aefb84a301327ad115e9d346c8e2760009131d9d4b4c6b213648d02e2abe144"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:702d8fc6f25bbf412ee706bd73019da5e44a8400861dfff7ff31eb5b4a1276dc"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a3c1ebd4ed8e76e886507c9eddb1a891673686c813adf889b864a17fafcf6d66"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:50921c140561d3db2ab9f5b11c5184846cde686bb5a9dc64cae442926e86f3af"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:7db345956ecce0c99b97b042b4ca7326feeec6b75facd8390af73b18e2650ffc"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:763b64853b0a8f4f9cfb41a76a4a85a9bcda7fdda5cb057016e7706fde928e66"}, - {file = "regex-2022.10.31-cp310-cp310-win32.whl", hash = "sha256:44136355e2f5e06bf6b23d337a75386371ba742ffa771440b85bed367c1318d1"}, - {file = "regex-2022.10.31-cp310-cp310-win_amd64.whl", hash = "sha256:bfff48c7bd23c6e2aec6454aaf6edc44444b229e94743b34bdcdda2e35126cf5"}, - {file = "regex-2022.10.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b4b1fe58cd102d75ef0552cf17242705ce0759f9695334a56644ad2d83903fe"}, - {file = "regex-2022.10.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:542e3e306d1669b25936b64917285cdffcd4f5c6f0247636fec037187bd93542"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c27cc1e4b197092e50ddbf0118c788d9977f3f8f35bfbbd3e76c1846a3443df7"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8e38472739028e5f2c3a4aded0ab7eadc447f0d84f310c7a8bb697ec417229e"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76c598ca73ec73a2f568e2a72ba46c3b6c8690ad9a07092b18e48ceb936e9f0c"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c28d3309ebd6d6b2cf82969b5179bed5fefe6142c70f354ece94324fa11bf6a1"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9af69f6746120998cd9c355e9c3c6aec7dff70d47247188feb4f829502be8ab4"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a5f9505efd574d1e5b4a76ac9dd92a12acb2b309551e9aa874c13c11caefbe4f"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5ff525698de226c0ca743bfa71fc6b378cda2ddcf0d22d7c37b1cc925c9650a5"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4fe7fda2fe7c8890d454f2cbc91d6c01baf206fbc96d89a80241a02985118c0c"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2cdc55ca07b4e70dda898d2ab7150ecf17c990076d3acd7a5f3b25cb23a69f1c"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:44a6c2f6374e0033873e9ed577a54a3602b4f609867794c1a3ebba65e4c93ee7"}, - {file = "regex-2022.10.31-cp311-cp311-win32.whl", hash = "sha256:d8716f82502997b3d0895d1c64c3b834181b1eaca28f3f6336a71777e437c2af"}, - {file = "regex-2022.10.31-cp311-cp311-win_amd64.whl", hash = "sha256:61edbca89aa3f5ef7ecac8c23d975fe7261c12665f1d90a6b1af527bba86ce61"}, - {file = "regex-2022.10.31-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a069c8483466806ab94ea9068c34b200b8bfc66b6762f45a831c4baaa9e8cdd"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26166acf62f731f50bdd885b04b38828436d74e8e362bfcb8df221d868b5d9b"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac741bf78b9bb432e2d314439275235f41656e189856b11fb4e774d9f7246d81"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75f591b2055523fc02a4bbe598aa867df9e953255f0b7f7715d2a36a9c30065c"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b30bddd61d2a3261f025ad0f9ee2586988c6a00c780a2fb0a92cea2aa702c54"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef4163770525257876f10e8ece1cf25b71468316f61451ded1a6f44273eedeb5"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7b280948d00bd3973c1998f92e22aa3ecb76682e3a4255f33e1020bd32adf443"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:d0213671691e341f6849bf33cd9fad21f7b1cb88b89e024f33370733fec58742"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:22e7ebc231d28393dfdc19b185d97e14a0f178bedd78e85aad660e93b646604e"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8ad241da7fac963d7573cc67a064c57c58766b62a9a20c452ca1f21050868dfa"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:586b36ebda81e6c1a9c5a5d0bfdc236399ba6595e1397842fd4a45648c30f35e"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0653d012b3bf45f194e5e6a41df9258811ac8fc395579fa82958a8b76286bea4"}, - {file = "regex-2022.10.31-cp36-cp36m-win32.whl", hash = "sha256:144486e029793a733e43b2e37df16a16df4ceb62102636ff3db6033994711066"}, - {file = "regex-2022.10.31-cp36-cp36m-win_amd64.whl", hash = "sha256:c14b63c9d7bab795d17392c7c1f9aaabbffd4cf4387725a0ac69109fb3b550c6"}, - {file = "regex-2022.10.31-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4cac3405d8dda8bc6ed499557625585544dd5cbf32072dcc72b5a176cb1271c8"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23cbb932cc53a86ebde0fb72e7e645f9a5eec1a5af7aa9ce333e46286caef783"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74bcab50a13960f2a610cdcd066e25f1fd59e23b69637c92ad470784a51b1347"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d680ef3e4d405f36f0d6d1ea54e740366f061645930072d39bca16a10d8c93"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce6910b56b700bea7be82c54ddf2e0ed792a577dfaa4a76b9af07d550af435c6"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:659175b2144d199560d99a8d13b2228b85e6019b6e09e556209dfb8c37b78a11"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1ddf14031a3882f684b8642cb74eea3af93a2be68893901b2b387c5fd92a03ec"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b683e5fd7f74fb66e89a1ed16076dbab3f8e9f34c18b1979ded614fe10cdc4d9"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2bde29cc44fa81c0a0c8686992c3080b37c488df167a371500b2a43ce9f026d1"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4919899577ba37f505aaebdf6e7dc812d55e8f097331312db7f1aab18767cce8"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:9c94f7cc91ab16b36ba5ce476f1904c91d6c92441f01cd61a8e2729442d6fcf5"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae1e96785696b543394a4e3f15f3f225d44f3c55dafe3f206493031419fedf95"}, - {file = "regex-2022.10.31-cp37-cp37m-win32.whl", hash = "sha256:c670f4773f2f6f1957ff8a3962c7dd12e4be54d05839b216cb7fd70b5a1df394"}, - {file = "regex-2022.10.31-cp37-cp37m-win_amd64.whl", hash = "sha256:8e0caeff18b96ea90fc0eb6e3bdb2b10ab5b01a95128dfeccb64a7238decf5f0"}, - {file = "regex-2022.10.31-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:131d4be09bea7ce2577f9623e415cab287a3c8e0624f778c1d955ec7c281bd4d"}, - {file = "regex-2022.10.31-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e613a98ead2005c4ce037c7b061f2409a1a4e45099edb0ef3200ee26ed2a69a8"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052b670fafbe30966bbe5d025e90b2a491f85dfe5b2583a163b5e60a85a321ad"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa62a07ac93b7cb6b7d0389d8ef57ffc321d78f60c037b19dfa78d6b17c928ee"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5352bea8a8f84b89d45ccc503f390a6be77917932b1c98c4cdc3565137acc714"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20f61c9944f0be2dc2b75689ba409938c14876c19d02f7585af4460b6a21403e"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29c04741b9ae13d1e94cf93fca257730b97ce6ea64cfe1eba11cf9ac4e85afb6"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:543883e3496c8b6d58bd036c99486c3c8387c2fc01f7a342b760c1ea3158a318"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7a8b43ee64ca8f4befa2bea4083f7c52c92864d8518244bfa6e88c751fa8fff"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6a9a19bea8495bb419dc5d38c4519567781cd8d571c72efc6aa959473d10221a"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6ffd55b5aedc6f25fd8d9f905c9376ca44fcf768673ffb9d160dd6f409bfda73"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4bdd56ee719a8f751cf5a593476a441c4e56c9b64dc1f0f30902858c4ef8771d"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ca88da1bd78990b536c4a7765f719803eb4f8f9971cc22d6ca965c10a7f2c4c"}, - {file = "regex-2022.10.31-cp38-cp38-win32.whl", hash = "sha256:5a260758454580f11dd8743fa98319bb046037dfab4f7828008909d0aa5292bc"}, - {file = "regex-2022.10.31-cp38-cp38-win_amd64.whl", hash = "sha256:5e6a5567078b3eaed93558842346c9d678e116ab0135e22eb72db8325e90b453"}, - {file = "regex-2022.10.31-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5217c25229b6a85049416a5c1e6451e9060a1edcf988641e309dbe3ab26d3e49"}, - {file = "regex-2022.10.31-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4bf41b8b0a80708f7e0384519795e80dcb44d7199a35d52c15cc674d10b3081b"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf0da36a212978be2c2e2e2d04bdff46f850108fccc1851332bcae51c8907cc"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d403d781b0e06d2922435ce3b8d2376579f0c217ae491e273bab8d092727d244"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a37d51fa9a00d265cf73f3de3930fa9c41548177ba4f0faf76e61d512c774690"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4f781ffedd17b0b834c8731b75cce2639d5a8afe961c1e58ee7f1f20b3af185"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d243b36fbf3d73c25e48014961e83c19c9cc92530516ce3c43050ea6276a2ab7"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:370f6e97d02bf2dd20d7468ce4f38e173a124e769762d00beadec3bc2f4b3bc4"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:597f899f4ed42a38df7b0e46714880fb4e19a25c2f66e5c908805466721760f5"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7dbdce0c534bbf52274b94768b3498abdf675a691fec5f751b6057b3030f34c1"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:22960019a842777a9fa5134c2364efaed5fbf9610ddc5c904bd3a400973b0eb8"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7f5a3ffc731494f1a57bd91c47dc483a1e10048131ffb52d901bfe2beb6102e8"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7ef6b5942e6bfc5706301a18a62300c60db9af7f6368042227ccb7eeb22d0892"}, - {file = "regex-2022.10.31-cp39-cp39-win32.whl", hash = "sha256:395161bbdbd04a8333b9ff9763a05e9ceb4fe210e3c7690f5e68cedd3d65d8e1"}, - {file = "regex-2022.10.31-cp39-cp39-win_amd64.whl", hash = "sha256:957403a978e10fb3ca42572a23e6f7badff39aa1ce2f4ade68ee452dc6807692"}, - {file = "regex-2022.10.31.tar.gz", hash = "sha256:a3a98921da9a1bf8457aeee6a551948a83601689e5ecdd736894ea9bbec77e83"}, +python-versions = ">=3.8" +files = [ + {file = "regex-2024.5.15-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a81e3cfbae20378d75185171587cbf756015ccb14840702944f014e0d93ea09f"}, + {file = "regex-2024.5.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b59138b219ffa8979013be7bc85bb60c6f7b7575df3d56dc1e403a438c7a3f6"}, + {file = "regex-2024.5.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0bd000c6e266927cb7a1bc39d55be95c4b4f65c5be53e659537537e019232b1"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eaa7ddaf517aa095fa8da0b5015c44d03da83f5bd49c87961e3c997daed0de7"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba68168daedb2c0bab7fd7e00ced5ba90aebf91024dea3c88ad5063c2a562cca"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6e8d717bca3a6e2064fc3a08df5cbe366369f4b052dcd21b7416e6d71620dca1"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1337b7dbef9b2f71121cdbf1e97e40de33ff114801263b275aafd75303bd62b5"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9ebd0a36102fcad2f03696e8af4ae682793a5d30b46c647eaf280d6cfb32796"}, + {file = "regex-2024.5.15-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9efa1a32ad3a3ea112224897cdaeb6aa00381627f567179c0314f7b65d354c62"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1595f2d10dff3d805e054ebdc41c124753631b6a471b976963c7b28543cf13b0"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b802512f3e1f480f41ab5f2cfc0e2f761f08a1f41092d6718868082fc0d27143"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a0981022dccabca811e8171f913de05720590c915b033b7e601f35ce4ea7019f"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:19068a6a79cf99a19ccefa44610491e9ca02c2be3305c7760d3831d38a467a6f"}, + {file = "regex-2024.5.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1b5269484f6126eee5e687785e83c6b60aad7663dafe842b34691157e5083e53"}, + {file = "regex-2024.5.15-cp310-cp310-win32.whl", hash = "sha256:ada150c5adfa8fbcbf321c30c751dc67d2f12f15bd183ffe4ec7cde351d945b3"}, + {file = "regex-2024.5.15-cp310-cp310-win_amd64.whl", hash = "sha256:ac394ff680fc46b97487941f5e6ae49a9f30ea41c6c6804832063f14b2a5a145"}, + {file = "regex-2024.5.15-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f5b1dff3ad008dccf18e652283f5e5339d70bf8ba7c98bf848ac33db10f7bc7a"}, + {file = "regex-2024.5.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c6a2b494a76983df8e3d3feea9b9ffdd558b247e60b92f877f93a1ff43d26656"}, + {file = "regex-2024.5.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a32b96f15c8ab2e7d27655969a23895eb799de3665fa94349f3b2fbfd547236f"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10002e86e6068d9e1c91eae8295ef690f02f913c57db120b58fdd35a6bb1af35"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ec54d5afa89c19c6dd8541a133be51ee1017a38b412b1321ccb8d6ddbeb4cf7d"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10e4ce0dca9ae7a66e6089bb29355d4432caed736acae36fef0fdd7879f0b0cb"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e507ff1e74373c4d3038195fdd2af30d297b4f0950eeda6f515ae3d84a1770f"}, + {file = "regex-2024.5.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1f059a4d795e646e1c37665b9d06062c62d0e8cc3c511fe01315973a6542e40"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0721931ad5fe0dda45d07f9820b90b2148ccdd8e45bb9e9b42a146cb4f695649"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:833616ddc75ad595dee848ad984d067f2f31be645d603e4d158bba656bbf516c"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:287eb7f54fc81546346207c533ad3c2c51a8d61075127d7f6d79aaf96cdee890"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:19dfb1c504781a136a80ecd1fff9f16dddf5bb43cec6871778c8a907a085bb3d"}, + {file = "regex-2024.5.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:119af6e56dce35e8dfb5222573b50c89e5508d94d55713c75126b753f834de68"}, + {file = "regex-2024.5.15-cp311-cp311-win32.whl", hash = "sha256:1c1c174d6ec38d6c8a7504087358ce9213d4332f6293a94fbf5249992ba54efa"}, + {file = "regex-2024.5.15-cp311-cp311-win_amd64.whl", hash = "sha256:9e717956dcfd656f5055cc70996ee2cc82ac5149517fc8e1b60261b907740201"}, + {file = "regex-2024.5.15-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:632b01153e5248c134007209b5c6348a544ce96c46005d8456de1d552455b014"}, + {file = "regex-2024.5.15-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e64198f6b856d48192bf921421fdd8ad8eb35e179086e99e99f711957ffedd6e"}, + {file = "regex-2024.5.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68811ab14087b2f6e0fc0c2bae9ad689ea3584cad6917fc57be6a48bbd012c49"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8ec0c2fea1e886a19c3bee0cd19d862b3aa75dcdfb42ebe8ed30708df64687a"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d0c0c0003c10f54a591d220997dd27d953cd9ccc1a7294b40a4be5312be8797b"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2431b9e263af1953c55abbd3e2efca67ca80a3de8a0437cb58e2421f8184717a"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a605586358893b483976cffc1723fb0f83e526e8f14c6e6614e75919d9862cf"}, + {file = "regex-2024.5.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:391d7f7f1e409d192dba8bcd42d3e4cf9e598f3979cdaed6ab11288da88cb9f2"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9ff11639a8d98969c863d4617595eb5425fd12f7c5ef6621a4b74b71ed8726d5"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4eee78a04e6c67e8391edd4dad3279828dd66ac4b79570ec998e2155d2e59fd5"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8fe45aa3f4aa57faabbc9cb46a93363edd6197cbc43523daea044e9ff2fea83e"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:d0a3d8d6acf0c78a1fff0e210d224b821081330b8524e3e2bc5a68ef6ab5803d"}, + {file = "regex-2024.5.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c486b4106066d502495b3025a0a7251bf37ea9540433940a23419461ab9f2a80"}, + {file = "regex-2024.5.15-cp312-cp312-win32.whl", hash = "sha256:c49e15eac7c149f3670b3e27f1f28a2c1ddeccd3a2812cba953e01be2ab9b5fe"}, + {file = "regex-2024.5.15-cp312-cp312-win_amd64.whl", hash = "sha256:673b5a6da4557b975c6c90198588181029c60793835ce02f497ea817ff647cb2"}, + {file = "regex-2024.5.15-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:87e2a9c29e672fc65523fb47a90d429b70ef72b901b4e4b1bd42387caf0d6835"}, + {file = "regex-2024.5.15-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c3bea0ba8b73b71b37ac833a7f3fd53825924165da6a924aec78c13032f20850"}, + {file = "regex-2024.5.15-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bfc4f82cabe54f1e7f206fd3d30fda143f84a63fe7d64a81558d6e5f2e5aaba9"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5bb9425fe881d578aeca0b2b4b3d314ec88738706f66f219c194d67179337cb"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64c65783e96e563103d641760664125e91bd85d8e49566ee560ded4da0d3e704"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf2430df4148b08fb4324b848672514b1385ae3807651f3567871f130a728cc3"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5397de3219a8b08ae9540c48f602996aa6b0b65d5a61683e233af8605c42b0f2"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:455705d34b4154a80ead722f4f185b04c4237e8e8e33f265cd0798d0e44825fa"}, + {file = "regex-2024.5.15-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2b6f1b3bb6f640c1a92be3bbfbcb18657b125b99ecf141fb3310b5282c7d4ed"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3ad070b823ca5890cab606c940522d05d3d22395d432f4aaaf9d5b1653e47ced"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5b5467acbfc153847d5adb21e21e29847bcb5870e65c94c9206d20eb4e99a384"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:e6662686aeb633ad65be2a42b4cb00178b3fbf7b91878f9446075c404ada552f"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:2b4c884767504c0e2401babe8b5b7aea9148680d2e157fa28f01529d1f7fcf67"}, + {file = "regex-2024.5.15-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:3cd7874d57f13bf70078f1ff02b8b0aa48d5b9ed25fc48547516c6aba36f5741"}, + {file = "regex-2024.5.15-cp38-cp38-win32.whl", hash = "sha256:e4682f5ba31f475d58884045c1a97a860a007d44938c4c0895f41d64481edbc9"}, + {file = "regex-2024.5.15-cp38-cp38-win_amd64.whl", hash = "sha256:d99ceffa25ac45d150e30bd9ed14ec6039f2aad0ffa6bb87a5936f5782fc1569"}, + {file = "regex-2024.5.15-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13cdaf31bed30a1e1c2453ef6015aa0983e1366fad2667657dbcac7b02f67133"}, + {file = "regex-2024.5.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cac27dcaa821ca271855a32188aa61d12decb6fe45ffe3e722401fe61e323cd1"}, + {file = "regex-2024.5.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7dbe2467273b875ea2de38ded4eba86cbcbc9a1a6d0aa11dcf7bd2e67859c435"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64f18a9a3513a99c4bef0e3efd4c4a5b11228b48aa80743be822b71e132ae4f5"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d347a741ea871c2e278fde6c48f85136c96b8659b632fb57a7d1ce1872547600"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1878b8301ed011704aea4c806a3cadbd76f84dece1ec09cc9e4dc934cfa5d4da"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4babf07ad476aaf7830d77000874d7611704a7fcf68c9c2ad151f5d94ae4bfc4"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35cb514e137cb3488bce23352af3e12fb0dbedd1ee6e60da053c69fb1b29cc6c"}, + {file = "regex-2024.5.15-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cdd09d47c0b2efee9378679f8510ee6955d329424c659ab3c5e3a6edea696294"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:72d7a99cd6b8f958e85fc6ca5b37c4303294954eac1376535b03c2a43eb72629"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a094801d379ab20c2135529948cb84d417a2169b9bdceda2a36f5f10977ebc16"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c0c18345010870e58238790a6779a1219b4d97bd2e77e1140e8ee5d14df071aa"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:16093f563098448ff6b1fa68170e4acbef94e6b6a4e25e10eae8598bb1694b5d"}, + {file = "regex-2024.5.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e38a7d4e8f633a33b4c7350fbd8bad3b70bf81439ac67ac38916c4a86b465456"}, + {file = "regex-2024.5.15-cp39-cp39-win32.whl", hash = "sha256:71a455a3c584a88f654b64feccc1e25876066c4f5ef26cd6dd711308aa538694"}, + {file = "regex-2024.5.15-cp39-cp39-win_amd64.whl", hash = "sha256:cab12877a9bdafde5500206d1020a584355a97884dfd388af3699e9137bf7388"}, + {file = "regex-2024.5.15.tar.gz", hash = "sha256:d3ee02d9e5f482cc8309134a91eeaacbdd2261ba111b0fef3748eeb4913e6a2c"}, ] [[package]] name = "requests" -version = "2.28.2" +version = "2.32.3" description = "Python HTTP for Humans." -category = "main" optional = false -python-versions = ">=3.7, <4" +python-versions = ">=3.8" files = [ - {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"}, - {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"}, + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] certifi = ">=2017.4.17" charset-normalizer = ">=2,<4" idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<1.27" +urllib3 = ">=1.21.1,<3" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] -[[package]] -name = "requests-toolbelt" -version = "0.10.1" -description = "A utility belt for advanced users of python-requests" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "requests-toolbelt-0.10.1.tar.gz", hash = "sha256:62e09f7ff5ccbda92772a29f394a49c3ad6cb181d568b1337626b2abb628a63d"}, - {file = "requests_toolbelt-0.10.1-py2.py3-none-any.whl", hash = "sha256:18565aa58116d9951ac39baa288d3adb5b3ff975c4f25eee78555d89e8f247f7"}, -] - -[package.dependencies] -requests = ">=2.0.1,<3.0.0" - [[package]] name = "rlp" -version = "3.0.0" -description = "A package for Recursive Length Prefix encoding and decoding" -category = "main" +version = "4.0.1" +description = "rlp: A package for Recursive Length Prefix encoding and decoding" optional = false -python-versions = "*" +python-versions = "<4,>=3.8" files = [ - {file = "rlp-3.0.0-py2.py3-none-any.whl", hash = "sha256:d2a963225b3f26795c5b52310e0871df9824af56823d739511583ef459895a7d"}, - {file = "rlp-3.0.0.tar.gz", hash = "sha256:63b0465d2948cd9f01de449d7adfb92d207c1aef3982f20310f8009be4a507e8"}, + {file = "rlp-4.0.1-py3-none-any.whl", hash = "sha256:ff6846c3c27b97ee0492373aa074a7c3046aadd973320f4fffa7ac45564b0258"}, + {file = "rlp-4.0.1.tar.gz", hash = "sha256:bcefb11013dfadf8902642337923bd0c786dc8a27cb4c21da6e154e52869ecb1"}, ] [package.dependencies] -eth-utils = ">=2.0.0,<3" +eth-utils = ">=2" [package.extras] -dev = ["Sphinx (>=1.6.5,<2)", "bumpversion (>=0.5.3,<1)", "flake8 (==3.4.1)", "hypothesis (==5.19.0)", "ipython", "pytest (>=6.2.5,<7)", "pytest-watch (>=4.1.0,<5)", "pytest-xdist", "setuptools (>=36.2.0)", "sphinx-rtd-theme (>=0.1.9)", "tox (>=2.9.1,<3)", "twine", "wheel"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9)"] -lint = ["flake8 (==3.4.1)"] -rust-backend = ["rusty-rlp (>=0.2.1,<0.3)"] -test = ["hypothesis (==5.19.0)", "pytest (>=6.2.5,<7)", "tox (>=2.9.1,<3)"] - -[[package]] -name = "secretstorage" -version = "3.3.3" -description = "Python bindings to FreeDesktop.org Secret Service API" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"}, - {file = "SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77"}, -] - -[package.dependencies] -cryptography = ">=2.0" -jeepney = ">=0.6" - -[[package]] -name = "shellingham" -version = "1.5.0.post1" -description = "Tool to Detect Surrounding Shell" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "shellingham-1.5.0.post1-py2.py3-none-any.whl", hash = "sha256:368bf8c00754fd4f55afb7bbb86e272df77e4dc76ac29dbcbb81a59e9fc15744"}, - {file = "shellingham-1.5.0.post1.tar.gz", hash = "sha256:823bc5fb5c34d60f285b624e7264f4dda254bc803a3774a147bf99c0e3004a28"}, +dev = ["build (>=0.9.0)", "bumpversion (>=0.5.3)", "hypothesis (==5.19.0)", "ipython", "pre-commit (>=3.4.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)", "sphinx (>=6.0.0)", "sphinx-autobuild (>=2021.3.14)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=4.0.0)", "twine", "wheel"] +docs = ["sphinx (>=6.0.0)", "sphinx-autobuild (>=2021.3.14)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] +rust-backend = ["rusty-rlp (>=0.2.1)"] +test = ["hypothesis (==5.19.0)", "pytest (>=7.0.0)", "pytest-xdist (>=2.4.0)"] + +[[package]] +name = "rpds-py" +version = "0.18.1" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"}, + {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"}, + {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"}, + {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"}, + {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"}, + {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"}, + {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"}, + {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"}, + {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"}, + {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"}, + {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"}, + {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"}, + {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"}, + {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"}, + {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"}, + {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"}, + {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"}, + {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"}, + {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"}, + {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"}, + {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"}, + {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"}, + {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"}, + {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"}, + {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"}, + {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"}, + {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"}, + {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"}, + {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"}, + {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"}, + {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"}, + {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"}, + {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"}, + {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"}, ] [[package]] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2667,7 +2251,6 @@ files = [ name = "sortedcontainers" version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" -category = "dev" optional = false python-versions = "*" files = [ @@ -2679,7 +2262,6 @@ files = [ name = "timeout-decorator" version = "0.5.0" description = "Timeout decorator" -category = "main" optional = false python-versions = "*" files = [ @@ -2688,180 +2270,138 @@ files = [ [[package]] name = "tomlkit" -version = "0.11.6" +version = "0.12.5" description = "Style preserving TOML library" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "tomlkit-0.11.6-py3-none-any.whl", hash = "sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b"}, - {file = "tomlkit-0.11.6.tar.gz", hash = "sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73"}, + {file = "tomlkit-0.12.5-py3-none-any.whl", hash = "sha256:af914f5a9c59ed9d0762c7b64d3b5d5df007448eb9cd2edc8a46b1eafead172f"}, + {file = "tomlkit-0.12.5.tar.gz", hash = "sha256:eef34fba39834d4d6b73c9ba7f3e4d1c417a4e56f89a7e96e090dd0d24b8fb3c"}, ] [[package]] name = "toolz" -version = "0.12.0" +version = "0.12.1" description = "List processing tools and functional utilities" -category = "main" optional = false -python-versions = ">=3.5" -files = [ - {file = "toolz-0.12.0-py3-none-any.whl", hash = "sha256:2059bd4148deb1884bb0eb770a3cde70e7f954cfbbdc2285f1f2de01fd21eb6f"}, - {file = "toolz-0.12.0.tar.gz", hash = "sha256:88c570861c440ee3f2f6037c4654613228ff40c93a6c25e0eba70d17282c6194"}, -] - -[[package]] -name = "trove-classifiers" -version = "2023.2.20" -description = "Canonical source for classifiers on PyPI (pypi.org)." -category = "main" -optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "trove-classifiers-2023.2.20.tar.gz", hash = "sha256:860b0c0d8c9e0d32629ca5ef137ea1e637580b634b74ba40e1539fd34464c0f5"}, - {file = "trove_classifiers-2023.2.20-py3-none-any.whl", hash = "sha256:de61417c958b06fd4923b2e26d4e70dd7ffc691d5435bcd7ed78d061278885f1"}, + {file = "toolz-0.12.1-py3-none-any.whl", hash = "sha256:d22731364c07d72eea0a0ad45bafb2c2937ab6fd38a3507bf55eae8744aa7d85"}, + {file = "toolz-0.12.1.tar.gz", hash = "sha256:ecca342664893f177a13dac0e6b41cbd8ac25a358e5f215316d43e2100224f4d"}, ] [[package]] name = "types-requests" -version = "2.28.11.15" +version = "2.32.0.20240602" description = "Typing stubs for requests" -category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "types-requests-2.28.11.15.tar.gz", hash = "sha256:fc8eaa09cc014699c6b63c60c2e3add0c8b09a410c818b5ac6e65f92a26dde09"}, - {file = "types_requests-2.28.11.15-py3-none-any.whl", hash = "sha256:a05e4c7bc967518fba5789c341ea8b0c942776ee474c7873129a61161978e586"}, + {file = "types-requests-2.32.0.20240602.tar.gz", hash = "sha256:3f98d7bbd0dd94ebd10ff43a7fbe20c3b8528acace6d8efafef0b6a184793f06"}, + {file = "types_requests-2.32.0.20240602-py3-none-any.whl", hash = "sha256:ed3946063ea9fbc6b5fc0c44fa279188bae42d582cb63760be6cb4b9d06c3de8"}, ] [package.dependencies] -types-urllib3 = "<1.27" +urllib3 = ">=2" [[package]] name = "types-setuptools" -version = "67.6.0.0" +version = "67.8.0.0" description = "Typing stubs for setuptools" -category = "dev" optional = false python-versions = "*" files = [ - {file = "types-setuptools-67.6.0.0.tar.gz", hash = "sha256:70b5e6a379e9fccf6579871a93ca3301a46252e3ae66957ec64281a2b6a812d9"}, - {file = "types_setuptools-67.6.0.0-py3-none-any.whl", hash = "sha256:d669a80ee8e37eb1697dc31a23d41ea2c48a635464e2c7e6370dda811459b466"}, + {file = "types-setuptools-67.8.0.0.tar.gz", hash = "sha256:95c9ed61871d6c0e258433373a4e1753c0a7c3627a46f4d4058c7b5a08ab844f"}, + {file = "types_setuptools-67.8.0.0-py3-none-any.whl", hash = "sha256:6df73340d96b238a4188b7b7668814b37e8018168aef1eef94a3b1872e3f60ff"}, ] [[package]] name = "types-urllib3" -version = "1.26.25.8" +version = "1.26.25.14" description = "Typing stubs for urllib3" -category = "dev" optional = false python-versions = "*" files = [ - {file = "types-urllib3-1.26.25.8.tar.gz", hash = "sha256:ecf43c42d8ee439d732a1110b4901e9017a79a38daca26f08e42c8460069392c"}, - {file = "types_urllib3-1.26.25.8-py3-none-any.whl", hash = "sha256:95ea847fbf0bf675f50c8ae19a665baedcf07e6b4641662c4c3c72e7b2edf1a9"}, + {file = "types-urllib3-1.26.25.14.tar.gz", hash = "sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f"}, + {file = "types_urllib3-1.26.25.14-py3-none-any.whl", hash = "sha256:9683bbb7fb72e32bfe9d2be6e04875fbe1b3eeec3cbb4ea231435aa7fd6b4f0e"}, ] [[package]] name = "typing-extensions" -version = "4.5.0" -description = "Backported and Experimental Type Hints for Python 3.7+" -category = "dev" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, - {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] name = "urllib3" -version = "1.26.14" +version = "2.2.1" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.8" files = [ - {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"}, - {file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"}, + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] [[package]] name = "varint" version = "1.0.2" description = "Simple python varint implementation" -category = "dev" optional = false python-versions = "*" files = [ {file = "varint-1.0.2.tar.gz", hash = "sha256:a6ecc02377ac5ee9d65a6a8ad45c9ff1dac8ccee19400a5950fb51d594214ca5"}, ] -[[package]] -name = "virtualenv" -version = "20.19.0" -description = "Virtual Python Environment builder" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "virtualenv-20.19.0-py3-none-any.whl", hash = "sha256:54eb59e7352b573aa04d53f80fc9736ed0ad5143af445a1e539aada6eb947dd1"}, - {file = "virtualenv-20.19.0.tar.gz", hash = "sha256:37a640ba82ed40b226599c522d411e4be5edb339a0c0de030c0dc7b646d61590"}, -] - -[package.dependencies] -distlib = ">=0.3.6,<1" -filelock = ">=3.4.1,<4" -platformdirs = ">=2.4,<4" - -[package.extras] -docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"] -test = ["covdefaults (>=2.2.2)", "coverage (>=7.1)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23)", "pytest (>=7.2.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)"] - [[package]] name = "web3" -version = "6.0.0b10" +version = "6.19.0" description = "web3.py" -category = "main" optional = false python-versions = ">=3.7.2" files = [ - {file = "web3-6.0.0b10-py3-none-any.whl", hash = "sha256:607297e35efe2285dfe2a2f764f46c1314409c9c59ca5a5dbd03a18236f998ec"}, - {file = "web3-6.0.0b10.tar.gz", hash = "sha256:517d5b1062fb1cddcc681cb22c75d19407f862999ec6b3e615f6b6731b2cb5b9"}, + {file = "web3-6.19.0-py3-none-any.whl", hash = "sha256:fb39683d6aa7586ce0ab0be4be392f8acb62c2503958079d61b59f2a0b883718"}, + {file = "web3-6.19.0.tar.gz", hash = "sha256:d27fbd4ac5aa70d0e0c516bd3e3b802fbe74bc159b407c34052d9301b400f757"}, ] [package.dependencies] aiohttp = ">=3.7.4.post0" -eth-abi = ">=4.0.0-b.2" -eth-account = ">=0.8.0" +eth-abi = ">=4.0.0" +eth-account = ">=0.8.0,<0.13" eth-hash = {version = ">=0.5.1", extras = ["pycryptodome"]} -eth-typing = ">=3.0.0" +eth-typing = ">=3.0.0,<4.2.0 || >4.2.0" eth-utils = ">=2.1.0" -hexbytes = ">=0.1.0" +hexbytes = ">=0.1.0,<0.4.0" jsonschema = ">=4.0.0" -lru-dict = ">=1.1.6" -parsimonious = "0.9.0" +lru-dict = ">=1.1.6,<1.3.0" protobuf = ">=4.21.6" +pyunormalize = ">=15.0.0" pywin32 = {version = ">=223", markers = "platform_system == \"Windows\""} requests = ">=2.16.0" +typing-extensions = ">=4.0.1" websockets = ">=10.0.0" [package.extras] -dev = ["black (>=22.1.0)", "bumpversion", "click (>=5.1)", "configparser (==3.5.0)", "contextlib2 (>=0.5.4)", "eth-tester[py-evm] (==v0.8.0-b.3)", "flake8 (==3.8.3)", "flaky (>=3.7.0)", "hypothesis (>=3.31.2)", "importlib-metadata (<5.0)", "ipfshttpclient (==0.8.0a2)", "isort (>=5.11.0)", "mock", "mypy (==0.910)", "pluggy (==0.13.1)", "py-geth (>=3.10.0)", "py-geth (>=3.9.1)", "py-solc-x (>=1.1.1)", "pytest (>=6.2.5)", "pytest-asyncio (>=0.18.1)", "pytest-mock (>=1.10)", "pytest-pythonpath (>=0.3)", "pytest-watch (>=4.2)", "pytest-xdist (>=1.29)", "setuptools (>=38.6.0)", "sphinx (>=4.2.0)", "sphinx-rtd-theme (>=0.5.2)", "toposort (>=1.4)", "towncrier (==18.5.0)", "tox (>=3.18.0)", "tqdm (>4.32)", "twine (>=1.13)", "types-protobuf (==3.19.13)", "types-requests (>=2.26.1)", "types-setuptools (>=57.4.4)", "urllib3", "wheel", "when-changed (>=0.3.0)"] -docs = ["click (>=5.1)", "configparser (==3.5.0)", "contextlib2 (>=0.5.4)", "mock", "py-geth (>=3.9.1)", "py-solc-x (>=1.1.1)", "pytest (>=6.2.5)", "sphinx (>=4.2.0)", "sphinx-rtd-theme (>=0.5.2)", "toposort (>=1.4)", "towncrier (==18.5.0)", "urllib3", "wheel"] +dev = ["build (>=0.9.0)", "bumpversion", "eth-tester[py-evm] (>=0.11.0b1,<0.12.0b1)", "eth-tester[py-evm] (>=0.9.0b1,<0.10.0b1)", "flaky (>=3.7.0)", "hypothesis (>=3.31.2)", "importlib-metadata (<5.0)", "ipfshttpclient (==0.8.0a2)", "pre-commit (>=2.21.0)", "py-geth (>=3.14.0)", "pytest (>=7.0.0)", "pytest-asyncio (>=0.21.2,<0.23)", "pytest-mock (>=1.10)", "pytest-watch (>=4.2)", "pytest-xdist (>=1.29)", "setuptools (>=38.6.0)", "sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)", "tox (>=3.18.0)", "tqdm (>4.32)", "twine (>=1.13)", "when-changed (>=0.3.0)"] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.0.0)", "towncrier (>=21,<22)"] ipfs = ["ipfshttpclient (==0.8.0a2)"] -linter = ["black (>=22.1.0)", "flake8 (==3.8.3)", "isort (>=5.11.0)", "mypy (==0.910)", "types-protobuf (==3.19.13)", "types-requests (>=2.26.1)", "types-setuptools (>=57.4.4)"] -tester = ["eth-tester[py-evm] (==v0.8.0-b.3)", "py-geth (>=3.10.0)"] +tester = ["eth-tester[py-evm] (>=0.11.0b1,<0.12.0b1)", "eth-tester[py-evm] (>=0.9.0b1,<0.10.0b1)", "py-geth (>=3.14.0)"] [[package]] name = "web3-multi-provider" version = "0.6.0" description = "Web3py provider that makes it easy to switch between different blockchain nodes to make sure application will be be online if main blockchain node will be unavailable." -category = "main" optional = false python-versions = ">=3.7.10,<4" files = [ @@ -2872,361 +2412,191 @@ files = [ [package.dependencies] web3 = ">=5.22.0,<7" -[[package]] -name = "webencodings" -version = "0.5.1" -description = "Character encoding aliases for legacy web content" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, - {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, -] - [[package]] name = "websockets" -version = "10.4" +version = "12.0" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "websockets-10.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d58804e996d7d2307173d56c297cf7bc132c52df27a3efaac5e8d43e36c21c48"}, - {file = "websockets-10.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc0b82d728fe21a0d03e65f81980abbbcb13b5387f733a1a870672c5be26edab"}, - {file = "websockets-10.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ba089c499e1f4155d2a3c2a05d2878a3428cf321c848f2b5a45ce55f0d7d310c"}, - {file = "websockets-10.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33d69ca7612f0ddff3316b0c7b33ca180d464ecac2d115805c044bf0a3b0d032"}, - {file = "websockets-10.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62e627f6b6d4aed919a2052efc408da7a545c606268d5ab5bfab4432734b82b4"}, - {file = "websockets-10.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ea7b82bfcae927eeffc55d2ffa31665dc7fec7b8dc654506b8e5a518eb4d50"}, - {file = "websockets-10.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e0cb5cc6ece6ffa75baccfd5c02cffe776f3f5c8bf486811f9d3ea3453676ce8"}, - {file = "websockets-10.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ae5e95cfb53ab1da62185e23b3130e11d64431179debac6dc3c6acf08760e9b1"}, - {file = "websockets-10.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7c584f366f46ba667cfa66020344886cf47088e79c9b9d39c84ce9ea98aaa331"}, - {file = "websockets-10.4-cp310-cp310-win32.whl", hash = "sha256:b029fb2032ae4724d8ae8d4f6b363f2cc39e4c7b12454df8df7f0f563ed3e61a"}, - {file = "websockets-10.4-cp310-cp310-win_amd64.whl", hash = "sha256:8dc96f64ae43dde92530775e9cb169979f414dcf5cff670455d81a6823b42089"}, - {file = "websockets-10.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:47a2964021f2110116cc1125b3e6d87ab5ad16dea161949e7244ec583b905bb4"}, - {file = "websockets-10.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e789376b52c295c4946403bd0efecf27ab98f05319df4583d3c48e43c7342c2f"}, - {file = "websockets-10.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7d3f0b61c45c3fa9a349cf484962c559a8a1d80dae6977276df8fd1fa5e3cb8c"}, - {file = "websockets-10.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f55b5905705725af31ccef50e55391621532cd64fbf0bc6f4bac935f0fccec46"}, - {file = "websockets-10.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00c870522cdb69cd625b93f002961ffb0c095394f06ba8c48f17eef7c1541f96"}, - {file = "websockets-10.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f38706e0b15d3c20ef6259fd4bc1700cd133b06c3c1bb108ffe3f8947be15fa"}, - {file = "websockets-10.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f2c38d588887a609191d30e902df2a32711f708abfd85d318ca9b367258cfd0c"}, - {file = "websockets-10.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fe10ddc59b304cb19a1bdf5bd0a7719cbbc9fbdd57ac80ed436b709fcf889106"}, - {file = "websockets-10.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:90fcf8929836d4a0e964d799a58823547df5a5e9afa83081761630553be731f9"}, - {file = "websockets-10.4-cp311-cp311-win32.whl", hash = "sha256:b9968694c5f467bf67ef97ae7ad4d56d14be2751000c1207d31bf3bb8860bae8"}, - {file = "websockets-10.4-cp311-cp311-win_amd64.whl", hash = "sha256:a7a240d7a74bf8d5cb3bfe6be7f21697a28ec4b1a437607bae08ac7acf5b4882"}, - {file = "websockets-10.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:74de2b894b47f1d21cbd0b37a5e2b2392ad95d17ae983e64727e18eb281fe7cb"}, - {file = "websockets-10.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3a686ecb4aa0d64ae60c9c9f1a7d5d46cab9bfb5d91a2d303d00e2cd4c4c5cc"}, - {file = "websockets-10.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d15c968ea7a65211e084f523151dbf8ae44634de03c801b8bd070b74e85033"}, - {file = "websockets-10.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00213676a2e46b6ebf6045bc11d0f529d9120baa6f58d122b4021ad92adabd41"}, - {file = "websockets-10.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:e23173580d740bf8822fd0379e4bf30aa1d5a92a4f252d34e893070c081050df"}, - {file = "websockets-10.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:dd500e0a5e11969cdd3320935ca2ff1e936f2358f9c2e61f100a1660933320ea"}, - {file = "websockets-10.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4239b6027e3d66a89446908ff3027d2737afc1a375f8fd3eea630a4842ec9a0c"}, - {file = "websockets-10.4-cp37-cp37m-win32.whl", hash = "sha256:8a5cc00546e0a701da4639aa0bbcb0ae2bb678c87f46da01ac2d789e1f2d2038"}, - {file = "websockets-10.4-cp37-cp37m-win_amd64.whl", hash = "sha256:a9f9a735deaf9a0cadc2d8c50d1a5bcdbae8b6e539c6e08237bc4082d7c13f28"}, - {file = "websockets-10.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5c1289596042fad2cdceb05e1ebf7aadf9995c928e0da2b7a4e99494953b1b94"}, - {file = "websockets-10.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0cff816f51fb33c26d6e2b16b5c7d48eaa31dae5488ace6aae468b361f422b63"}, - {file = "websockets-10.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:dd9becd5fe29773d140d68d607d66a38f60e31b86df75332703757ee645b6faf"}, - {file = "websockets-10.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45ec8e75b7dbc9539cbfafa570742fe4f676eb8b0d3694b67dabe2f2ceed8aa6"}, - {file = "websockets-10.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f72e5cd0f18f262f5da20efa9e241699e0cf3a766317a17392550c9ad7b37d8"}, - {file = "websockets-10.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:185929b4808b36a79c65b7865783b87b6841e852ef5407a2fb0c03381092fa3b"}, - {file = "websockets-10.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7d27a7e34c313b3a7f91adcd05134315002aaf8540d7b4f90336beafaea6217c"}, - {file = "websockets-10.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:884be66c76a444c59f801ac13f40c76f176f1bfa815ef5b8ed44321e74f1600b"}, - {file = "websockets-10.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:931c039af54fc195fe6ad536fde4b0de04da9d5916e78e55405436348cfb0e56"}, - {file = "websockets-10.4-cp38-cp38-win32.whl", hash = "sha256:db3c336f9eda2532ec0fd8ea49fef7a8df8f6c804cdf4f39e5c5c0d4a4ad9a7a"}, - {file = "websockets-10.4-cp38-cp38-win_amd64.whl", hash = "sha256:48c08473563323f9c9debac781ecf66f94ad5a3680a38fe84dee5388cf5acaf6"}, - {file = "websockets-10.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:40e826de3085721dabc7cf9bfd41682dadc02286d8cf149b3ad05bff89311e4f"}, - {file = "websockets-10.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:56029457f219ade1f2fc12a6504ea61e14ee227a815531f9738e41203a429112"}, - {file = "websockets-10.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f5fc088b7a32f244c519a048c170f14cf2251b849ef0e20cbbb0fdf0fdaf556f"}, - {file = "websockets-10.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fc8709c00704194213d45e455adc106ff9e87658297f72d544220e32029cd3d"}, - {file = "websockets-10.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0154f7691e4fe6c2b2bc275b5701e8b158dae92a1ab229e2b940efe11905dff4"}, - {file = "websockets-10.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c6d2264f485f0b53adf22697ac11e261ce84805c232ed5dbe6b1bcb84b00ff0"}, - {file = "websockets-10.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9bc42e8402dc5e9905fb8b9649f57efcb2056693b7e88faa8fb029256ba9c68c"}, - {file = "websockets-10.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:edc344de4dac1d89300a053ac973299e82d3db56330f3494905643bb68801269"}, - {file = "websockets-10.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:84bc2a7d075f32f6ed98652db3a680a17a4edb21ca7f80fe42e38753a58ee02b"}, - {file = "websockets-10.4-cp39-cp39-win32.whl", hash = "sha256:c94ae4faf2d09f7c81847c63843f84fe47bf6253c9d60b20f25edfd30fb12588"}, - {file = "websockets-10.4-cp39-cp39-win_amd64.whl", hash = "sha256:bbccd847aa0c3a69b5f691a84d2341a4f8a629c6922558f2a70611305f902d74"}, - {file = "websockets-10.4-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:82ff5e1cae4e855147fd57a2863376ed7454134c2bf49ec604dfe71e446e2193"}, - {file = "websockets-10.4-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d210abe51b5da0ffdbf7b43eed0cfdff8a55a1ab17abbec4301c9ff077dd0342"}, - {file = "websockets-10.4-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:942de28af58f352a6f588bc72490ae0f4ccd6dfc2bd3de5945b882a078e4e179"}, - {file = "websockets-10.4-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9b27d6c1c6cd53dc93614967e9ce00ae7f864a2d9f99fe5ed86706e1ecbf485"}, - {file = "websockets-10.4-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:3d3cac3e32b2c8414f4f87c1b2ab686fa6284a980ba283617404377cd448f631"}, - {file = "websockets-10.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:da39dd03d130162deb63da51f6e66ed73032ae62e74aaccc4236e30edccddbb0"}, - {file = "websockets-10.4-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:389f8dbb5c489e305fb113ca1b6bdcdaa130923f77485db5b189de343a179393"}, - {file = "websockets-10.4-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09a1814bb15eff7069e51fed0826df0bc0702652b5cb8f87697d469d79c23576"}, - {file = "websockets-10.4-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff64a1d38d156d429404aaa84b27305e957fd10c30e5880d1765c9480bea490f"}, - {file = "websockets-10.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b343f521b047493dc4022dd338fc6db9d9282658862756b4f6fd0e996c1380e1"}, - {file = "websockets-10.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:932af322458da7e4e35df32f050389e13d3d96b09d274b22a7aa1808f292fee4"}, - {file = "websockets-10.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a4162139374a49eb18ef5b2f4da1dd95c994588f5033d64e0bbfda4b6b6fcf"}, - {file = "websockets-10.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c57e4c1349fbe0e446c9fa7b19ed2f8a4417233b6984277cce392819123142d3"}, - {file = "websockets-10.4-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b627c266f295de9dea86bd1112ed3d5fafb69a348af30a2422e16590a8ecba13"}, - {file = "websockets-10.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:05a7233089f8bd355e8cbe127c2e8ca0b4ea55467861906b80d2ebc7db4d6b72"}, - {file = "websockets-10.4.tar.gz", hash = "sha256:eef610b23933c54d5d921c92578ae5f89813438fded840c2e9809d378dc765d3"}, -] - -[[package]] -name = "wrapt" -version = "1.14.1" -description = "Module for decorators, wrappers and monkey patching." -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -files = [ - {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, - {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"}, - {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"}, - {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"}, - {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"}, - {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"}, - {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"}, - {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"}, - {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"}, - {file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"}, - {file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"}, - {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"}, - {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"}, - {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"}, - {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"}, - {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"}, - {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"}, - {file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"}, - {file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"}, - {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"}, - {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"}, - {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"}, - {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"}, - {file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"}, - {file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"}, - {file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"}, - {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"}, - {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"}, - {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"}, - {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"}, - {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"}, - {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"}, - {file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"}, - {file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"}, - {file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"}, - {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"}, - {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"}, - {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"}, - {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"}, - {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"}, - {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"}, - {file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"}, - {file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"}, - {file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"}, - {file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"}, - {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"}, - {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"}, - {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"}, - {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"}, - {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"}, - {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"}, - {file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"}, - {file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"}, - {file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"}, - {file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"}, - {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"}, - {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"}, - {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"}, - {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"}, - {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"}, - {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"}, - {file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"}, - {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, - {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, -] - -[[package]] -name = "xattr" -version = "0.10.1" -description = "Python wrapper for extended filesystem attributes" -category = "main" optional = false -python-versions = "*" -files = [ - {file = "xattr-0.10.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:16a660a883e703b311d1bbbcafc74fa877585ec081cd96e8dd9302c028408ab1"}, - {file = "xattr-0.10.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1e2973e72faa87ca29d61c23b58c3c89fe102d1b68e091848b0e21a104123503"}, - {file = "xattr-0.10.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:13279fe8f7982e3cdb0e088d5cb340ce9cbe5ef92504b1fd80a0d3591d662f68"}, - {file = "xattr-0.10.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1dc9b9f580ef4b8ac5e2c04c16b4d5086a611889ac14ecb2e7e87170623a0b75"}, - {file = "xattr-0.10.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:485539262c2b1f5acd6b6ea56e0da2bc281a51f74335c351ea609c23d82c9a79"}, - {file = "xattr-0.10.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:295b3ab335fcd06ca0a9114439b34120968732e3f5e9d16f456d5ec4fa47a0a2"}, - {file = "xattr-0.10.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:a126eb38e14a2f273d584a692fe36cff760395bf7fc061ef059224efdb4eb62c"}, - {file = "xattr-0.10.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:b0e919c24f5b74428afa91507b15e7d2ef63aba98e704ad13d33bed1288dca81"}, - {file = "xattr-0.10.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:e31d062cfe1aaeab6ba3db6bd255f012d105271018e647645941d6609376af18"}, - {file = "xattr-0.10.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:209fb84c09b41c2e4cf16dd2f481bb4a6e2e81f659a47a60091b9bcb2e388840"}, - {file = "xattr-0.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c4120090dac33eddffc27e487f9c8f16b29ff3f3f8bcb2251b2c6c3f974ca1e1"}, - {file = "xattr-0.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3e739d624491267ec5bb740f4eada93491de429d38d2fcdfb97b25efe1288eca"}, - {file = "xattr-0.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2677d40b95636f3482bdaf64ed9138fb4d8376fb7933f434614744780e46e42d"}, - {file = "xattr-0.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40039f1532c4456fd0f4c54e9d4e01eb8201248c321c6c6856262d87e9a99593"}, - {file = "xattr-0.10.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:148466e5bb168aba98f80850cf976e931469a3c6eb11e9880d9f6f8b1e66bd06"}, - {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0aedf55b116beb6427e6f7958ccd80a8cbc80e82f87a4cd975ccb61a8d27b2ee"}, - {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c3024a9ff157247c8190dd0eb54db4a64277f21361b2f756319d9d3cf20e475f"}, - {file = "xattr-0.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f1be6e733e9698f645dbb98565bb8df9b75e80e15a21eb52787d7d96800e823b"}, - {file = "xattr-0.10.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7880c8a54c18bc091a4ce0adc5c6d81da1c748aec2fe7ac586d204d6ec7eca5b"}, - {file = "xattr-0.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:89c93b42c3ba8aedbc29da759f152731196c2492a2154371c0aae3ef8ba8301b"}, - {file = "xattr-0.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6b905e808df61b677eb972f915f8a751960284358b520d0601c8cbc476ba2df6"}, - {file = "xattr-0.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1ef954d0655f93a34d07d0cc7e02765ec779ff0b59dc898ee08c6326ad614d5"}, - {file = "xattr-0.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:199b20301b6acc9022661412346714ce764d322068ef387c4de38062474db76c"}, - {file = "xattr-0.10.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec0956a8ab0f0d3f9011ba480f1e1271b703d11542375ef73eb8695a6bd4b78b"}, - {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ffcb57ca1be338d69edad93cf59aac7c6bb4dbb92fd7bf8d456c69ea42f7e6d2"}, - {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f0563196ee54756fe2047627d316977dc77d11acd7a07970336e1a711e934db"}, - {file = "xattr-0.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc354f086f926a1c7f04886f97880fed1a26d20e3bc338d0d965fd161dbdb8ab"}, - {file = "xattr-0.10.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c0cd2d02ef2fb45ecf2b0da066a58472d54682c6d4f0452dfe7ae2f3a76a42ea"}, - {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49626096ddd72dcc1654aadd84b103577d8424f26524a48d199847b5d55612d0"}, - {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ceaa26bef8fcb17eb59d92a7481c2d15d20211e217772fb43c08c859b01afc6a"}, - {file = "xattr-0.10.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8c014c371391f28f8cd27d73ea59f42b30772cd640b5a2538ad4f440fd9190b"}, - {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:46c32cd605673606b9388a313b0050ee7877a0640d7561eea243ace4fa2cc5a6"}, - {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:772b22c4ff791fe5816a7c2a1c9fcba83f9ab9bea138eb44d4d70f34676232b4"}, - {file = "xattr-0.10.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:183ad611a2d70b5a3f5f7aadef0fcef604ea33dcf508228765fd4ddac2c7321d"}, - {file = "xattr-0.10.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8068df3ebdfa9411e58d5ae4a05d807ec5994645bb01af66ec9f6da718b65c5b"}, - {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bc40570155beb85e963ae45300a530223d9822edfdf09991b880e69625ba38a"}, - {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:436e1aaf23c07e15bed63115f1712d2097e207214fc6bcde147c1efede37e2c5"}, - {file = "xattr-0.10.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7298455ccf3a922d403339781b10299b858bb5ec76435445f2da46fb768e31a5"}, - {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:986c2305c6c1a08f78611eb38ef9f1f47682774ce954efb5a4f3715e8da00d5f"}, - {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5dc6099e76e33fa3082a905fe59df766b196534c705cf7a2e3ad9bed2b8a180e"}, - {file = "xattr-0.10.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:042ad818cda6013162c0bfd3816f6b74b7700e73c908cde6768da824686885f8"}, - {file = "xattr-0.10.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:9d4c306828a45b41b76ca17adc26ac3dc00a80e01a5ba85d71df2a3e948828f2"}, - {file = "xattr-0.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a606280b0c9071ef52572434ecd3648407b20df3d27af02c6592e84486b05894"}, - {file = "xattr-0.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5b49d591cf34cda2079fd7a5cb2a7a1519f54dc2e62abe3e0720036f6ed41a85"}, - {file = "xattr-0.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b8705ac6791426559c1a5c2b88bb2f0e83dc5616a09b4500899bfff6a929302"}, - {file = "xattr-0.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5ea974930e876bc5c146f54ac0f85bb39b7b5de2b6fc63f90364712ae368ebe"}, - {file = "xattr-0.10.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f55a2dd73a12a1ae5113c5d9cd4b4ab6bf7950f4d76d0a1a0c0c4264d50da61d"}, - {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:475c38da0d3614cc5564467c4efece1e38bd0705a4dbecf8deeb0564a86fb010"}, - {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:925284a4a28e369459b2b7481ea22840eed3e0573a4a4c06b6b0614ecd27d0a7"}, - {file = "xattr-0.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa32f1b45fed9122bed911de0fcc654da349e1f04fa4a9c8ef9b53e1cc98b91e"}, - {file = "xattr-0.10.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c5d3d0e728bace64b74c475eb4da6148cd172b2d23021a1dcd055d92f17619ac"}, - {file = "xattr-0.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8faaacf311e2b5cc67c030c999167a78a9906073e6abf08eaa8cf05b0416515c"}, - {file = "xattr-0.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cc6b8d5ca452674e1a96e246a3d2db5f477aecbc7c945c73f890f56323e75203"}, - {file = "xattr-0.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3725746a6502f40f72ef27e0c7bfc31052a239503ff3eefa807d6b02a249be22"}, - {file = "xattr-0.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:789bd406d1aad6735e97b20c6d6a1701e1c0661136be9be862e6a04564da771f"}, - {file = "xattr-0.10.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9a7a807ab538210ff8532220d8fc5e2d51c212681f63dbd4e7ede32543b070f"}, - {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3e5825b5fc99ecdd493b0cc09ec35391e7a451394fdf623a88b24726011c950d"}, - {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:80638d1ce7189dc52f26c234cee3522f060fadab6a8bc3562fe0ddcbe11ba5a4"}, - {file = "xattr-0.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3ff0dbe4a6ce2ce065c6de08f415bcb270ecfd7bf1655a633ddeac695ce8b250"}, - {file = "xattr-0.10.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5267e5f9435c840d2674194150b511bef929fa7d3bc942a4a75b9eddef18d8d8"}, - {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b27dfc13b193cb290d5d9e62f806bb9a99b00cd73bb6370d556116ad7bb5dc12"}, - {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:636ebdde0277bce4d12d2ef2550885804834418fee0eb456b69be928e604ecc4"}, - {file = "xattr-0.10.1-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d60c27922ec80310b45574351f71e0dd3a139c5295e8f8b19d19c0010196544f"}, - {file = "xattr-0.10.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b34df5aad035d0343bd740a95ca30db99b776e2630dca9cc1ba8e682c9cc25ea"}, - {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f24a7c04ff666d0fe905dfee0a84bc899d624aeb6dccd1ea86b5c347f15c20c1"}, - {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3878e1aff8eca64badad8f6d896cb98c52984b1e9cd9668a3ab70294d1ef92d"}, - {file = "xattr-0.10.1-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4abef557028c551d59cf2fb3bf63f2a0c89f00d77e54c1c15282ecdd56943496"}, - {file = "xattr-0.10.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0e14bd5965d3db173d6983abdc1241c22219385c22df8b0eb8f1846c15ce1fee"}, - {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f9be588a4b6043b03777d50654c6079af3da60cc37527dbb80d36ec98842b1e"}, - {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bc4ae264aa679aacf964abf3ea88e147eb4a22aea6af8c6d03ebdebd64cfd6"}, - {file = "xattr-0.10.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:827b5a97673b9997067fde383a7f7dc67342403093b94ea3c24ae0f4f1fec649"}, - {file = "xattr-0.10.1.tar.gz", hash = "sha256:c12e7d81ffaa0605b3ac8c22c2994a8e18a9cf1c59287a1b7722a2289c952ec5"}, +python-versions = ">=3.8" +files = [ + {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"}, + {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"}, + {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"}, + {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"}, + {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"}, + {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"}, + {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"}, + {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"}, + {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"}, + {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"}, + {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"}, + {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"}, + {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"}, + {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"}, + {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"}, + {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"}, + {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"}, + {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"}, + {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"}, + {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"}, + {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"}, + {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"}, + {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"}, + {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"}, + {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"}, + {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"}, + {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"}, + {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"}, + {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"}, + {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"}, + {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"}, + {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"}, + {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"}, + {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"}, + {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"}, + {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"}, + {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"}, + {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"}, + {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"}, + {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"}, + {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"}, + {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"}, ] -[package.dependencies] -cffi = ">=1.0" - [[package]] name = "yarl" -version = "1.8.2" +version = "1.9.4" description = "Yet another URL library" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "yarl-1.8.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bb81f753c815f6b8e2ddd2eef3c855cf7da193b82396ac013c661aaa6cc6b0a5"}, - {file = "yarl-1.8.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:47d49ac96156f0928f002e2424299b2c91d9db73e08c4cd6742923a086f1c863"}, - {file = "yarl-1.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3fc056e35fa6fba63248d93ff6e672c096f95f7836938241ebc8260e062832fe"}, - {file = "yarl-1.8.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58a3c13d1c3005dbbac5c9f0d3210b60220a65a999b1833aa46bd6677c69b08e"}, - {file = "yarl-1.8.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10b08293cda921157f1e7c2790999d903b3fd28cd5c208cf8826b3b508026996"}, - {file = "yarl-1.8.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de986979bbd87272fe557e0a8fcb66fd40ae2ddfe28a8b1ce4eae22681728fef"}, - {file = "yarl-1.8.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c4fcfa71e2c6a3cb568cf81aadc12768b9995323186a10827beccf5fa23d4f8"}, - {file = "yarl-1.8.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae4d7ff1049f36accde9e1ef7301912a751e5bae0a9d142459646114c70ecba6"}, - {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bf071f797aec5b96abfc735ab97da9fd8f8768b43ce2abd85356a3127909d146"}, - {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:74dece2bfc60f0f70907c34b857ee98f2c6dd0f75185db133770cd67300d505f"}, - {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:df60a94d332158b444301c7f569659c926168e4d4aad2cfbf4bce0e8fb8be826"}, - {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:63243b21c6e28ec2375f932a10ce7eda65139b5b854c0f6b82ed945ba526bff3"}, - {file = "yarl-1.8.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cfa2bbca929aa742b5084fd4663dd4b87c191c844326fcb21c3afd2d11497f80"}, - {file = "yarl-1.8.2-cp310-cp310-win32.whl", hash = "sha256:b05df9ea7496df11b710081bd90ecc3a3db6adb4fee36f6a411e7bc91a18aa42"}, - {file = "yarl-1.8.2-cp310-cp310-win_amd64.whl", hash = "sha256:24ad1d10c9db1953291f56b5fe76203977f1ed05f82d09ec97acb623a7976574"}, - {file = "yarl-1.8.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2a1fca9588f360036242f379bfea2b8b44cae2721859b1c56d033adfd5893634"}, - {file = "yarl-1.8.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f37db05c6051eff17bc832914fe46869f8849de5b92dc4a3466cd63095d23dfd"}, - {file = "yarl-1.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:77e913b846a6b9c5f767b14dc1e759e5aff05502fe73079f6f4176359d832581"}, - {file = "yarl-1.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0978f29222e649c351b173da2b9b4665ad1feb8d1daa9d971eb90df08702668a"}, - {file = "yarl-1.8.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388a45dc77198b2460eac0aca1efd6a7c09e976ee768b0d5109173e521a19daf"}, - {file = "yarl-1.8.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2305517e332a862ef75be8fad3606ea10108662bc6fe08509d5ca99503ac2aee"}, - {file = "yarl-1.8.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42430ff511571940d51e75cf42f1e4dbdded477e71c1b7a17f4da76c1da8ea76"}, - {file = "yarl-1.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3150078118f62371375e1e69b13b48288e44f6691c1069340081c3fd12c94d5b"}, - {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c15163b6125db87c8f53c98baa5e785782078fbd2dbeaa04c6141935eb6dab7a"}, - {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4d04acba75c72e6eb90745447d69f84e6c9056390f7a9724605ca9c56b4afcc6"}, - {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e7fd20d6576c10306dea2d6a5765f46f0ac5d6f53436217913e952d19237efc4"}, - {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:75c16b2a900b3536dfc7014905a128a2bea8fb01f9ee26d2d7d8db0a08e7cb2c"}, - {file = "yarl-1.8.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6d88056a04860a98341a0cf53e950e3ac9f4e51d1b6f61a53b0609df342cc8b2"}, - {file = "yarl-1.8.2-cp311-cp311-win32.whl", hash = "sha256:fb742dcdd5eec9f26b61224c23baea46c9055cf16f62475e11b9b15dfd5c117b"}, - {file = "yarl-1.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:8c46d3d89902c393a1d1e243ac847e0442d0196bbd81aecc94fcebbc2fd5857c"}, - {file = "yarl-1.8.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ceff9722e0df2e0a9e8a79c610842004fa54e5b309fe6d218e47cd52f791d7ef"}, - {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f6b4aca43b602ba0f1459de647af954769919c4714706be36af670a5f44c9c1"}, - {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1684a9bd9077e922300ecd48003ddae7a7474e0412bea38d4631443a91d61077"}, - {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ebb78745273e51b9832ef90c0898501006670d6e059f2cdb0e999494eb1450c2"}, - {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3adeef150d528ded2a8e734ebf9ae2e658f4c49bf413f5f157a470e17a4a2e89"}, - {file = "yarl-1.8.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57a7c87927a468e5a1dc60c17caf9597161d66457a34273ab1760219953f7f4c"}, - {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:efff27bd8cbe1f9bd127e7894942ccc20c857aa8b5a0327874f30201e5ce83d0"}, - {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a783cd344113cb88c5ff7ca32f1f16532a6f2142185147822187913eb989f739"}, - {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:705227dccbe96ab02c7cb2c43e1228e2826e7ead880bb19ec94ef279e9555b5b"}, - {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:34c09b43bd538bf6c4b891ecce94b6fa4f1f10663a8d4ca589a079a5018f6ed7"}, - {file = "yarl-1.8.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a48f4f7fea9a51098b02209d90297ac324241bf37ff6be6d2b0149ab2bd51b37"}, - {file = "yarl-1.8.2-cp37-cp37m-win32.whl", hash = "sha256:0414fd91ce0b763d4eadb4456795b307a71524dbacd015c657bb2a39db2eab89"}, - {file = "yarl-1.8.2-cp37-cp37m-win_amd64.whl", hash = "sha256:d881d152ae0007809c2c02e22aa534e702f12071e6b285e90945aa3c376463c5"}, - {file = "yarl-1.8.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5df5e3d04101c1e5c3b1d69710b0574171cc02fddc4b23d1b2813e75f35a30b1"}, - {file = "yarl-1.8.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7a66c506ec67eb3159eea5096acd05f5e788ceec7b96087d30c7d2865a243918"}, - {file = "yarl-1.8.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2b4fa2606adf392051d990c3b3877d768771adc3faf2e117b9de7eb977741229"}, - {file = "yarl-1.8.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e21fb44e1eff06dd6ef971d4bdc611807d6bd3691223d9c01a18cec3677939e"}, - {file = "yarl-1.8.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93202666046d9edadfe9f2e7bf5e0782ea0d497b6d63da322e541665d65a044e"}, - {file = "yarl-1.8.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fc77086ce244453e074e445104f0ecb27530d6fd3a46698e33f6c38951d5a0f1"}, - {file = "yarl-1.8.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dd68a92cab699a233641f5929a40f02a4ede8c009068ca8aa1fe87b8c20ae3"}, - {file = "yarl-1.8.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b372aad2b5f81db66ee7ec085cbad72c4da660d994e8e590c997e9b01e44901"}, - {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e6f3515aafe0209dd17fb9bdd3b4e892963370b3de781f53e1746a521fb39fc0"}, - {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:dfef7350ee369197106805e193d420b75467b6cceac646ea5ed3049fcc950a05"}, - {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:728be34f70a190566d20aa13dc1f01dc44b6aa74580e10a3fb159691bc76909d"}, - {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:ff205b58dc2929191f68162633d5e10e8044398d7a45265f90a0f1d51f85f72c"}, - {file = "yarl-1.8.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:baf211dcad448a87a0d9047dc8282d7de59473ade7d7fdf22150b1d23859f946"}, - {file = "yarl-1.8.2-cp38-cp38-win32.whl", hash = "sha256:272b4f1599f1b621bf2aabe4e5b54f39a933971f4e7c9aa311d6d7dc06965165"}, - {file = "yarl-1.8.2-cp38-cp38-win_amd64.whl", hash = "sha256:326dd1d3caf910cd26a26ccbfb84c03b608ba32499b5d6eeb09252c920bcbe4f"}, - {file = "yarl-1.8.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f8ca8ad414c85bbc50f49c0a106f951613dfa5f948ab69c10ce9b128d368baf8"}, - {file = "yarl-1.8.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:418857f837347e8aaef682679f41e36c24250097f9e2f315d39bae3a99a34cbf"}, - {file = "yarl-1.8.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ae0eec05ab49e91a78700761777f284c2df119376e391db42c38ab46fd662b77"}, - {file = "yarl-1.8.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:009a028127e0a1755c38b03244c0bea9d5565630db9c4cf9572496e947137a87"}, - {file = "yarl-1.8.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3edac5d74bb3209c418805bda77f973117836e1de7c000e9755e572c1f7850d0"}, - {file = "yarl-1.8.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da65c3f263729e47351261351b8679c6429151ef9649bba08ef2528ff2c423b2"}, - {file = "yarl-1.8.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ef8fb25e52663a1c85d608f6dd72e19bd390e2ecaf29c17fb08f730226e3a08"}, - {file = "yarl-1.8.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcd7bb1e5c45274af9a1dd7494d3c52b2be5e6bd8d7e49c612705fd45420b12d"}, - {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44ceac0450e648de86da8e42674f9b7077d763ea80c8ceb9d1c3e41f0f0a9951"}, - {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:97209cc91189b48e7cfe777237c04af8e7cc51eb369004e061809bcdf4e55220"}, - {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:48dd18adcf98ea9cd721a25313aef49d70d413a999d7d89df44f469edfb38a06"}, - {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e59399dda559688461762800d7fb34d9e8a6a7444fd76ec33220a926c8be1516"}, - {file = "yarl-1.8.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d617c241c8c3ad5c4e78a08429fa49e4b04bedfc507b34b4d8dceb83b4af3588"}, - {file = "yarl-1.8.2-cp39-cp39-win32.whl", hash = "sha256:cb6d48d80a41f68de41212f3dfd1a9d9898d7841c8f7ce6696cf2fd9cb57ef83"}, - {file = "yarl-1.8.2-cp39-cp39-win_amd64.whl", hash = "sha256:6604711362f2dbf7160df21c416f81fac0de6dbcf0b5445a2ef25478ecc4c778"}, - {file = "yarl-1.8.2.tar.gz", hash = "sha256:49d43402c6e3013ad0978602bf6bf5328535c48d192304b91b97a3c6790b1562"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, + {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, + {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, + {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, + {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, + {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, + {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, + {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, + {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, + {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, + {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, + {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, + {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, + {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, + {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, + {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, ] [package.dependencies] idna = ">=2.0" multidict = ">=4.0" -[[package]] -name = "zipp" -version = "3.14.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" -optional = false -python-versions = ">=3.7" -files = [ - {file = "zipp-3.14.0-py3-none-any.whl", hash = "sha256:188834565033387710d046e3fe96acfc9b5e86cbca7f39ff69cf21a4128198b7"}, - {file = "zipp-3.14.0.tar.gz", hash = "sha256:9e5421e176ef5ab4c0ad896624e87a7b2f07aca746c9b2aa305952800cb8eecb"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - [metadata] lock-version = "2.0" -python-versions = "^3.11" -content-hash = "38edf3fe6968ec179ae684e5091f22d0fec4cfb5114f4e55740bceb3a29ca5f2" +python-versions = "^3.12" +content-hash = "6476dd65625dc6b9285db39294c10e455ab2cc8d90641af2aac337d42379e986" diff --git a/pyproject.toml b/pyproject.toml index 3bf7c31bd..9728e2bd4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,35 +1,38 @@ [tool.poetry] name = "lido-oracle" -version = "3.0.0" +version = "4.0.0-rc.1" description = "Oracle daemon for Lido decentralized staking service. Collects and reports Ethereum 2.0 beacon chain states (the number of visible validators and their summarized balances) to the Lido dApp contract running on Ethereum 1.0 side." authors = [ + "Dmitry Chernukhin", + "Dmitry Suldin", + "George Avsetsin", + "Kirill Varlamov", "Raman Siamionau", "Roman Kolpakov", - "Vladimir Gorkavenko", - "Sergey Khomutinin", "Sergey Ivanenko", - "George Avsetsin", - "Kirill Varlamov", + "Sergey Khomutinin", "Smelov Vladimir", - "Dmitry Suldin", + "Vladimir Gorkavenko", ] license = "GPL 3.0" [tool.poetry.dependencies] -python = "^3.11" -web3 = "6.0.0b10" +python = "^3.12" prometheus-client = "^0.16.0" timeout-decorator = "^0.5.0" pytest = "^7.2.1" -poetry = "^1.3.2" pytest-xdist = "^3.2.1" +more-itertools = "^10.1.0" +web3 = "^6.10.0" web3-multi-provider = "^0.6.0" +json-stream = "^2.3.2" +lazy-object-proxy = "^1.9.0" +oz-merkle-tree = {git = "https://github.com/lidofinance/oz-merkle-tree"} [tool.poetry.group.dev.dependencies] base58 = "^2.1.1" ipfshttpclient = "^0.7.0" -pylint = "^2.16.2" -mypy = "^1.0.1" +pydantic = "1.10.6" pytest-cov = "^4.0.0" pydantic-factories = "^1.17.2" # {{{ stubs for mypy @@ -39,6 +42,8 @@ types-urllib3 = "^1.26.25.8" # }}} hypothesis = "^6.68.2" black = "^23.3.0" +pylint = "^3.2.3" +mypy = "^1.10.0" [build-system] requires = ["poetry-core>=1.0.0"] @@ -51,14 +56,14 @@ markers = [ "possible_integration: tests with using providers, but can be run using mocks", "e2e: complex tests with using providers and real Ethereum network", ] -addopts = "-s --pdbcls pudb.debugger:Debugger" +addopts = "-s -vv --pdbcls pudb.debugger:Debugger" [tool.coverage.run] branch = true [tool.pylint.format] max-line-length = "120" - +min-similarity-lines=6 [tool.pylint."messages control"] disable = [ @@ -94,8 +99,10 @@ disable = [ ] [tool.mypy] +python_version = "3.12" strict_equality = true mypy_path = "stubs" +disable_error_code = "valid-type,name-defined" [[tool.mypy.overrides]] module = "src.web3py.contract_tweak" @@ -104,3 +111,9 @@ ignore_errors = true # skipped because of extensive copy-paste from the upstrea [tool.black] line-length = 120 skip-string-normalization = true + +[tool.ruff] +line-length = 120 + +[tool.ruff.format] +quote-style = "preserve" diff --git a/src/constants.py b/src/constants.py index bb0fb327d..c0e7d54e8 100644 --- a/src/constants.py +++ b/src/constants.py @@ -18,6 +18,8 @@ # https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator-cycle MIN_PER_EPOCH_CHURN_LIMIT = 2 ** 2 CHURN_LIMIT_QUOTIENT = 2 ** 16 +# https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#time-parameters +SLOTS_PER_HISTORICAL_ROOT = 8192 # Local constants GWEI_TO_WEI = 10 ** 9 @@ -25,3 +27,5 @@ TOTAL_BASIS_POINTS = 10000 MAX_BLOCK_GAS_LIMIT = 30_000_000 + +UINT64_MAX = 2**64 - 1 diff --git a/src/main.py b/src/main.py index 01be0bcbb..287f54fb5 100644 --- a/src/main.py +++ b/src/main.py @@ -1,5 +1,5 @@ import sys -from typing import cast +from typing import Iterable, cast from prometheus_client import start_http_server from web3.middleware import simple_cache_middleware @@ -11,7 +11,9 @@ from src.modules.accounting.accounting import Accounting from src.modules.ejector.ejector import Ejector from src.modules.checks.checks_module import ChecksModule -from src.typings import OracleModule +from src.modules.csm.csm import CSOracle +from src.providers.ipfs import GW3, IPFSProvider, MultiIPFSProvider, Pinata, PublicIPFS +from src.types import OracleModule from src.utils.build import get_build_info from src.web3py.extensions import ( LidoContracts, @@ -19,10 +21,11 @@ ConsensusClientModule, KeysAPIClientModule, LidoValidatorsProvider, - FallbackProviderModule + FallbackProviderModule, + LazyCSM ) from src.web3py.middleware import metrics_collector -from src.web3py.typings import Web3 +from src.web3py.types import Web3 from src.web3py.contract_tweak import tweak_w3_contracts @@ -39,12 +42,15 @@ def main(module_name: OracleModule): 'module': module_name, 'ACCOUNT': variables.ACCOUNT.address if variables.ACCOUNT else 'Dry', 'LIDO_LOCATOR_ADDRESS': variables.LIDO_LOCATOR_ADDRESS, + 'CSM_MODULE_ADDRESS': variables.CSM_MODULE_ADDRESS, + 'FINALIZATION_BATCH_MAX_REQUEST_COUNT': variables.FINALIZATION_BATCH_MAX_REQUEST_COUNT, 'MAX_CYCLE_LIFETIME_IN_SECONDS': variables.MAX_CYCLE_LIFETIME_IN_SECONDS, }, }) ENV_VARIABLES_INFO.info({ "ACCOUNT": str(variables.ACCOUNT.address) if variables.ACCOUNT else 'Dry', "LIDO_LOCATOR_ADDRESS": str(variables.LIDO_LOCATOR_ADDRESS), + "CSM_MODULE_ADDRESS": str(variables.CSM_MODULE_ADDRESS), "FINALIZATION_BATCH_MAX_REQUEST_COUNT": str(variables.FINALIZATION_BATCH_MAX_REQUEST_COUNT), "MAX_CYCLE_LIFETIME_IN_SECONDS": str(variables.MAX_CYCLE_LIFETIME_IN_SECONDS), }) @@ -71,14 +77,23 @@ def main(module_name: OracleModule): logger.info({'msg': 'Initialize keys api client.'}) kac = KeysAPIClientModule(variables.KEYS_API_URI, web3) + logger.info({'msg': 'Initialize IPFS providers.'}) + ipfs = MultiIPFSProvider( + ipfs_providers(), + retries=variables.HTTP_REQUEST_RETRY_COUNT_IPFS, + ) + + logger.info({'msg': 'Check configured providers.'}) check_providers_chain_ids(web3, cc, kac) web3.attach_modules({ 'lido_contracts': LidoContracts, 'lido_validators': LidoValidatorsProvider, 'transaction': TransactionUtils, + 'csm': LazyCSM, 'cc': lambda: cc, # type: ignore[dict-item] 'kac': lambda: kac, # type: ignore[dict-item] + 'ipfs': lambda: ipfs, # type: ignore[dict-item] }) logger.info({'msg': 'Add metrics middleware for ETH1 requests.'}) @@ -87,12 +102,16 @@ def main(module_name: OracleModule): logger.info({'msg': 'Sanity checks.'}) + instance: Accounting | Ejector | CSOracle if module_name == OracleModule.ACCOUNTING: logger.info({'msg': 'Initialize Accounting module.'}) instance = Accounting(web3) elif module_name == OracleModule.EJECTOR: logger.info({'msg': 'Initialize Ejector module.'}) - instance = Ejector(web3) # type: ignore[assignment] + instance = Ejector(web3) + elif module_name == OracleModule.CSM: + logger.info({'msg': 'Initialize CSM performance oracle module.'}) + instance = CSOracle(web3) else: raise ValueError(f'Unexpected arg: {module_name=}.') @@ -124,6 +143,23 @@ def check_providers_chain_ids(web3: Web3, cc: ConsensusClientModule, kac: KeysAP f'Keys API chain id: {keys_api_chain_id}\n') +def ipfs_providers() -> Iterable[IPFSProvider]: + if variables.GW3_ACCESS_KEY and variables.GW3_SECRET_KEY: + yield GW3( + variables.GW3_ACCESS_KEY, + variables.GW3_SECRET_KEY, + timeout=variables.HTTP_REQUEST_TIMEOUT_IPFS, + ) + + if variables.PINATA_JWT: + yield Pinata( + variables.PINATA_JWT, + timeout=variables.HTTP_REQUEST_TIMEOUT_IPFS, + ) + + yield PublicIPFS(timeout=variables.HTTP_REQUEST_TIMEOUT_IPFS) + + if __name__ == '__main__': module_name_arg = sys.argv[-1] if module_name_arg not in iter(OracleModule): diff --git a/src/metrics/healthcheck_server.py b/src/metrics/healthcheck_server.py index f7fc80a76..83c5efe40 100644 --- a/src/metrics/healthcheck_server.py +++ b/src/metrics/healthcheck_server.py @@ -1,19 +1,25 @@ +import logging import threading from datetime import datetime, timedelta from http.server import SimpleHTTPRequestHandler, HTTPServer import requests +from requests.exceptions import ConnectionError as RequestsConnectionError from src import variables from src.variables import MAX_CYCLE_LIFETIME_IN_SECONDS _last_pulse = datetime.now() +logger = logging.getLogger(__name__) def pulse(): """Ping to healthcheck server that application is ok""" - requests.get(f'http://localhost:{variables.HEALTHCHECK_SERVER_PORT}/pulse/', timeout=10) + try: + requests.get(f'http://localhost:{variables.HEALTHCHECK_SERVER_PORT}/pulse/', timeout=10) + except RequestsConnectionError: + logger.warning({'Healthcheck server is not responding.'}) class PulseRequestHandler(SimpleHTTPRequestHandler): @@ -42,7 +48,7 @@ def start_pulse_server(): """ This is simple server for bots without any API. If bot didn't call pulse for a while (5 minutes but should be changed individually) - healthcheck in docker returns 1 and bot will be restarted + Docker healthcheck fails to do request """ server = HTTPServer(('localhost', variables.HEALTHCHECK_SERVER_PORT), RequestHandlerClass=PulseRequestHandler) thread = threading.Thread(target=server.serve_forever, daemon=True) diff --git a/src/metrics/logging.py b/src/metrics/logging.py index f25ce1342..b6d1881ce 100644 --- a/src/metrics/logging.py +++ b/src/metrics/logging.py @@ -10,6 +10,7 @@ def format(self, record: logging.LogRecord) -> str: message['value'] = str(message['value']) to_json_msg = json.dumps({ + 'timestamp': int(record.created), 'name': record.name, 'levelname': record.levelname, 'funcName': record.funcName, diff --git a/src/metrics/prometheus/business.py b/src/metrics/prometheus/business.py index 39b8f4538..d0048b037 100644 --- a/src/metrics/prometheus/business.py +++ b/src/metrics/prometheus/business.py @@ -30,11 +30,13 @@ FRAME_PREV_REPORT_REF_SLOT = Gauge( "frame_prev_report_ref_slot", "Oracle frame previous report ref slot", + ['type'], namespace=PROMETHEUS_PREFIX, ) CONTRACT_ON_PAUSE = Gauge( "contract_on_pause", "Contract on pause", + ['type'], namespace=PROMETHEUS_PREFIX, ) diff --git a/src/metrics/prometheus/duration_meter.py b/src/metrics/prometheus/duration_meter.py index b1fdefc72..39f372c95 100644 --- a/src/metrics/prometheus/duration_meter.py +++ b/src/metrics/prometheus/duration_meter.py @@ -1,17 +1,14 @@ import logging from functools import wraps from time import perf_counter -from typing import Callable, TypeVar +from typing import Callable from src.metrics.prometheus.basic import FUNCTIONS_DURATION, Status logger = logging.getLogger(__name__) -T = TypeVar("T") - - -def duration_meter(): +def duration_meter[T](): def decorator(func: Callable[..., T]) -> Callable[..., T]: @wraps(func) def wrapper(*args, **kwargs) -> T: diff --git a/src/metrics/prometheus/ejector.py b/src/metrics/prometheus/ejector.py index d61c1159f..cdd53c802 100644 --- a/src/metrics/prometheus/ejector.py +++ b/src/metrics/prometheus/ejector.py @@ -9,8 +9,8 @@ namespace=PROMETHEUS_PREFIX, ) -EJECTOR_MAX_EXIT_EPOCH = Gauge( - "ejector_max_exit_epoch", +EJECTOR_MAX_WITHDRAWAL_EPOCH = Gauge( + "ejector_max_withdrawal_epoch", "The max exit epoch", namespace=PROMETHEUS_PREFIX, ) diff --git a/src/modules/accounting/accounting.py b/src/modules/accounting/accounting.py index cae79057d..94c7e5bdf 100644 --- a/src/modules/accounting/accounting.py +++ b/src/modules/accounting/accounting.py @@ -6,11 +6,12 @@ from src import variables from src.constants import SHARE_RATE_PRECISION_E27 -from src.modules.accounting.typings import ( +from src.modules.accounting.third_phase.extra_data import ExtraDataService +from src.modules.accounting.third_phase.extra_data_v2 import ExtraDataServiceV2 +from src.modules.accounting.third_phase.types import ExtraData, FormatList +from src.modules.accounting.types import ( ReportData, - AccountingProcessingState, LidoReportRebase, - SharesRequestedToBurn, ) from src.metrics.prometheus.accounting import ( ACCOUNTING_IS_BUNKER, @@ -19,17 +20,17 @@ ACCOUNTING_WITHDRAWAL_VAULT_BALANCE_WEI ) from src.metrics.prometheus.duration_meter import duration_meter +from src.providers.execution.contracts.accounting_oracle import AccountingOracleContract from src.services.validator_state import LidoValidatorStateService from src.modules.submodules.consensus import ConsensusModule from src.modules.submodules.oracle_module import BaseModule, ModuleExecuteDelay from src.services.withdrawal import Withdrawal from src.services.bunker import BunkerService -from src.typings import BlockStamp, Gwei, ReferenceBlockStamp -from src.utils.abi import named_tuple_to_dataclass +from src.types import BlockStamp, Gwei, ReferenceBlockStamp, StakingModuleId, NodeOperatorGlobalIndex from src.utils.cache import global_lru_cache as lru_cache from src.variables import ALLOW_REPORTING_IN_BUNKER_MODE -from src.web3py.typings import Web3 -from src.web3py.extensions.lido_validators import StakingModule, NodeOperatorGlobalIndex, StakingModuleId +from src.web3py.types import Web3 +from src.web3py.extensions.lido_validators import StakingModule logger = logging.getLogger(__name__) @@ -46,11 +47,11 @@ class Accounting(BaseModule, ConsensusModule): - Send extra data Contains stuck and exited validators count by each node operator. """ - CONSENSUS_VERSION = 1 - CONTRACT_VERSION = 1 + COMPATIBLE_CONTRACT_VERSIONS = [1, 2] + COMPATIBLE_CONSENSUS_VERSIONS = [1, 2] def __init__(self, w3: Web3): - self.report_contract = w3.lido_contracts.accounting_oracle + self.report_contract: AccountingOracleContract = w3.lido_contracts.accounting_oracle super().__init__(w3) self.lido_validator_state_service = LidoValidatorStateService(self.w3) @@ -90,14 +91,15 @@ def process_extra_data(self, blockstamp: ReferenceBlockStamp): self._submit_extra_data(blockstamp) def _submit_extra_data(self, blockstamp: ReferenceBlockStamp) -> None: - extra_data = self.lido_validator_state_service.get_extra_data(blockstamp, self.get_chain_config(blockstamp)) + extra_data = self.get_extra_data(blockstamp) - if extra_data.extra_data: - tx = self.report_contract.functions.submitReportExtraDataList(extra_data.extra_data) + if extra_data.format == FormatList.EXTRA_DATA_FORMAT_LIST_EMPTY.value: + tx = self.report_contract.submit_report_extra_data_empty() + self.w3.transaction.check_and_send_transaction(tx, variables.ACCOUNT) else: - tx = self.report_contract.functions.submitReportExtraDataEmpty() - - self.w3.transaction.check_and_send_transaction(tx, variables.ACCOUNT) + for tx_data in extra_data.extra_data_list: + tx = self.report_contract.submit_report_extra_data_list(tx_data) + self.w3.transaction.check_and_send_transaction(tx, variables.ACCOUNT) @lru_cache(maxsize=1) @duration_meter() @@ -108,13 +110,13 @@ def build_report(self, blockstamp: ReferenceBlockStamp) -> tuple: def is_main_data_submitted(self, blockstamp: BlockStamp) -> bool: # Consensus module: if contract got report data (second phase) - processing_state = self._get_processing_state(blockstamp) + processing_state = self.report_contract.get_processing_state(blockstamp.block_hash) logger.debug({'msg': 'Check if main data was submitted.', 'value': processing_state.main_data_submitted}) return processing_state.main_data_submitted def can_submit_extra_data(self, blockstamp: BlockStamp) -> bool: """Check if Oracle can submit extra data. Can only be submitted after second phase.""" - processing_state = self._get_processing_state(blockstamp) + processing_state = self.report_contract.get_processing_state(blockstamp.block_hash) return processing_state.main_data_submitted and not processing_state.extra_data_submitted def is_contract_reportable(self, blockstamp: BlockStamp) -> bool: @@ -132,26 +134,17 @@ def is_reporting_allowed(self, blockstamp: ReferenceBlockStamp) -> bool: logger.warning({'msg': '!' * 50}) return ALLOW_REPORTING_IN_BUNKER_MODE - @lru_cache(maxsize=1) - def _get_processing_state(self, blockstamp: BlockStamp) -> AccountingProcessingState: - ps = named_tuple_to_dataclass( - self.report_contract.functions.getProcessingState().call(block_identifier=blockstamp.block_hash), - AccountingProcessingState, - ) - logger.info({'msg': 'Fetch processing state.', 'value': ps}) - return ps - # ---------------------------------------- Build report ---------------------------------------- def _calculate_report(self, blockstamp: ReferenceBlockStamp) -> ReportData: validators_count, cl_balance = self._get_consensus_lido_state(blockstamp) staking_module_ids_list, exit_validators_count_list = self._get_newly_exited_validators_by_modules(blockstamp) - extra_data = self.lido_validator_state_service.get_extra_data(blockstamp, self.get_chain_config(blockstamp)) + extra_data = self.get_extra_data(blockstamp) finalization_share_rate, finalization_batches = self._get_finalization_data(blockstamp) report_data = ReportData( - consensus_version=self.CONSENSUS_VERSION, + consensus_version=self.report_contract.get_consensus_version(blockstamp.block_hash), ref_slot=blockstamp.ref_slot, validators_count=validators_count, cl_balance_gwei=cl_balance, @@ -183,7 +176,7 @@ def _get_newly_exited_validators_by_modules( Calculate exited validators count in all modules. Exclude modules without changes from the report. """ - staking_modules = self.w3.lido_validators.get_staking_modules(blockstamp) + staking_modules = self.w3.lido_contracts.staking_router.get_staking_modules(blockstamp.block_hash) exited_validators = self.lido_validator_state_service.get_exited_lido_validators(blockstamp) return self.get_updated_modules_stats(staking_modules, exited_validators) @@ -260,10 +253,10 @@ def simulate_rebase_after_report( chain_conf = self.get_chain_config(blockstamp) - simulated_tx = self.w3.lido_contracts.lido.functions.handleOracleReport( - # We use block timestamp, instead of slot timestamp, - # because missed slot will break simulation contract logics - # Details: https://github.com/lidofinance/lido-oracle/issues/291 + return self.w3.lido_contracts.lido.handle_oracle_report( + # Lido contract has sanity check that timestamp is not in the future. + # That's why we get revert if timestamp in args > call block timestamp. + # In normal case, we call handleOracleReport with timestamp == call block timestamp. blockstamp.block_timestamp, # _reportTimestamp self._get_slots_elapsed_from_last_report(blockstamp) * chain_conf.seconds_per_slot, # _timeElapsed # CL values @@ -273,31 +266,12 @@ def simulate_rebase_after_report( self.w3.lido_contracts.get_withdrawal_balance(blockstamp), # _withdrawalVaultBalance el_rewards, # _elRewardsVaultBalance self.get_shares_to_burn(blockstamp), # _sharesRequestedToBurn - # Decision about withdrawals processing - [], # _lastFinalizableRequestId - 0, # _simulatedShareRate + self.w3.lido_contracts.accounting_oracle.address, + blockstamp.block_hash, ) - logger.info({'msg': 'Simulate lido rebase for report.', 'value': simulated_tx.args}) - - result = simulated_tx.call( - transaction={'from': self.w3.lido_contracts.accounting_oracle.address}, - block_identifier=blockstamp.block_hash, - ) - - logger.info({'msg': 'Fetch simulated lido rebase for report.', 'value': result}) - - return LidoReportRebase(*result) - - @lru_cache(maxsize=1) def get_shares_to_burn(self, blockstamp: BlockStamp) -> int: - shares_data = named_tuple_to_dataclass( - self.w3.lido_contracts.burner.functions.getSharesRequestedToBurn().call( - block_identifier=blockstamp.block_hash, - ), - SharesRequestedToBurn, - ) - + shares_data = self.w3.lido_contracts.burner.get_shares_requested_to_burn(blockstamp.block_hash) return shares_data.cover_shares + shares_data.non_cover_shares def _get_slots_elapsed_from_last_report(self, blockstamp: ReferenceBlockStamp): @@ -327,3 +301,29 @@ def _is_bunker(self, blockstamp: ReferenceBlockStamp) -> bool: ) logger.info({'msg': 'Calculate bunker mode.', 'value': bunker_mode}) return bunker_mode + + @lru_cache(maxsize=1) + def get_extra_data(self, blockstamp: ReferenceBlockStamp) -> ExtraData: + consensus_version = self.w3.lido_contracts.accounting_oracle.get_consensus_version(blockstamp.block_hash) + + chain_config = self.get_chain_config(blockstamp) + stuck_validators = self.lido_validator_state_service.get_lido_newly_stuck_validators(blockstamp, chain_config) + logger.info({'msg': 'Calculate stuck validators.', 'value': stuck_validators}) + exited_validators = self.lido_validator_state_service.get_lido_newly_exited_validators(blockstamp) + logger.info({'msg': 'Calculate exited validators.', 'value': exited_validators}) + orl = self.w3.lido_contracts.oracle_report_sanity_checker.get_oracle_report_limits(blockstamp.block_hash) + + if consensus_version == 1: + return ExtraDataService.collect( + stuck_validators, + exited_validators, + orl.max_accounting_extra_data_list_items_count, + orl.max_node_operators_per_extra_data_item_count, + ) + + return ExtraDataServiceV2.collect( + stuck_validators, + exited_validators, + orl.max_accounting_extra_data_list_items_count, + orl.max_node_operators_per_extra_data_item_count, + ) diff --git a/src/modules/accounting/third_phase/__init__.py b/src/modules/accounting/third_phase/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/modules/accounting/extra_data.py b/src/modules/accounting/third_phase/extra_data.py similarity index 71% rename from src/modules/accounting/extra_data.py rename to src/modules/accounting/third_phase/extra_data.py index 8c54ec938..d805bc5d8 100644 --- a/src/modules/accounting/extra_data.py +++ b/src/modules/accounting/third_phase/extra_data.py @@ -1,22 +1,12 @@ import itertools from dataclasses import dataclass -from enum import Enum from hexbytes import HexBytes -from src.modules.submodules.typings import ZERO_HASH -from src.web3py.extensions.lido_validators import NodeOperatorGlobalIndex -from src.web3py.typings import Web3 - - -class ItemType(Enum): - EXTRA_DATA_TYPE_STUCK_VALIDATORS = 1 - EXTRA_DATA_TYPE_EXITED_VALIDATORS = 2 - - -class FormatList(Enum): - EXTRA_DATA_FORMAT_LIST_EMPTY = 0 - EXTRA_DATA_FORMAT_LIST_NON_EMPTY = 1 +from src.modules.accounting.third_phase.types import ItemType, ExtraData, FormatList, ExtraDataLengths +from src.modules.submodules.types import ZERO_HASH +from src.types import NodeOperatorGlobalIndex +from src.web3py.types import Web3 @dataclass @@ -34,14 +24,6 @@ class ExtraDataItem: item_payload: ItemPayload -@dataclass -class ExtraData: - extra_data: bytes - data_hash: HexBytes - format: int - items_count: int - - class ExtraDataService: """ Service that encodes extra data into bytes in correct order. @@ -57,38 +39,31 @@ class ExtraDataService: max_items_count - max itemIndex in extra data. max_no_in_payload_count - max nodeOpsCount that could be used in itemPayload. """ - - class Lengths: - ITEM_INDEX = 3 - ITEM_TYPE = 2 - MODULE_ID = 3 - NODE_OPS_COUNT = 8 - NODE_OPERATOR_IDS = 8 - STUCK_OR_EXITED_VALS_COUNT = 16 - + @classmethod def collect( - self, + cls, stuck_validators: dict[NodeOperatorGlobalIndex, int], exited_validators: dict[NodeOperatorGlobalIndex, int], max_items_count: int, max_no_in_payload_count: int, ) -> ExtraData: + stuck_payloads = cls.build_validators_payloads(stuck_validators, max_no_in_payload_count) + exited_payloads = cls.build_validators_payloads(exited_validators, max_no_in_payload_count) - stuck_payloads = self.build_validators_payloads(stuck_validators, max_no_in_payload_count) - exited_payloads = self.build_validators_payloads(exited_validators, max_no_in_payload_count) - - extra_data = self.build_extra_data(stuck_payloads, exited_payloads, max_items_count) - extra_data_bytes = self.to_bytes(extra_data) + extra_data = cls.build_extra_data(stuck_payloads, exited_payloads, max_items_count) + extra_data_bytes = cls.to_bytes(extra_data) if extra_data: + extra_data_list = [extra_data_bytes] data_format = FormatList.EXTRA_DATA_FORMAT_LIST_NON_EMPTY data_hash = Web3.keccak(extra_data_bytes) else: + extra_data_list = [] data_format = FormatList.EXTRA_DATA_FORMAT_LIST_EMPTY data_hash = HexBytes(ZERO_HASH) return ExtraData( - extra_data=extra_data_bytes, + extra_data_list=extra_data_list, data_hash=data_hash, format=data_format.value, items_count=len(extra_data), @@ -109,13 +84,13 @@ def build_validators_payloads( vals_count = [] for ((_, no_id), validators_count) in list(operators_by_module)[:max_no_in_payload_count]: - operator_ids.append(no_id.to_bytes(ExtraDataService.Lengths.NODE_OPERATOR_IDS)) - vals_count.append(validators_count.to_bytes(ExtraDataService.Lengths.STUCK_OR_EXITED_VALS_COUNT)) + operator_ids.append(no_id.to_bytes(ExtraDataLengths.NODE_OPERATOR_IDS)) + vals_count.append(validators_count.to_bytes(ExtraDataLengths.STUCK_OR_EXITED_VALS_COUNT)) payloads.append( ItemPayload( - module_id=module_id.to_bytes(ExtraDataService.Lengths.MODULE_ID), - node_ops_count=len(operator_ids).to_bytes(ExtraDataService.Lengths.NODE_OPS_COUNT), + module_id=module_id.to_bytes(ExtraDataLengths.MODULE_ID), + node_ops_count=len(operator_ids).to_bytes(ExtraDataLengths.NODE_OPS_COUNT), node_operator_ids=b"".join(operator_ids), vals_counts=b"".join(vals_count), ) @@ -134,7 +109,7 @@ def build_extra_data(stuck_payloads: list[ItemPayload], exited_payloads: list[It ]: for payload in payloads: extra_data.append(ExtraDataItem( - item_index=index.to_bytes(ExtraDataService.Lengths.ITEM_INDEX), + item_index=index.to_bytes(ExtraDataLengths.ITEM_INDEX), item_type=item_type, item_payload=payload )) @@ -150,7 +125,7 @@ def to_bytes(extra_data: list[ExtraDataItem]) -> bytes: extra_data_bytes = b'' for item in extra_data: extra_data_bytes += item.item_index - extra_data_bytes += item.item_type.value.to_bytes(ExtraDataService.Lengths.ITEM_TYPE) + extra_data_bytes += item.item_type.value.to_bytes(ExtraDataLengths.ITEM_TYPE) extra_data_bytes += item.item_payload.module_id extra_data_bytes += item.item_payload.node_ops_count extra_data_bytes += item.item_payload.node_operator_ids diff --git a/src/modules/accounting/third_phase/extra_data_v2.py b/src/modules/accounting/third_phase/extra_data_v2.py new file mode 100644 index 000000000..81867a9fe --- /dev/null +++ b/src/modules/accounting/third_phase/extra_data_v2.py @@ -0,0 +1,138 @@ +from dataclasses import dataclass +from itertools import groupby, batched +from typing import Sequence + +from src.modules.accounting.third_phase.types import ExtraData, ItemType, ExtraDataLengths, FormatList +from src.modules.submodules.types import ZERO_HASH +from src.types import NodeOperatorGlobalIndex +from src.web3py.types import Web3 + + +@dataclass +class ItemPayload: + module_id: int + node_operator_ids: Sequence[int] + vals_counts: Sequence[int] + + +class ExtraDataServiceV2: + """ + Service that encodes extra data into bytes in correct order. + + Extra data is an array of items, each item being encoded as follows: + | 32 bytes | 3 bytes | 2 bytes | X bytes | + | nextHash | itemIndex | itemType | itemPayload | + + itemPayload format: + | 3 bytes | 8 bytes | nodeOpsCount * 8 bytes | nodeOpsCount * 16 bytes | + | moduleId | nodeOpsCount | nodeOperatorIds | stuckOrExitedValsCount | + + max_items_count - max itemIndex in extra data. + max_no_in_payload_count - max nodeOpsCount that could be used in itemPayload. + """ + @classmethod + def collect( + cls, + stuck_validators: dict[NodeOperatorGlobalIndex, int], + exited_validators: dict[NodeOperatorGlobalIndex, int], + max_items_count: int, + max_no_in_payload_count: int, + ) -> ExtraData: + stuck_payloads = cls.build_validators_payloads(stuck_validators, max_no_in_payload_count) + exited_payloads = cls.build_validators_payloads(exited_validators, max_no_in_payload_count) + items_count, txs = cls.build_extra_transactions_data(stuck_payloads, exited_payloads, max_items_count) + first_hash, hashed_txs = cls.add_hashes_to_transactions(txs) + + if items_count: + extra_data_format = FormatList.EXTRA_DATA_FORMAT_LIST_NON_EMPTY + else: + extra_data_format = FormatList.EXTRA_DATA_FORMAT_LIST_EMPTY + + return ExtraData( + items_count=items_count, + extra_data_list=hashed_txs, + data_hash=first_hash, + format=extra_data_format.value, + ) + + @classmethod + def build_validators_payloads( + cls, + validators: dict[NodeOperatorGlobalIndex, int], + max_no_in_payload_count: int, + ) -> list[ItemPayload]: + operator_validators = sorted(validators.items(), key=lambda x: x[0]) + + payloads = [] + + for module_id, operators_by_module in groupby(operator_validators, key=lambda x: x[0][0]): + for nos_in_batch in batched(list(operators_by_module), max_no_in_payload_count): + operator_ids = [] + vals_count = [] + + for ((_, no_id), validators_count) in nos_in_batch: + operator_ids.append(no_id) + vals_count.append(validators_count) + + payloads.append( + ItemPayload( + module_id=module_id, + node_operator_ids=operator_ids, + vals_counts=vals_count, + ) + ) + + return payloads + + @classmethod + def build_extra_transactions_data( + cls, + stuck_payloads: list[ItemPayload], + exited_payloads: list[ItemPayload], + max_items_count: int, + ) -> tuple[int, list[bytes]]: + all_payloads = [ + *[(ItemType.EXTRA_DATA_TYPE_STUCK_VALIDATORS, payload) for payload in stuck_payloads], + *[(ItemType.EXTRA_DATA_TYPE_EXITED_VALIDATORS, payload) for payload in exited_payloads], + ] + + index = 0 + result = [] + + for payload_batch in batched(all_payloads, max_items_count): + tx = b'' + for item_type, payload in payload_batch: + tx += index.to_bytes(ExtraDataLengths.ITEM_INDEX) + tx += item_type.value.to_bytes(ExtraDataLengths.ITEM_TYPE) + tx += payload.module_id.to_bytes(ExtraDataLengths.MODULE_ID) + tx += len(payload.node_operator_ids).to_bytes(ExtraDataLengths.NODE_OPS_COUNT) + tx += b''.join( + no_id.to_bytes(ExtraDataLengths.NODE_OPERATOR_IDS) + for no_id in payload.node_operator_ids + ) + tx += b''.join( + count.to_bytes(ExtraDataLengths.STUCK_OR_EXITED_VALS_COUNT) + for count in payload.vals_counts + ) + + index += 1 + + result.append(tx) + + return index, result + + @staticmethod + def add_hashes_to_transactions(txs_data: list[bytes]) -> tuple[bytes, list[bytes]]: + txs_data.reverse() + + txs_with_hashes = [] + next_hash = ZERO_HASH + + for tx in txs_data: + full_tx_data = next_hash + tx + txs_with_hashes.append(full_tx_data) + next_hash = Web3.keccak(full_tx_data) + + txs_with_hashes.reverse() + + return next_hash, txs_with_hashes diff --git a/src/modules/accounting/third_phase/types.py b/src/modules/accounting/third_phase/types.py new file mode 100644 index 000000000..5510f1397 --- /dev/null +++ b/src/modules/accounting/third_phase/types.py @@ -0,0 +1,30 @@ +from dataclasses import dataclass +from enum import Enum + + +class ItemType(Enum): + EXTRA_DATA_TYPE_STUCK_VALIDATORS = 1 + EXTRA_DATA_TYPE_EXITED_VALIDATORS = 2 + + +class FormatList(Enum): + EXTRA_DATA_FORMAT_LIST_EMPTY = 0 + EXTRA_DATA_FORMAT_LIST_NON_EMPTY = 1 + + +@dataclass +class ExtraData: + extra_data_list: list[bytes] + data_hash: bytes + format: int + items_count: int + + +class ExtraDataLengths: + NEXT_HASH = 32 + ITEM_INDEX = 3 + ITEM_TYPE = 2 + MODULE_ID = 3 + NODE_OPS_COUNT = 8 + NODE_OPERATOR_IDS = 8 + STUCK_OR_EXITED_VALS_COUNT = 16 diff --git a/src/modules/accounting/typings.py b/src/modules/accounting/types.py similarity index 77% rename from src/modules/accounting/typings.py rename to src/modules/accounting/types.py index 1b9dd86ff..c3f8ea458 100644 --- a/src/modules/accounting/typings.py +++ b/src/modules/accounting/types.py @@ -1,11 +1,11 @@ from dataclasses import dataclass +from typing import Self from eth_typing import ChecksumAddress from hexbytes import HexBytes from web3.types import Wei -from src.typings import SlotNumber, Gwei -from src.web3py.extensions.lido_validators import StakingModuleId +from src.types import SlotNumber, Gwei, StakingModuleId @dataclass @@ -23,7 +23,7 @@ class ReportData: finalization_share_rate: int is_bunker: bool extra_data_format: int - extra_data_hash: HexBytes + extra_data_hash: bytes extra_data_items_count: int def as_tuple(self): @@ -62,7 +62,7 @@ class AccountingProcessingState: @dataclass class OracleReportLimits: - churn_validators_per_day_limit: int + exited_validators_per_day_limit: int one_off_cl_balance_decrease_bp_limit: int annual_balance_increase_bp_limit: int simulated_share_rate_deviation_bp_limit: int @@ -71,6 +71,14 @@ class OracleReportLimits: max_node_operators_per_extra_data_item_count: int request_timestamp_margin: int max_positive_token_rebase: int + appeared_validators_per_day_limit: int | None = None + + @classmethod + def from_response(cls, **kwargs) -> Self: + # Compatability breaking rename + # churn_validators_per_day_limit -> exited_validators_per_day_limit + # Unpack structure by order + return cls(*kwargs.values()) # pylint: disable=no-value-for-parameter @dataclass(frozen=True) @@ -81,17 +89,11 @@ class LidoReportRebase: el_reward: Wei -@dataclass -class Account: - address: ChecksumAddress - _private_key: HexBytes - - @dataclass class BatchState: remaining_eth_budget: int finished: bool - batches: list[int] + batches: tuple[int, ...] batches_length: int def as_tuple(self): @@ -99,7 +101,7 @@ def as_tuple(self): self.remaining_eth_budget, self.finished, self.batches, - self.batches_length + self.batches_length, ) @@ -107,3 +109,13 @@ def as_tuple(self): class SharesRequestedToBurn: cover_shares: int non_cover_shares: int + + +@dataclass +class WithdrawalRequestStatus: + amount_of_st_eth: int + amount_of_shares: int + owner: ChecksumAddress + timestamp: int + is_finalized: bool + is_claimed: bool diff --git a/src/modules/checks/suites/common.py b/src/modules/checks/suites/common.py index 2bd9310ed..46417b5a6 100644 --- a/src/modules/checks/suites/common.py +++ b/src/modules/checks/suites/common.py @@ -4,6 +4,7 @@ from src.main import check_providers_chain_ids as chain_ids_check # rename to not conflict with test from src.modules.accounting.accounting import Accounting from src.modules.ejector.ejector import Ejector +from src.modules.csm.csm import CSOracle @pytest.fixture() @@ -12,6 +13,12 @@ def skip_locator(web3): pytest.skip('LIDO_LOCATOR_ADDRESS is not set') +@pytest.fixture() +def skip_csm(web3): + if not hasattr(web3, 'csm'): + pytest.skip('CSM_MODULE_ADDRESS is not set') + + @pytest.fixture() def accounting(web3, skip_locator): return Accounting(web3) @@ -22,6 +29,11 @@ def ejector(web3, skip_locator): return Ejector(web3) +@pytest.fixture() +def csm(web3, skip_locator, skip_csm): + return CSOracle(web3) + + def check_providers_chain_ids(web3): """Make sure all providers are on the same chain""" chain_ids_check(web3, web3.cc, web3.kac) @@ -35,3 +47,8 @@ def check_accounting_contract_configs(accounting): def check_ejector_contract_configs(ejector): """Make sure ejector contract configs are valid""" ejector.check_contract_configs() + + +def check_csm_contract_configs(csm): + """Make sure csm contract configs are valid""" + csm.check_contract_configs() diff --git a/src/modules/checks/suites/conftest.py b/src/modules/checks/suites/conftest.py index 9e31852f3..dd935d991 100644 --- a/src/modules/checks/suites/conftest.py +++ b/src/modules/checks/suites/conftest.py @@ -4,7 +4,7 @@ from xdist.dsession import TerminalDistReporter # type: ignore[import] from src import variables -from src.typings import EpochNumber, SlotNumber, BlockRoot +from src.types import EpochNumber, SlotNumber, BlockRoot from src.utils.blockstamp import build_blockstamp from src.utils.slot import get_reference_blockstamp from src.web3py.contract_tweak import tweak_w3_contracts @@ -15,8 +15,9 @@ TransactionUtils, LidoContracts, FallbackProviderModule, + CSM, ) -from src.web3py.typings import Web3 +from src.web3py.types import Web3 TITLE_PROPERTY_NAME = "test_title" @@ -24,30 +25,54 @@ @pytest.fixture() def web3(): - web3 = Web3(FallbackProviderModule( - variables.EXECUTION_CLIENT_URI, - request_kwargs={'timeout': variables.HTTP_REQUEST_TIMEOUT_EXECUTION} - )) + web3 = Web3( + FallbackProviderModule( + variables.EXECUTION_CLIENT_URI, request_kwargs={'timeout': variables.HTTP_REQUEST_TIMEOUT_EXECUTION} + ) + ) tweak_w3_contracts(web3) cc = ConsensusClientModule(variables.CONSENSUS_CLIENT_URI, web3) kac = KeysAPIClientModule(variables.KEYS_API_URI, web3) - web3.attach_modules({ - 'lido_validators': LidoValidatorsProvider, - 'transaction': TransactionUtils, - 'cc': lambda: cc, # type: ignore[dict-item] - 'kac': lambda: kac, # type: ignore[dict-item] - }) + web3.attach_modules( + { + 'lido_validators': LidoValidatorsProvider, + 'transaction': TransactionUtils, + 'cc': lambda: cc, # type: ignore[dict-item] + 'kac': lambda: kac, # type: ignore[dict-item] + } + ) if variables.LIDO_LOCATOR_ADDRESS: web3.attach_modules({'lido_contracts': LidoContracts}) + if variables.CSM_MODULE_ADDRESS: + web3.attach_modules({'csm': CSM}) return web3 -@pytest.fixture(params=[pytest.param("finalized_blockstamp", id="Finalized blockstamp"), - pytest.param("blockstamp_frame_ago", id="Blockstamp frame ago")]) -def blockstamp(request): - return request.getfixturevalue(request.param) +@pytest.fixture( + params=[ + pytest.param(0, id="Finalized blockstamp"), + pytest.param(270, id="Blockstamp accounting frame ago"), + pytest.param( + 6300, + id="Blockstamp CSM frame ago", + marks=pytest.mark.skipif(variables.CSM_MODULE_ADDRESS is None, reason="CSM_MODULE_ADDRESS is not set"), + ), + ] +) +def blockstamp(web3, finalized_blockstamp, request): + epochs_per_frame = request.param + cc_config = web3.cc.get_config_spec() + slots_per_frame = epochs_per_frame * int(cc_config.SLOTS_PER_EPOCH) + last_report_ref_slot = SlotNumber(finalized_blockstamp.slot_number - slots_per_frame) + + return get_reference_blockstamp( + web3.cc, + last_report_ref_slot, + ref_epoch=EpochNumber(last_report_ref_slot // int(cc_config.SLOTS_PER_EPOCH)), + last_finalized_slot_number=finalized_blockstamp.slot_number, + ) @pytest.fixture @@ -60,22 +85,7 @@ def finalized_blockstamp(web3): web3.cc, bs.slot_number, ref_epoch=EpochNumber(bs.slot_number // int(cc_config.SLOTS_PER_EPOCH)), - last_finalized_slot_number=bs.slot_number - ) - - -@pytest.fixture -def blockstamp_frame_ago(web3, finalized_blockstamp): - epochs_per_frame = 270 - cc_config = web3.cc.get_config_spec() - slots_per_frame = epochs_per_frame * int(cc_config.SLOTS_PER_EPOCH) - last_report_ref_slot = SlotNumber(finalized_blockstamp.slot_number - slots_per_frame) - - return get_reference_blockstamp( - web3.cc, - last_report_ref_slot, - ref_epoch=EpochNumber(last_report_ref_slot // int(cc_config.SLOTS_PER_EPOCH)), - last_finalized_slot_number=finalized_blockstamp.slot_number + last_finalized_slot_number=bs.slot_number, ) @@ -93,6 +103,7 @@ def ensure_show_status(self): def pytest_configure(config): class SessionLike: config = None + session_like = SessionLike() session_like.config = config if is_xdist_controller(session_like): @@ -114,22 +125,24 @@ def pytest_report_teststatus(report, config): return "passed", "✅ Checked", "✅ Checked" if report.failed: return "failed", "❌ Failed", "❌ Failed" + if report.skipped: + reason = report.longrepr[-1] + return "skipped", reason, "Skipped" return None @pytest.hookimpl(tryfirst=True) def pytest_runtest_logreport(report) -> None: - title = [prop for name, prop in report.user_properties if name == TITLE_PROPERTY_NAME][0] if report.when == 'setup' and not report.passed: - print(title, end="") + print(report.head_line, end="") if report.when == 'call': - print(title, end="") + print(report.head_line, end="") if report.when == 'teardown': print() def pytest_runtest_setup(item: pytest.Item): - tw: TerminalWriter = item.config.pluginmanager.get_plugin("terminalreporter")._tw # pylint: disable=protected-access + tw: TerminalWriter = item.config.pluginmanager.get_plugin("terminalreporter")._tw # type: ignore # pylint: disable=protected-access obj = getattr(item, "obj", None) parent = getattr(item.parent, "obj", None) diff --git a/src/modules/checks/suites/consensus_node.py b/src/modules/checks/suites/consensus_node.py index ab351bba7..87d5fcf9b 100644 --- a/src/modules/checks/suites/consensus_node.py +++ b/src/modules/checks/suites/consensus_node.py @@ -1,23 +1,42 @@ """Consensus node""" -from src.web3py.typings import Web3 +from src.web3py.types import Web3 def check_validators_provided(web3: Web3, blockstamp): """Check that consensus-client able to provide validators""" - result = web3.cc.get_validators_no_cache(blockstamp) - assert len(result) > 0, "consensus-client provide no validators" + assert web3.cc.get_validators_no_cache(blockstamp), "consensus-client provide no validators" def check_block_details_provided(web3: Web3, blockstamp): """Check that consensus-client able to provide block details""" - web3.cc.get_block_details(blockstamp.slot_number) + assert web3.cc.get_block_details(blockstamp.slot_number), "consensus-client provide no block details" def check_block_root_provided(web3: Web3, blockstamp): """Check that consensus-client able to provide block root""" - web3.cc.get_block_root(blockstamp.slot_number) + assert web3.cc.get_block_root(blockstamp.slot_number), "consensus-client provide no block root" def check_block_header_provided(web3: Web3, blockstamp): """Check that consensus-client able to provide block header""" - web3.cc.get_block_header(blockstamp.slot_number) + assert web3.cc.get_block_header(blockstamp.slot_number), "consensus-client provide no block header" + + +def check_block_roots_from_state_provided(web3: Web3, blockstamp): + """Check that consensus-client able to provide block roots from state""" + assert web3.cc.get_state_block_roots(blockstamp.slot_number), "consensus-client provide no block roots from state" + + +def check_attestation_committees(web3: Web3, blockstamp): + """Check that consensus-client able to provide attestation committees""" + cc_config = web3.cc.get_config_spec() + slots_per_epoch = int(cc_config.SLOTS_PER_EPOCH) + epoch = ( + blockstamp.slot_number // slots_per_epoch - int(cc_config.SLOTS_PER_HISTORICAL_ROOT) // slots_per_epoch + ) + assert web3.cc.get_attestation_committees(blockstamp, epoch), "consensus-client provide no attestation committees" + + +def check_block_attestations(web3: Web3, blockstamp): + """Check that consensus-client able to provide block attestations""" + assert web3.cc.get_block_attestations(blockstamp.slot_number), "consensus-client provide no block attestations" diff --git a/src/modules/checks/suites/execution_node.py b/src/modules/checks/suites/execution_node.py index 5d90ce9b2..af261a361 100644 --- a/src/modules/checks/suites/execution_node.py +++ b/src/modules/checks/suites/execution_node.py @@ -1,6 +1,9 @@ """Execution node""" import pytest +from src.providers.execution.contracts.deposit_contract import DepositContract +from src.utils.events import get_events_in_range + get_deposit_count_abi = { "inputs": [], "name": "get_deposit_count", @@ -25,13 +28,14 @@ def deposit_contract(web3): cc_config = web3.cc.get_config_spec() return web3.eth.contract( address=web3.to_checksum_address(cc_config.DEPOSIT_CONTRACT_ADDRESS), - abi=[get_deposit_count_abi, deposit_event_abi], + ContractFactoryClass=DepositContract, + decode_tuples=True, ) def check_eth_call_availability(blockstamp, deposit_contract): """Check that execution-client able to make eth_call on the provided blockstamp""" - deposit_contract.functions.get_deposit_count().call(block_identifier=blockstamp.block_hash) + deposit_contract.get_deposit_count(block_identifier=blockstamp.block_hash) def check_balance_availability(web3, blockstamp, deposit_contract): @@ -39,16 +43,16 @@ def check_balance_availability(web3, blockstamp, deposit_contract): web3.eth.get_balance(deposit_contract.address, block_identifier=blockstamp.block_hash) -def check_events_range_availability(web3, blockstamp, deposit_contract): - """Check that execution-client able to get event logs on the blockstamp state""" - latest_block = web3.eth.get_block('latest') - deposit_contract.events.DepositEvent.get_logs(fromBlock=blockstamp.block_number, toBlock=latest_block.number) - - -def check_events_week_range_availability(web3, deposit_contract): - """Check that execution-client able to get event logs a week ago""" - latest_block = web3.eth.get_block('latest') - deposit_contract.events.DepositEvent.get_logs( - fromBlock=latest_block.number - 8 * 225 * 32, # 8 days - toBlock=latest_block.number, +def check_events_range_availability(deposit_contract, blockstamp, finalized_blockstamp): + """Check that execution-client able to get event logs in a range""" + events = list( + get_events_in_range( + deposit_contract.events.DepositEvent, + l_block=blockstamp.block_number, + r_block=finalized_blockstamp.block_number, + ) ) + deposits_count_before = deposit_contract.get_deposit_count(blockstamp.block_hash) + deposits_count_now = deposit_contract.get_deposit_count(finalized_blockstamp.block_hash) + assert deposits_count_now >= deposits_count_before, "Deposits count decreased" + assert len(events) == (deposits_count_now - deposits_count_before), "Events count doesn't match deposits count" diff --git a/src/modules/checks/suites/ipfs.py b/src/modules/checks/suites/ipfs.py new file mode 100644 index 000000000..ad484a565 --- /dev/null +++ b/src/modules/checks/suites/ipfs.py @@ -0,0 +1,55 @@ +"""IPFS provider""" + + +import random +import string + +import pytest + +from src import variables +from src.main import ipfs_providers +from src.providers.ipfs import GW3, IPFSError, IPFSProvider, Pinata, PublicIPFS + + +@pytest.fixture() +def content(): + letters = string.ascii_letters + return "".join(random.choice(letters) for _ in range(255)) + + +def providers(): + configured_providers = tuple(ipfs_providers()) + + for typ in (GW3, Pinata): + try: + provider = [p for p in configured_providers if isinstance(p, typ)].pop() + except IndexError: + yield pytest.param( + None, + marks=pytest.mark.skip(f"{typ.__name__} provider is not configured"), + id=typ.__name__, + ) + else: + yield pytest.param(provider, id=typ.__name__) + + +@pytest.mark.parametrize("provider", providers()) +def check_ipfs_provider(provider: IPFSProvider, content: str): + """Checks that configured IPFS provider can be used by CSM""" + + try: + cid = provider.publish(content.encode()) + ret = provider.fetch(cid).decode() + if ret != content: + raise IPFSError(f"Content mismatch, got={ret}, expected={content}") + except IPFSError as e: + raise AssertionError(f"Provider {provider.__class__.__name__} is not working") from e + + +def check_csm_requires_ipfs_provider(): + if not variables.CSM_MODULE_ADDRESS: + pytest.skip("IPFS provider is not requirement for non-CSM oracle") + + providers = [p for p in ipfs_providers() if not isinstance(p, PublicIPFS)] + if not providers: + pytest.fail("CSM oracle requires IPFS provider with pinnig support") diff --git a/src/modules/csm/__init__.py b/src/modules/csm/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/modules/csm/checkpoint.py b/src/modules/csm/checkpoint.py new file mode 100644 index 000000000..eb5595262 --- /dev/null +++ b/src/modules/csm/checkpoint.py @@ -0,0 +1,250 @@ +import logging +import time +from concurrent.futures import ThreadPoolExecutor, as_completed +from dataclasses import dataclass +from itertools import batched +from threading import Lock +from typing import Iterable + +from timeout_decorator import TimeoutError as DecoratorTimeoutError + +from src import variables +from src.constants import SLOTS_PER_HISTORICAL_ROOT +from src.modules.csm.state import State +from src.providers.consensus.client import ConsensusClient +from src.providers.consensus.types import BlockAttestation +from src.types import BlockRoot, BlockStamp, EpochNumber, SlotNumber, ValidatorIndex +from src.utils.range import sequence +from src.utils.web3converter import Web3Converter + +logger = logging.getLogger(__name__) +lock = Lock() + + +class MinStepIsNotReached(Exception): + ... + + +@dataclass +class Checkpoint: + slot: SlotNumber # last slot of the epoch + duty_epochs: list[EpochNumber] # max 255 elements + + +@dataclass +class ValidatorDuty: + index: ValidatorIndex + included: bool + + +class CheckpointsIterator: + converter: Web3Converter + + l_epoch: EpochNumber + r_epoch: EpochNumber + + # Max available epoch to process according to the finalized epoch + max_available_epoch_to_check: EpochNumber + + # Min checkpoint step is 10 because it's a reasonable number of epochs to process at once (~1 hour) + MIN_CHECKPOINT_STEP = 10 + # Max checkpoint step is 255 epochs because block_roots size from state is 8192 slots (256 epochs) + # to check duty of every epoch, we need to check 64 slots (32 slots of duty epoch + 32 slots of next epoch). + # In the end we got 255 committees and 8192 block_roots to check them for every checkpoint. + MAX_CHECKPOINT_STEP = 255 + # Delay from last duty epoch to get checkpoint slot + CHECKPOINT_SLOT_DELAY_EPOCHS = 2 + + def __init__( + self, converter: Web3Converter, l_epoch: EpochNumber, r_epoch: EpochNumber, finalized_epoch: EpochNumber + ): + if l_epoch > r_epoch: + raise ValueError("Left border epoch should be less or equal right border epoch") + self.converter = converter + self.l_epoch = l_epoch + self.r_epoch = r_epoch + + self.max_available_epoch_to_check = min( + self.r_epoch, EpochNumber(finalized_epoch - self.CHECKPOINT_SLOT_DELAY_EPOCHS) + ) + + if self.r_epoch > self.max_available_epoch_to_check and not self._is_min_step_reached(): + raise MinStepIsNotReached() + + def __iter__(self): + for checkpoint_epochs in batched( + sequence(self.l_epoch, self.max_available_epoch_to_check), + self.MAX_CHECKPOINT_STEP, + ): + checkpoint_slot = self.converter.get_epoch_first_slot( + EpochNumber(max(checkpoint_epochs) + self.CHECKPOINT_SLOT_DELAY_EPOCHS) + ) + logger.info( + {"msg": f"Checkpoint slot {checkpoint_slot} with {len(checkpoint_epochs)} duty epochs is prepared"} + ) + yield Checkpoint(checkpoint_slot, checkpoint_epochs) + + def _is_min_step_reached(self): + processing_delay = self.max_available_epoch_to_check - self.l_epoch + if processing_delay >= self.MIN_CHECKPOINT_STEP: + return True + logger.info( + { + "msg": f"Minimum checkpoint step is not reached, current delay is {processing_delay} epochs", + "max_available_epoch_to_check": self.max_available_epoch_to_check, + "l_epoch": self.l_epoch, + "r_epoch": self.r_epoch, + } + ) + return False + + +class CheckpointProcessor: + cc: ConsensusClient + converter: Web3Converter + + state: State + finalized_blockstamp: BlockStamp + + def __init__(self, cc: ConsensusClient, state: State, converter: Web3Converter, finalized_blockstamp: BlockStamp): + self.cc = cc + self.converter = converter + self.state = state + self.finalized_blockstamp = finalized_blockstamp + + def exec(self, checkpoint: Checkpoint) -> int: + logger.info( + {"msg": f"Processing checkpoint for slot {checkpoint.slot} with {len(checkpoint.duty_epochs)} epochs"} + ) + unprocessed_epochs = [e for e in checkpoint.duty_epochs if e in self.state.unprocessed_epochs] + if not unprocessed_epochs: + logger.info({"msg": "Nothing to process in the checkpoint"}) + return 0 + block_roots = self._get_block_roots(checkpoint.slot) + duty_epochs_roots = { + duty_epoch: self._select_block_roots(duty_epoch, block_roots, checkpoint.slot) + for duty_epoch in unprocessed_epochs + } + self._process(unprocessed_epochs, duty_epochs_roots) + return len(unprocessed_epochs) + + def _get_block_roots(self, checkpoint_slot: SlotNumber): + logger.info({"msg": f"Get block roots for slot {checkpoint_slot}"}) + # Checkpoint for us like a time point, that's why we use slot, not root. + # `s % 8192 = i` is the index where slot `s` will be located. + # If `s` is `checkpoint_slot -> state.slot`, then it cannot yet be in `block_roots`. + # So it is the index that will be overwritten in the next slot, i.e. the index of the oldest root. + pivot_index = checkpoint_slot % SLOTS_PER_HISTORICAL_ROOT + br = self.cc.get_state_block_roots(checkpoint_slot) + # Replace duplicated roots to None to mark missed slots + return [br[i] if i == pivot_index or br[i] != br[i - 1] else None for i in range(len(br))] + + def _select_block_roots( + self, duty_epoch: EpochNumber, block_roots: list[BlockRoot | None], checkpoint_slot: SlotNumber + ) -> list[BlockRoot]: + roots_to_check = [] + # To check duties in the current epoch you need to + # have 32 slots of the current epoch and 32 slots of the next epoch + slots = sequence( + self.converter.get_epoch_first_slot(duty_epoch), + self.converter.get_epoch_last_slot(EpochNumber(duty_epoch + 1)), + ) + for slot_to_check in slots: + # From spec + # https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#get_block_root_at_slot + if not slot_to_check < checkpoint_slot <= slot_to_check + SLOTS_PER_HISTORICAL_ROOT: + raise ValueError("Slot is out of the state block roots range") + if br := block_roots[slot_to_check % SLOTS_PER_HISTORICAL_ROOT]: + roots_to_check.append(br) + + return roots_to_check + + def _process(self, unprocessed_epochs: list[EpochNumber], duty_epochs_roots: dict[EpochNumber, list[BlockRoot]]): + with ThreadPoolExecutor(max_workers=variables.CSM_ORACLE_MAX_CONCURRENCY) as ext: + try: + futures = { + ext.submit(self._check_duty, duty_epoch, duty_epochs_roots[duty_epoch]) + for duty_epoch in unprocessed_epochs + } + for future in as_completed(futures): + future.result() + except DecoratorTimeoutError as e: + logger.error({"msg": "Timeout processing epochs in threads", "error": str(e)}) + # Don't wait the current running tasks to finish, cancel the rest and shutdown the executor + # To interrupt the current running tasks, we need to raise a special exception + ext.shutdown(wait=False, cancel_futures=True) + raise SystemExit(1) from e + except Exception as e: + logger.error({"msg": "Error processing epochs in threads, wait the current threads", "error": str(e)}) + # Wait only for the current running threads to prevent + # a lot of similar error-possible requests to the consensus node. + # Raise the error after a batch of running threads is finished + ext.shutdown(wait=True, cancel_futures=True) + raise ValueError(e) from e + + def _check_duty( + self, + duty_epoch: EpochNumber, + block_roots: list[BlockRoot], + ): + logger.info({"msg": f"Process epoch {duty_epoch}"}) + start = time.time() + committees = self._prepare_committees(EpochNumber(duty_epoch)) + for root in block_roots: + attestations = self.cc.get_block_attestations(BlockRoot(root)) + process_attestations(attestations, committees) + + with lock: + for committee in committees.values(): + for validator_duty in committee: + self.state.inc( + validator_duty.index, + included=validator_duty.included, + ) + if duty_epoch not in self.state.unprocessed_epochs: + raise ValueError(f"Epoch {duty_epoch} is not in epochs that should be processed") + self.state.add_processed_epoch(duty_epoch) + self.state.commit() + self.state.status() + + logger.info({"msg": f"Epoch {duty_epoch} processed in {time.time() - start:.2f} seconds"}) + + def _prepare_committees(self, epoch: EpochNumber) -> dict[tuple[str, str], list[ValidatorDuty]]: + start = time.time() + committees = {} + for committee in self.cc.get_attestation_committees(self.finalized_blockstamp, EpochNumber(epoch)): + validators = [] + # Order of insertion is used to track the positions in the committees. + for validator in committee.validators: + validators.append(ValidatorDuty(index=ValidatorIndex(int(validator)), included=False)) + committees[(committee.slot, committee.index)] = validators + logger.info({"msg": f"Committees for epoch {epoch} processed in {time.time() - start:.2f} seconds"}) + return committees + + +def process_attestations( + attestations: Iterable[BlockAttestation], committees: dict[tuple[str, str], list[ValidatorDuty]] +) -> None: + for attestation in attestations: + committee_id = (attestation.data.slot, attestation.data.index) + committee = committees.get(committee_id) + att_bits = _to_bits(attestation.aggregation_bits) + if not committee: + continue + for index_in_committee, validator_duty in enumerate(committee): + if validator_duty.included: + # validator has already fulfilled its duties + continue + if _is_attested(att_bits, index_in_committee): + validator_duty.included = True + committees[committee_id][index_in_committee] = validator_duty + + +def _is_attested(bits: list[bool], index: int) -> bool: + return bits[index] + + +def _to_bits(aggregation_bits: str): + # copied from https://github.com/ethereum/py-ssz/blob/main/ssz/sedes/bitvector.py#L66 + att_bytes = bytes.fromhex(aggregation_bits[2:]) + return [bool((att_bytes[bit_index // 8] >> bit_index % 8) % 2) for bit_index in range(len(att_bytes) * 8)] diff --git a/src/modules/csm/csm.py b/src/modules/csm/csm.py new file mode 100644 index 000000000..f3fb4a91b --- /dev/null +++ b/src/modules/csm/csm.py @@ -0,0 +1,304 @@ +import logging +import time +from collections import defaultdict +from functools import cached_property +from typing import Iterable + +from web3.types import BlockIdentifier + +from src.constants import TOTAL_BASIS_POINTS, UINT64_MAX +from src.metrics.prometheus.business import CONTRACT_ON_PAUSE +from src.metrics.prometheus.duration_meter import duration_meter +from src.modules.csm.checkpoint import CheckpointProcessor, CheckpointsIterator, MinStepIsNotReached +from src.modules.csm.state import InvalidState, State +from src.modules.csm.tree import Tree +from src.modules.csm.types import ReportData +from src.modules.submodules.consensus import ConsensusModule +from src.modules.submodules.oracle_module import BaseModule, ModuleExecuteDelay +from src.modules.submodules.types import ZERO_HASH +from src.providers.execution.contracts.cs_fee_oracle import CSFeeOracleContract +from src.types import BlockStamp, EpochNumber, ReferenceBlockStamp, SlotNumber, StakingModuleAddress, ValidatorIndex +from src.utils.cache import global_lru_cache as lru_cache +from src.utils.slot import get_first_non_missed_slot +from src.utils.web3converter import Web3Converter +from src.web3py.extensions.lido_validators import NodeOperatorId, StakingModule, ValidatorsByNodeOperator +from src.web3py.types import Web3 + +logger = logging.getLogger(__name__) + + +class CSOracle(BaseModule, ConsensusModule): + """ + CSM performance module collects performance of CSM node operators and creates a Merkle tree of the resulting + distribution of shares among the oprators. The root of the tree is then submitted to the module contract. + + The algorithm for calculating performance includes the following steps: + 1. Collect all the attestation duties of the network validators for the frame. + 2. Calculate the performance of each validator based on the attestations. + 3. Calculate the share of each CSM node operator excluding underperforming validators. + """ + + CONSENSUS_VERSION = 1 + CONTRACT_VERSION = 1 + + report_contract: CSFeeOracleContract + + def __init__(self, w3: Web3): + self.report_contract = w3.csm.oracle + self.state = State.load() + super().__init__(w3) + + def refresh_contracts(self): + self.report_contract = self.w3.csm.oracle # type: ignore + + def execute_module(self, last_finalized_blockstamp: BlockStamp) -> ModuleExecuteDelay: + collected = self.collect_data(last_finalized_blockstamp) + if not collected: + logger.info( + {"msg": "Data required for the report is not fully collected yet. Waiting for the next finalized epoch"} + ) + return ModuleExecuteDelay.NEXT_FINALIZED_EPOCH + + # pylint:disable=duplicate-code + report_blockstamp = self.get_blockstamp_for_report(last_finalized_blockstamp) + if not report_blockstamp: + return ModuleExecuteDelay.NEXT_FINALIZED_EPOCH + + self.process_report(report_blockstamp) + return ModuleExecuteDelay.NEXT_SLOT + + @lru_cache(maxsize=1) + @duration_meter() + def build_report(self, blockstamp: ReferenceBlockStamp) -> tuple: + # pylint: disable=too-many-branches,too-many-statements + + converter = self.converter(blockstamp) + l_ref_slot, _ = self.current_frame_range(blockstamp) + l_epoch = EpochNumber(converter.get_epoch_by_slot(l_ref_slot) + 1) + r_epoch = blockstamp.ref_epoch + + try: + self.state.validate_for_report(l_epoch, r_epoch) + except InvalidState as e: + raise ValueError(f"State is not valid for the report. {e}") from e + + self.state.status() + + distributed, shares = self.calculate_distribution(blockstamp) + if not distributed: + logger.info({"msg": "No shares distributed in the current frame"}) + + # Load the previous tree if any. + root = self.w3.csm.get_csm_tree_root(blockstamp) + cid = self.w3.csm.get_csm_tree_cid(blockstamp) + + if cid: + logger.info({"msg": "Fetching tree by CID from IPFS", "cid": repr(cid)}) + tree = Tree.decode(self.w3.ipfs.fetch(cid)) + logger.info({"msg": "Restored tree from IPFS dump", "root": repr(root)}) + + if tree.root != root: + raise ValueError("Unexpected tree root got from IPFS dump") + + # Update cumulative amount of shares for all operators. + for v in tree.tree.values: + no_id, amount = v["value"] + shares[no_id] += amount + + # XXX: We put a stone here to make sure, that even with only 1 node operator in the tree, it's still possible to + # claim rewards. The CSModule contract skips pulling rewards if the proof's length is zero, which is the case + # when the tree has only one leaf. + stone = NodeOperatorId(self.w3.csm.module.MAX_OPERATORS_COUNT) + if shares: + shares[stone] = 0 + if stone in shares and len(shares) > 2: + shares.pop(stone) + + if distributed: + tree = Tree.new(tuple((no_id, amount) for (no_id, amount) in shares.items())) + logger.info({"msg": "New tree built for the report", "root": repr(tree.root)}) + cid = self.w3.ipfs.publish(tree.encode()) + root = tree.root + + if root == ZERO_HASH: + logger.info({"msg": "No fee distributed so far, and tree doesn't exist"}) + + return ReportData( + self.CONSENSUS_VERSION, + blockstamp.ref_slot, + tree_root=root, + tree_cid=cid, + distributed=distributed, + ).as_tuple() + + def is_main_data_submitted(self, blockstamp: BlockStamp) -> bool: + last_ref_slot = self.w3.csm.get_csm_last_processing_ref_slot(blockstamp) + ref_slot = self.get_current_frame(blockstamp).ref_slot + return last_ref_slot == ref_slot + + def is_contract_reportable(self, blockstamp: BlockStamp) -> bool: + return not self.is_main_data_submitted(blockstamp) and not self.w3.csm.module.is_paused() + + def is_reporting_allowed(self, blockstamp: ReferenceBlockStamp) -> bool: + on_pause = self.report_contract.is_paused(blockstamp.block_hash) + CONTRACT_ON_PAUSE.labels("csm").set(on_pause) + return not on_pause + + @cached_property + def module(self) -> StakingModule: + modules: list[StakingModule] = self.w3.lido_contracts.staking_router.get_staking_modules( + self._receive_last_finalized_slot().block_hash + ) + + for mod in modules: + if mod.staking_module_address == self.w3.csm.module.address: + return mod + + raise ValueError("No CSM module found. Wrong address?") + + @lru_cache(maxsize=1) + def module_validators_by_node_operators(self, blockstamp: BlockStamp) -> ValidatorsByNodeOperator: + return self.w3.lido_validators.get_module_validators_by_node_operators( + StakingModuleAddress(self.module.staking_module_address), blockstamp + ) + + def collect_data(self, blockstamp: BlockStamp) -> bool: + """Ongoing report data collection before the report ref slot and it's submission""" + logger.info({"msg": "Collecting data for the report"}) + + converter = self.converter(blockstamp) + + l_ref_slot, r_ref_slot = self.current_frame_range(blockstamp) + logger.info({"msg": f"Frame for performance data collect: ({l_ref_slot};{r_ref_slot}]"}) + + # Finalized slot is the first slot of justifying epoch, so we need to take the previous + finalized_epoch = EpochNumber(converter.get_epoch_by_slot(blockstamp.slot_number) - 1) + + l_epoch = EpochNumber(converter.get_epoch_by_slot(l_ref_slot) + 1) + if l_epoch > finalized_epoch: + return False + r_epoch = converter.get_epoch_by_slot(r_ref_slot) + + self.state.validate_for_collect(l_epoch, r_epoch) + self.state.status() + + if done := self.state.is_fulfilled: + logger.info({"msg": "All epochs are already processed. Nothing to collect"}) + return done + + try: + checkpoints = CheckpointsIterator( + converter, min(self.state.unprocessed_epochs) or l_epoch, r_epoch, finalized_epoch + ) + except MinStepIsNotReached: + return False + + processor = CheckpointProcessor(self.w3.cc, self.state, converter, blockstamp) + + new_processed_epochs = 0 + start = time.time() + for checkpoint in checkpoints: + if self.current_frame_range(self._receive_last_finalized_slot()) != (l_ref_slot, r_ref_slot): + logger.info({"msg": "Checkpoints were prepared for an outdated frame, stop processing"}) + raise ValueError("Outdated checkpoint") + new_processed_epochs += processor.exec(checkpoint) + + if new_processed_epochs: + logger.info( + {"msg": f"Collecting data for {new_processed_epochs} epochs was done in {time.time() - start:.2f} sec"} + ) + + return self.state.is_fulfilled + + def calculate_distribution(self, blockstamp: BlockStamp) -> tuple[int, defaultdict[NodeOperatorId, int]]: + """Computes distribution of fee shares at the given timestamp""" + + threshold = self.state.avg_perf - self.w3.csm.oracle.perf_leeway_bp(blockstamp.block_hash) / TOTAL_BASIS_POINTS + operators_to_validators = self.module_validators_by_node_operators(blockstamp) + + # Build the map of the current distribution operators. + distribution: dict[NodeOperatorId, int] = defaultdict(int) + stuck_operators = self.stuck_operators(blockstamp) + for (_, no_id), validators in operators_to_validators.items(): + if no_id in stuck_operators: + continue + + for v in validators: + try: + aggr = self.state.data[ValidatorIndex(int(v.index))] + except KeyError: + # It's possible that the validator is not assigned to any duty, hence it's performance + # is not presented in the aggregates (e.g. exited, pending for activation etc). + continue + + if aggr.perf > threshold: + # Count of assigned attestations used as a metrics of time + # the validator was active in the current frame. + distribution[no_id] += aggr.assigned + + # Calculate share of each CSM node operator. + shares = defaultdict[NodeOperatorId, int](int) + total = sum(p for p in distribution.values()) + + if not total: + return 0, shares + + to_distribute = self.w3.csm.fee_distributor.shares_to_distribute(blockstamp.block_hash) + for no_id, no_share in distribution.items(): + if no_share: + shares[no_id] = to_distribute * no_share // total + + distributed = sum(s for s in shares.values()) + assert distributed <= to_distribute + return distributed, shares + + def stuck_operators(self, blockstamp) -> Iterable[NodeOperatorId]: + l_ref_slot, _ = self.current_frame_range(blockstamp) + # NOTE: r_block is guaranteed to be <= ref_slot, and the check + # in the inner frames assures the l_block <= r_block. + return self.w3.csm.get_csm_stuck_node_operators( + get_first_non_missed_slot( + self.w3.cc, + l_ref_slot, + blockstamp.slot_number, + direction='forward', + ).message.body.execution_payload.block_hash, + blockstamp.block_hash, + ) + + @lru_cache(maxsize=1) + def current_frame_range(self, blockstamp: BlockStamp) -> tuple[SlotNumber, SlotNumber]: + converter = self.converter(blockstamp) + + far_future_initial_epoch = converter.get_epoch_by_timestamp(UINT64_MAX) + if converter.frame_config.initial_epoch == far_future_initial_epoch: + raise ValueError("CSM oracle initial epoch is not set yet") + + l_ref_slot = self.w3.csm.get_csm_last_processing_ref_slot(blockstamp) + r_ref_slot = self.get_current_frame(blockstamp).ref_slot + + # The very first report, no previous ref slot. + if not l_ref_slot: + l_ref_slot = SlotNumber(self.get_initial_ref_slot(blockstamp) - converter.slots_per_frame) + if l_ref_slot < 0: + raise ValueError("Invalid frame configuration for the current network") + + # We are between reports, next report slot didn't happen yet. Predicting the next ref slot for the report + # to calculate epochs range to collect the data. + if l_ref_slot == r_ref_slot: + r_ref_slot = converter.get_epoch_last_slot( + EpochNumber(converter.get_epoch_by_slot(l_ref_slot) + converter.frame_config.epochs_per_frame) + ) + + return l_ref_slot, r_ref_slot + + def converter(self, blockstamp: BlockStamp) -> Web3Converter: + return Web3Converter(self.get_chain_config(blockstamp), self.get_frame_config(blockstamp)) + + def _slot_to_block_identifier(self, slot: SlotNumber) -> BlockIdentifier: + block = self.w3.cc.get_block_details(slot) + + try: + return block.message.body.execution_payload.block_hash + except KeyError as e: + raise ValueError(f"ExecutionPayload not found in slot {slot}") from e diff --git a/src/modules/csm/state.py b/src/modules/csm/state.py new file mode 100644 index 000000000..030b8d468 --- /dev/null +++ b/src/modules/csm/state.py @@ -0,0 +1,167 @@ +import logging +import os +import pickle +from dataclasses import dataclass, field +from pathlib import Path +from typing import Self + +from src.types import EpochNumber, ValidatorIndex +from src.utils.range import sequence + +logger = logging.getLogger(__name__) + + +class InvalidState(Exception): + """State has data considered as invalid for a report""" + + +@dataclass +class AttestationsAggregate: + """Aggregate of attestations duties observed for a validator""" + + assigned: int + included: int + + @property + def perf(self) -> float: + return self.included / self.assigned if self.assigned else 0 + + +@dataclass +class State: + """Processing state of a CSM performance oracle frame""" + + data: dict[ValidatorIndex, AttestationsAggregate] = field(default_factory=dict) + + _epochs_to_process: set[EpochNumber] = field(default_factory=set) + _processed_epochs: set[EpochNumber] = field(default_factory=set) + + EXTENSION = ".pkl" + + @classmethod + def load(cls) -> Self: + """Used to restore the object from the persistent storage""" + + obj: Self | None = None + file = cls.file() + try: + with file.open(mode="rb") as f: + obj = pickle.load(f) + assert obj + + logger.info({"msg": f"{cls.__name__} read from {file.absolute()}"}) + except Exception as e: # pylint: disable=broad-exception-caught + logger.info({"msg": f"Unable to restore {cls.__name__} instance from {file.absolute()}", "error": str(e)}) + return obj or cls() + + @classmethod + def file(cls) -> Path: + return Path("cache").with_suffix(cls.EXTENSION) + + def commit(self) -> None: + with self.buffer.open(mode="wb") as f: + pickle.dump(self, f) + + os.replace(self.buffer, self.file()) + + def clear(self) -> None: + self.data = {} + self._epochs_to_process.clear() + self._processed_epochs.clear() + assert self.is_empty + + def inc(self, key: ValidatorIndex, included: bool) -> None: + perf = self.data.get(key, AttestationsAggregate(0, 0)) + perf.assigned += 1 + perf.included += 1 if included else 0 + self.data[key] = perf + + def add_processed_epoch(self, epoch: EpochNumber) -> None: + self._processed_epochs.add(epoch) + + def status(self) -> None: + network_aggr = self.network_aggr + + logger.info( + { + "msg": f"Processed {len(self._processed_epochs)} of {len(self._epochs_to_process)} epochs", + "assigned": network_aggr.assigned, + "included": network_aggr.included, + "avg_perf": self.avg_perf, + } + ) + + def validate_for_report(self, l_epoch: EpochNumber, r_epoch: EpochNumber) -> None: + if not self.is_fulfilled: + raise InvalidState(f'State is not fulfilled. {self.unprocessed_epochs=}') + + for epoch in self._processed_epochs: + if l_epoch <= epoch <= r_epoch: + continue + raise InvalidState(f'Processed epoch {epoch} is out of range') + + for epoch in sequence(l_epoch, r_epoch): + if epoch not in self._processed_epochs: + raise InvalidState(f'Epoch {epoch} should be processed') + + def validate_for_collect(self, l_epoch: EpochNumber, r_epoch: EpochNumber): + invalidated = False + + for epoch in self._epochs_to_process: + if l_epoch <= epoch <= r_epoch: + continue + invalidated = True + break + + for epoch in self._processed_epochs: + if l_epoch <= epoch <= r_epoch: + continue + invalidated = True + break + + if invalidated: + logger.warning({"msg": "Discarding invalidated state cache"}) + self.clear() + self.commit() + + if self.is_empty or r_epoch > max(self._epochs_to_process): + self._epochs_to_process.update(sequence(l_epoch, r_epoch)) + self.commit() + + @property + def is_empty(self) -> bool: + return not self.data and not self._epochs_to_process and not self._processed_epochs + + @property + def unprocessed_epochs(self) -> set[EpochNumber]: + if not self._epochs_to_process: + raise ValueError("Epochs to process are not set") + return self._epochs_to_process - self._processed_epochs + + @property + def is_fulfilled(self) -> bool: + return not self.unprocessed_epochs + + @property + def avg_perf(self) -> float: + """Returns average performance of all validators in the cache""" + return self.network_aggr.perf + + @property + def network_aggr(self) -> AttestationsAggregate: + included = assigned = 0 + for aggr in self.data.values(): + assert aggr.included <= aggr.assigned + included += aggr.included + assigned += aggr.assigned + return AttestationsAggregate( + included=included, + assigned=assigned, + ) + + @property + def buffer(self) -> Path: + return self.file().with_suffix(".buf") + + def __bool__(self) -> bool: + return True diff --git a/src/modules/csm/tree.py b/src/modules/csm/tree.py new file mode 100644 index 000000000..a348ec9e0 --- /dev/null +++ b/src/modules/csm/tree.py @@ -0,0 +1,46 @@ +import json +from dataclasses import dataclass +from typing import Self, Sequence, TypeAlias + +from hexbytes import HexBytes +from oz_merkle_tree import StandardMerkleTree + +from src.web3py.extensions.lido_validators import NodeOperatorId + +Shares: TypeAlias = int +Leaf: TypeAlias = tuple[NodeOperatorId, Shares] + + +@dataclass +class Tree: + """A wrapper around StandardMerkleTree to cover use cases of the CSM oracle""" + + tree: StandardMerkleTree[Leaf] + + @property + def root(self) -> HexBytes: + return HexBytes(self.tree.root) + + @classmethod + def decode(cls, content: bytes) -> Self: + """Restore a tree from a supported binary representation""" + + try: + return cls(StandardMerkleTree.load(json.loads(content))) + except json.JSONDecodeError as e: + raise ValueError("Unsupported tree format") from e + + def encode(self) -> bytes: + """Convert the underlying StandardMerkleTree to a binary representation""" + + def default(o): + if isinstance(o, bytes): + return f"0x{o.hex()}" + raise ValueError(f"Unexpected type for json encoding, got {repr(o)}") + + return json.dumps(self.tree.dump(), indent=2, default=default).encode() + + @classmethod + def new(cls, values: Sequence[Leaf]) -> Self: + """Create new instance around the wrapped tree out of the given values""" + return cls(StandardMerkleTree(values, ("uint256", "uint256"))) diff --git a/src/modules/csm/types.py b/src/modules/csm/types.py new file mode 100644 index 000000000..9977372d2 --- /dev/null +++ b/src/modules/csm/types.py @@ -0,0 +1,28 @@ +import logging +from dataclasses import dataclass + +from hexbytes import HexBytes + +from src.providers.ipfs import CID +from src.types import SlotNumber + +logger = logging.getLogger(__name__) + + +@dataclass +class ReportData: + consensusVersion: int + ref_slot: SlotNumber + tree_root: HexBytes + tree_cid: CID + distributed: int + + def as_tuple(self): + # Tuple with report in correct order + return ( + self.consensusVersion, + self.ref_slot, + self.tree_root, + str(self.tree_cid), + self.distributed, + ) diff --git a/src/modules/ejector/ejector.py b/src/modules/ejector/ejector.py index 3df45f68f..851fffad3 100644 --- a/src/modules/ejector/ejector.py +++ b/src/modules/ejector/ejector.py @@ -4,39 +4,40 @@ from web3.types import Wei from src.constants import ( - CHURN_LIMIT_QUOTIENT, FAR_FUTURE_EPOCH, MAX_EFFECTIVE_BALANCE, - MAX_SEED_LOOKAHEAD, MAX_WITHDRAWALS_PER_PAYLOAD, - MIN_PER_EPOCH_CHURN_LIMIT, MIN_VALIDATOR_WITHDRAWABILITY_DELAY, ) -from src.metrics.prometheus.business import CONTRACT_ON_PAUSE, FRAME_PREV_REPORT_REF_SLOT +from src.metrics.prometheus.business import CONTRACT_ON_PAUSE from src.metrics.prometheus.ejector import ( EJECTOR_VALIDATORS_COUNT_TO_EJECT, EJECTOR_TO_WITHDRAW_WEI_AMOUNT, - EJECTOR_MAX_EXIT_EPOCH + EJECTOR_MAX_WITHDRAWAL_EPOCH, ) from src.metrics.prometheus.duration_meter import duration_meter from src.modules.ejector.data_encode import encode_data -from src.modules.ejector.typings import EjectorProcessingState, ReportData +from src.modules.ejector.types import ReportData from src.modules.submodules.consensus import ConsensusModule from src.modules.submodules.oracle_module import BaseModule, ModuleExecuteDelay -from src.providers.consensus.typings import Validator -from src.services.exit_order_iterator import ExitOrderIterator +from src.providers.consensus.types import Validator +from src.providers.execution.contracts.exit_bus_oracle import ExitBusOracleContract +from src.services.exit_order.iterator import ExitOrderIterator +from src.services.exit_order_v2.iterator import ValidatorExitIteratorV2 from src.services.prediction import RewardsPredictionService from src.services.validator_state import LidoValidatorStateService -from src.typings import BlockStamp, EpochNumber, ReferenceBlockStamp -from src.utils.abi import named_tuple_to_dataclass +from src.types import BlockStamp, EpochNumber, ReferenceBlockStamp, NodeOperatorGlobalIndex from src.utils.cache import global_lru_cache as lru_cache from src.utils.validator_state import ( is_active_validator, is_fully_withdrawable_validator, is_partially_withdrawable_validator, + compute_activation_exit_epoch, + compute_exit_churn_limit, ) -from src.web3py.extensions.lido_validators import LidoValidator, NodeOperatorGlobalIndex -from src.web3py.typings import Web3 +from src.web3py.extensions.lido_validators import LidoValidator +from src.web3py.types import Web3 + logger = logging.getLogger(__name__) @@ -58,13 +59,14 @@ class Ejector(BaseModule, ConsensusModule): 3. Decode lido validators into bytes and send report transaction """ - CONSENSUS_VERSION = 1 - CONTRACT_VERSION = 1 + COMPATIBLE_CONTRACT_VERSIONS = [1] + COMPATIBLE_CONSENSUS_VERSIONS = [1, 2] AVG_EXPECTING_WITHDRAWALS_SWEEP_DURATION_MULTIPLIER = 0.5 def __init__(self, w3: Web3): - self.report_contract = w3.lido_contracts.validators_exit_bus_oracle + self.report_contract: ExitBusOracleContract = w3.lido_contracts.validators_exit_bus_oracle + super().__init__(w3) self.prediction_service = RewardsPredictionService(w3) @@ -85,8 +87,9 @@ def execute_module(self, last_finalized_blockstamp: BlockStamp) -> ModuleExecute @lru_cache(maxsize=1) @duration_meter() def build_report(self, blockstamp: ReferenceBlockStamp) -> tuple: - last_report_ref_slot = self.w3.lido_contracts.get_ejector_last_processing_ref_slot(blockstamp) - FRAME_PREV_REPORT_REF_SLOT.set(last_report_ref_slot) + # For metrics only + self.w3.lido_contracts.get_ejector_last_processing_ref_slot(blockstamp) + validators: list[tuple[NodeOperatorGlobalIndex, LidoValidator]] = self.get_validators_to_eject(blockstamp) logger.info({ 'msg': f'Calculate validators to eject. Count: {len(validators)}', @@ -96,7 +99,7 @@ def build_report(self, blockstamp: ReferenceBlockStamp) -> tuple: data, data_format = encode_data(validators) report_data = ReportData( - self.CONSENSUS_VERSION, + self.report_contract.get_consensus_version(blockstamp.block_hash), blockstamp.ref_slot, len(validators), data_format, @@ -108,24 +111,45 @@ def build_report(self, blockstamp: ReferenceBlockStamp) -> tuple: return report_data.as_tuple() def get_validators_to_eject(self, blockstamp: ReferenceBlockStamp) -> list[tuple[NodeOperatorGlobalIndex, LidoValidator]]: - to_withdraw_amount = self.get_total_unfinalized_withdrawal_requests_amount(blockstamp) + to_withdraw_amount = self.w3.lido_contracts.withdrawal_queue_nft.unfinalized_steth(blockstamp.block_hash) + EJECTOR_TO_WITHDRAW_WEI_AMOUNT.set(to_withdraw_amount) logger.info({'msg': 'Calculate to withdraw amount.', 'value': to_withdraw_amount}) - EJECTOR_TO_WITHDRAW_WEI_AMOUNT.set(to_withdraw_amount) + expected_balance = self._get_total_expected_balance(0, blockstamp) - if to_withdraw_amount == Wei(0): - return [] + consensus_version = self.w3.lido_contracts.validators_exit_bus_oracle.get_consensus_version(blockstamp.block_hash) + validators_iterator = iter(self.get_validators_iterator(consensus_version, blockstamp)) - chain_config = self.get_chain_config(blockstamp) + validators_to_eject: list[tuple[NodeOperatorGlobalIndex, LidoValidator]] = [] + validator_to_eject_balance_sum = 0 - rewards_speed_per_epoch = self.prediction_service.get_rewards_per_epoch(blockstamp, chain_config) - logger.info({'msg': 'Calculate average rewards speed per epoch.', 'value': rewards_speed_per_epoch}) + try: + while expected_balance < to_withdraw_amount: + gid, next_validator = next(validators_iterator) + validators_to_eject.append((gid, next_validator)) + validator_to_eject_balance_sum += self._get_predicted_withdrawable_balance(next_validator) + expected_balance = self._get_total_expected_balance(len(validators_to_eject), blockstamp) + validator_to_eject_balance_sum + except StopIteration: + pass - epochs_to_sweep = self._get_sweep_delay_in_epochs(blockstamp) - logger.info({'msg': 'Calculate epochs to sweep.', 'value': epochs_to_sweep}) + logger.info({ + 'msg': 'Calculate validators to eject', + 'expected_balance': expected_balance, + 'to_withdraw_amount': to_withdraw_amount, + 'validators_to_eject_count': len(validators_to_eject), + }) + + if consensus_version != 1: + forced_validators = validators_iterator.get_remaining_forced_validators() + if forced_validators: + logger.info({'msg': 'Eject forced to exit validators.', 'value': len(forced_validators)}) + validators_to_eject.extend(forced_validators) - total_available_balance = self._get_total_el_balance(blockstamp) - logger.info({'msg': 'Calculate el balance.', 'value': total_available_balance}) + return validators_to_eject + + @lru_cache(maxsize=1) + def _get_total_expected_balance(self, vals_to_exit: int, blockstamp: ReferenceBlockStamp): + chain_config = self.get_chain_config(blockstamp) validators_going_to_exit = self.validators_state_service.get_recently_requested_but_not_exited_validators(blockstamp, chain_config) going_to_withdraw_balance = sum(map( @@ -134,72 +158,54 @@ def get_validators_to_eject(self, blockstamp: ReferenceBlockStamp) -> list[tuple )) logger.info({'msg': 'Calculate going to exit validators balance.', 'value': going_to_withdraw_balance}) - validators_to_eject: list[tuple[NodeOperatorGlobalIndex, LidoValidator]] = [] - validator_to_eject_balance_sum = 0 + epochs_to_sweep = self._get_sweep_delay_in_epochs(blockstamp) + logger.info({'msg': 'Calculate epochs to sweep.', 'value': epochs_to_sweep}) - validators_iterator = ExitOrderIterator( - web3=self.w3, - blockstamp=blockstamp, - chain_config=chain_config - ) + rewards_speed_per_epoch = self.prediction_service.get_rewards_per_epoch(blockstamp, chain_config) + logger.info({'msg': 'Calculate average rewards speed per epoch.', 'value': rewards_speed_per_epoch}) - for validator_container in validators_iterator: - withdrawal_epoch = self._get_predicted_withdrawable_epoch(blockstamp, len(validators_to_eject) + len(validators_going_to_exit) + 1) - future_rewards = (withdrawal_epoch + epochs_to_sweep - blockstamp.ref_epoch) * rewards_speed_per_epoch + withdrawal_epoch = self._get_predicted_withdrawable_epoch(blockstamp, len(validators_going_to_exit) + vals_to_exit + 1) + logger.info({'msg': 'Withdrawal epoch', 'value': withdrawal_epoch}) + EJECTOR_MAX_WITHDRAWAL_EPOCH.set(withdrawal_epoch) - future_withdrawals = self._get_withdrawable_lido_validators_balance(blockstamp, withdrawal_epoch) + future_withdrawals = self._get_withdrawable_lido_validators_balance(withdrawal_epoch, blockstamp) + future_rewards = (withdrawal_epoch + epochs_to_sweep - blockstamp.ref_epoch) * rewards_speed_per_epoch + logger.info({'msg': 'Calculate future rewards.', 'value': future_rewards}) - expected_balance = ( - future_withdrawals + # Validators that have withdrawal_epoch - future_rewards + # Rewards we get until last validator in validators_to_eject will be withdrawn - total_available_balance + # Current EL balance (el vault, wc vault, buffered eth) - validator_to_eject_balance_sum + # Validators that we expected to be ejected (requested to exit, not delayed) - going_to_withdraw_balance # validators_to_eject balance - ) - if expected_balance >= to_withdraw_amount: - logger.info({ - 'msg': f'Expected withdrawal epoch: {withdrawal_epoch=}, ' - f'will be reached in {withdrawal_epoch - blockstamp.ref_epoch} epochs. ' - f'Validators with withdrawal_epoch before expected: {future_withdrawals=}. ' - f'Future rewards from skimming and EL rewards: {future_rewards=}. ' - f'Currently available balance: {total_available_balance=}. ' - f'Validators expecting to start exit balance: {validator_to_eject_balance_sum=}. ' - f'Validators going to eject balance: {going_to_withdraw_balance=}. ', - 'withdrawal_epoch': withdrawal_epoch, - 'ref_epoch': blockstamp.ref_epoch, - 'future_withdrawals': future_withdrawals, - 'future_rewards': future_rewards, - 'total_available_balance': total_available_balance, - 'validator_to_eject_balance_sum': validator_to_eject_balance_sum, - 'going_to_withdraw_balance': going_to_withdraw_balance, - }) - - return validators_to_eject - - validators_to_eject.append(validator_container) - (_, validator) = validator_container - validator_to_eject_balance_sum += self._get_predicted_withdrawable_balance(validator) + total_available_balance = self._get_total_el_balance(blockstamp) + logger.info({'msg': 'Calculate el balance.', 'value': total_available_balance}) - return validators_to_eject + return future_rewards + future_withdrawals + total_available_balance + going_to_withdraw_balance - def _is_paused(self, blockstamp: ReferenceBlockStamp) -> bool: - return self.report_contract.functions.isPaused().call(block_identifier=blockstamp.block_hash) + def get_validators_iterator(self, consensus_version: int, blockstamp: ReferenceBlockStamp): + chain_config = self.get_chain_config(blockstamp) + + if consensus_version == 1: + return ExitOrderIterator( + web3=self.w3, + blockstamp=blockstamp, + chain_config=chain_config + ) + + return ValidatorExitIteratorV2( + w3=self.w3, + blockstamp=blockstamp, + seconds_per_slot=chain_config.seconds_per_slot + ) def is_reporting_allowed(self, blockstamp: ReferenceBlockStamp) -> bool: - on_pause = self._is_paused(blockstamp) - CONTRACT_ON_PAUSE.set(on_pause) + on_pause = self.report_contract.is_paused(blockstamp.block_hash) + CONTRACT_ON_PAUSE.labels('reporting').set(on_pause) logger.info({'msg': 'Fetch isPaused from ejector bus contract.', 'value': on_pause}) return not on_pause @lru_cache(maxsize=1) - def _get_withdrawable_lido_validators_balance(self, blockstamp: BlockStamp, on_epoch: EpochNumber) -> Wei: + def _get_withdrawable_lido_validators_balance(self, on_epoch: EpochNumber, blockstamp: BlockStamp) -> Wei: lido_validators = self.w3.lido_validators.get_lido_validators(blockstamp=blockstamp) def get_total_withdrawable_balance(balance: Wei, validator: Validator) -> Wei: if is_fully_withdrawable_validator(validator, on_epoch): - balance = Wei( - balance + self._get_predicted_withdrawable_balance(validator) - ) + return Wei(balance + self._get_predicted_withdrawable_balance(validator)) return balance @@ -215,32 +221,13 @@ def _get_predicted_withdrawable_balance(self, validator: Validator) -> Wei: return self.w3.to_wei(min(int(validator.balance), MAX_EFFECTIVE_BALANCE), 'gwei') def _get_total_el_balance(self, blockstamp: BlockStamp) -> Wei: - total_el_balance = Wei( + return Wei( self.w3.lido_contracts.get_el_vault_balance(blockstamp) + self.w3.lido_contracts.get_withdrawal_balance(blockstamp) + - self._get_buffer_ether(blockstamp) - ) - return total_el_balance - - def _get_buffer_ether(self, blockstamp: BlockStamp) -> Wei: - """ - The reserved buffered ether is min(current_buffered_ether, unfinalized_withdrawal_requests_amount) - We can skip calculating reserved buffer for ejector, because in case if - (unfinalized_withdrawal_requests_amount <= current_buffered_ether) - We won't eject validators at all, because we have enough eth to fulfill all requests. - """ - return Wei( - self.w3.lido_contracts.lido.functions.getBufferedEther().call( - block_identifier=blockstamp.block_hash - ) + self.w3.lido_contracts.lido.get_buffered_ether(blockstamp.block_hash) ) - def get_total_unfinalized_withdrawal_requests_amount(self, blockstamp: BlockStamp) -> Wei: - unfinalized_steth = self.w3.lido_contracts.withdrawal_queue_nft.functions.unfinalizedStETH().call( - block_identifier=blockstamp.block_hash, - ) - return unfinalized_steth - + @lru_cache(maxsize=1) def _get_predicted_withdrawable_epoch( self, blockstamp: ReferenceBlockStamp, @@ -251,39 +238,28 @@ def _get_predicted_withdrawable_epoch( """ max_exit_epoch_number, latest_to_exit_validators_count = self._get_latest_exit_epoch(blockstamp) - activation_exit_epoch = self.compute_activation_exit_epoch(blockstamp) + activation_exit_epoch = compute_activation_exit_epoch(blockstamp.ref_epoch) if activation_exit_epoch > max_exit_epoch_number: max_exit_epoch_number = activation_exit_epoch latest_to_exit_validators_count = 0 - EJECTOR_MAX_EXIT_EPOCH.set(max_exit_epoch_number) - churn_limit = self._get_churn_limit(blockstamp) - remain_exits_capacity_for_epoch = churn_limit - latest_to_exit_validators_count - epochs_required_to_exit_validators = (validators_to_eject_count - remain_exits_capacity_for_epoch) // churn_limit + 1 + epochs_required_to_exit_validators = (validators_to_eject_count + latest_to_exit_validators_count) // churn_limit return EpochNumber(max_exit_epoch_number + epochs_required_to_exit_validators + MIN_VALIDATOR_WITHDRAWABILITY_DELAY) - @staticmethod - def compute_activation_exit_epoch(blockstamp: ReferenceBlockStamp): - """ - Return the epoch during which validator activations and exits initiated in ``epoch`` take effect. - - Spec: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#compute_activation_exit_epoch - """ - return blockstamp.ref_epoch + 1 + MAX_SEED_LOOKAHEAD - - @lru_cache(maxsize=1) - def _get_latest_exit_epoch(self, blockstamp: BlockStamp) -> tuple[EpochNumber, int]: + def _get_latest_exit_epoch(self, blockstamp: ReferenceBlockStamp) -> tuple[EpochNumber, int]: """ Returns the latest exit epoch and amount of validators that are exiting in this epoch """ max_exit_epoch_number = EpochNumber(0) latest_to_exit_validators_count = 0 - for validator in self.w3.cc.get_validators(blockstamp): + validators = self.w3.cc.get_validators(blockstamp) + + for validator in validators: val_exit_epoch = EpochNumber(int(validator.validator.exit_epoch)) if val_exit_epoch == FAR_FUTURE_EPOCH: @@ -296,40 +272,49 @@ def _get_latest_exit_epoch(self, blockstamp: BlockStamp) -> tuple[EpochNumber, i max_exit_epoch_number = val_exit_epoch latest_to_exit_validators_count = 1 + logger.info({ + 'msg': 'Calculate latest exit epoch', + 'value': max_exit_epoch_number, + 'latest_to_exit_validators_count': latest_to_exit_validators_count, + }) + return max_exit_epoch_number, latest_to_exit_validators_count + @lru_cache(maxsize=1) def _get_sweep_delay_in_epochs(self, blockstamp: ReferenceBlockStamp) -> int: """Returns amount of epochs that will take to sweep all validators in chain.""" - validators = self.w3.cc.get_validators(blockstamp) + chain_config = self.get_chain_config(blockstamp) + total_withdrawable_validators = self._get_total_withdrawable_validators(blockstamp) + full_sweep_in_epochs = total_withdrawable_validators / MAX_WITHDRAWALS_PER_PAYLOAD / chain_config.slots_per_epoch + return int(full_sweep_in_epochs * self.AVG_EXPECTING_WITHDRAWALS_SWEEP_DURATION_MULTIPLIER) + + def _get_total_withdrawable_validators(self, blockstamp: ReferenceBlockStamp) -> int: total_withdrawable_validators = len(list(filter(lambda validator: ( is_partially_withdrawable_validator(validator) or is_fully_withdrawable_validator(validator, blockstamp.ref_epoch) - ), validators))) + ), self.w3.cc.get_validators(blockstamp)))) - chain_config = self.get_chain_config(blockstamp) - full_sweep_in_epochs = total_withdrawable_validators / MAX_WITHDRAWALS_PER_PAYLOAD / chain_config.slots_per_epoch - return int(full_sweep_in_epochs * self.AVG_EXPECTING_WITHDRAWALS_SWEEP_DURATION_MULTIPLIER) + logger.info({'msg': 'Calculate total withdrawable validators.', 'value': total_withdrawable_validators}) + return total_withdrawable_validators @lru_cache(maxsize=1) def _get_churn_limit(self, blockstamp: ReferenceBlockStamp) -> int: - total_active_validators = reduce( - lambda total, validator: total + int(is_active_validator(validator, blockstamp.ref_epoch)), - self.w3.cc.get_validators(blockstamp), - 0, - ) - return max(MIN_PER_EPOCH_CHURN_LIMIT, total_active_validators // CHURN_LIMIT_QUOTIENT) - - def _get_processing_state(self, blockstamp: BlockStamp) -> EjectorProcessingState: - ps = named_tuple_to_dataclass( - self.report_contract.functions.getProcessingState().call(block_identifier=blockstamp.block_hash), - EjectorProcessingState, - ) - logger.info({'msg': 'Fetch processing state.', 'value': ps}) - return ps + total_active_validators = self._get_total_active_validators(blockstamp) + churn_limit = compute_exit_churn_limit(total_active_validators) + logger.info({'msg': 'Calculate churn limit.', 'value': churn_limit}) + return churn_limit + + def _get_total_active_validators(self, blockstamp: ReferenceBlockStamp) -> int: + total_active_validators = len([ + is_active_validator(val, blockstamp.ref_epoch) + for val in self.w3.cc.get_validators(blockstamp) + ]) + logger.info({'msg': 'Calculate total active validators.', 'value': total_active_validators}) + return total_active_validators def is_main_data_submitted(self, blockstamp: BlockStamp) -> bool: - processing_state = self._get_processing_state(blockstamp) + processing_state = self.report_contract.get_processing_state(blockstamp.block_hash) return processing_state.data_submitted def is_contract_reportable(self, blockstamp: BlockStamp) -> bool: diff --git a/src/modules/ejector/typings.py b/src/modules/ejector/types.py similarity index 94% rename from src/modules/ejector/typings.py rename to src/modules/ejector/types.py index fa5c9f9ff..c60268e0c 100644 --- a/src/modules/ejector/typings.py +++ b/src/modules/ejector/types.py @@ -1,6 +1,6 @@ from dataclasses import dataclass -from src.typings import SlotNumber +from src.types import SlotNumber @dataclass diff --git a/src/modules/submodules/consensus.py b/src/modules/submodules/consensus.py index a9314e617..d9722798f 100644 --- a/src/modules/submodules/consensus.py +++ b/src/modules/submodules/consensus.py @@ -1,30 +1,30 @@ import logging from abc import ABC, abstractmethod from time import sleep -from typing import Optional +from typing import cast from eth_abi import encode -from eth_typing import ChecksumAddress from hexbytes import HexBytes -from web3.contract import AsyncContract, Contract from src import variables from src.metrics.prometheus.basic import ORACLE_SLOT_NUMBER, ORACLE_BLOCK_NUMBER, GENESIS_TIME, ACCOUNT_BALANCE -from src.typings import BlockStamp, ReferenceBlockStamp, SlotNumber +from src.providers.execution.contracts.base_oracle import BaseOracleContract +from src.providers.execution.contracts.hash_consensus import HashConsensusContract +from src.types import BlockStamp, ReferenceBlockStamp, SlotNumber from src.metrics.prometheus.business import ( ORACLE_MEMBER_LAST_REPORT_REF_SLOT, FRAME_CURRENT_REF_SLOT, FRAME_DEADLINE_SLOT, ORACLE_MEMBER_INFO ) -from src.modules.submodules.exceptions import IsNotMemberException, IncompatibleContractVersion -from src.modules.submodules.typings import ChainConfig, MemberInfo, ZERO_HASH, CurrentFrame, FrameConfig -from src.utils.abi import named_tuple_to_dataclass +from src.modules.submodules.exceptions import IsNotMemberException, IncompatibleOracleVersion +from src.modules.submodules.types import ChainConfig, MemberInfo, ZERO_HASH, CurrentFrame, FrameConfig from src.utils.blockstamp import build_blockstamp from src.utils.web3converter import Web3Converter from src.utils.slot import get_reference_blockstamp from src.utils.cache import global_lru_cache as lru_cache -from src.web3py.typings import Web3 +from src.web3py.types import Web3 + logger = logging.getLogger(__name__) @@ -40,10 +40,10 @@ class ConsensusModule(ABC): report_contract should contain getConsensusContract method. """ - report_contract: Contract + report_contract: BaseOracleContract - CONTRACT_VERSION: int - CONSENSUS_VERSION: int + COMPATIBLE_CONTRACT_VERSIONS: list[int] + COMPATIBLE_CONSENSUS_VERSIONS: list[int] def __init__(self, w3: Web3): self.w3 = w3 @@ -51,8 +51,11 @@ def __init__(self, w3: Web3): if getattr(self, "report_contract", None) is None: raise NotImplementedError('report_contract attribute should be set.') - if getattr(self, "CONTRACT_VERSION", None) is None or getattr(self, "CONSENSUS_VERSION", None) is None: - raise NotImplementedError('CONTRACT_VERSION and CONSENSUS_VERSION should be set.') + if getattr(self, "COMPATIBLE_CONTRACT_VERSIONS", None) is None: + raise NotImplementedError('COMPATIBLE_CONTRACT_VERSIONS attribute should be set.') + + if getattr(self, "COMPATIBLE_CONSENSUS_VERSIONS", None) is None: + raise NotImplementedError('COMPATIBLE_CONSENSUS_VERSIONS attribute should be set.') def check_contract_configs(self): root = self.w3.cc.get_block_root('head').root @@ -72,50 +75,36 @@ def check_contract_configs(self): # ----- Web3 data requests ----- @lru_cache(maxsize=1) - def _get_consensus_contract(self, blockstamp: BlockStamp) -> Contract | AsyncContract: - return self.w3.eth.contract( - address=self._get_consensus_contract_address(blockstamp), - abi=self.w3.lido_contracts.load_abi('HashConsensus'), + def _get_consensus_contract(self, blockstamp: BlockStamp) -> HashConsensusContract: + return cast(HashConsensusContract, self.w3.eth.contract( + address=self.report_contract.get_consensus_contract(blockstamp.block_hash), + ContractFactoryClass=HashConsensusContract, decode_tuples=True, - ) - - def _get_consensus_contract_address(self, blockstamp: BlockStamp) -> ChecksumAddress: - return self.report_contract.functions.getConsensusContract().call(block_identifier=blockstamp.block_hash) + )) def _get_consensus_contract_members(self, blockstamp: BlockStamp): consensus_contract = self._get_consensus_contract(blockstamp) - members, last_reported_ref_slots = consensus_contract.functions.getMembers().call(block_identifier=blockstamp.block_hash) - return members, last_reported_ref_slots + return consensus_contract.get_members(blockstamp.block_hash) @lru_cache(maxsize=1) def get_chain_config(self, blockstamp: BlockStamp) -> ChainConfig: consensus_contract = self._get_consensus_contract(blockstamp) - cc = named_tuple_to_dataclass( - consensus_contract.functions.getChainConfig().call(block_identifier=blockstamp.block_hash), - ChainConfig, - ) - logger.info({'msg': 'Fetch chain config.', 'value': cc}) - return cc + return consensus_contract.get_chain_config(blockstamp.block_hash) @lru_cache(maxsize=1) def get_current_frame(self, blockstamp: BlockStamp) -> CurrentFrame: consensus_contract = self._get_consensus_contract(blockstamp) - cf = named_tuple_to_dataclass( - consensus_contract.functions.getCurrentFrame().call(block_identifier=blockstamp.block_hash), - CurrentFrame, - ) - logger.info({'msg': 'Fetch current frame.', 'value': cf}) - return cf + return consensus_contract.get_current_frame(blockstamp.block_hash) + + @lru_cache(maxsize=1) + def get_initial_ref_slot(self, blockstamp: BlockStamp) -> SlotNumber: + consensus_contract = self._get_consensus_contract(blockstamp) + return consensus_contract.get_initial_ref_slot(blockstamp.block_hash) @lru_cache(maxsize=1) def get_frame_config(self, blockstamp: BlockStamp) -> FrameConfig: consensus_contract = self._get_consensus_contract(blockstamp) - fc = named_tuple_to_dataclass( - consensus_contract.functions.getFrameConfig().call(block_identifier=blockstamp.block_hash), - FrameConfig, - ) - logger.info({'msg': 'Fetch frame config.', 'value': fc}) - return fc + return consensus_contract.get_frame_config(blockstamp.block_hash) @lru_cache(maxsize=1) def get_member_info(self, blockstamp: BlockStamp) -> MemberInfo: @@ -144,9 +133,10 @@ def get_member_info(self, blockstamp: BlockStamp) -> MemberInfo: last_member_report_ref_slot, # The hash reported by the member for the current frame, if any. current_frame_member_report, - ) = consensus_contract.functions.getConsensusStateForMember( + ) = consensus_contract.get_consensus_state_for_member( variables.ACCOUNT.address, - ).call(block_identifier=blockstamp.block_hash) + blockstamp.block_hash, + ) is_submit_member = self._is_submit_member(blockstamp) @@ -175,20 +165,14 @@ def _is_submit_member(self, blockstamp: BlockStamp) -> bool: if not variables.ACCOUNT: return True - submit_role = self.report_contract.functions.SUBMIT_DATA_ROLE().call( - block_identifier=blockstamp.block_hash, - ) - is_submit_member = self.report_contract.functions.hasRole( - submit_role, + return self.report_contract.has_role( + self.report_contract.submit_data_role(blockstamp.block_hash), variables.ACCOUNT.address, - ).call( - block_identifier=blockstamp.block_hash, + blockstamp.block_hash ) - return is_submit_member - # ----- Calculation reference slot for report ----- - def get_blockstamp_for_report(self, last_finalized_blockstamp: BlockStamp) -> Optional[ReferenceBlockStamp]: + def get_blockstamp_for_report(self, last_finalized_blockstamp: BlockStamp) -> ReferenceBlockStamp | None: """ Get blockstamp that should be used to build and send report for current frame. Returns: @@ -196,13 +180,6 @@ def get_blockstamp_for_report(self, last_finalized_blockstamp: BlockStamp) -> Op """ latest_blockstamp = self._get_latest_blockstamp() - if not self._check_contract_versions(latest_blockstamp): - logger.info({ - 'msg': 'Oracle\'s version is higher than contract and/or consensus version. ' - 'Skipping report. Waiting for Contracts to be updated.', - }) - return None - # Check if contract is currently reportable if not self.is_contract_reportable(latest_blockstamp): logger.info({'msg': 'Contract is not reportable.'}) @@ -233,29 +210,29 @@ def get_blockstamp_for_report(self, last_finalized_blockstamp: BlockStamp) -> Op last_finalized_slot_number=last_finalized_blockstamp.slot_number, ) logger.info({'msg': 'Calculate blockstamp for report.', 'value': bs}) - return bs - def _check_contract_versions(self, blockstamp: BlockStamp) -> bool: - contract_version = self.report_contract.functions.getContractVersion().call(block_identifier=blockstamp.block_hash) - consensus_version = self.report_contract.functions.getConsensusVersion().call(block_identifier=blockstamp.block_hash) + # Make sure module is compatible with contracts on reference blockstamp. + self._check_contract_versions(bs) + return bs - if contract_version > self.CONTRACT_VERSION or consensus_version > self.CONSENSUS_VERSION: - raise IncompatibleContractVersion( - f'Incompatible Oracle version. ' - f'Expected contract version {contract_version} got {self.CONTRACT_VERSION}. ' - f'Expected consensus version {consensus_version} got {self.CONSENSUS_VERSION}.' - ) + def _check_contract_versions(self, blockstamp: ReferenceBlockStamp): + """ + Check if Oracle can process report on reference blockstamp. + """ + contract_version = self.report_contract.get_contract_version(blockstamp.block_hash) + consensus_version = self.report_contract.get_consensus_version(blockstamp.block_hash) - compatibility = contract_version == self.CONTRACT_VERSION and consensus_version == self.CONSENSUS_VERSION + compatibility = ( + contract_version in self.COMPATIBLE_CONTRACT_VERSIONS + and consensus_version in self.COMPATIBLE_CONSENSUS_VERSIONS + ) if not compatibility: - logger.warning({ - 'msg': f'Oracle\'s version higher than contract supports. ' - f'Expected contract version {contract_version} got {self.CONTRACT_VERSION}. ' - f'Expected consensus version {consensus_version} got {self.CONSENSUS_VERSION}.' - }) - - return compatibility + raise IncompatibleOracleVersion( + f'Incompatible Oracle version. ' + f'Expected contract versions, one of: {self.COMPATIBLE_CONTRACT_VERSIONS} got {contract_version}. ' + f'Expected consensus versions, one of: {self.COMPATIBLE_CONSENSUS_VERSIONS} got {consensus_version}.' + ) # ----- Working with report ----- def process_report(self, blockstamp: ReferenceBlockStamp) -> None: @@ -264,7 +241,7 @@ def process_report(self, blockstamp: ReferenceBlockStamp) -> None: logger.info({'msg': 'Build report.', 'value': report_data}) report_hash = self._encode_data_hash(report_data) - logger.info({'msg': 'Calculate report hash.', 'value': report_hash}) + logger.info({'msg': 'Calculate report hash.', 'value': repr(report_hash)}) # We need to check whether report has unexpected data before sending. # otherwise we have to check it manually. if not self.is_reporting_allowed(blockstamp): @@ -297,8 +274,10 @@ def _process_report_hash(self, blockstamp: ReferenceBlockStamp, report_hash: Hex logger.info({'msg': 'Consensus reached with provided hash.'}) return None - logger.info({'msg': f'Send report hash. Consensus version: [{self.CONSENSUS_VERSION}]'}) - self._send_report_hash(blockstamp, report_hash, self.CONSENSUS_VERSION) + consensus_version = self.report_contract.get_consensus_version(blockstamp.block_hash) + + logger.info({'msg': f'Send report hash. Consensus version: [{consensus_version}]'}) + self._send_report_hash(blockstamp, report_hash, consensus_version) return None def _process_report_data(self, blockstamp: ReferenceBlockStamp, report_data: tuple, report_hash: HexBytes): @@ -312,8 +291,8 @@ def _process_report_data(self, blockstamp: ReferenceBlockStamp, report_data: tup msg = 'Oracle`s hash differs from consensus report hash.' logger.error({ 'msg': msg, - 'consensus_report_hash': str(HexBytes(member_info.current_frame_consensus_report)), - 'report_hash': str(report_hash), + 'consensus_report_hash': HexBytes(member_info.current_frame_consensus_report).hex(), + 'report_hash': report_hash.hex(), }) return @@ -338,9 +317,11 @@ def _process_report_data(self, blockstamp: ReferenceBlockStamp, report_data: tup logger.info({'msg': 'Main data already submitted.'}) return - logger.info({'msg': f'Send report data. Contract version: [{self.CONTRACT_VERSION}]'}) + contract_version = self.report_contract.get_contract_version(blockstamp.block_hash) + + logger.info({'msg': f'Send report data. Contract version: [{contract_version}]'}) # If data already submitted transaction will be locally reverted, no need to check status manually - self._submit_report(report_data, self.CONTRACT_VERSION) + self._submit_report(report_data, contract_version) def _get_latest_data(self) -> tuple[BlockStamp, MemberInfo]: latest_blockstamp = self._get_latest_blockstamp() @@ -365,7 +346,7 @@ def _get_latest_data(self) -> tuple[BlockStamp, MemberInfo]: return latest_blockstamp, member_info - def _encode_data_hash(self, report_data: tuple): + def _encode_data_hash(self, report_data: tuple) -> HexBytes: # The Accounting Oracle and Ejector Bus has same named method to report data report_function_name = 'submitReportData' @@ -386,12 +367,12 @@ def _encode_data_hash(self, report_data: tuple): def _send_report_hash(self, blockstamp: ReferenceBlockStamp, report_hash: bytes, consensus_version: int): consensus_contract = self._get_consensus_contract(blockstamp) - tx = consensus_contract.functions.submitReport(blockstamp.ref_slot, report_hash, consensus_version) + tx = consensus_contract.submit_report(blockstamp.ref_slot, report_hash, consensus_version) self.w3.transaction.check_and_send_transaction(tx, variables.ACCOUNT) def _submit_report(self, report: tuple, contract_version: int): - tx = self.report_contract.functions.submitReportData(report, contract_version) + tx = self.report_contract.submit_report_data(report, contract_version) self.w3.transaction.check_and_send_transaction(tx, variables.ACCOUNT) diff --git a/src/modules/submodules/exceptions.py b/src/modules/submodules/exceptions.py index 039775ec3..aadc55c10 100644 --- a/src/modules/submodules/exceptions.py +++ b/src/modules/submodules/exceptions.py @@ -2,5 +2,5 @@ class IsNotMemberException(Exception): pass -class IncompatibleContractVersion(Exception): +class IncompatibleOracleVersion(Exception): pass diff --git a/src/modules/submodules/oracle_module.py b/src/modules/submodules/oracle_module.py index f93e3b5dd..f23ae795a 100644 --- a/src/modules/submodules/oracle_module.py +++ b/src/modules/submodules/oracle_module.py @@ -6,20 +6,23 @@ from requests.exceptions import ConnectionError as RequestsConnectionError from timeout_decorator import timeout, TimeoutError as DecoratorTimeoutError +from web3.exceptions import Web3Exception +from src.metrics.healthcheck_server import pulse from src.metrics.prometheus.basic import ORACLE_BLOCK_NUMBER, ORACLE_SLOT_NUMBER -from src.modules.submodules.exceptions import IsNotMemberException, IncompatibleContractVersion +from src.modules.submodules.exceptions import IsNotMemberException, IncompatibleOracleVersion from src.providers.http_provider import NotOkResponse +from src.providers.ipfs import IPFSError from src.providers.keys.client import KeysOutdatedException from src.utils.cache import clear_global_cache from src.web3py.extensions.lido_validators import CountOfKeysDiffersException from src.utils.blockstamp import build_blockstamp from src.utils.slot import NoSlotsAvailable, SlotNotFinalized, InconsistentData -from src.web3py.typings import Web3 +from src.web3py.types import Web3 from web3_multi_provider import NoActiveProviderError from src import variables -from src.typings import SlotNumber, BlockStamp, BlockRoot +from src.types import SlotNumber, BlockStamp, BlockRoot logger = logging.getLogger(__name__) @@ -50,7 +53,7 @@ def __init__(self, w3: Web3): def run_as_daemon(self): logger.info({'msg': 'Run module as daemon.'}) while True: - logger.info({'msg': 'Startup new cycle.'}) + logger.debug({'msg': 'Startup new cycle.'}) self.cycle_handler() @timeout(variables.MAX_CYCLE_LIFETIME_IN_SECONDS) @@ -84,14 +87,15 @@ def _receive_last_finalized_slot(self) -> BlockStamp: return bs def run_cycle(self, blockstamp: BlockStamp) -> ModuleExecuteDelay: + # pylint: disable=too-many-branches logger.info({'msg': 'Execute module.', 'value': blockstamp}) try: - return self.execute_module(blockstamp) + result = self.execute_module(blockstamp) except IsNotMemberException as exception: logger.error({'msg': 'Provided account is not part of Oracle`s committee.'}) raise exception - except IncompatibleContractVersion as exception: + except IncompatibleOracleVersion as exception: logger.error({'msg': 'Incompatible Contract version. Please update Oracle Daemon.'}) raise exception except DecoratorTimeoutError as exception: @@ -108,8 +112,16 @@ def run_cycle(self, blockstamp: BlockStamp) -> ModuleExecuteDelay: logger.error({'msg': 'Keys API service returns outdated data.', 'error': str(error)}) except CountOfKeysDiffersException as error: logger.error({'msg': 'Keys API service returned incorrect number of keys.', 'error': str(error)}) + except Web3Exception as error: + logger.error({'msg': 'Web3py exception.', 'error': str(error)}) + except IPFSError as error: + logger.error({'msg': 'IPFS provider error.', 'error': str(error)}) except ValueError as error: logger.error({'msg': 'Unexpected error.', 'error': str(error)}) + else: + # if there are no exceptions, then pulse + pulse() + return result return ModuleExecuteDelay.NEXT_SLOT diff --git a/src/modules/submodules/typings.py b/src/modules/submodules/types.py similarity index 95% rename from src/modules/submodules/typings.py rename to src/modules/submodules/types.py index 6a9101920..5cd940b86 100644 --- a/src/modules/submodules/typings.py +++ b/src/modules/submodules/types.py @@ -1,6 +1,9 @@ from dataclasses import dataclass -from src.typings import SlotNumber +from src.types import SlotNumber + + +ZERO_HASH = bytes([0]*32) @dataclass @@ -36,6 +39,3 @@ class FrameConfig: initial_epoch: int epochs_per_frame: int fast_lane_length_slots: int - - -ZERO_HASH = bytes([0]*32) diff --git a/src/providers/consensus/client.py b/src/providers/consensus/client.py index adcb8a456..c7dd324d9 100644 --- a/src/providers/consensus/client.py +++ b/src/providers/consensus/client.py @@ -1,9 +1,11 @@ from http import HTTPStatus -from typing import Literal, Optional, Union +from typing import Literal, cast + +from json_stream.base import TransientStreamingJSONObject # type: ignore from src.metrics.logging import logging from src.metrics.prometheus.basic import CL_REQUESTS_DURATION -from src.providers.consensus.typings import ( +from src.providers.consensus.types import ( BlockDetailsResponse, BlockHeaderFullResponse, BlockHeaderResponseData, @@ -11,9 +13,10 @@ Validator, BeaconSpecResponse, GenesisResponse, + SlotAttestationCommittee, BlockAttestation, ) from src.providers.http_provider import HTTPProvider, NotOkResponse -from src.typings import BlockRoot, BlockStamp, SlotNumber +from src.types import BlockRoot, BlockStamp, SlotNumber, EpochNumber from src.utils.dataclass import list_of_dataclasses from src.utils.cache import global_lru_cache as lru_cache @@ -36,6 +39,9 @@ class ConsensusClient(HTTPProvider): API_GET_BLOCK_ROOT = 'eth/v1/beacon/blocks/{}/root' API_GET_BLOCK_HEADER = 'eth/v1/beacon/headers/{}' API_GET_BLOCK_DETAILS = 'eth/v2/beacon/blocks/{}' + API_GET_BLOCK_ATTESTATIONS = 'eth/v1/beacon/blocks/{}/attestations' + API_GET_ATTESTATION_COMMITTEES = 'eth/v1/beacon/states/{}/committees' + API_GET_STATE = 'eth/v2/debug/beacon/states/{}' API_GET_VALIDATORS = 'eth/v1/beacon/states/{}/validators' API_GET_SPEC = 'eth/v1/config/spec' API_GET_GENESIS = 'eth/v1/beacon/genesis' @@ -56,7 +62,7 @@ def get_genesis(self): raise ValueError("Expected mapping response from getGenesis") return GenesisResponse.from_response(**data) - def get_block_root(self, state_id: Union[SlotNumber, BlockRoot, LiteralState]) -> BlockRootResponse: + def get_block_root(self, state_id: SlotNumber | BlockRoot | LiteralState) -> BlockRootResponse: """ Spec: https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockRoot @@ -72,20 +78,20 @@ def get_block_root(self, state_id: Union[SlotNumber, BlockRoot, LiteralState]) - return BlockRootResponse.from_response(**data) @lru_cache(maxsize=1) - def get_block_header(self, state_id: Union[SlotNumber, BlockRoot]) -> BlockHeaderFullResponse: + def get_block_header(self, state_id: SlotNumber | BlockRoot) -> BlockHeaderFullResponse: """Spec: https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockHeader""" - data, meta_data = self._get( + data, meta_data = cast(tuple[dict, dict], self._get( self.API_GET_BLOCK_HEADER, path_params=(state_id,), force_raise=self.__raise_last_missed_slot_error, - ) + )) if not isinstance(data, dict): raise ValueError("Expected mapping response from getBlockHeader") resp = BlockHeaderFullResponse.from_response(data=BlockHeaderResponseData.from_response(**data), **meta_data) return resp @lru_cache(maxsize=1) - def get_block_details(self, state_id: Union[SlotNumber, BlockRoot]) -> BlockDetailsResponse: + def get_block_details(self, state_id: SlotNumber | BlockRoot) -> BlockDetailsResponse: """Spec: https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockV2""" data, _ = self._get( self.API_GET_BLOCK_DETAILS, @@ -96,13 +102,57 @@ def get_block_details(self, state_id: Union[SlotNumber, BlockRoot]) -> BlockDeta raise ValueError("Expected mapping response from getBlockV2") return BlockDetailsResponse.from_response(**data) + @lru_cache(maxsize=256) + def get_block_attestations(self, state_id: SlotNumber | BlockRoot) -> list[BlockAttestation]: + """Spec: https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockAttestations""" + data, _ = self._get( + self.API_GET_BLOCK_ATTESTATIONS, + path_params=(state_id,), + force_raise=self.__raise_last_missed_slot_error, + ) + if not isinstance(data, list): + raise ValueError("Expected list response from getBlockAttestations") + return [BlockAttestation.from_response(**att) for att in data] + + @list_of_dataclasses(SlotAttestationCommittee.from_response) + def get_attestation_committees( + self, + blockstamp: BlockStamp, + epoch: EpochNumber | None = None, + index: int | None = None, + slot: SlotNumber | None = None + ) -> list[SlotAttestationCommittee]: + """Spec: https://ethereum.github.io/beacon-APIs/#/Beacon/getEpochCommittees""" + try: + data, _ = self._get( + self.API_GET_ATTESTATION_COMMITTEES, + path_params=(blockstamp.state_root,), + query_params={'epoch': epoch, 'index': index, 'slot': slot}, + force_raise=self.__raise_on_prysm_error + ) + except NotOkResponse as error: + if self.PRYSM_STATE_NOT_FOUND_ERROR in error.text: + data = self._get_attestation_committees_with_prysm(blockstamp, epoch, index, slot) + else: + raise error + return cast(list[SlotAttestationCommittee], data) + + @lru_cache(maxsize=1) + def get_state_block_roots(self, state_id: SlotNumber) -> list[BlockRoot]: + streamed_json = cast(TransientStreamingJSONObject, self._get( + self.API_GET_STATE, + path_params=(state_id,), + stream=True, + )) + return list(streamed_json['data']['block_roots']) + @lru_cache(maxsize=1) def get_validators(self, blockstamp: BlockStamp) -> list[Validator]: """Spec: https://ethereum.github.io/beacon-APIs/#/Beacon/getStateValidators""" return self.get_validators_no_cache(blockstamp) @list_of_dataclasses(Validator.from_response) - def get_validators_no_cache(self, blockstamp: BlockStamp, pub_keys: Optional[str | tuple] = None) -> list[dict]: + def get_validators_no_cache(self, blockstamp: BlockStamp, pub_keys: str | tuple | None = None) -> list[dict]: """Spec: https://ethereum.github.io/beacon-APIs/#/Beacon/getStateValidators""" try: data, _ = self._get( @@ -133,7 +183,25 @@ def __raise_on_prysm_error(self, errors: list[Exception]) -> Exception | None: return last_error return None - def _get_validators_with_prysm(self, blockstamp: BlockStamp, pub_keys: Optional[str | tuple] = None) -> list[dict]: + def _get_attestation_committees_with_prysm( + self, + blockstamp: BlockStamp, + epoch: EpochNumber | None = None, + index: int | None = None, + slot: SlotNumber | None = None + ) -> list[dict]: + # Avoid Prysm issue with state root - https://github.com/prysmaticlabs/prysm/issues/12053 + # Trying to get committees by slot number + data, _ = self._get( + self.API_GET_ATTESTATION_COMMITTEES, + path_params=(blockstamp.slot_number,), + query_params={'epoch': epoch, 'index': index, 'slot': slot}, + ) + if not isinstance(data, list): + raise ValueError("Expected list response from getEpochCommittees") + return data + + def _get_validators_with_prysm(self, blockstamp: BlockStamp, pub_keys: str | tuple | None = None) -> list[dict]: # Avoid Prysm issue with state root - https://github.com/prysmaticlabs/prysm/issues/12053 # Trying to get validators by slot number data, _ = self._get( @@ -142,7 +210,7 @@ def _get_validators_with_prysm(self, blockstamp: BlockStamp, pub_keys: Optional[ query_params={'id': pub_keys} ) if not isinstance(data, list): - raise ValueError("Expected list response from getStateValidators") # pylint: disable=raise-missing-from + raise ValueError("Expected list response from getStateValidators") return data def __raise_last_missed_slot_error(self, errors: list[Exception]) -> Exception | None: diff --git a/src/providers/consensus/typings.py b/src/providers/consensus/types.py similarity index 71% rename from src/providers/consensus/typings.py rename to src/providers/consensus/types.py index f5022e56b..7b257b34c 100644 --- a/src/providers/consensus/typings.py +++ b/src/providers/consensus/types.py @@ -1,8 +1,7 @@ from dataclasses import dataclass from enum import Enum -from typing import Optional -from src.typings import BlockRoot, StateRoot +from src.types import BlockHash, BlockRoot, StateRoot from src.utils.dataclass import Nested, FromResponse @@ -12,6 +11,7 @@ class BeaconSpecResponse(FromResponse): SLOTS_PER_EPOCH: str SECONDS_PER_SLOT: str DEPOSIT_CONTRACT_ADDRESS: str + SLOTS_PER_HISTORICAL_ROOT: str @dataclass @@ -55,16 +55,51 @@ class BlockHeaderFullResponse(Nested, FromResponse): # https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockHeader execution_optimistic: bool data: BlockHeaderResponseData - finalized: Optional[bool] = None + finalized: bool | None = None @dataclass -class BlockMessage(FromResponse): +class ExecutionPayload(FromResponse): + parent_hash: BlockHash + block_number: str + timestamp: str + block_hash: BlockHash + + +@dataclass +class Checkpoint: + epoch: str + root: BlockRoot + + +@dataclass +class AttestationData(Nested, FromResponse): + slot: str + index: str + beacon_block_root: BlockRoot + source: Checkpoint + target: Checkpoint + + +@dataclass +class BlockAttestation(Nested, FromResponse): + aggregation_bits: str + data: AttestationData + + +@dataclass +class BeaconBlockBody(Nested, FromResponse): + execution_payload: ExecutionPayload + attestations: list[BlockAttestation] + + +@dataclass +class BlockMessage(Nested, FromResponse): slot: str proposer_index: str parent_root: str state_root: StateRoot - body: dict + body: BeaconBlockBody class ValidatorStatus(Enum): @@ -108,3 +143,10 @@ class BlockDetailsResponse(Nested, FromResponse): # https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockV2 message: BlockMessage signature: str + + +@dataclass +class SlotAttestationCommittee(FromResponse): + index: str + slot: str + validators: list[str] diff --git a/src/providers/consistency.py b/src/providers/consistency.py index ea65ee2d9..3e71ffa75 100644 --- a/src/providers/consistency.py +++ b/src/providers/consistency.py @@ -1,4 +1,4 @@ -from typing import Any, Optional +from typing import Any from abc import abstractmethod, ABC @@ -19,7 +19,7 @@ class ProviderConsistencyModule(ABC): def get_all_providers(self) -> [any]: def _get_chain_id_with_provider(self, int) -> int: """ - def check_providers_consistency(self) -> Optional[int]: + def check_providers_consistency(self) -> int | None: chain_id = None for provider_index in range(len(self.get_all_providers())): diff --git a/src/providers/execution/__init__.py b/src/providers/execution/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/providers/execution/base_interface.py b/src/providers/execution/base_interface.py new file mode 100644 index 000000000..47ec8f052 --- /dev/null +++ b/src/providers/execution/base_interface.py @@ -0,0 +1,32 @@ +import json +import logging +from typing import Any, Self, Type + +from web3 import Web3 +from web3.types import BlockIdentifier + +from src.web3py.contract_tweak import Contract + +logger = logging.getLogger(__name__) + + +class ContractInterface(Contract): + abi_path: str + + @staticmethod + def load_abi(abi_file: str) -> dict: + with open(abi_file) as abi_json: + return json.load(abi_json) + + @classmethod + def factory(cls, w3: Web3, class_name: str | None = None, **kwargs: Any) -> Type[Self]: + if cls.abi_path is None: + raise AttributeError(f'abi_path attribute is missing in {cls.__name__} class') + + kwargs['abi'] = cls.load_abi(cls.abi_path) + return super().factory(w3, class_name, **kwargs) + + def is_deployed(self, block: BlockIdentifier) -> bool: + result = self.w3.eth.get_code(self.address, block_identifier=block) != b"" + logger.info({"msg": f"Check that the contract {self.__class__.__name__} exists at {block=}", "value": result}) + return result diff --git a/src/providers/execution/contracts/accounting_oracle.py b/src/providers/execution/contracts/accounting_oracle.py new file mode 100644 index 000000000..c1a6f2471 --- /dev/null +++ b/src/providers/execution/contracts/accounting_oracle.py @@ -0,0 +1,47 @@ +import logging +from src.utils.cache import global_lru_cache as lru_cache + +from web3.contract.contract import ContractFunction +from web3.types import BlockIdentifier + +from src.modules.accounting.types import AccountingProcessingState +from src.providers.execution.contracts.base_oracle import BaseOracleContract +from src.utils.abi import named_tuple_to_dataclass + + +logger = logging.getLogger(__name__) + + +class AccountingOracleContract(BaseOracleContract): + abi_path = './assets/AccountingOracle.json' + + @lru_cache(maxsize=1) + def get_processing_state(self, block_identifier: BlockIdentifier = 'latest') -> AccountingProcessingState: + """ + Returns data processing state for the current reporting frame. + """ + response = self.functions.getProcessingState().call(block_identifier=block_identifier) + response = named_tuple_to_dataclass(response, AccountingProcessingState) + logger.info({ + 'msg': 'Call `getProcessingState()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + def submit_report_extra_data_empty(self) -> ContractFunction: + """ + Triggers the processing required when no extra data is present in the report, + i.e. when extra data format equals EXTRA_DATA_FORMAT_EMPTY. + """ + tx = self.functions.submitReportExtraDataEmpty() + logger.info({'msg': 'Build `submitReportExtraDataEmpty()` tx.'}) + return tx + + def submit_report_extra_data_list(self, extra_data: bytes) -> ContractFunction: + """ + Submits report extra data in the EXTRA_DATA_FORMAT_LIST format for processing. + """ + tx = self.functions.submitReportExtraDataList(extra_data) + logger.info({'msg': f'Build `submitReportExtraDataList({extra_data.hex()})` tx.'}) + return tx diff --git a/src/providers/execution/contracts/base_oracle.py b/src/providers/execution/contracts/base_oracle.py new file mode 100644 index 000000000..8805a26ed --- /dev/null +++ b/src/providers/execution/contracts/base_oracle.py @@ -0,0 +1,117 @@ +import logging +from src.utils.cache import global_lru_cache as lru_cache + +from eth_typing import ChecksumAddress, Hash32 +from web3.contract.contract import ContractFunction +from web3.types import BlockIdentifier + +from src.providers.execution.base_interface import ContractInterface +from src.types import SlotNumber + + +logger = logging.getLogger(__name__) + + +class BaseOracleContract(ContractInterface): + + @lru_cache(maxsize=1) + def get_consensus_contract(self, block_identifier: BlockIdentifier = 'latest') -> ChecksumAddress: + """ + Returns the address of the HashConsensus contract. + """ + response = self.functions.getConsensusContract().call(block_identifier=block_identifier) + logger.info({ + 'msg': 'Call `getConsensusContract()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def submit_data_role(self, block_identifier: BlockIdentifier = 'latest') -> Hash32: + """ + An ACL role granting the permission to submit the data for a committee report. + """ + response = self.functions.SUBMIT_DATA_ROLE().call(block_identifier=block_identifier) + logger.info({ + 'msg': 'Call `SUBMIT_DATA_ROLE()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def has_role(self, role: Hash32, address: ChecksumAddress, block_identifier: BlockIdentifier = 'latest') -> bool: + """ + Returns `true` if `account` has been granted `role`. + """ + response = self.functions.hasRole(role, address).call(block_identifier=block_identifier) + logger.info({ + 'msg': f'Call `hasRole({role.hex()}, {address})`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def get_contract_version(self, block_identifier: BlockIdentifier = 'latest') -> int: + """ + Returns the current contract version. + """ + response = self.functions.getContractVersion().call(block_identifier=block_identifier) + logger.info({ + 'msg': 'Call `getContractVersion().', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def get_consensus_version(self, block_identifier: BlockIdentifier = 'latest') -> int: + """ + Returns the current consensus version expected by the oracle contract. + Consensus version must change every time consensus rules change, meaning that + an oracle looking at the same reference slot would calculate a different hash. + """ + response = self.functions.getConsensusVersion().call(block_identifier=block_identifier) + logger.info({ + 'msg': 'Call `getConsensusVersion().', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + def submit_report_data(self, report: tuple, contract_version: int) -> ContractFunction: + """ + Submits report data for processing. + data. See the `ReportData` structure's docs for details. + contractVersion Expected version of the oracle contract. + + Reverts if: + - The caller is not a member of the oracle committee and doesn't possess the SUBMIT_DATA_ROLE. + - The provided contract version is different from the current one. + - The provided consensus version is different from the expected one. + - The provided reference slot differs from the current consensus frame's one. + - The processing deadline for the current consensus frame is missed. + - The keccak256 hash of the ABI-encoded data is different from the last hash provided by the hash consensus contract. + - The provided data doesn't meet safety checks. + """ + tx = self.functions.submitReportData(report, contract_version) + logger.info({ + 'msg': f'Build `submitReport({report}, {contract_version}) tx.' + }) + return tx + + @lru_cache(maxsize=1) + def get_last_processing_ref_slot(self, block_identifier: BlockIdentifier = 'latest') -> SlotNumber: + """ + Returns the last reference slot for which processing of the report was started. + HashConsensus won't submit reports for any slot less than or equal to this slot. + """ + response = self.functions.getLastProcessingRefSlot().call(block_identifier=block_identifier) + logger.info({ + 'msg': 'Call `getLastProcessingRefSlot().', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return SlotNumber(response) diff --git a/src/providers/execution/contracts/burner.py b/src/providers/execution/contracts/burner.py new file mode 100644 index 000000000..89641555e --- /dev/null +++ b/src/providers/execution/contracts/burner.py @@ -0,0 +1,30 @@ +import logging +from src.utils.cache import global_lru_cache as lru_cache + +from web3.types import BlockIdentifier + +from src.modules.accounting.types import SharesRequestedToBurn +from src.providers.execution.base_interface import ContractInterface +from src.utils.abi import named_tuple_to_dataclass + + +logger = logging.getLogger(__name__) + + +class BurnerContract(ContractInterface): + abi_path = './assets/Burner.json' + + @lru_cache(maxsize=1) + def get_shares_requested_to_burn(self, block_identifier: BlockIdentifier = 'latest') -> SharesRequestedToBurn: + """ + Returns the current amount of shares locked on the contract to be burnt. + """ + response = self.functions.getSharesRequestedToBurn().call(block_identifier=block_identifier) + + response = named_tuple_to_dataclass(response, SharesRequestedToBurn) + logger.info({ + 'msg': 'Call `totalSupply()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response diff --git a/src/providers/execution/contracts/cs_accounting.py b/src/providers/execution/contracts/cs_accounting.py new file mode 100644 index 000000000..d6f7854f3 --- /dev/null +++ b/src/providers/execution/contracts/cs_accounting.py @@ -0,0 +1,26 @@ +import logging + +from eth_typing import ChecksumAddress +from web3 import Web3 +from web3.types import BlockIdentifier + +from ..base_interface import ContractInterface + +logger = logging.getLogger(__name__) + + +class CSAccountingContract(ContractInterface): + abi_path = "./assets/CSAccounting.json" + + def fee_distributor(self, block_identifier: BlockIdentifier = "latest") -> ChecksumAddress: + """Returns the address of the CSFeeDistributor contract""" + + resp = self.functions.feeDistributor().call(block_identifier=block_identifier) + logger.info( + { + "msg": "Call to feeDistributor()", + "value": resp, + "block_identifier": repr(block_identifier), + } + ) + return Web3.to_checksum_address(resp) diff --git a/src/providers/execution/contracts/cs_fee_distributor.py b/src/providers/execution/contracts/cs_fee_distributor.py new file mode 100644 index 000000000..1be2cf263 --- /dev/null +++ b/src/providers/execution/contracts/cs_fee_distributor.py @@ -0,0 +1,66 @@ +import logging + +from eth_typing import ChecksumAddress +from hexbytes import HexBytes +from web3 import Web3 +from web3.types import BlockIdentifier + +from ..base_interface import ContractInterface + +logger = logging.getLogger(__name__) + + +class CSFeeDistributorContract(ContractInterface): + abi_path = "./assets/CSFeeDistributor.json" + + def oracle(self, block_identifier: BlockIdentifier = "latest") -> ChecksumAddress: + """Returns the address of the CSFeeOracle contract""" + + resp = self.functions.ORACLE().call(block_identifier=block_identifier) + logger.info( + { + "msg": "Call to ORACLE()", + "value": resp, + "block_identifier": repr(block_identifier), + } + ) + return Web3.to_checksum_address(resp) + + def shares_to_distribute(self, block_identifier: BlockIdentifier = "latest") -> int: + """Returns the amount of shares that are pending to be distributed""" + + resp = self.functions.pendingSharesToDistribute().call(block_identifier=block_identifier) + logger.info( + { + "msg": "Call to pendingSharesToDistribute()", + "value": resp, + "block_identifier": repr(block_identifier), + } + ) + return resp + + def tree_root(self, block_identifier: BlockIdentifier = "latest") -> HexBytes: + """Root of the latest published Merkle tree""" + + resp = self.functions.treeRoot().call(block_identifier=block_identifier) + logger.info( + { + "msg": "Call to treeRoot()", + "value": resp, + "block_identifier": repr(block_identifier), + } + ) + return HexBytes(resp) + + def tree_cid(self, block_identifier: BlockIdentifier = "latest") -> str: + """CID of the latest published Merkle tree""" + + resp = self.functions.treeCid().call(block_identifier=block_identifier) + logger.info( + { + "msg": "Call to treeCid()", + "value": resp, + "block_identifier": repr(block_identifier), + } + ) + return resp diff --git a/src/providers/execution/contracts/cs_fee_oracle.py b/src/providers/execution/contracts/cs_fee_oracle.py new file mode 100644 index 000000000..6d75a5911 --- /dev/null +++ b/src/providers/execution/contracts/cs_fee_oracle.py @@ -0,0 +1,37 @@ +import logging + +from web3.types import BlockIdentifier + +from src.providers.execution.contracts.base_oracle import BaseOracleContract + +logger = logging.getLogger(__name__) + + +class CSFeeOracleContract(BaseOracleContract): + abi_path = "./assets/CSFeeOracle.json" + + def is_paused(self, block_identifier: BlockIdentifier = "latest") -> bool: + """Returns whether the contract is paused""" + + resp = self.functions.isPaused().call(block_identifier=block_identifier) + logger.info( + { + "msg": "Call isPaused().", + "value": resp, + "block_identifier": repr(block_identifier), + } + ) + return resp + + def perf_leeway_bp(self, block_identifier: BlockIdentifier = "latest") -> int: + """Performance threshold leeway used to determine underperforming validators""" + + resp = self.functions.avgPerfLeewayBP().call(block_identifier=block_identifier) + logger.info( + { + "msg": "Call to avgPerfLeewayBP()", + "value": resp, + "block_identifier": repr(block_identifier), + } + ) + return resp diff --git a/src/providers/execution/contracts/cs_module.py b/src/providers/execution/contracts/cs_module.py new file mode 100644 index 000000000..c84238a3a --- /dev/null +++ b/src/providers/execution/contracts/cs_module.py @@ -0,0 +1,95 @@ +import logging +from typing import Iterable, NamedTuple + +from eth_typing import ChecksumAddress +from web3 import Web3 +from web3.types import BlockIdentifier + +from src.utils.cache import global_lru_cache as lru_cache +from src.web3py.extensions.lido_validators import NodeOperatorId + +from ..base_interface import ContractInterface + +logger = logging.getLogger(__name__) + + +# TODO: Move to types? +class NodeOperatorSummary(NamedTuple): + """getNodeOperatorSummary response, @see IStakingModule.sol""" + + targetLimitMode: int + targetValidatorsCount: int + stuckValidatorsCount: int + refundedValidatorsCount: int + stuckPenaltyEndTimestamp: int + totalExitedValidators: int + totalDepositedValidators: int + depositableValidatorsCount: int + + +class CSModuleContract(ContractInterface): + abi_path = "./assets/CSModule.json" + + MAX_OPERATORS_COUNT = 2**64 + + def accounting(self, block_identifier: BlockIdentifier = "latest") -> ChecksumAddress: + """Returns the address of the CSAccounting contract""" + + resp = self.functions.accounting().call(block_identifier=block_identifier) + logger.info( + { + "msg": "Call to accounting()", + "value": resp, + "block_identifier": repr(block_identifier), + } + ) + return Web3.to_checksum_address(resp) + + @lru_cache(maxsize=1) + def get_stuck_operators_ids(self, block_identifier: BlockIdentifier = "latest") -> Iterable[NodeOperatorId]: + if not self.is_deployed(block_identifier): + return + + # TODO: Check performance on a large amount of node operators in a module. + for no_id in self.node_operators_ids(block_identifier): + if self.node_operator_summary(no_id, block_identifier).stuckValidatorsCount > 0: + yield no_id + + def is_paused(self, block: BlockIdentifier = "latest") -> bool: + resp = self.functions.isPaused().call(block_identifier=block) + logger.info( + { + "msg": "Call to isPaused()", + "value": resp, + "block_identifier": repr(block), + } + ) + return resp + + def node_operators_ids(self, block_identifier: BlockIdentifier = "latest") -> Iterable[NodeOperatorId]: + for no_id in range(self.node_operators_count(block_identifier)): + yield NodeOperatorId(no_id) + + def node_operators_count(self, block_identifier: BlockIdentifier = "latest") -> int: + resp = self.functions.getNodeOperatorsCount().call(block_identifier=block_identifier) + logger.info( + { + "msg": "Call to getNodeOperatorsCount()", + "value": resp, + "block_identifier": repr(block_identifier), + } + ) + return resp + + def node_operator_summary( + self, no_id: NodeOperatorId, block_identifier: BlockIdentifier = "latest" + ) -> NodeOperatorSummary: + resp = self.functions.getNodeOperatorSummary(no_id).call(block_identifier=block_identifier) + logger.info( + { + "msg": f"Call to getNodeOperatorSummary({no_id=})", + "value": resp, + "block_identifier": repr(block_identifier), + } + ) + return resp diff --git a/src/providers/execution/contracts/deposit_contract.py b/src/providers/execution/contracts/deposit_contract.py new file mode 100644 index 000000000..7da1e3944 --- /dev/null +++ b/src/providers/execution/contracts/deposit_contract.py @@ -0,0 +1,22 @@ +import logging + +from eth_typing import BlockIdentifier + +from ..base_interface import ContractInterface + +logger = logging.getLogger(__name__) + + +class DepositContract(ContractInterface): + abi_path = "./assets/DepositContract.json" + + def get_deposit_count(self, block_identifier: BlockIdentifier) -> int: + resp = self.functions.get_deposit_count().call(block_identifier=block_identifier) + logger.info( + { + "msg": "Call to get_deposit_count()", + "value": resp, + "block_identifier": repr(block_identifier), + } + ) + return int.from_bytes(resp, "little") diff --git a/src/providers/execution/contracts/exit_bus_oracle.py b/src/providers/execution/contracts/exit_bus_oracle.py new file mode 100644 index 000000000..449dfbf49 --- /dev/null +++ b/src/providers/execution/contracts/exit_bus_oracle.py @@ -0,0 +1,66 @@ +import logging +from src.utils.cache import global_lru_cache as lru_cache +from typing import Sequence + +from web3.types import BlockIdentifier + +from src.modules.ejector.types import EjectorProcessingState +from src.providers.execution.contracts.base_oracle import BaseOracleContract +from src.utils.abi import named_tuple_to_dataclass + + +logger = logging.getLogger(__name__) + + +class ExitBusOracleContract(BaseOracleContract): + abi_path = './assets/ValidatorsExitBusOracle.json' + + @lru_cache(maxsize=1) + def is_paused(self, block_identifier: BlockIdentifier = 'latest') -> bool: + """ + Returns whether the contract is paused. + """ + response = self.functions.isPaused().call(block_identifier=block_identifier) + logger.info({ + 'msg': 'Call `isPaused()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def get_processing_state(self, block_identifier: BlockIdentifier = 'latest') -> EjectorProcessingState: + """ + Returns data processing state for the current reporting frame. + """ + response = self.functions.getProcessingState().call(block_identifier=block_identifier) + response = named_tuple_to_dataclass(response, EjectorProcessingState) + logger.info({ + 'msg': 'Call `getProcessingState()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + def get_last_requested_validator_indices( + self, + module_id: int, + node_operators_ids_in_module: Sequence[int], + block_identifier: BlockIdentifier = 'latest', + ) -> list[int]: + """ + Returns the latest validator indices that were requested to exit for the given + `nodeOpIds` in the given `moduleId`. For node operators that were never requested to exit + any validator, index is set to -1. + """ + response = self.functions.getLastRequestedValidatorIndices( + module_id, + node_operators_ids_in_module, + ).call(block_identifier=block_identifier) + + logger.info({ + 'msg': f'Call `getLastRequestedValidatorIndices({module_id}, {node_operators_ids_in_module})`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response diff --git a/src/providers/execution/contracts/hash_consensus.py b/src/providers/execution/contracts/hash_consensus.py new file mode 100644 index 000000000..83277ca05 --- /dev/null +++ b/src/providers/execution/contracts/hash_consensus.py @@ -0,0 +1,149 @@ +import logging +from src.types import SlotNumber +from src.utils.cache import global_lru_cache as lru_cache + +from eth_typing import ChecksumAddress +from web3.contract.contract import ContractFunction +from web3.types import BlockIdentifier + +from src.modules.submodules.types import ChainConfig, CurrentFrame, FrameConfig +from src.providers.execution.base_interface import ContractInterface +from src.utils.abi import named_tuple_to_dataclass + +logger = logging.getLogger(__name__) + + +class HashConsensusContract(ContractInterface): + abi_path = './assets/HashConsensus.json' + + @lru_cache(maxsize=1) + def get_members(self, block_identifier: BlockIdentifier = 'latest') -> tuple[list[ChecksumAddress], list[int]]: + """ + Returns all current members, together with the last reference slot each member + submitted a report for. + """ + response = self.functions.getMembers().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `getMembers()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + + return response + + @lru_cache(maxsize=1) + def get_chain_config(self, block_identifier: BlockIdentifier = 'latest') -> ChainConfig: + """ + Returns the immutable chain parameters required to calculate epoch and slot + given a timestamp. + """ + response = self.functions.getChainConfig().call(block_identifier=block_identifier) + response = named_tuple_to_dataclass(response, ChainConfig) + + logger.info({ + 'msg': 'Call `getChainConfig()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + + return response + + @lru_cache(maxsize=1) + def get_current_frame(self, block_identifier: BlockIdentifier = 'latest') -> CurrentFrame: + """ + Returns the current reporting frame. + + ref_slot The frame's reference slot: if the data the consensus is being reached upon + includes or depends on any onchain state, this state should be queried at the + reference slot. If the slot contains a block, the state should include all changes + from that block. + + report_processing_deadline_slot: The last slot at which the report can be processed + by the report processor contract. + """ + response = self.functions.getCurrentFrame().call(block_identifier=block_identifier) + response = named_tuple_to_dataclass(response, CurrentFrame) + + logger.info({ + 'msg': 'Call `getCurrentFrame()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + + return response + + @lru_cache(maxsize=1) + def get_initial_ref_slot(self, block_identifier: BlockIdentifier = 'latest') -> SlotNumber: + """Returns the earliest possible reference slot, i.e. the reference slot of the reporting frame with zero index.""" + response = self.functions.getInitialRefSlot().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `getInitialRefSlot()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + + return response + + @lru_cache(maxsize=1) + def get_frame_config(self, block_identifier: BlockIdentifier = 'latest') -> FrameConfig: + """ + Returns the time-related configuration. + + initialEpoch Epoch of the frame with zero index. + epochsPerFrame Length of a frame in epochs. + fastLaneLengthSlots Length of the fast lane interval in slots; see `getIsFastLaneMember`. + """ + response = self.functions.getFrameConfig().call(block_identifier=block_identifier) + response = named_tuple_to_dataclass(response, FrameConfig) + + logger.info({ + 'msg': 'Call `getFrameConfig()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + + return response + + @lru_cache(maxsize=1) + def get_consensus_state_for_member(self, address: ChecksumAddress, block_identifier: BlockIdentifier = 'latest') -> tuple: + """ + Returns the extended information related to an oracle committee member with the + given address and the current consensus state. Provides all the information needed for + an oracle daemon to decide if it needs to submit a report. + """ + response = self.functions.getConsensusStateForMember(address).call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `getConsensusStateForMember()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + + return response + + def submit_report(self, ref_slot: int, report_hash: bytes, consensus_version: int) -> ContractFunction: + """ + Used by oracle members to submit hash of the data calculated for the given reference slot. + + ref_slot: The reference slot the data was calculated for. Reverts if doesn't match + the current reference slot. + + report_hash: of the data calculated for the given reference slot. + + consensus_version: Version of the oracle consensus rules. Reverts if doesn't + match the version returned by the currently set consensus report processor, + or zero if no report processor is set. + """ + tx = self.functions.submitReport(ref_slot, report_hash, consensus_version) + + logger.info({ + 'msg': 'Build `submitReport({}, {}, {})`.'.format( # pylint: disable=consider-using-f-string + ref_slot, + report_hash.hex(), + consensus_version, + ), + }) + + return tx diff --git a/src/providers/execution/contracts/lido.py b/src/providers/execution/contracts/lido.py new file mode 100644 index 000000000..8d8e0535e --- /dev/null +++ b/src/providers/execution/contracts/lido.py @@ -0,0 +1,101 @@ +import logging + +from eth_typing import ChecksumAddress +from web3.types import Wei, BlockIdentifier + +from src.modules.accounting.types import LidoReportRebase +from src.providers.execution.base_interface import ContractInterface + + +logger = logging.getLogger(__name__) + + +class LidoContract(ContractInterface): + abi_path = './assets/Lido.json' + + def handle_oracle_report( + self, + timestamp: int, + time_elapsed: int, + validators_count: int, + cl_balance: Wei, + withdrawal_vault_balance: Wei, + el_rewards: Wei, + shares_to_burn: int, + accounting_oracle_address: ChecksumAddress, + block_identifier: BlockIdentifier = 'latest', + ) -> LidoReportRebase: + """ + Updates accounting stats, collects EL rewards and distributes collected rewards + if beacon balance increased, performs withdrawal requests finalization + periodically called by the AccountingOracle contract + + NB: `_simulatedShareRate` should be calculated off-chain by calling the method with `eth_call` JSON-RPC API + while passing empty `_withdrawalFinalizationBatches` and `_simulatedShareRate` == 0, plugging the returned values + to the following formula: `_simulatedShareRate = (postTotalPooledEther * 1e27) / postTotalShares` + """ + response = self.functions.handleOracleReport( + timestamp, + time_elapsed, + validators_count, + cl_balance, + withdrawal_vault_balance, + el_rewards, + shares_to_burn, + [], + 0, + ).call( + transaction={'from': accounting_oracle_address}, + block_identifier=block_identifier, + ) + + response = LidoReportRebase(*response) + + logger.info({ + 'msg': 'Call `handleOracleReport({}, {}, {}, {}, {}, {}, {}, {}, {})`.'.format( # pylint: disable=consider-using-f-string + timestamp, + time_elapsed, + validators_count, + cl_balance, + withdrawal_vault_balance, + el_rewards, + shares_to_burn, + [], + 0, + ), + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + def get_buffered_ether(self, block_identifier: BlockIdentifier = 'latest') -> Wei: + """ + Get the amount of Ether temporary buffered on this contract balance + Buffered balance is kept on the contract from the moment the funds are received from user + until the moment they are actually sent to the official Deposit contract. + return amount of buffered funds in wei + """ + response = self.functions.getBufferedEther().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `getBufferedEther()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return Wei(response) + + def total_supply(self, block_identifier: BlockIdentifier = 'latest') -> Wei: + """ + return the amount of tokens in existence. + + Always equals to `_getTotalPooledEther()` since token amount + is pegged to the total amount of Ether controlled by the protocol. + """ + response = self.functions.totalSupply().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `totalSupply()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return Wei(response) diff --git a/src/providers/execution/contracts/lido_locator.py b/src/providers/execution/contracts/lido_locator.py new file mode 100644 index 000000000..986e000fd --- /dev/null +++ b/src/providers/execution/contracts/lido_locator.py @@ -0,0 +1,124 @@ +import logging +from src.utils.cache import global_lru_cache as lru_cache + +from eth_typing import ChecksumAddress +from web3.types import BlockIdentifier + +from src.providers.execution.base_interface import ContractInterface + + +logger = logging.getLogger(__name__) + + +class LidoLocatorContract(ContractInterface): + abi_path = './assets/LidoLocator.json' + + @lru_cache(maxsize=1) + def lido(self, block_identifier: BlockIdentifier = 'latest') -> ChecksumAddress: + response = self.functions.lido().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `lido()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def accounting_oracle(self, block_identifier: BlockIdentifier = 'latest') -> ChecksumAddress: + response = self.functions.accountingOracle().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `accountingOracle()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def staking_router(self, block_identifier: BlockIdentifier = 'latest') -> ChecksumAddress: + response = self.functions.stakingRouter().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `stakingRouter()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def validator_exit_bus_oracle(self, block_identifier: BlockIdentifier = 'latest') -> ChecksumAddress: + response = self.functions.validatorsExitBusOracle().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `validatorsExitBusOracle()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def withdrawal_queue(self, block_identifier: BlockIdentifier = 'latest') -> ChecksumAddress: + response = self.functions.withdrawalQueue().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `withdrawalQueue()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def oracle_report_sanity_checker(self, block_identifier: BlockIdentifier = 'latest') -> ChecksumAddress: + response = self.functions.oracleReportSanityChecker().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `oracleReportSanityChecker()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def oracle_daemon_config(self, block_identifier: BlockIdentifier = 'latest') -> ChecksumAddress: + response = self.functions.oracleDaemonConfig().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `oracleDaemonConfig()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def burner(self, block_identifier: BlockIdentifier = 'latest') -> ChecksumAddress: + response = self.functions.burner().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `burner()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def withdrawal_vault(self, block_identifier: BlockIdentifier = 'latest') -> ChecksumAddress: + response = self.functions.withdrawalVault().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `withdrawalVault()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def el_rewards_vault(self, block_identifier: BlockIdentifier = 'latest') -> ChecksumAddress: + response = self.functions.elRewardsVault().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `elRewardsVault()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response diff --git a/src/providers/execution/contracts/oracle_daemon_config.py b/src/providers/execution/contracts/oracle_daemon_config.py new file mode 100644 index 000000000..1c0f8c9a8 --- /dev/null +++ b/src/providers/execution/contracts/oracle_daemon_config.py @@ -0,0 +1,61 @@ +import logging + +from src.utils.cache import global_lru_cache as lru_cache + +from web3 import Web3 +from web3.types import BlockIdentifier + +from src.providers.execution.base_interface import ContractInterface + + +logger = logging.getLogger(__name__) + + +class OracleDaemonConfigContract(ContractInterface): + abi_path = './assets/OracleDaemonConfig.json' + + def _get(self, param: str, block_identifier: BlockIdentifier = 'latest') -> int: + response = Web3.to_int(self.functions.get(param).call(block_identifier=block_identifier)) + + logger.info({ + 'msg': f'Call `get({param})`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def normalized_cl_reward_per_epoch(self, block_identifier: BlockIdentifier = 'latest') -> int: + return self._get('NORMALIZED_CL_REWARD_PER_EPOCH', block_identifier) + + @lru_cache(maxsize=1) + def normalized_cl_reward_mistake_rate_bp(self, block_identifier: BlockIdentifier = 'latest') -> int: + return self._get('NORMALIZED_CL_REWARD_MISTAKE_RATE_BP', block_identifier) + + @lru_cache(maxsize=1) + def rebase_check_nearest_epoch_distance(self, block_identifier: BlockIdentifier = 'latest') -> int: + return self._get('REBASE_CHECK_NEAREST_EPOCH_DISTANCE', block_identifier) + + @lru_cache(maxsize=1) + def rebase_check_distant_epoch_distance(self, block_identifier: BlockIdentifier = 'latest') -> int: + return self._get('REBASE_CHECK_DISTANT_EPOCH_DISTANCE', block_identifier) + + @lru_cache(maxsize=1) + def node_operator_network_penetration_threshold_bp(self, block_identifier: BlockIdentifier = 'latest') -> int: + return self._get('NODE_OPERATOR_NETWORK_PENETRATION_THRESHOLD_BP', block_identifier) + + @lru_cache(maxsize=1) + def prediction_duration_in_slots(self, block_identifier: BlockIdentifier = 'latest') -> int: + return self._get('PREDICTION_DURATION_IN_SLOTS', block_identifier) + + @lru_cache(maxsize=1) + def finalization_max_negative_rebase_epoch_shift(self, block_identifier: BlockIdentifier = 'latest') -> int: + return self._get('FINALIZATION_MAX_NEGATIVE_REBASE_EPOCH_SHIFT', block_identifier) + + @lru_cache(maxsize=1) + def validator_delayed_timeout_in_slots(self, block_identifier: BlockIdentifier = 'latest') -> int: + return self._get('VALIDATOR_DELAYED_TIMEOUT_IN_SLOTS', block_identifier) + + @lru_cache(maxsize=1) + def validator_delinquent_timeout_in_slots(self, block_identifier: BlockIdentifier = 'latest') -> int: + return self._get('VALIDATOR_DELINQUENT_TIMEOUT_IN_SLOTS', block_identifier) diff --git a/src/providers/execution/contracts/oracle_report_sanity_checker.py b/src/providers/execution/contracts/oracle_report_sanity_checker.py new file mode 100644 index 000000000..82aed0995 --- /dev/null +++ b/src/providers/execution/contracts/oracle_report_sanity_checker.py @@ -0,0 +1,30 @@ +import logging +from src.utils.cache import global_lru_cache as lru_cache + +from web3.types import BlockIdentifier + +from src.modules.accounting.types import OracleReportLimits +from src.providers.execution.base_interface import ContractInterface +from src.utils.abi import named_tuple_to_dataclass + + +logger = logging.getLogger(__name__) + + +class OracleReportSanityCheckerContract(ContractInterface): + abi_path = './assets/OracleReportSanityChecker.json' + + @lru_cache(maxsize=1) + def get_oracle_report_limits(self, block_identifier: BlockIdentifier = 'latest') -> OracleReportLimits: + """ + Returns the limits list for the Lido's oracle report sanity checks + """ + response = self.functions.getOracleReportLimits().call(block_identifier=block_identifier) + response = named_tuple_to_dataclass(response, OracleReportLimits.from_response) + + logger.info({ + 'msg': 'Call `getOracleReportLimits()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response diff --git a/src/providers/execution/contracts/staking_router.py b/src/providers/execution/contracts/staking_router.py new file mode 100644 index 000000000..69995472c --- /dev/null +++ b/src/providers/execution/contracts/staking_router.py @@ -0,0 +1,88 @@ +import logging +from src.utils.cache import global_lru_cache as lru_cache + +from web3.types import BlockIdentifier + +from src.providers.execution.base_interface import ContractInterface +from src.utils.dataclass import list_of_dataclasses +from src.web3py.extensions.lido_validators import StakingModule, NodeOperator + +logger = logging.getLogger(__name__) + + +class StakingRouterContract(ContractInterface): + abi_path = './assets/StakingRouter.json' + + @lru_cache(maxsize=1) + def get_contract_version(self, block_identifier: BlockIdentifier = 'latest') -> int: + response = self.functions.getContractVersion().call(block_identifier=block_identifier) + logger.info( + { + 'msg': 'Call `getContractVersion()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + } + ) + return response + + @lru_cache(maxsize=1) + @list_of_dataclasses(StakingModule.from_response) + def get_staking_modules(self, block_identifier: BlockIdentifier = 'latest') -> list[StakingModule]: + """ + Returns all registered staking modules + """ + response = self.functions.getStakingModules().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `getStakingModules()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + def get_all_node_operator_digests(self, module: StakingModule, block_identifier: BlockIdentifier = 'latest') -> list[NodeOperator]: + """ + Returns node operator digest for each node operator in lido protocol + """ + response = self.functions.getAllNodeOperatorDigests(module.id).call(block_identifier=block_identifier) + response = [NodeOperator.from_response(no, module) for no in response] + + logger.info({ + 'msg': f'Call `getAllNodeOperatorDigests({module.id})`.', + # Too long response + 'value': len(response), + 'block_identifier': repr(block_identifier), + }) + return response + + +class StakingRouterContractV2(StakingRouterContract): + abi_path = './assets/StakingRouterV2.json' + + @lru_cache(maxsize=1) + @list_of_dataclasses(StakingModule.from_response) + def get_staking_modules(self, block_identifier: BlockIdentifier = 'latest') -> list[StakingModule]: + """ + Returns all registered staking modules + """ + contract_version = self.get_contract_version(block_identifier) + + if contract_version == 1: + # Backward compatibility in case if new oracle have to build report for old protocol version + # But latest contracts has new version + logger.warning({'msg': 'Use StakingRouter.json abi (old one) to parse the response.'}) + staking_router = self.w3.eth.contract( + address=self.address, + abi=self.load_abi(super().abi_path), + decode_tuples=True, + ) + response = staking_router.functions.getStakingModules().call(block_identifier=block_identifier) + else: + response = self.functions.getStakingModules().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `getStakingModules()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response diff --git a/src/providers/execution/contracts/withdrawal_queue_nft.py b/src/providers/execution/contracts/withdrawal_queue_nft.py new file mode 100644 index 000000000..bcf4ab8fb --- /dev/null +++ b/src/providers/execution/contracts/withdrawal_queue_nft.py @@ -0,0 +1,150 @@ +import logging +from src.utils.cache import global_lru_cache as lru_cache + +from web3.types import Wei, BlockIdentifier + +from src.modules.accounting.types import BatchState, WithdrawalRequestStatus +from src.providers.execution.base_interface import ContractInterface +from src.utils.abi import named_tuple_to_dataclass + +logger = logging.getLogger(__name__) + + +class WithdrawalQueueNftContract(ContractInterface): + abi_path = './assets/WithdrawalQueueERC721.json' + + @lru_cache(maxsize=1) + def unfinalized_steth(self, block_identifier: BlockIdentifier = 'latest') -> Wei: + """ + Returns the amount of stETH in the queue yet to be finalized + """ + response = self.functions.unfinalizedStETH().call(block_identifier=block_identifier) + logger.info({ + 'msg': 'Call `unfinalizedStETH()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return Wei(response) + + @lru_cache(maxsize=1) + def bunker_mode_since_timestamp(self, block_identifier: BlockIdentifier = 'latest') -> int: + """ + Get bunker mode activation timestamp. + + returns `BUNKER_MODE_DISABLED_TIMESTAMP` if bunker mode is disable (i.e., protocol in turbo mode) + """ + response = self.functions.bunkerModeSinceTimestamp().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `bunkerModeSinceTimestamp()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def get_last_finalized_request_id(self, block_identifier: BlockIdentifier = 'latest') -> int: + """ + id of the last finalized request + NB! requests are indexed from 1, so it returns 0 if there is no finalized requests in the queue + """ + response = self.functions.getLastFinalizedRequestId().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `getLastFinalizedRequestId()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def get_withdrawal_status(self, request_id: int, block_identifier: BlockIdentifier = 'latest') -> WithdrawalRequestStatus: + """ + Returns status for requests with provided ids + request_id: id of request to check status + """ + response = self.functions.getWithdrawalStatus([request_id]).call(block_identifier=block_identifier) + response = named_tuple_to_dataclass(response[0], WithdrawalRequestStatus) + + logger.info({ + 'msg': f'Call `getWithdrawalStatus({[request_id]})`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def get_last_request_id(self, block_identifier: BlockIdentifier = 'latest') -> int: + """ + returns id of the last request + NB! requests are indexed from 1, so it returns 0 if there is no requests in the queue + """ + response = self.functions.getLastRequestId().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `getLastRequestId()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def is_paused(self, block_identifier: BlockIdentifier = 'latest') -> bool: + """ + Returns whether the withdrawal queue is paused + """ + response = self.functions.isPaused().call(block_identifier=block_identifier) + logger.info({ + 'msg': 'Call `isPaused()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def max_batches_length(self, block_identifier: BlockIdentifier = 'latest') -> int: + """ + maximal length of the batch array provided for prefinalization. + """ + response = self.functions.MAX_BATCHES_LENGTH().call(block_identifier=block_identifier) + + logger.info({ + 'msg': 'Call `MAX_BATCHES_LENGTH()`.', + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response + + @lru_cache(maxsize=1) + def calculate_finalization_batches( + self, + share_rate: int, + timestamp: int, + max_batch_request_count: int, + batch_state: tuple, + block_identifier: BlockIdentifier = 'latest', + ) -> BatchState: + """ + Offchain view for the oracle daemon that calculates how many requests can be finalized within + the given budget, time period and share rate limits. Returned requests are split into batches. + Each batch consist of the requests that all have the share rate below the `_maxShareRate` or above it. + """ + response = self.functions.calculateFinalizationBatches( + share_rate, + timestamp, + max_batch_request_count, + batch_state, + ).call(block_identifier=block_identifier) + response = named_tuple_to_dataclass(response, BatchState) + + logger.info({ + 'msg': 'Call `calculateFinalizationBatches({}, {}, {}, {})`.'.format( # pylint: disable=consider-using-f-string + share_rate, + timestamp, + max_batch_request_count, + batch_state, + ), + 'value': response, + 'block_identifier': repr(block_identifier), + }) + return response diff --git a/src/providers/execution/exceptions.py b/src/providers/execution/exceptions.py new file mode 100644 index 000000000..6749c670e --- /dev/null +++ b/src/providers/execution/exceptions.py @@ -0,0 +1,5 @@ +"""Module for exceptions caused by the execution provider""" + + +class InconsistentEvents(ValueError): + ... diff --git a/src/providers/http_provider.py b/src/providers/http_provider.py index 9f97632cd..b8abea4aa 100644 --- a/src/providers/http_provider.py +++ b/src/providers/http_provider.py @@ -1,9 +1,13 @@ import logging from abc import ABC from http import HTTPStatus -from typing import Optional, Tuple, Sequence, Callable +from typing import Sequence, Callable from urllib.parse import urljoin, urlparse +# NOTE: Missing library stubs or py.typed marker. That's why we use `type: ignore` +from json_stream import requests as json_stream_requests # type: ignore +from json_stream.base import TransientStreamingJSONList, TransientStreamingJSONObject # type: ignore + from prometheus_client import Histogram from requests import Session, JSONDecodeError from requests.adapters import HTTPAdapter @@ -71,12 +75,13 @@ def _urljoin(host, url): def _get( self, endpoint: str, - path_params: Optional[Sequence[str | int]] = None, - query_params: Optional[dict] = None, + path_params: Sequence[str | int] | None = None, + query_params: dict | None = None, force_raise: Callable[..., Exception | None] = lambda _: None, - ) -> Tuple[dict | list, dict]: + stream: bool = False, + ) -> tuple[dict | list, dict] | TransientStreamingJSONObject | TransientStreamingJSONList: """ - Get request with fallbacks + Get plain or streamed request with fallbacks Returns (data, meta) or raises exception force_raise - function that returns an Exception if it should be thrown immediately. @@ -86,7 +91,7 @@ def _get( for host in self.hosts: try: - return self._get_without_fallbacks(host, endpoint, path_params, query_params) + return self._get_without_fallbacks(host, endpoint, path_params, query_params, stream) except Exception as e: # pylint: disable=W0703 errors.append(e) @@ -109,12 +114,13 @@ def _get_without_fallbacks( self, host: str, endpoint: str, - path_params: Optional[Sequence[str | int]] = None, - query_params: Optional[dict] = None - ) -> Tuple[dict | list, dict]: + path_params: Sequence[str | int] | None = None, + query_params: dict | None = None, + stream: bool = False, + ) -> tuple[dict | list, dict] | TransientStreamingJSONObject | TransientStreamingJSONList: """ Simple get request without fallbacks - Returns (data, meta) or raises exception + Returns (data, meta) or streamed transient list-like or dict-like object JSON or raises exception """ complete_endpoint = endpoint.format(*path_params) if path_params else endpoint @@ -124,6 +130,7 @@ def _get_without_fallbacks( self._urljoin(host, complete_endpoint if path_params else endpoint), params=query_params, timeout=self.request_timeout, + stream=stream ) except Exception as error: logger.error({'msg': str(error)}) @@ -140,15 +147,23 @@ def _get_without_fallbacks( domain=urlparse(host).netloc, ) - response_fail_msg = f'Response from {complete_endpoint} [{response.status_code}] with text: "{str(response.text)}" returned.' - if response.status_code != HTTPStatus.OK: + response_fail_msg = ( + f'Response from {complete_endpoint} [{response.status_code}]' + f' with text: "{str(response.text)}" returned.' + ) logger.debug({'msg': response_fail_msg}) raise NotOkResponse(response_fail_msg, status=response.status_code, text=response.text) + if stream: + return json_stream_requests.load(response) + try: json_response = response.json() except JSONDecodeError as error: + response_fail_msg = ( + f'Failed to decode JSON response from {complete_endpoint} with text: "{str(response.text)}"' + ) logger.debug({'msg': response_fail_msg}) raise error diff --git a/src/providers/ipfs/__init__.py b/src/providers/ipfs/__init__.py new file mode 100644 index 000000000..ca99541d2 --- /dev/null +++ b/src/providers/ipfs/__init__.py @@ -0,0 +1,7 @@ +from .cid import * +from .dummy import * +from .gw3 import * +from .multi import * +from .pinata import * +from .public import * +from .types import * diff --git a/src/providers/ipfs/cid.py b/src/providers/ipfs/cid.py new file mode 100644 index 000000000..1c93dcd1e --- /dev/null +++ b/src/providers/ipfs/cid.py @@ -0,0 +1,19 @@ +from collections import UserString + + +class CID(UserString): + def __repr__(self): + return f"{self.__class__.__name__}({self.data})" + + +class CIDv0(CID): + ... + + +class CIDv1(CID): + ... + + +# @see https://github.com/multiformats/cid/blob/master/README.md#decoding-algorithm +def is_cid_v0(cid: str) -> bool: + return cid.startswith("Qm") and len(cid) == 46 diff --git a/src/providers/ipfs/dummy.py b/src/providers/ipfs/dummy.py new file mode 100644 index 000000000..35773cc42 --- /dev/null +++ b/src/providers/ipfs/dummy.py @@ -0,0 +1,36 @@ +import hashlib + +from .types import CIDv0, CIDv1, IPFSProvider, FetchError + + +class DummyIPFSProvider(IPFSProvider): + """Dummy IPFS provider which using the local filesystem as a backend""" + + # pylint: disable=unreachable + + mempool: dict[CIDv0 | CIDv1, bytes] + + def __init__(self) -> None: + self.mempool = {} + + def fetch(self, cid: CIDv0 | CIDv1) -> bytes: + try: + return self.mempool[cid] + except KeyError: + try: + with open(str(cid), mode="r") as f: + return f.read().encode("utf-8") + except Exception as e: + raise FetchError(cid) from e + + + def upload(self, content: bytes, name: str | None = None) -> CIDv0 | CIDv1: + cid = CIDv0("Qm" + hashlib.sha256(content).hexdigest()) # XXX: Dummy. + self.mempool[cid] = content + return cid + + def pin(self, cid: CIDv0 | CIDv1) -> None: + content = self.fetch(cid) + + with open(str(cid), mode="w", encoding="utf-8") as f: + f.write(content.decode()) diff --git a/src/providers/ipfs/gw3.py b/src/providers/ipfs/gw3.py new file mode 100644 index 000000000..67612284a --- /dev/null +++ b/src/providers/ipfs/gw3.py @@ -0,0 +1,90 @@ +import base64 +import hashlib +import hmac +from json import JSONDecodeError +import logging +import time +from urllib.parse import urlencode, urlparse + +import requests + +from src.providers.ipfs.cid import CIDv0, CIDv1, is_cid_v0 + +from .types import IPFSError, IPFSProvider, FetchError, PinError, UploadError + +logger = logging.getLogger(__name__) + + +class GW3(IPFSProvider): + """gw3.io client""" + + ENDPOINT = "https://gw3.io" + + def __init__(self, access_key: str, access_secret: str, *, timeout: int) -> None: + super().__init__() + self.access_key = access_key + self.access_secret = base64.urlsafe_b64decode(access_secret) + self.timeout = timeout + + def fetch(self, cid: CIDv0 | CIDv1): + try: + resp = self._send("GET", f"{self.ENDPOINT}/ipfs/{cid}") + except IPFSError as ex: + raise FetchError(cid) from ex + return resp.content + + def upload(self, content: bytes, name: str | None = None) -> CIDv0 | CIDv1: + url = self._auth_upload(len(content)) + try: + response = requests.post(url, data=content, timeout=self.timeout) + except IPFSError as ex: + raise UploadError from ex + try: + cid = response.headers["IPFS-Hash"] + except KeyError as ex: + raise UploadError from ex + + return CIDv0(cid) if is_cid_v0(cid) else CIDv1(cid) + + def pin(self, cid: CIDv0 | CIDv1) -> None: + try: + self._send("POST", f"{self.ENDPOINT}/api/v0/pin/add", {"arg": str(cid)}) + except IPFSError as ex: + raise PinError(cid) from ex + + def _auth_upload(self, size: int) -> str: + try: + response = self._send("POST", f"{self.ENDPOINT}/ipfs/", {"size": size}) + except IPFSError as ex: + raise UploadError from ex + try: + return response.json()["data"]["url"] + except JSONDecodeError as ex: + raise UploadError from ex + except KeyError as ex: + raise UploadError from ex + + def _send(self, method: str, url: str, params: dict | None = None) -> requests.Response: + req = self._signed_req(method, url, params) + try: + response = requests.Session().send(req, timeout=self.timeout) + response.raise_for_status() + except requests.RequestException as ex: + logger.error({"msg": "Request has been failed", "error": str(ex)}) + raise IPFSError from ex + return response + + def _signed_req(self, method: str, url: str, params: dict | None = None) -> requests.PreparedRequest: + params = params or {} + params["ts"] = str(int(time.time())) + query = urlencode(params, doseq=True) + + parsed_url = urlparse(url) + data = "\n".join((method, parsed_url.path, query)).encode("utf-8") + mac = hmac.new(self.access_secret, data, hashlib.sha256) + sign = base64.urlsafe_b64encode(mac.digest()) + + req = requests.Request(method=method, url=url, params=params) + req.headers["X-Access-Key"] = self.access_key + req.headers["X-Access-Signature"] = sign.decode("utf-8") + return req.prepare() diff --git a/src/providers/ipfs/multi.py b/src/providers/ipfs/multi.py new file mode 100644 index 000000000..e03df8e7a --- /dev/null +++ b/src/providers/ipfs/multi.py @@ -0,0 +1,92 @@ +import logging +from functools import wraps +from typing import Iterable + +from .cid import CIDv0, CIDv1 +from .types import IPFSError, IPFSProvider + +logger = logging.getLogger(__name__) + + +class MaxRetryError(IPFSError): + ... + + +class MultiIPFSProvider(IPFSProvider): + """Fallback-driven provider for IPFS""" + + # NOTE: The provider is NOT thread-safe. + + providers: list[IPFSProvider] + current_provider_index: int = 0 + last_working_provider_index: int = 0 + + def __init__(self, providers: Iterable[IPFSProvider], *, retries: int = 3) -> None: + super().__init__() + self.retries = retries + self.providers = list(providers) + assert self.providers + for p in self.providers: + assert isinstance(p, IPFSProvider) + + @staticmethod + def with_fallback(fn): + @wraps(fn) + def wrapped(self: "MultiIPFSProvider", *args, **kwargs): + try: + result = fn(self, *args, **kwargs) + except IPFSError: + self.current_provider_index = (self.current_provider_index + 1) % len(self.providers) + if self.last_working_provider_index == self.current_provider_index: + logger.error({"msg": "No more IPFS providers left to call"}) + raise + return wrapped(self, *args, **kwargs) + + self.last_working_provider_index = self.current_provider_index + return result + + return wrapped + + @staticmethod + def retry(fn): + @wraps(fn) + def wrapped(self: "MultiIPFSProvider", *args, **kwargs): + retries_left = self.retries + while retries_left: + try: + return fn(self, *args, **kwargs) + except IPFSError as ex: + retries_left -= 1 + if not retries_left: + raise MaxRetryError from ex + logger.warning( + {"msg": f"Retrying a failed call of {fn.__name__}, {retries_left=}", "error": str(ex)} + ) + raise MaxRetryError + + return wrapped + + @property + def provider(self) -> IPFSProvider: + return self.providers[self.current_provider_index] + + @with_fallback + @retry + def fetch(self, cid: CIDv0 | CIDv1) -> bytes: + return self.provider.fetch(cid) + + @with_fallback + @retry + def publish(self, content: bytes, name: str | None = None) -> CIDv0 | CIDv1: + # If the current provider fails to upload or pin a file, it makes sense + # to try to both upload and to pin via a different provider. + return self.provider.publish(content, name) + + def upload(self, content: bytes, name: str | None = None) -> CIDv0 | CIDv1: + # It doesn't make sense to upload a file to a different providers networks + # without a guarantee the file will be available via another one. + raise NotImplementedError + + def pin(self, cid: CIDv0 | CIDv1) -> None: + # CID can be unavailable for the next provider in the providers list. + raise NotImplementedError diff --git a/src/providers/ipfs/pinata.py b/src/providers/ipfs/pinata.py new file mode 100644 index 000000000..3b47e2282 --- /dev/null +++ b/src/providers/ipfs/pinata.py @@ -0,0 +1,59 @@ +from json import JSONDecodeError +import logging +import requests + +from .cid import CIDv0, CIDv1, is_cid_v0 +from .types import FetchError, IPFSProvider, PinError, UploadError + + +logger = logging.getLogger(__name__) + + +class Pinata(IPFSProvider): + """pinata.cloud IPFS provider""" + + API_ENDPOINT = "https://api.pinata.cloud" + GATEWAY = "https://gateway.pinata.cloud" + + def __init__(self, jwt_token: str, *, timeout: int) -> None: + super().__init__() + self.timeout = timeout + self.session = requests.Session() + self.session.headers["Authorization"] = f"Bearer {jwt_token}" + + def fetch(self, cid: CIDv0 | CIDv1) -> bytes: + url = f"{self.GATEWAY}/ipfs/{cid}" + try: + resp = requests.get(url, timeout=self.timeout) + resp.raise_for_status() + except requests.RequestException as ex: + logger.error({"msg": "Request has been failed", "error": str(ex)}) + raise FetchError(cid) from ex + return resp.content + + def upload(self, content: bytes, name: str | None = None) -> CIDv0 | CIDv1: + url = f"{self.API_ENDPOINT}/pinning/pinFileToIPFS" + try: + with self.session as s: + resp = s.post(url, files={"file": content}) + resp.raise_for_status() + except requests.RequestException as ex: + logger.error({"msg": "Request has been failed", "error": str(ex)}) + raise UploadError from ex + try: + cid = resp.json()["IpfsHash"] + except JSONDecodeError as ex: + raise UploadError from ex + except KeyError as ex: + raise UploadError from ex + return CIDv0(cid) if is_cid_v0(cid) else CIDv1(cid) + + def pin(self, cid: CIDv0 | CIDv1) -> None: + url = f"{self.API_ENDPOINT}/pinning/pinByHash" + try: + with self.session as s: + resp = s.post(url, json={"hashToPin": str(cid)}) + resp.raise_for_status() + except requests.RequestException as ex: + logger.error({"msg": "Request has been failed", "error": str(ex)}) + raise PinError(cid) from ex diff --git a/src/providers/ipfs/public.py b/src/providers/ipfs/public.py new file mode 100644 index 000000000..96f65b665 --- /dev/null +++ b/src/providers/ipfs/public.py @@ -0,0 +1,36 @@ +import logging +import requests + +from .types import FetchError, IPFSProvider, PinError, UploadError +from .cid import CIDv0, CIDv1 + + +logger = logging.getLogger(__name__) + + +class PublicIPFS(IPFSProvider): + """Public IPFS gateway (fetch-only provider)""" + + # pylint:disable=duplicate-code + + GATEWAY = "https://ipfs.io" + + def __init__(self, *, timeout: int) -> None: + super().__init__() + self.timeout = timeout + + def fetch(self, cid: CIDv0 | CIDv1) -> bytes: + url = f"{self.GATEWAY}/ipfs/{cid}" + try: + resp = requests.get(url, timeout=self.timeout) + resp.raise_for_status() + except requests.RequestException as ex: + logger.error({"msg": "Request has been failed", "error": str(ex)}) + raise FetchError(cid) from ex + return resp.content + + def upload(self, content: bytes, name: str | None = None) -> CIDv0 | CIDv1: + raise UploadError + + def pin(self, cid: CIDv0 | CIDv1) -> None: + raise PinError(cid) diff --git a/src/providers/ipfs/types.py b/src/providers/ipfs/types.py new file mode 100644 index 000000000..1502cef1c --- /dev/null +++ b/src/providers/ipfs/types.py @@ -0,0 +1,56 @@ +from abc import ABC, abstractmethod +from .cid import CIDv0, CIDv1 + + +class IPFSError(Exception): + """Base class for IPFS provider errors""" + + +class FetchError(IPFSError): + """Raised if no content found for the given CID""" + + cid: CIDv0 | CIDv1 + + def __init__(self, cid: CIDv0 | CIDv1) -> None: + super().__init__(self) + self.cid = cid + + def __str__(self) -> str: + return f"Unable to fetch {repr(self.cid)}" + + +class UploadError(IPFSError): + ... + + +class PinError(IPFSError): + + cid: CIDv0 | CIDv1 + + def __init__(self, cid: CIDv0 | CIDv1) -> None: + super().__init__(self) + self.cid = cid + + def __str__(self) -> str: + return f"Unable to pin {repr(self.cid)}" + + +class IPFSProvider(ABC): + """Interface for all implementations of an [IPFS](https://docs.ipfs.tech) provider""" + + @abstractmethod + def fetch(self, cid: CIDv0 | CIDv1) -> bytes: + ... + + def publish(self, content: bytes, name: str | None = None) -> CIDv0 | CIDv1: + cid = self.upload(content, name) + self.pin(cid) + return cid + + @abstractmethod + def upload(self, content: bytes, name: str | None = None) -> CIDv0 | CIDv1: + ... + + @abstractmethod + def pin(self, cid: CIDv0 | CIDv1) -> None: + """Pin the content, see https://docs.ipfs.tech/how-to/pin-files""" diff --git a/src/providers/keys/client.py b/src/providers/keys/client.py index 8d3c116d2..62314e69d 100644 --- a/src/providers/keys/client.py +++ b/src/providers/keys/client.py @@ -1,10 +1,10 @@ from time import sleep -from typing import Optional, cast +from typing import cast from src.metrics.prometheus.basic import KEYS_API_REQUESTS_DURATION, KEYS_API_LATEST_BLOCKNUMBER from src.providers.http_provider import HTTPProvider -from src.providers.keys.typings import LidoKey, KeysApiStatus -from src.typings import BlockStamp +from src.providers.keys.types import LidoKey, KeysApiStatus +from src.types import BlockStamp, StakingModuleAddress from src.utils.dataclass import list_of_dataclasses from src.utils.cache import global_lru_cache as lru_cache @@ -25,10 +25,11 @@ class KeysAPIClient(HTTPProvider): """ PROMETHEUS_HISTOGRAM = KEYS_API_REQUESTS_DURATION + MODULE_OPERATORS_KEYS = 'v1/modules/{}/operators/keys' USED_KEYS = 'v1/keys?used=true' STATUS = 'v1/status' - def _get_with_blockstamp(self, url: str, blockstamp: BlockStamp, params: Optional[dict] = None) -> dict | list: + def _get_with_blockstamp(self, url: str, blockstamp: BlockStamp, params: dict | None = None) -> dict | list: """ Returns response if blockstamp < blockNumber from response """ @@ -50,6 +51,13 @@ def get_used_lido_keys(self, blockstamp: BlockStamp) -> list[dict]: """Docs: https://keys-api.lido.fi/api/static/index.html#/keys/KeysController_get""" return cast(list[dict], self._get_with_blockstamp(self.USED_KEYS, blockstamp)) + @lru_cache(maxsize=1) + def get_module_operators_keys(self, module_address: StakingModuleAddress, blockstamp: BlockStamp) -> dict: + """ + Docs: https://keys-api.lido.fi/api/static/index.html#/operators-keys/SRModulesOperatorsKeysController_getOperatorsKeys + """ + return cast(dict, self._get_with_blockstamp(self.MODULE_OPERATORS_KEYS.format(module_address), blockstamp)) + def get_status(self) -> KeysApiStatus: """Docs: https://keys-api.lido.fi/api/static/index.html#/status/StatusController_get""" data, _ = self._get(self.STATUS) diff --git a/src/providers/keys/typings.py b/src/providers/keys/types.py similarity index 100% rename from src/providers/keys/typings.py rename to src/providers/keys/types.py diff --git a/src/services/bunker.py b/src/services/bunker.py index f19d01066..6060d310a 100644 --- a/src/services/bunker.py +++ b/src/services/bunker.py @@ -11,12 +11,12 @@ from src.services.bunker_cases.abnormal_cl_rebase import AbnormalClRebase from src.services.bunker_cases.midterm_slashing_penalty import MidtermSlashingPenalty -from src.modules.accounting.typings import LidoReportRebase +from src.modules.accounting.types import LidoReportRebase from src.modules.submodules.consensus import FrameConfig, ChainConfig -from src.services.bunker_cases.typings import BunkerConfig +from src.services.bunker_cases.types import BunkerConfig from src.services.safe_border import filter_slashed_validators -from src.typings import BlockStamp, ReferenceBlockStamp, Gwei -from src.web3py.typings import Web3 +from src.types import BlockStamp, ReferenceBlockStamp, Gwei +from src.web3py.types import Web3 logger = logging.getLogger(__name__) @@ -91,30 +91,19 @@ def get_cl_rebase_for_current_report(self, blockstamp: BlockStamp, simulated_cl_ Get simulated Cl rebase and subtract total supply before report """ logger.info({"msg": "Getting CL rebase for frame"}) - before_report_total_pooled_ether = self._get_total_supply(blockstamp) + before_report_total_pooled_ether = self.w3.lido_contracts.lido.total_supply(blockstamp.block_hash) # Can't use from_wei - because rebase can be negative frame_cl_rebase = (simulated_cl_rebase.post_total_pooled_ether - before_report_total_pooled_ether) // GWEI_TO_WEI logger.info({"msg": f"Simulated CL rebase for frame: {frame_cl_rebase} Gwei"}) return Gwei(frame_cl_rebase) - def _get_total_supply(self, blockstamp: BlockStamp) -> Gwei: - return self.w3.lido_contracts.lido.functions.totalSupply().call(block_identifier=blockstamp.block_hash) - def _get_config(self, blockstamp: BlockStamp) -> BunkerConfig: """Get config values from OracleDaemonConfig contract""" config = self.w3.lido_contracts.oracle_daemon_config return BunkerConfig( - Web3.to_int( - config.functions.get('NORMALIZED_CL_REWARD_PER_EPOCH').call(block_identifier=blockstamp.block_hash) - ), - Web3.to_int( - config.functions.get('NORMALIZED_CL_REWARD_MISTAKE_RATE_BP').call(block_identifier=blockstamp.block_hash) - ) / TOTAL_BASIS_POINTS, - Web3.to_int( - config.functions.get('REBASE_CHECK_NEAREST_EPOCH_DISTANCE').call(block_identifier=blockstamp.block_hash) - ), - Web3.to_int( - config.functions.get('REBASE_CHECK_DISTANT_EPOCH_DISTANCE').call(block_identifier=blockstamp.block_hash) - ) + config.normalized_cl_reward_per_epoch(blockstamp.block_hash), + config.normalized_cl_reward_mistake_rate_bp(blockstamp.block_hash) / TOTAL_BASIS_POINTS, + config.rebase_check_nearest_epoch_distance(blockstamp.block_hash), + config.rebase_check_distant_epoch_distance(blockstamp.block_hash), ) diff --git a/src/services/bunker_cases/abnormal_cl_rebase.py b/src/services/bunker_cases/abnormal_cl_rebase.py index abab257ba..ef74a7fca 100644 --- a/src/services/bunker_cases/abnormal_cl_rebase.py +++ b/src/services/bunker_cases/abnormal_cl_rebase.py @@ -1,27 +1,28 @@ import logging import math -from typing import Sequence +from typing import Sequence, cast +from web3.contract.contract import ContractEvent from web3.types import EventData from src.constants import MAX_EFFECTIVE_BALANCE, EFFECTIVE_BALANCE_INCREMENT -from src.modules.submodules.typings import ChainConfig -from src.providers.consensus.typings import Validator -from src.providers.keys.typings import LidoKey -from src.services.bunker_cases.typings import BunkerConfig -from src.typings import ReferenceBlockStamp, Gwei, BlockNumber, SlotNumber, BlockStamp, EpochNumber +from src.modules.submodules.types import ChainConfig +from src.providers.consensus.types import Validator +from src.providers.keys.types import LidoKey +from src.services.bunker_cases.types import BunkerConfig +from src.types import ReferenceBlockStamp, Gwei, BlockNumber, SlotNumber, BlockStamp, EpochNumber +from src.utils.events import get_events_in_range from src.utils.slot import get_blockstamp, get_reference_blockstamp from src.utils.validator_state import calculate_active_effective_balance_sum from src.web3py.extensions.lido_validators import LidoValidator, LidoValidatorsProvider -from src.web3py.typings import Web3 +from src.web3py.types import Web3 logger = logging.getLogger(__name__) class AbnormalClRebase: - all_validators: list[Validator] lido_validators: list[LidoValidator] lido_keys: list[LidoKey] @@ -36,7 +37,7 @@ def is_abnormal_cl_rebase( blockstamp: ReferenceBlockStamp, all_validators: list[Validator], lido_validators: list[LidoValidator], - current_report_cl_rebase: Gwei + current_report_cl_rebase: Gwei, ) -> bool: """ First of all, we should calculate the normal CL rebase for this report @@ -55,14 +56,19 @@ def is_abnormal_cl_rebase( logger.info({"msg": "Checking abnormal CL rebase"}) normal_report_cl_rebase = self._calculate_lido_normal_cl_rebase(blockstamp) + + # If there were no cl balance, no need to check changes + if normal_report_cl_rebase == 0: + return False + diff_current_with_normal = 1 - current_report_cl_rebase / normal_report_cl_rebase if diff_current_with_normal > self.b_conf.normalized_cl_reward_mistake_rate: logger.info({"msg": "CL rebase in frame is abnormal"}) no_need_intraframe_sampled_cl_rebase_check = ( - self.b_conf.rebase_check_nearest_epoch_distance == 0 and - self.b_conf.rebase_check_distant_epoch_distance == 0 + self.b_conf.rebase_check_nearest_epoch_distance == 0 + and self.b_conf.rebase_check_distant_epoch_distance == 0 ) if no_need_intraframe_sampled_cl_rebase_check: logger.info({"msg": "Intraframe sampled CL rebase calculation are disabled. Cl rebase is abnormal"}) @@ -98,7 +104,7 @@ def _calculate_lido_normal_cl_rebase(self, blockstamp: ReferenceBlockStamp) -> G self.b_conf, mean_sum_of_all_effective_balance, mean_sum_of_lido_effective_balance, - epochs_passed_since_last_report + epochs_passed_since_last_report, ) logger.info({"msg": f"Normal CL rebase: {normal_cl_rebase} Gwei"}) @@ -143,9 +149,7 @@ def _get_nearest_and_distant_blockstamps( ref_blockstamp.ref_slot - self.b_conf.rebase_check_distant_epoch_distance * self.c_conf.slots_per_epoch ) - AbnormalClRebase.validate_slot_distance( - distant_slot, nearest_slot, ref_blockstamp.slot_number - ) + AbnormalClRebase.validate_slot_distance(distant_slot, nearest_slot, ref_blockstamp.slot_number) nearest_blockstamp = get_blockstamp( self.w3.cc, nearest_slot, last_finalized_slot_number=ref_blockstamp.slot_number @@ -178,9 +182,7 @@ def _calculate_cl_rebase_between_blocks( ) # Get Lido validators' balances with WithdrawalVault balance - ref_lido_balance_with_vault = self._get_lido_validators_balance_with_vault( - ref_blockstamp, self.lido_validators - ) + ref_lido_balance_with_vault = self._get_lido_validators_balance_with_vault(ref_blockstamp, self.lido_validators) prev_lido_balance_with_vault = self._get_lido_validators_balance_with_vault( prev_blockstamp, prev_lido_validators ) @@ -199,9 +201,11 @@ def _calculate_cl_rebase_between_blocks( # Finally, we can calculate corrected CL rebase cl_rebase = Gwei(raw_cl_rebase + validators_count_diff_in_gwei + withdrawn_from_vault) - logger.info({ - "msg": f"CL rebase between {prev_blockstamp.block_number,ref_blockstamp.block_number} blocks: {cl_rebase} Gwei" - }) + logger.info( + { + "msg": f"CL rebase between {prev_blockstamp.block_number,ref_blockstamp.block_number} blocks: {cl_rebase} Gwei" + } + ) return cl_rebase @@ -226,7 +230,9 @@ def _get_withdrawn_from_vault_between_blocks( """ logger.info( - {"msg": f"Get withdrawn from vault between {prev_blockstamp.block_number,ref_blockstamp.block_number} blocks"} + { + "msg": f"Get withdrawn from vault between {prev_blockstamp.block_number,ref_blockstamp.block_number} blocks" + } ) events = self._get_eth_distributed_events( @@ -250,9 +256,12 @@ def _get_withdrawn_from_vault_between_blocks( def _get_eth_distributed_events(self, from_block: BlockNumber, to_block: BlockNumber) -> list[EventData]: """Get ETHDistributed events between blocks""" - return self.w3.lido_contracts.lido.events.ETHDistributed.get_logs( # type: ignore[attr-defined] - fromBlock=from_block, - toBlock=to_block, + return list( + get_events_in_range( + cast(ContractEvent, self.w3.lido_contracts.lido.events.ETHDistributed), + from_block, + to_block, + ) ) def _get_last_report_reference_blockstamp(self, ref_blockstamp: ReferenceBlockStamp) -> ReferenceBlockStamp: @@ -262,7 +271,7 @@ def _get_last_report_reference_blockstamp(self, ref_blockstamp: ReferenceBlockSt self.w3.cc, last_report_ref_slot, ref_epoch=EpochNumber(last_report_ref_slot // self.c_conf.slots_per_epoch), - last_finalized_slot_number=ref_blockstamp.slot_number + last_finalized_slot_number=ref_blockstamp.slot_number, ) @staticmethod @@ -295,9 +304,7 @@ def get_mean_sum_of_effective_balance( last_report_effective_balance_sum = calculate_active_effective_balance_sum( last_report_validators, last_report_blockstamp.ref_epoch ) - ref_effective_balance_sum = calculate_active_effective_balance_sum( - ref_validators, ref_blockstamp.ref_epoch - ) + ref_effective_balance_sum = calculate_active_effective_balance_sum(ref_validators, ref_blockstamp.ref_epoch) return Gwei((ref_effective_balance_sum + last_report_effective_balance_sum) // 2) @staticmethod diff --git a/src/services/bunker_cases/midterm_slashing_penalty.py b/src/services/bunker_cases/midterm_slashing_penalty.py index 690031b62..721238378 100644 --- a/src/services/bunker_cases/midterm_slashing_penalty.py +++ b/src/services/bunker_cases/midterm_slashing_penalty.py @@ -7,9 +7,9 @@ PROPORTIONAL_SLASHING_MULTIPLIER_BELLATRIX, EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE ) -from src.modules.submodules.typings import FrameConfig, ChainConfig -from src.providers.consensus.typings import Validator -from src.typings import EpochNumber, Gwei, ReferenceBlockStamp, FrameNumber, SlotNumber +from src.modules.submodules.types import FrameConfig, ChainConfig +from src.providers.consensus.types import Validator +from src.types import EpochNumber, Gwei, ReferenceBlockStamp, FrameNumber, SlotNumber from src.utils.validator_state import calculate_total_active_effective_balance from src.web3py.extensions.lido_validators import LidoValidator diff --git a/src/services/bunker_cases/typings.py b/src/services/bunker_cases/types.py similarity index 100% rename from src/services/bunker_cases/typings.py rename to src/services/bunker_cases/types.py diff --git a/src/services/exit_order/__init__.py b/src/services/exit_order/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/services/exit_order_iterator.py b/src/services/exit_order/iterator.py similarity index 93% rename from src/services/exit_order_iterator.py rename to src/services/exit_order/iterator.py index b3b9716b6..bf398352a 100644 --- a/src/services/exit_order_iterator.py +++ b/src/services/exit_order/iterator.py @@ -5,18 +5,13 @@ from eth_typing import ChecksumAddress from src.metrics.prometheus.duration_meter import duration_meter -from src.modules.submodules.typings import ChainConfig -from src.services.exit_order_iterator_state import ExitOrderIteratorStateService, NodeOperatorPredictableState -from src.typings import ReferenceBlockStamp +from src.modules.submodules.types import ChainConfig +from src.services.exit_order.iterator_state import ExitOrderIteratorStateService, NodeOperatorPredictableState +from src.types import ReferenceBlockStamp, NodeOperatorGlobalIndex, StakingModuleId, NodeOperatorId from src.utils.validator_state import get_validator_age -from src.web3py.extensions.lido_validators import ( - LidoValidator, - NodeOperatorGlobalIndex, - NodeOperatorId, - StakingModuleId, -) -from src.web3py.typings import Web3 +from src.web3py.extensions.lido_validators import LidoValidator +from src.web3py.types import Web3 logger = logging.getLogger(__name__) @@ -59,7 +54,9 @@ def __iter__(self) -> Iterator[tuple[NodeOperatorGlobalIndex, LidoValidator]]: eois = ExitOrderIteratorStateService(self.w3, self.blockstamp) self.left_queue_count = 0 - self.max_validators_to_exit = eois.get_oracle_report_limits(self.blockstamp).max_validator_exit_requests_per_report + self.max_validators_to_exit = eois.w3.lido_contracts.oracle_report_sanity_checker.get_oracle_report_limits( + self.blockstamp.block_hash, + ).max_validator_exit_requests_per_report self.operator_network_penetration_threshold = eois.get_operator_network_penetration_threshold(self.blockstamp) # Prepare list of exitable validators, which will be sorted by exit order predicates diff --git a/src/services/exit_order_iterator_state.py b/src/services/exit_order/iterator_state.py similarity index 90% rename from src/services/exit_order_iterator_state.py rename to src/services/exit_order/iterator_state.py index 8ed7863f6..fda17a37e 100644 --- a/src/services/exit_order_iterator_state.py +++ b/src/services/exit_order/iterator_state.py @@ -3,12 +3,12 @@ from more_itertools import ilen from src.constants import TOTAL_BASIS_POINTS -from src.modules.submodules.typings import ChainConfig +from src.modules.submodules.types import ChainConfig from src.services.validator_state import LidoValidatorStateService -from src.typings import ReferenceBlockStamp +from src.types import ReferenceBlockStamp from src.utils.validator_state import is_on_exit, get_validator_age from src.web3py.extensions.lido_validators import NodeOperatorGlobalIndex, LidoValidator -from src.web3py.typings import Web3 +from src.web3py.types import Web3 @dataclass @@ -23,8 +23,8 @@ class NodeOperatorPredictableState: class ExitOrderIteratorStateService(LidoValidatorStateService): """Service prepares lido operator statistic, which used to form validators queue in right order""" - def __init__(self, web3: Web3, blockstamp: ReferenceBlockStamp): - super().__init__(web3) + def __init__(self, w3: Web3, blockstamp: ReferenceBlockStamp): + super().__init__(w3) self._operators = self.w3.lido_validators.get_lido_node_operators(blockstamp) self._operator_validators = self.w3.lido_validators.get_lido_validators_by_node_operators(blockstamp) @@ -50,8 +50,9 @@ def prepare_lido_node_operator_stats( ) -> dict[NodeOperatorGlobalIndex, NodeOperatorPredictableState]: """Prepare node operators stats for sorting their validators in exit order""" - recently_requested_to_exit_indexes_per_operator = self.get_recently_requests_to_exit_indexes_by_operators( - blockstamp, chain_config, self._operator_validators.keys() + recently_requested_to_exit_indexes_per_operator = self.get_recently_requested_validators_by_operator( + chain_config.seconds_per_slot, + blockstamp, ) operator_predictable_stats: dict[NodeOperatorGlobalIndex, NodeOperatorPredictableState] = {} @@ -108,11 +109,8 @@ def get_total_predictable_validators_count( ) def get_operator_network_penetration_threshold(self, blockstamp: ReferenceBlockStamp) -> float: - exiting_keys_delayed_border_in_slots_bytes = self.w3.lido_contracts.oracle_daemon_config.functions.get( - 'NODE_OPERATOR_NETWORK_PENETRATION_THRESHOLD_BP' - ).call(block_identifier=blockstamp.block_hash) - - return self.w3.to_int(exiting_keys_delayed_border_in_slots_bytes) / TOTAL_BASIS_POINTS + delay_border = self.w3.lido_contracts.oracle_daemon_config.node_operator_network_penetration_threshold_bp(blockstamp.block_hash) + return delay_border / TOTAL_BASIS_POINTS @staticmethod def count_operator_validators_stats( diff --git a/src/services/exit_order_v2/__init__.py b/src/services/exit_order_v2/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/services/exit_order_v2/iterator.py b/src/services/exit_order_v2/iterator.py new file mode 100644 index 000000000..3d1dc0e1e --- /dev/null +++ b/src/services/exit_order_v2/iterator.py @@ -0,0 +1,290 @@ +from dataclasses import dataclass +from typing import Iterator + +from more_itertools import ilen + +from src.constants import TOTAL_BASIS_POINTS +from src.metrics.prometheus.duration_meter import duration_meter +from src.services.validator_state import LidoValidatorStateService +from src.types import ReferenceBlockStamp, NodeOperatorGlobalIndex, StakingModuleId +from src.utils.validator_state import is_on_exit, get_validator_age +from src.web3py.extensions.lido_validators import LidoValidator, StakingModule, NodeOperator, NodeOperatorLimitMode +from src.web3py.types import Web3 + + +@dataclass +class StakingModuleStats: + staking_module: StakingModule + exitable_validators: int = 0 + + +@dataclass +class NodeOperatorStats: + node_operator: NodeOperator + module_stats: StakingModuleStats + + exitable_validators: int = 0 + delayed_validators: int = 0 + total_age: int = 0 + force_exit_to: int | None = None + soft_exit_to: int | None = None + + +class ValidatorExitIteratorV2: + """ + To determine which validators to request for exit, the VEBO selects one entry + from the sorted list of exitable Lido validators until the demand in WQ is covered by + the exiting validators and future rewards, or until the limit per report is reached. + + Staking Router 1.5 ejection order. + + | Sorting | Module | Node Operator | Validator | + | ------- | ------------------------------------------- | ----------------------------------------------------- | ---------------------- | + | V | | Lowest number of delayed validators | | + | V | | Highest number of targeted validators to boosted exit | | + | V | | Highest number of targeted validators to smooth exit | | + | V | Highest deviation from the exit share limit | | | + | V | | Highest stake weight | | + | V | | Highest number of validators | | + | V | | | Lowest validator index | + """ + index: int = 0 + total_lido_exitable_validators: int = 0 + module_stats: dict[StakingModuleId, StakingModuleStats] = {} + node_operators_stats: dict[NodeOperatorGlobalIndex, NodeOperatorStats] = {} + exitable_validators: dict[NodeOperatorGlobalIndex, list[LidoValidator]] = {} + + max_validators_to_exit: int + + no_penetration_threshold: int = 0 + eth_validators_count: int = 0 + + def __init__(self, w3: Web3, blockstamp: ReferenceBlockStamp, seconds_per_slot: int): + self.w3 = w3 + self.blockstamp = blockstamp + self.seconds_per_slot = seconds_per_slot + + self.lvs = LidoValidatorStateService(self.w3) + + @duration_meter() + def __iter__(self) -> Iterator[tuple[NodeOperatorGlobalIndex, LidoValidator]]: + self.index = 0 + self.total_lido_exitable_validators = 0 + self._prepare_data_structure() + self._calculate_lido_stats() + self._load_constants() + return self + + @duration_meter() + def __next__(self) -> tuple[NodeOperatorGlobalIndex, LidoValidator]: + if self.index == self.max_validators_to_exit: + raise StopIteration + + for node_operator in sorted(self.node_operators_stats.values(), key=self._no_predicate): + if not node_operator.exitable_validators: + break + + self.index += 1 + gid = ( + node_operator.module_stats.staking_module.id, + node_operator.node_operator.id, + ) + return gid, self._eject_validator(gid) + + raise StopIteration + + def _prepare_data_structure(self): + modules = self.w3.lido_contracts.staking_router.get_staking_modules(self.blockstamp.block_hash) + for module in modules: + self.module_stats[module.id] = StakingModuleStats(module) + + node_operators = self.w3.lido_validators.get_lido_node_operators(self.blockstamp) + for node_operator in node_operators: + self.node_operators_stats[(node_operator.staking_module.id, node_operator.id)] = NodeOperatorStats( + node_operator, + self.module_stats[node_operator.staking_module.id], + ) + + lido_validators = self.w3.lido_validators.get_lido_validators_by_node_operators(self.blockstamp) + for gid, validators_list in lido_validators.items(): + self.exitable_validators[gid] = list(filter(self.get_filter_non_exitable_validators(gid), validators_list)) + self.exitable_validators[gid].sort(key=lambda val: val.index) + + def _calculate_lido_stats(self): + lido_validators = self.w3.lido_validators.get_lido_validators_by_node_operators(self.blockstamp) + delayed_validators = self._get_delayed_validators() + + for gid, validators in self.exitable_validators.items(): + + # Calculate validators that are not yet in CL + deposited_validators = self.node_operators_stats[gid].node_operator.total_deposited_validators + transient_validators_count = deposited_validators - len(lido_validators[gid]) + + no_validators = len(validators) + transient_validators_count + + self.total_lido_exitable_validators += no_validators + self.module_stats[gid[0]].exitable_validators += no_validators + self.node_operators_stats[gid].exitable_validators = no_validators + + self.node_operators_stats[gid].delayed_validators = delayed_validators[gid] + self.node_operators_stats[gid].total_age = self.calculate_validators_age(validators) + + if self.node_operators_stats[gid].node_operator.is_target_limit_active == NodeOperatorLimitMode.FORCE: + self.node_operators_stats[gid].force_exit_to = self.node_operators_stats[gid].node_operator.target_validators_count + + elif self.node_operators_stats[gid].node_operator.is_target_limit_active == NodeOperatorLimitMode.SOFT: + self.node_operators_stats[gid].soft_exit_to = self.node_operators_stats[gid].node_operator.target_validators_count + + def _load_constants(self): + self.max_validators_to_exit = self.w3.lido_contracts.oracle_report_sanity_checker.get_oracle_report_limits( + self.blockstamp.block_hash, + ).max_validator_exit_requests_per_report + + self.no_penetration_threshold = self.w3.lido_contracts.oracle_daemon_config.node_operator_network_penetration_threshold_bp( + block_identifier=self.blockstamp.block_hash, + ) / TOTAL_BASIS_POINTS + + self.eth_validators_count = ilen(v for v in self.w3.cc.get_validators(self.blockstamp) if not is_on_exit(v)) + + def get_filter_non_exitable_validators(self, gid: NodeOperatorGlobalIndex): + """Validators that were deposited, but not yet represented on CL side are exitable.""" + indexes = self.lvs.get_operators_with_last_exited_validator_indexes(self.blockstamp) + + def is_validator_exitable(validator: LidoValidator): + """Returns True if validator is exitable: not on exit and not requested to exit""" + requested_to_exit = int(validator.index) <= indexes[gid] + return not is_on_exit(validator) and not requested_to_exit + + return is_validator_exitable + + def _get_delayed_validators(self) -> dict[NodeOperatorGlobalIndex, int]: + last_requested_to_exit = self.lvs.get_operators_with_last_exited_validator_indexes(self.blockstamp) + + recent_requests = self.lvs.get_recently_requested_validators_by_operator( + self.seconds_per_slot, + self.blockstamp, + ) + + result = {} + + for gid, validators_list in self.exitable_validators.items(): + + def is_delayed(validator: LidoValidator) -> bool: + requested_to_exit = int(validator.index) <= last_requested_to_exit[gid] + recently_requested_to_exit = int(validator.index) in recent_requests[gid] + return requested_to_exit and not recently_requested_to_exit and not is_on_exit(validator) + + result[gid] = ilen(val for val in validators_list if is_delayed(val)) + + return result + + def calculate_validators_age(self, validators: list[LidoValidator]) -> int: + result = 0 + + for validator in validators: + result += get_validator_age(validator, self.blockstamp.ref_epoch) + + return result + + def _eject_validator(self, gid: NodeOperatorGlobalIndex) -> LidoValidator: + validator = self.exitable_validators[gid].pop(0) + + # Change lido total + self.total_lido_exitable_validators -= 1 + # Change module total + self.module_stats[gid[0]].exitable_validators -= 1 + # Change node operator stats + self.node_operators_stats[gid].exitable_validators -= 1 + self.node_operators_stats[gid].total_age -= get_validator_age(validator, self.blockstamp.ref_epoch) + + return validator + + def _no_predicate(self, node_operator: NodeOperatorStats) -> tuple: + return ( + node_operator.delayed_validators, + - self._no_force_predicate(node_operator), + - self._no_soft_predicate(node_operator), + - self._max_share_rate_coefficient_predicate(node_operator), + - self._stake_weight_coefficient_predicate( + node_operator, + self.no_penetration_threshold, + self.eth_validators_count, + ), + - node_operator.exitable_validators + ) + + @staticmethod + def _no_force_predicate(node_operator: NodeOperatorStats) -> int: + return ValidatorExitIteratorV2._get_expected_validators_diff( + node_operator.exitable_validators, + node_operator.force_exit_to, + ) + + @staticmethod + def _no_soft_predicate(node_operator: NodeOperatorStats) -> int: + return ValidatorExitIteratorV2._get_expected_validators_diff( + node_operator.exitable_validators, + node_operator.soft_exit_to, + ) + + @staticmethod + def _get_expected_validators_diff(current: int, expected: int | None): + if expected is not None: + if current > expected: + return current - expected + return 0 + + def _max_share_rate_coefficient_predicate(self, node_operator: NodeOperatorStats) -> int: + """ + The higher coefficient the higher priority to eject validator + """ + priority_exit_share_threshold = node_operator.module_stats.staking_module.priority_exit_share_threshold + + # ToDo: remove after upgrade to sr v2 + priority_exit_share_threshold = priority_exit_share_threshold if priority_exit_share_threshold is not None else TOTAL_BASIS_POINTS + + max_share_rate = priority_exit_share_threshold / TOTAL_BASIS_POINTS + + max_validators_count = int(max_share_rate * self.total_lido_exitable_validators) + return max(node_operator.module_stats.exitable_validators - max_validators_count, 0) + + @staticmethod + def _stake_weight_coefficient_predicate( + node_operator: NodeOperatorStats, + total_validators: int, + no_penetration: float, + ) -> int: + """ + The higher coefficient the higher priority to eject validator + """ + if total_validators * no_penetration < node_operator.exitable_validators: + return node_operator.total_age + + return 0 + + def get_remaining_forced_validators(self) -> list[tuple[NodeOperatorGlobalIndex, LidoValidator]]: + """ + Returns a list of validators from NOs that are requested for forced exit. + This includes an additional scenario where enough validators have been ejected to fulfill the withdrawal requests, + but forced ejections are still necessary. + """ + result: list[tuple[NodeOperatorGlobalIndex, LidoValidator]] = [] + + # Extra validators limited by VEBO report + while self.index != self.max_validators_to_exit: + for node_operator in sorted(self.node_operators_stats.values(), key=lambda no: -self._no_force_predicate(no)): + if self._no_force_predicate(node_operator) == 0: + # First in list no has no forced validators. Cycle done + return result + + if node_operator.exitable_validators: + # When found Node Operator + self.index += 1 + gid = ( + node_operator.module_stats.staking_module.id, + node_operator.node_operator.id, + ) + result.append((gid, self._eject_validator(gid))) + break + + return result diff --git a/src/services/prediction.py b/src/services/prediction.py index 37b3aa979..9c545c464 100644 --- a/src/services/prediction.py +++ b/src/services/prediction.py @@ -1,20 +1,17 @@ import logging +from functools import lru_cache -from web3.types import Wei, EventData +from web3.types import EventData, Wei -from src.modules.submodules.typings import ChainConfig -from src.typings import ReferenceBlockStamp +from src.modules.submodules.types import ChainConfig +from src.providers.execution.exceptions import InconsistentEvents +from src.types import ReferenceBlockStamp from src.utils.events import get_events_in_past -from src.web3py.typings import Web3 - +from src.web3py.types import Web3 logger = logging.getLogger(__name__) -class InconsistentEvents(ValueError): - pass - - class RewardsPredictionService: """ Based on events predicts amount of eth that protocol will earn per epoch. @@ -25,13 +22,13 @@ class RewardsPredictionService: def __init__(self, w3: Web3): self.w3 = w3 + @lru_cache(maxsize=1) def get_rewards_per_epoch( self, blockstamp: ReferenceBlockStamp, chain_configs: ChainConfig, ) -> Wei: - prediction_duration_in_slots = self._get_prediction_duration_in_slots(blockstamp) - logger.info({'msg': 'Fetch prediction frame in slots.', 'value': prediction_duration_in_slots}) + prediction_duration_in_slots = self.w3.lido_contracts.oracle_daemon_config.prediction_duration_in_slots(blockstamp.block_hash) token_rebase_events = get_events_in_past( self.w3.lido_contracts.lido.events.TokenRebased, # type: ignore[arg-type] @@ -102,10 +99,3 @@ def _group_events_by_transaction_hash(event_type_1: list[EventData], event_type_ raise InconsistentEvents('Events are inconsistent: unexpected events_type_1 amount.') return result_event_data - - def _get_prediction_duration_in_slots(self, blockstamp: ReferenceBlockStamp) -> int: - return Web3.to_int( - self.w3.lido_contracts.oracle_daemon_config.functions.get('PREDICTION_DURATION_IN_SLOTS').call( - block_identifier=blockstamp.block_hash, - ) - ) diff --git a/src/services/safe_border.py b/src/services/safe_border.py index a52a8546d..f355e9493 100644 --- a/src/services/safe_border.py +++ b/src/services/safe_border.py @@ -1,17 +1,15 @@ import math -from typing import Any, Iterable, Optional +from typing import Iterable from eth_typing import HexStr from src.constants import EPOCHS_PER_SLASHINGS_VECTOR, MIN_VALIDATOR_WITHDRAWABILITY_DELAY from src.metrics.prometheus.duration_meter import duration_meter from src.modules.submodules.consensus import ChainConfig, FrameConfig -from src.modules.accounting.typings import OracleReportLimits from src.utils.web3converter import Web3Converter -from src.utils.abi import named_tuple_to_dataclass -from src.typings import EpochNumber, FrameNumber, ReferenceBlockStamp, SlotNumber +from src.types import EpochNumber, FrameNumber, ReferenceBlockStamp, SlotNumber from src.web3py.extensions.lido_validators import Validator -from src.web3py.typings import Web3 +from src.web3py.types import Web3 from src.utils.slot import get_blockstamp @@ -34,7 +32,6 @@ class SafeBorder(Web3Converter): 2. Negative rebase border 3. Associated slashing border """ - chain_config: ChainConfig frame_config: FrameConfig blockstamp: ReferenceBlockStamp @@ -57,9 +54,15 @@ def __init__( self.frame_config = frame_config self.converter = Web3Converter(chain_config, frame_config) - self._retrieve_constants() + def _retrieve_constants(self): + limits_list = self.w3.lido_contracts.oracle_report_sanity_checker.get_oracle_report_limits(self.blockstamp.block_hash) + + self.finalization_default_shift = math.ceil( + limits_list.request_timestamp_margin / (self.chain_config.slots_per_epoch * self.chain_config.seconds_per_slot) + ) + @duration_meter() def get_safe_border_epoch( self, @@ -91,8 +94,9 @@ def _get_negative_rebase_border_epoch(self) -> EpochNumber: bunker_start_or_last_successful_report_epoch = self._get_bunker_start_or_last_successful_report_epoch() latest_allowable_epoch = bunker_start_or_last_successful_report_epoch - self.finalization_default_shift - earliest_allowable_epoch = self.get_epoch_by_slot( - self.blockstamp.ref_slot) - self.finalization_max_negative_rebase_shift + + max_negative_rebase = self.w3.lido_contracts.oracle_daemon_config.finalization_max_negative_rebase_epoch_shift(self.blockstamp.block_hash) + earliest_allowable_epoch = self.get_epoch_by_slot(self.blockstamp.ref_slot) - max_negative_rebase return EpochNumber(max(earliest_allowable_epoch, latest_allowable_epoch)) @@ -124,7 +128,7 @@ def _get_associated_slashings_border_epoch(self) -> EpochNumber: return self._get_default_requests_border_epoch() @duration_meter() - def _get_earliest_slashed_epoch_among_incomplete_slashings(self) -> Optional[EpochNumber]: + def _get_earliest_slashed_epoch_among_incomplete_slashings(self) -> EpochNumber | None: validators = self.w3.lido_validators.get_lido_validators(self.blockstamp) validators_slashed = filter_slashed_validators(validators) @@ -156,7 +160,7 @@ def _get_earliest_slashed_epoch_among_incomplete_slashings(self) -> Optional[Epo # The exit period for a specific validator may be equal to the MIN_VALIDATOR_WITHDRAWAL_DELAY. # This means that there are so many validators in the queue that the exit epoch moves with the withdrawable epoch, # and we cannot detect when slashing has started. - def _predict_earliest_slashed_epoch(self, validator: Validator) -> Optional[EpochNumber]: + def _predict_earliest_slashed_epoch(self, validator: Validator) -> EpochNumber | None: exit_epoch = int(validator.validator.exit_epoch) withdrawable_epoch = int(validator.validator.withdrawable_epoch) @@ -239,8 +243,8 @@ def _get_validators_earliest_activation_epoch(self, validators: list[Validator]) ) return EpochNumber(int(sorted_validators[0].validator.activation_epoch)) - def _get_bunker_mode_start_timestamp(self) -> Optional[int]: - start_timestamp = self._get_bunker_start_timestamp() + def _get_bunker_mode_start_timestamp(self) -> int | None: + start_timestamp = self.w3.lido_contracts.withdrawal_queue_nft.bunker_mode_since_timestamp(self.blockstamp.block_hash) if start_timestamp > self.blockstamp.block_timestamp: return None @@ -248,57 +252,18 @@ def _get_bunker_mode_start_timestamp(self) -> Optional[int]: return start_timestamp def _get_last_finalized_withdrawal_request_slot(self) -> SlotNumber: - last_finalized_request_id = self._get_last_finalized_request_id() + last_finalized_request_id = self.w3.lido_contracts.withdrawal_queue_nft.get_last_finalized_request_id(self.blockstamp.block_hash) if last_finalized_request_id == 0: # request with id: 0 is reserved by protocol. No requests were finalized. return SlotNumber(0) - last_finalized_request_data = self._get_withdrawal_request_status(last_finalized_request_id) + last_finalized_request_data = self.w3.lido_contracts.withdrawal_queue_nft.get_withdrawal_status(last_finalized_request_id) return self.get_epoch_first_slot(self.get_epoch_by_timestamp(last_finalized_request_data.timestamp)) def _get_blockstamp(self, last_slot_in_frame: SlotNumber): return get_blockstamp(self.w3.cc, last_slot_in_frame, self.blockstamp.ref_slot) - def _retrieve_constants(self): - limits_list = self._fetch_oracle_report_limits_list() - self.finalization_default_shift = math.ceil( - limits_list.request_timestamp_margin / (self.chain_config.slots_per_epoch * self.chain_config.seconds_per_slot) - ) - - self.finalization_max_negative_rebase_shift = self._fetch_finalization_max_negative_rebase_epoch_shift() - - def _fetch_oracle_report_limits_list(self): - return named_tuple_to_dataclass( - self.w3.lido_contracts.oracle_report_sanity_checker.functions.getOracleReportLimits().call( - block_identifier=self.blockstamp.block_hash - ), - OracleReportLimits - ) - - def _fetch_finalization_max_negative_rebase_epoch_shift(self): - return self.w3.to_int( - primitive=self.w3.lido_contracts.oracle_daemon_config.functions.get( - 'FINALIZATION_MAX_NEGATIVE_REBASE_EPOCH_SHIFT', - ).call(block_identifier=self.blockstamp.block_hash) - ) - - def _get_bunker_start_timestamp(self) -> int: - # If bunker mode is off returns max(uint256) - return self.w3.lido_contracts.withdrawal_queue_nft.functions.bunkerModeSinceTimestamp().call( - block_identifier=self.blockstamp.block_hash - ) - - def _get_last_finalized_request_id(self) -> int: - return self.w3.lido_contracts.withdrawal_queue_nft.functions.getLastFinalizedRequestId().call( - block_identifier=self.blockstamp.block_hash - ) - - def _get_withdrawal_request_status(self, request_id: int) -> Any: - return self.w3.lido_contracts.withdrawal_queue_nft.functions.getWithdrawalStatus([request_id]).call( - block_identifier=self.blockstamp.block_hash - )[0] - def round_slot_by_frame(self, slot: SlotNumber) -> SlotNumber: rounded_epoch = self.round_epoch_by_frame(self.get_epoch_by_slot(slot)) return self.get_epoch_first_slot(rounded_epoch) diff --git a/src/services/validator_state.py b/src/services/validator_state.py index 38d623430..2645fa948 100644 --- a/src/services/validator_state.py +++ b/src/services/validator_state.py @@ -1,7 +1,6 @@ import logging from copy import deepcopy from functools import reduce -from typing import Sequence, Iterable from eth_typing import HexStr @@ -11,11 +10,8 @@ ACCOUNTING_EXITED_VALIDATORS, ACCOUNTING_DELAYED_VALIDATORS, ) -from src.modules.accounting.extra_data import ExtraDataService, ExtraData -from src.modules.accounting.typings import OracleReportLimits -from src.modules.submodules.typings import ChainConfig -from src.typings import BlockStamp, ReferenceBlockStamp, EpochNumber -from src.utils.abi import named_tuple_to_dataclass +from src.modules.submodules.types import ChainConfig +from src.types import BlockStamp, ReferenceBlockStamp, EpochNumber from src.utils.events import get_events_in_past from src.utils.types import bytes_to_hex_str from src.utils.validator_state import is_exited_validator, is_validator_eligible_to_exit, is_on_exit @@ -23,9 +19,8 @@ from src.web3py.extensions.lido_validators import ( NodeOperatorGlobalIndex, LidoValidator, - StakingModule, ) -from src.web3py.typings import Web3 +from src.web3py.types import Web3 logger = logging.getLogger(__name__) @@ -35,24 +30,6 @@ class LidoValidatorStateService: """Helper that calculates/aggregates Lido validator's states.""" def __init__(self, w3: Web3): self.w3 = w3 - self.extra_data_service = ExtraDataService() - - @lru_cache(maxsize=1) - def get_extra_data(self, blockstamp: ReferenceBlockStamp, chain_config: ChainConfig) -> ExtraData: - stuck_validators = self.get_lido_newly_stuck_validators(blockstamp, chain_config) - logger.info({'msg': 'Calculate stuck validators.', 'value': stuck_validators}) - exited_validators = self.get_lido_newly_exited_validators(blockstamp) - logger.info({'msg': 'Calculate exited validators.', 'value': exited_validators}) - orl = self.get_oracle_report_limits(blockstamp) - - extra_data = self.extra_data_service.collect( - stuck_validators=stuck_validators, - exited_validators=exited_validators, - max_items_count=orl.max_accounting_extra_data_list_items_count, - max_no_in_payload_count=orl.max_node_operators_per_extra_data_item_count, - ) - logger.info({'msg': 'Calculate extra data.', 'value': extra_data}) - return extra_data def get_lido_newly_stuck_validators(self, blockstamp: ReferenceBlockStamp, chain_config: ChainConfig) -> dict[NodeOperatorGlobalIndex, int]: lido_validators_by_no = self.w3.lido_validators.get_lido_validators_by_node_operators(blockstamp) @@ -76,7 +53,7 @@ def sum_stuck_validators(total: int, validator: LidoValidator) -> int: return total validator_available_to_exit_epoch = int(validator.validator.activation_epoch) + SHARD_COMMITTEE_PERIOD - delinquent_timeout_in_slots = self.get_validator_delinquent_timeout_in_slot(blockstamp) + delinquent_timeout_in_slots = self.w3.lido_contracts.oracle_daemon_config.validator_delinquent_timeout_in_slots(blockstamp.block_hash) last_slot_to_exit = validator_available_to_exit_epoch * chain_config.slots_per_epoch + delinquent_timeout_in_slots @@ -104,7 +81,7 @@ def sum_stuck_validators(total: int, validator: LidoValidator) -> int: return result def get_last_requested_to_exit_pubkeys(self, blockstamp: ReferenceBlockStamp, chain_config: ChainConfig) -> set[HexStr]: - exiting_keys_stuck_border_in_slots = self.get_validator_delinquent_timeout_in_slot(blockstamp) + exiting_keys_stuck_border_in_slots = self.w3.lido_contracts.oracle_daemon_config.validator_delinquent_timeout_in_slots(blockstamp.block_hash) events = get_events_in_past( self.w3.lido_contracts.validators_exit_bus_oracle.events.ValidatorExitRequest, # type: ignore[arg-type] @@ -118,26 +95,23 @@ def get_last_requested_to_exit_pubkeys(self, blockstamp: ReferenceBlockStamp, ch return set(bytes_to_hex_str(event['args']['validatorPubkey']) for event in events) @lru_cache(maxsize=1) - def get_validator_delinquent_timeout_in_slot(self, blockstamp: ReferenceBlockStamp) -> int: - exiting_keys_stuck_border_in_slots_bytes = self.w3.lido_contracts.oracle_daemon_config.functions.get( - 'VALIDATOR_DELINQUENT_TIMEOUT_IN_SLOTS' - ).call(block_identifier=blockstamp.block_hash) - - return self.w3.to_int(exiting_keys_stuck_border_in_slots_bytes) - def get_operators_with_last_exited_validator_indexes(self, blockstamp: BlockStamp) -> dict[NodeOperatorGlobalIndex, int]: - node_operators = self.w3.lido_validators.get_lido_node_operators(blockstamp) - staking_modules = self.w3.lido_validators.get_staking_modules(blockstamp) - result = {} - for module in staking_modules: - node_operators_ids_in_module = list(map(lambda op: op.id, filter(lambda operator: operator.staking_module.id == module.id, node_operators))) + staking_modules = self.w3.lido_contracts.staking_router.get_staking_modules(blockstamp.block_hash) + node_operators = self.w3.lido_validators.get_lido_node_operators_by_modules(blockstamp) - last_requested_validators = self._get_last_requested_validator_indices(blockstamp, module, node_operators_ids_in_module) + for module in staking_modules: + last_requested_ids = self.w3.lido_contracts.validators_exit_bus_oracle.get_last_requested_validator_indices( + module.id, + tuple(no.id for no in node_operators[module.id]), + blockstamp.block_hash, + ) - for no_id, validator_index in zip(node_operators_ids_in_module, last_requested_validators): - result[(module.id, no_id)] = validator_index + result.update({ + (module.id, no.id): last_requested_id + for no, last_requested_id in zip(node_operators[module.id], last_requested_ids) + }) return result @@ -171,20 +145,7 @@ def get_exited_lido_validators(self, blockstamp: ReferenceBlockStamp) -> dict[No return result - def get_oracle_report_limits(self, blockstamp: BlockStamp) -> OracleReportLimits: - result = self.w3.lido_contracts.oracle_report_sanity_checker.functions.getOracleReportLimits().call( - block_identifier=blockstamp.block_hash, - ) - orl = named_tuple_to_dataclass(result, OracleReportLimits) - logger.info({'msg': 'Fetch oracle sanity checks.', 'value': orl}) - return orl - - def _get_last_requested_validator_indices(self, blockstamp: BlockStamp, module: StakingModule, node_operators_ids_in_module: Sequence[int]) -> list[int]: - return self.w3.lido_contracts.validators_exit_bus_oracle.functions.getLastRequestedValidatorIndices( - module.id, - node_operators_ids_in_module, - ).call(block_identifier=blockstamp.block_hash) - + @lru_cache(maxsize=1) def get_recently_requested_but_not_exited_validators( self, blockstamp: ReferenceBlockStamp, @@ -201,8 +162,9 @@ def get_recently_requested_but_not_exited_validators( """ lido_validators_by_operator = self.w3.lido_validators.get_lido_validators_by_node_operators(blockstamp) ejected_indexes = self.get_operators_with_last_exited_validator_indexes(blockstamp) - recent_indexes = self.get_recently_requests_to_exit_indexes_by_operators( - blockstamp, chain_config, lido_validators_by_operator.keys() + recent_indexes = self.get_recently_requested_validators_by_operator( + chain_config.seconds_per_slot, + blockstamp, ) validators_recently_requested_to_exit = [] @@ -216,7 +178,8 @@ def validator_recently_requested_to_exit(validator: LidoValidator) -> bool: return int(validator.index) in recent_indexes[global_index] def validator_eligible_to_exit(validator: LidoValidator) -> bool: - delayed_timeout_in_epoch = self.get_validator_delayed_timeout_in_slot(blockstamp) // chain_config.slots_per_epoch + vals_delayed = self.w3.lido_contracts.oracle_daemon_config.validator_delayed_timeout_in_slots(blockstamp.block_hash) + delayed_timeout_in_epoch = vals_delayed // chain_config.slots_per_epoch return is_validator_eligible_to_exit(validator, EpochNumber(blockstamp.ref_epoch - delayed_timeout_in_epoch)) def is_validator_recently_requested_but_not_exited(validator: LidoValidator) -> bool: @@ -250,26 +213,29 @@ def is_validator_delayed(validator: LidoValidator) -> bool: return validators_recently_requested_to_exit - def get_recently_requests_to_exit_indexes_by_operators( + def get_recently_requested_validators_by_operator( self, + seconds_per_slot: int, blockstamp: ReferenceBlockStamp, - chain_config: ChainConfig, - operator_global_indexes: Iterable[NodeOperatorGlobalIndex], ) -> dict[NodeOperatorGlobalIndex, set[int]]: - exiting_keys_delayed_border_in_slots = self.get_validator_delayed_timeout_in_slot(blockstamp) + """ + Returns validators indexes that were asked to exit in last {{validator_delayed_timeout_in_slots}} slots. + """ + exiting_keys_delayed_border_in_slots = self.w3.lido_contracts.oracle_daemon_config.validator_delayed_timeout_in_slots(blockstamp.block_hash) events = get_events_in_past( self.w3.lido_contracts.validators_exit_bus_oracle.events.ValidatorExitRequest, # type: ignore[arg-type] to_blockstamp=blockstamp, for_slots=exiting_keys_delayed_border_in_slots, - seconds_per_slot=chain_config.seconds_per_slot, + seconds_per_slot=seconds_per_slot, ) logger.info({'msg': f'Fetch exit events. Got {len(events)} events.'}) + node_operators = self.w3.lido_validators.get_lido_node_operators(blockstamp) # Initialize dict with empty sets for operators which validators were not contained in any event global_indexes: dict[NodeOperatorGlobalIndex, set[int]] = { - operator: set() for operator in operator_global_indexes + (operator.staking_module.id, operator.id): set() for operator in node_operators } for event in events: @@ -277,11 +243,3 @@ def get_recently_requests_to_exit_indexes_by_operators( global_indexes[operator_global_index].add(event['args']['validatorIndex']) return global_indexes - - @lru_cache(maxsize=1) - def get_validator_delayed_timeout_in_slot(self, blockstamp: ReferenceBlockStamp) -> int: - exiting_keys_delayed_border_in_slots_bytes = self.w3.lido_contracts.oracle_daemon_config.functions.get( - 'VALIDATOR_DELAYED_TIMEOUT_IN_SLOTS' - ).call(block_identifier=blockstamp.block_hash) - - return self.w3.to_int(exiting_keys_delayed_border_in_slots_bytes) diff --git a/src/services/withdrawal.py b/src/services/withdrawal.py index 34c2ebe77..540492915 100644 --- a/src/services/withdrawal.py +++ b/src/services/withdrawal.py @@ -2,12 +2,11 @@ from src.metrics.prometheus.business import CONTRACT_ON_PAUSE from src.variables import FINALIZATION_BATCH_MAX_REQUEST_COUNT -from src.utils.abi import named_tuple_to_dataclass -from src.web3py.typings import Web3 -from src.typings import ReferenceBlockStamp +from src.web3py.types import Web3 +from src.types import ReferenceBlockStamp from src.services.safe_border import SafeBorder from src.modules.submodules.consensus import ChainConfig, FrameConfig -from src.modules.accounting.typings import BatchState +from src.modules.accounting.types import BatchState class Withdrawal: @@ -38,8 +37,8 @@ def get_finalization_batches( withdrawal_vault_balance: Wei, el_rewards_vault_balance: Wei ) -> list[int]: - on_pause = self._is_requests_finalization_paused() - CONTRACT_ON_PAUSE.set(on_pause) + on_pause = self.w3.lido_contracts.withdrawal_queue_nft.is_paused(self.blockstamp.block_hash) + CONTRACT_ON_PAUSE.labels('finalization').set(on_pause) if on_pause: return [] @@ -57,76 +56,43 @@ def get_finalization_batches( return self._calculate_finalization_batches(share_rate, available_eth, withdrawable_until_timestamp) def _has_unfinalized_requests(self) -> bool: - last_finalized_id = self._fetch_last_finalized_request_id() - last_requested_id = self._fetch_last_request_id() + last_finalized_id = self.w3.lido_contracts.withdrawal_queue_nft.get_last_finalized_request_id(self.blockstamp.block_hash) + last_requested_id = self.w3.lido_contracts.withdrawal_queue_nft.get_last_request_id(self.blockstamp.block_hash) return last_finalized_id < last_requested_id def _get_available_eth(self, withdrawal_vault_balance: Wei, el_rewards_vault_balance: Wei) -> Wei: - buffered_ether = self._fetch_buffered_ether() + buffered_ether = self.w3.lido_contracts.lido.get_buffered_ether(self.blockstamp.block_hash) + # This amount of eth could not be spent for deposits. - unfinalized_steth = self._fetch_unfinalized_steth() + unfinalized_steth = self.w3.lido_contracts.withdrawal_queue_nft.unfinalized_steth(self.blockstamp.block_hash) reserved_buffer = min(buffered_ether, unfinalized_steth) return Wei(withdrawal_vault_balance + el_rewards_vault_balance + reserved_buffer) def _calculate_finalization_batches( - self, share_rate: int, available_eth: int, until_timestamp: int + self, + share_rate: int, + available_eth: int, + until_timestamp: int ) -> list[int]: + max_length = self.w3.lido_contracts.withdrawal_queue_nft.max_batches_length(self.blockstamp.block_hash) + state = BatchState( remaining_eth_budget=available_eth, finished=False, - batches=[0] * self._fetch_max_batches_length(), + batches=tuple([0] * max_length), batches_length=0 ) while not state.finished: - state = self._fetch_finalization_batches( + state = self.w3.lido_contracts.withdrawal_queue_nft.calculate_finalization_batches( share_rate, until_timestamp, - state + FINALIZATION_BATCH_MAX_REQUEST_COUNT, + state.as_tuple(), + self.blockstamp.block_hash, ) return list(filter(lambda value: value > 0, state.batches)) - - def _fetch_last_finalized_request_id(self) -> int: - return self.w3.lido_contracts.withdrawal_queue_nft.functions.getLastFinalizedRequestId().call( - block_identifier=self.blockstamp.block_hash - ) - - def _fetch_last_request_id(self) -> int: - return self.w3.lido_contracts.withdrawal_queue_nft.functions.getLastRequestId().call( - block_identifier=self.blockstamp.block_hash - ) - - def _fetch_buffered_ether(self) -> Wei: - return Wei(self.w3.lido_contracts.lido.functions.getBufferedEther().call( - block_identifier=self.blockstamp.block_hash - )) - - def _fetch_unfinalized_steth(self) -> Wei: - return Wei(self.w3.lido_contracts.withdrawal_queue_nft.functions.unfinalizedStETH().call( - block_identifier=self.blockstamp.block_hash - )) - - def _is_requests_finalization_paused(self) -> bool: - return self.w3.lido_contracts.withdrawal_queue_nft.functions.isPaused().call( - block_identifier=self.blockstamp.block_hash - ) - - def _fetch_max_batches_length(self) -> int: - return self.w3.lido_contracts.withdrawal_queue_nft.functions.MAX_BATCHES_LENGTH().call( - block_identifier=self.blockstamp.block_hash - ) - - def _fetch_finalization_batches(self, share_rate: int, timestamp: int, batch_state: BatchState) -> BatchState: - return named_tuple_to_dataclass( - self.w3.lido_contracts.withdrawal_queue_nft.functions.calculateFinalizationBatches( - share_rate, - timestamp, - FINALIZATION_BATCH_MAX_REQUEST_COUNT, - batch_state.as_tuple() - ).call(block_identifier=self.blockstamp.block_hash), - BatchState - ) diff --git a/src/typings.py b/src/types.py similarity index 69% rename from src/typings.py rename to src/types.py index 38ce331c1..1a84d51e1 100644 --- a/src/typings.py +++ b/src/types.py @@ -2,7 +2,7 @@ from enum import StrEnum from typing import NewType -from eth_typing import HexStr +from eth_typing import BlockNumber, ChecksumAddress, HexStr from web3.types import Timestamp @@ -10,6 +10,7 @@ class OracleModule(StrEnum): ACCOUNTING = 'accounting' EJECTOR = 'ejector' CHECK = 'check' + CSM = 'csm' EpochNumber = NewType('EpochNumber', int) @@ -18,11 +19,18 @@ class OracleModule(StrEnum): BlockRoot = NewType('BlockRoot', HexStr) SlotNumber = NewType('SlotNumber', int) +StakingModuleAddress = NewType('StakingModuleAddress', ChecksumAddress) +StakingModuleId = NewType('StakingModuleId', int) +NodeOperatorId = NewType('NodeOperatorId', int) +NodeOperatorGlobalIndex = tuple[StakingModuleId, NodeOperatorId] + BlockHash = NewType('BlockHash', HexStr) -BlockNumber = NewType('BlockNumber', int) Gwei = NewType('Gwei', int) +ValidatorIndex = NewType('ValidatorIndex', int) +CommitteeIndex = NewType('CommitteeIndex', int) + @dataclass(frozen=True) class BlockStamp: diff --git a/src/utils/abi.py b/src/utils/abi.py index f9f7dadb9..81dc568c1 100644 --- a/src/utils/abi.py +++ b/src/utils/abi.py @@ -1,6 +1,5 @@ import re from collections.abc import Callable -from typing import TypeVar def camel_to_snake(name): @@ -8,10 +7,7 @@ def camel_to_snake(name): return re.sub('([a-z0-9])([A-Z])', r'\1_\2', name).lower() -T = TypeVar('T') - - -def named_tuple_to_dataclass(response, dataclass_factory: Callable[..., T] | type[T]) -> T: +def named_tuple_to_dataclass[T](response, dataclass_factory: Callable[..., T] | type[T]) -> T: """ Converts ABIDecodedNamedTuple to provided dataclass Example: diff --git a/src/utils/blockstamp.py b/src/utils/blockstamp.py index 909ffefff..897847806 100644 --- a/src/utils/blockstamp.py +++ b/src/utils/blockstamp.py @@ -1,7 +1,7 @@ from web3.types import Timestamp -from src.providers.consensus.typings import BlockDetailsResponse -from src.typings import SlotNumber, EpochNumber, ReferenceBlockStamp, BlockStamp, BlockNumber +from src.providers.consensus.types import BlockDetailsResponse +from src.types import SlotNumber, EpochNumber, ReferenceBlockStamp, BlockStamp, BlockNumber def build_reference_blockstamp( @@ -16,21 +16,20 @@ def build_reference_blockstamp( ) -def build_blockstamp( - slot_details: BlockDetailsResponse, -): +def build_blockstamp(slot_details: BlockDetailsResponse): return BlockStamp(**_build_blockstamp_data(slot_details)) def _build_blockstamp_data( slot_details: BlockDetailsResponse, ) -> dict: - execution_data = slot_details.message.body['execution_payload'] + + execution_payload = slot_details.message.body.execution_payload return { - 'slot_number': SlotNumber(int(slot_details.message.slot)), - 'state_root': slot_details.message.state_root, - 'block_number': BlockNumber(int(execution_data['block_number'])), - 'block_hash': execution_data['block_hash'], - 'block_timestamp': Timestamp(int(execution_data['timestamp'])) + "slot_number": SlotNumber(int(slot_details.message.slot)), + "state_root": slot_details.message.state_root, + "block_number": BlockNumber(int(execution_payload.block_number)), + "block_hash": execution_payload.block_hash, + "block_timestamp": Timestamp(int(execution_payload.timestamp)) } diff --git a/src/utils/cache.py b/src/utils/cache.py index 7e8d7391b..4164d69da 100644 --- a/src/utils/cache.py +++ b/src/utils/cache.py @@ -1,6 +1,8 @@ import functools from weakref import WeakKeyDictionary +from src.providers.execution.base_interface import ContractInterface + global_cache: WeakKeyDictionary = WeakKeyDictionary() @@ -9,6 +11,28 @@ def caching_decorator(func): cached_func = functools.lru_cache(*args, **kwargs)(func) def wrapper(*args, **kwargs): + # if lru_cache used for caching ContractInterface method + # Do not cache any requests with relative blocks + # Like 'latest', 'earliest', 'pending', 'safe', 'finalized' or if default ('latest') arg provided + var_names = func.__code__.co_varnames + + if issubclass(args[0].__class__, ContractInterface) and var_names[-1] == 'block_identifier': + block = kwargs.get('block_identifier', None) + if block is None: + if len(args) == len(var_names): + # block_identifier provided via kwargs and args + block = args[-1] + # Move to kwarg + kwargs['block_identifier'] = block + args = args[:-1] + else: + # block_identifier not provided + return func(*args, **kwargs) + + if block in ['latest', 'earliest', 'pending', 'safe', 'finalized']: + # block_identifier one of related markers + return func(*args, **kwargs) + result = cached_func(*args, **kwargs) global_cache[func] = cached_func return result diff --git a/src/utils/dataclass.py b/src/utils/dataclass.py index dd61d853e..116d77e5e 100644 --- a/src/utils/dataclass.py +++ b/src/utils/dataclass.py @@ -1,7 +1,7 @@ import functools from dataclasses import dataclass, fields, is_dataclass from types import GenericAlias -from typing import Callable, Self, Sequence, TypeVar +from typing import Callable, Self, Sequence from src.utils.abi import named_tuple_to_dataclass @@ -37,9 +37,6 @@ def __get_dataclass_factory(field_type): return field_type -T = TypeVar('T') - - @dataclass class FromResponse: """ @@ -52,7 +49,7 @@ def from_response(cls, **kwargs) -> Self: return cls(**{k: v for k, v in kwargs.items() if k in class_field_names}) -def list_of_dataclasses( +def list_of_dataclasses[T]( _dataclass_factory: Callable[..., T] ) -> Callable[[Callable[..., Sequence]], Callable[..., list[T]]]: """Decorator to transform list of dicts from func response to list of dataclasses""" @@ -61,6 +58,12 @@ def decorator(func: Callable[..., Sequence]) -> Callable[..., list[T]]: def wrapper_decorator(*args, **kwargs): list_of_elements = func(*args, **kwargs) + if not isinstance(list_of_elements, list) and not isinstance(list_of_elements, tuple): + raise DecodeToDataclassException(f'Type {type(list_of_elements)} is not supported.') + + if not list_of_elements: + return list_of_elements + if isinstance(list_of_elements[0], dict): return list(map(lambda x: _dataclass_factory(**x), list_of_elements)) diff --git a/src/utils/events.py b/src/utils/events.py index a881a39b4..ce9c45523 100644 --- a/src/utils/events.py +++ b/src/utils/events.py @@ -1,6 +1,14 @@ +import logging +from typing import Iterable +from eth_typing import BlockNumber from web3.contract.contract import ContractEvent +from web3.types import EventData +from src.providers.execution.exceptions import InconsistentEvents -from src.typings import ReferenceBlockStamp +from src.types import ReferenceBlockStamp +from src import variables + +logger = logging.getLogger(__name__) def get_events_in_past( @@ -11,8 +19,8 @@ def get_events_in_past( timestamp_field_name: str = 'timestamp', ): """ - This is protection against missed slots when between 10 and 11 block number could be 5 missed slots. - Events should contain Timestamp field. + This is protection against missed slots when between 10 and 11 block number could be 5 missed slots. + Events should contain Timestamp field. """ # [ ] - slot # [x] - slot with existed block @@ -46,6 +54,32 @@ def get_events_in_past( from_block = max(0, to_blockstamp.block_number - for_slots_without_missed_blocks) from_timestamp = to_blockstamp.block_timestamp - for_slots_without_missed_blocks * seconds_per_slot - events = contract_event.get_logs(fromBlock=from_block, toBlock=to_blockstamp.block_number) + events = get_events_in_range( + contract_event, + l_block=BlockNumber(from_block), + r_block=BlockNumber(to_blockstamp.block_number), + ) return [event for event in events if event['args'][timestamp_field_name] > from_timestamp] + + +def get_events_in_range(event: ContractEvent, l_block: BlockNumber, r_block: BlockNumber) -> Iterable[EventData]: + """Fetch all the events in the given blocks range (closed interval)""" + + if l_block > r_block: + raise ValueError(f"{l_block=} > {r_block=}") + + while True: + to_block = min(r_block, BlockNumber(l_block + variables.EVENTS_SEARCH_STEP)) + + logger.info({"msg": f"Fetching {event.event_name} events in range [{l_block};{to_block}]"}) + + for e in event.get_logs(fromBlock=l_block, toBlock=to_block): + if not l_block <= e["blockNumber"] <= to_block: + raise InconsistentEvents + yield e + + if to_block == r_block: + break + + l_block = BlockNumber(to_block + 1) diff --git a/src/utils/range.py b/src/utils/range.py new file mode 100644 index 000000000..3a4cce5c8 --- /dev/null +++ b/src/utils/range.py @@ -0,0 +1,10 @@ +from typing import Iterable, TypeVar, cast + +T = TypeVar("T", bound=int) + + +def sequence(start: T, stop: T) -> Iterable[T]: + """Returns inclusive range object [start;stop]""" + if start > stop: + raise ValueError(f"{start=} > {stop=}") + return cast(Iterable, range(start, stop + 1)) diff --git a/src/utils/slot.py b/src/utils/slot.py index 620e21a9b..d49b09699 100644 --- a/src/utils/slot.py +++ b/src/utils/slot.py @@ -1,10 +1,11 @@ import logging from http import HTTPStatus +from typing import Literal from src.providers.consensus.client import ConsensusClient -from src.providers.consensus.typings import BlockHeaderFullResponse, BlockDetailsResponse +from src.providers.consensus.types import BlockHeaderFullResponse, BlockDetailsResponse from src.providers.http_provider import NotOkResponse -from src.typings import SlotNumber, EpochNumber, ReferenceBlockStamp +from src.types import SlotNumber, EpochNumber, ReferenceBlockStamp from src.utils.blockstamp import build_reference_blockstamp, build_blockstamp logger = logging.getLogger(__name__) @@ -26,9 +27,10 @@ def get_first_non_missed_slot( cc: ConsensusClient, slot: SlotNumber, last_finalized_slot_number: SlotNumber, + direction: Literal['back'] | Literal['forward'] = 'back' ) -> BlockDetailsResponse: """ - Get past closest non-missed slot and returns its details. + Get past/next closest non-missed slot and returns its details. Raise NoSlotsAvailable if all slots are missed in range [slot, last_finalized_slot_number] and we have nowhere to take parent root. @@ -55,7 +57,8 @@ def get_first_non_missed_slot( # 3rd tick - 21 slot is missed. Check next slot. # 4th tick - 22 slot is missed. Check next slot. # 5th tick - 23 slot exists! - # Get `parent_root` of 23 slot and get its parent slot by this root + # If we seek for the next non-missed slot, we're finished. Otherwise, + # get `parent_root` of 23 slot and get its parent slot by this root # In our case it is 18 slot because it's first non-missed slot before 23 slot. # # So, in this strategy we always get parent slot of existed slot and can get the nearest slot for `ref_slot` @@ -68,41 +71,43 @@ def get_first_non_missed_slot( logger.info({'msg': f'Get Blockstamp for ref slot: {slot}.'}) - ref_slot_is_missed = False - existed_header = None + ref_slot_is_missing = False + existing_header = None for i in range(slot, last_finalized_slot_number + 1): try: - existed_header = cc.get_block_header(SlotNumber(i)) + existing_header = cc.get_block_header(SlotNumber(i)) except NotOkResponse as error: if error.status != HTTPStatus.NOT_FOUND: # Not expected status - raise exception raise error - ref_slot_is_missed = True + ref_slot_is_missing = True logger.warning({'msg': f'Missed slot: {i}. Check next slot.', 'error': str(error.__dict__)}) else: - _check_block_header(existed_header) break - if not existed_header: + if not existing_header: raise NoSlotsAvailable('No slots available for current report. Check your CL node.') - if ref_slot_is_missed: - # Ref slot is missed, and we have next non-missed slot. - # We should get parent root of this non-missed slot - non_missed_header_parent_root = existed_header.data.header.message.parent_root + if ref_slot_is_missing: + # Ref slot is missing. We need to check the parent root found non-missing slot + non_missed_header_parent_root = existing_header.data.header.message.parent_root + parent_header = cc.get_block_header(non_missed_header_parent_root) - existed_header = cc.get_block_header(non_missed_header_parent_root) - _check_block_header(existed_header) - - if int(existed_header.data.header.message.slot) >= slot: + if int(parent_header.data.header.message.slot) >= slot: raise InconsistentData( - "Parent root next to the ref slot's existing header doesn't match the expected slot. " - 'Probably problem with the consensus node.' + "Parent root next to the ref slot's existing header doesn't match the expected slot.\n" + 'Probably, a problem with the consensus node.' ) - slot_details = cc.get_block_details(existed_header.data.root) + if direction == 'back': + _check_block_header(existing_header) + existing_header = parent_header + + _check_block_header(existing_header) + slot_details = cc.get_block_details(existing_header.data.root) + logger.info({'msg': f'Resolved to slot: {slot_details.message.slot}'}) return slot_details diff --git a/src/utils/validator_state.py b/src/utils/validator_state.py index c34bb0c9b..56449f290 100644 --- a/src/utils/validator_state.py +++ b/src/utils/validator_state.py @@ -6,9 +6,12 @@ SHARD_COMMITTEE_PERIOD, FAR_FUTURE_EPOCH, EFFECTIVE_BALANCE_INCREMENT, + MAX_SEED_LOOKAHEAD, + MIN_PER_EPOCH_CHURN_LIMIT, + CHURN_LIMIT_QUOTIENT, ) -from src.providers.consensus.typings import Validator -from src.typings import EpochNumber, Gwei +from src.providers.consensus.types import Validator +from src.types import EpochNumber, Gwei def is_active_validator(validator: Validator, epoch: EpochNumber) -> bool: @@ -98,3 +101,16 @@ def calculate_active_effective_balance_sum(validators: Sequence[Validator], ref_ effective_balance_sum += int(validator.validator.effective_balance) return Gwei(effective_balance_sum) + + +def compute_activation_exit_epoch(ref_epoch: EpochNumber): + """ + Return the epoch during which validator activations and exits initiated in ``epoch`` take effect. + + Spec: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#compute_activation_exit_epoch + """ + return ref_epoch + 1 + MAX_SEED_LOOKAHEAD + + +def compute_exit_churn_limit(active_validators_count: int): + return max(MIN_PER_EPOCH_CHURN_LIMIT, active_validators_count // CHURN_LIMIT_QUOTIENT) diff --git a/src/utils/web3converter.py b/src/utils/web3converter.py index 176e5fa4e..5126fe4ac 100644 --- a/src/utils/web3converter.py +++ b/src/utils/web3converter.py @@ -1,5 +1,5 @@ -from src.typings import SlotNumber, EpochNumber, FrameNumber -from src.modules.submodules.typings import ChainConfig, FrameConfig +from src.types import SlotNumber, EpochNumber, FrameNumber +from src.modules.submodules.types import ChainConfig, FrameConfig class Web3Converter: @@ -17,9 +17,16 @@ def __init__(self, chain_config: ChainConfig, frame_config: FrameConfig): self.chain_config = chain_config self.frame_config = frame_config + @property + def slots_per_frame(self) -> int: + return self.frame_config.epochs_per_frame * self.chain_config.slots_per_epoch + def get_epoch_first_slot(self, epoch: EpochNumber) -> SlotNumber: return SlotNumber(epoch * self.chain_config.slots_per_epoch) + def get_epoch_last_slot(self, epoch: EpochNumber) -> SlotNumber: + return SlotNumber((epoch + 1) * self.chain_config.slots_per_epoch - 1) + def get_frame_last_slot(self, frame: FrameNumber) -> SlotNumber: return SlotNumber(self.get_frame_first_slot(FrameNumber(frame + 1)) - 1) diff --git a/src/variables.py b/src/variables.py index 4601f9741..62dbfb1f3 100644 --- a/src/variables.py +++ b/src/variables.py @@ -1,17 +1,21 @@ import os +from typing import Final from eth_account import Account # - Providers- -EXECUTION_CLIENT_URI = os.getenv('EXECUTION_CLIENT_URI', '').split(',') -CONSENSUS_CLIENT_URI = os.getenv('CONSENSUS_CLIENT_URI', '').split(',') -KEYS_API_URI = os.getenv('KEYS_API_URI', '').split(',') +EXECUTION_CLIENT_URI: Final = os.getenv('EXECUTION_CLIENT_URI', '').split(',') +CONSENSUS_CLIENT_URI: Final = os.getenv('CONSENSUS_CLIENT_URI', '').split(',') +KEYS_API_URI: Final = os.getenv('KEYS_API_URI', '').split(',') +GW3_ACCESS_KEY: Final = os.getenv('GW3_ACCESS_KEY') +GW3_SECRET_KEY: Final = os.getenv('GW3_SECRET_KEY') +PINATA_JWT: Final = os.getenv('PINATA_JWT') # - Account - ACCOUNT = None MEMBER_PRIV_KEY = os.getenv('MEMBER_PRIV_KEY') -MEMBER_PRIV_KEY_FILE = os.getenv('MEMBER_PRIV_KEY_FILE') +MEMBER_PRIV_KEY_FILE: Final = os.getenv('MEMBER_PRIV_KEY_FILE') if MEMBER_PRIV_KEY_FILE: if not os.path.exists(MEMBER_PRIV_KEY_FILE): raise ValueError(f'File {MEMBER_PRIV_KEY_FILE} does not exist. ' @@ -24,20 +28,26 @@ ACCOUNT = Account.from_key(MEMBER_PRIV_KEY) # False-positive. pylint: disable=no-value-for-parameter # - App specific - -LIDO_LOCATOR_ADDRESS = os.getenv('LIDO_LOCATOR_ADDRESS') -FINALIZATION_BATCH_MAX_REQUEST_COUNT = int(os.getenv('FINALIZATION_BATCH_MAX_REQUEST_COUNT', 1000)) +LIDO_LOCATOR_ADDRESS: Final = os.getenv('LIDO_LOCATOR_ADDRESS') +CSM_MODULE_ADDRESS: Final = os.getenv('CSM_MODULE_ADDRESS') +FINALIZATION_BATCH_MAX_REQUEST_COUNT: Final = int(os.getenv('FINALIZATION_BATCH_MAX_REQUEST_COUNT', 1000)) +CSM_ORACLE_MAX_CONCURRENCY: Final = int(os.getenv('CSM_ORACLE_MAX_CONCURRENCY', 2)) or None # We add some gas to the transaction to be sure that we have enough gas to execute corner cases # eg when we tried to submit a few reports in a single block # In this case the second report will force report finalization and will consume more gas -TX_GAS_ADDITION = int(os.getenv('TX_GAS_ADDITION', 100_000)) +TX_GAS_ADDITION: Final = int(os.getenv('TX_GAS_ADDITION', 100_000)) + +# Maximum length of a range for eth_getLogs method calls. +EVENTS_SEARCH_STEP: Final = int(os.getenv('EVENTS_SEARCH_STEP', 10_000)) +assert EVENTS_SEARCH_STEP, "EVENTS_SEARCH_STEP must be more than 0" # Transactions fee calculation variables -MIN_PRIORITY_FEE = int(os.getenv('MIN_PRIORITY_FEE', 50_000_000)) -MAX_PRIORITY_FEE = int(os.getenv('MIN_PRIORITY_FEE', 100_000_000_000)) -PRIORITY_FEE_PERCENTILE = int(os.getenv('PRIORITY_FEE_PERCENTILE', 3)) +MIN_PRIORITY_FEE: Final = int(os.getenv('MIN_PRIORITY_FEE', 50_000_000)) +MAX_PRIORITY_FEE: Final = int(os.getenv('MIN_PRIORITY_FEE', 100_000_000_000)) +PRIORITY_FEE_PERCENTILE: Final = int(os.getenv('PRIORITY_FEE_PERCENTILE', 3)) -DAEMON = os.getenv('DAEMON', 'True').lower() == 'true' +DAEMON: Final = os.getenv('DAEMON', 'True').lower() == 'true' if DAEMON: # Default delay for default Oracle members. Member with submit data role should submit data first. # If contract is reportable each member in order will submit data with difference with this amount of slots @@ -51,27 +61,30 @@ CYCLE_SLEEP_IN_SECONDS = 0 # HTTP variables -HTTP_REQUEST_TIMEOUT_EXECUTION = int(os.getenv('HTTP_REQUEST_TIMEOUT_EXECUTION', 2 * 60)) +HTTP_REQUEST_TIMEOUT_EXECUTION: Final = int(os.getenv('HTTP_REQUEST_TIMEOUT_EXECUTION', 2 * 60)) -HTTP_REQUEST_TIMEOUT_CONSENSUS = int(os.getenv('HTTP_REQUEST_TIMEOUT_CONSENSUS', 5 * 60)) -HTTP_REQUEST_RETRY_COUNT_CONSENSUS = int(os.getenv('HTTP_REQUEST_RETRY_COUNT_CONSENSUS', 5)) -HTTP_REQUEST_SLEEP_BEFORE_RETRY_IN_SECONDS_CONSENSUS = int( +HTTP_REQUEST_TIMEOUT_CONSENSUS: Final = int(os.getenv('HTTP_REQUEST_TIMEOUT_CONSENSUS', 5 * 60)) +HTTP_REQUEST_RETRY_COUNT_CONSENSUS: Final = int(os.getenv('HTTP_REQUEST_RETRY_COUNT_CONSENSUS', 5)) +HTTP_REQUEST_SLEEP_BEFORE_RETRY_IN_SECONDS_CONSENSUS: Final = int( os.getenv('HTTP_REQUEST_SLEEP_BEFORE_RETRY_IN_SECONDS_CONSENSUS', 5) ) -HTTP_REQUEST_TIMEOUT_KEYS_API = int(os.getenv('HTTP_REQUEST_TIMEOUT_KEYS_API', 120)) -HTTP_REQUEST_RETRY_COUNT_KEYS_API = int(os.getenv('HTTP_REQUEST_RETRY_COUNT_KEYS_API', 5)) -HTTP_REQUEST_SLEEP_BEFORE_RETRY_IN_SECONDS_KEYS_API = int( +HTTP_REQUEST_TIMEOUT_KEYS_API: Final = int(os.getenv('HTTP_REQUEST_TIMEOUT_KEYS_API', 120)) +HTTP_REQUEST_RETRY_COUNT_KEYS_API: Final = int(os.getenv('HTTP_REQUEST_RETRY_COUNT_KEYS_API', 5)) +HTTP_REQUEST_SLEEP_BEFORE_RETRY_IN_SECONDS_KEYS_API: Final = int( os.getenv('HTTP_REQUEST_SLEEP_BEFORE_RETRY_IN_SECONDS_KEYS_API', 5) ) +HTTP_REQUEST_TIMEOUT_IPFS: Final = int(os.getenv('HTTP_REQUEST_TIMEOUT_IPFS', 30)) +HTTP_REQUEST_RETRY_COUNT_IPFS: Final = int(os.getenv('HTTP_REQUEST_RETRY_COUNT_IPFS', 3)) + # - Metrics - -PROMETHEUS_PORT = int(os.getenv('PROMETHEUS_PORT', 9000)) -PROMETHEUS_PREFIX = os.getenv("PROMETHEUS_PREFIX", "lido_oracle") +PROMETHEUS_PORT: Final = int(os.getenv('PROMETHEUS_PORT', 9000)) +PROMETHEUS_PREFIX: Final = os.getenv("PROMETHEUS_PREFIX", "lido_oracle") -HEALTHCHECK_SERVER_PORT = int(os.getenv('HEALTHCHECK_SERVER_PORT', 9010)) +HEALTHCHECK_SERVER_PORT: Final = int(os.getenv('HEALTHCHECK_SERVER_PORT', 9010)) -MAX_CYCLE_LIFETIME_IN_SECONDS = int(os.getenv("MAX_CYCLE_LIFETIME_IN_SECONDS", 3000)) +MAX_CYCLE_LIFETIME_IN_SECONDS: Final = int(os.getenv("MAX_CYCLE_LIFETIME_IN_SECONDS", 3000)) def check_all_required_variables(): diff --git a/src/web3py/contract_tweak.py b/src/web3py/contract_tweak.py index d56ed5e1c..48399a255 100644 --- a/src/web3py/contract_tweak.py +++ b/src/web3py/contract_tweak.py @@ -1,5 +1,5 @@ import itertools -from typing import Any, Callable, Optional, Tuple +from typing import Any, Callable, Tuple from eth_abi.exceptions import DecodingError from eth_typing import ChecksumAddress @@ -33,12 +33,12 @@ def call_contract_function( # pylint: disable=keyword-arg-before-vararg normalizers: Tuple[Callable[..., Any], ...], function_identifier: FunctionIdentifier, transaction: TxParams, - block_id: Optional[BlockIdentifier] = None, - contract_abi: Optional[ABI] = None, - fn_abi: Optional[ABIFunction] = None, - state_override: Optional[CallOverride] = None, - ccip_read_enabled: Optional[bool] = None, - decode_tuples: Optional[bool] = False, + block_id: BlockIdentifier | None = None, + contract_abi: ABI | None = None, + fn_abi: ABIFunction | None = None, + state_override: CallOverride | None = None, + ccip_read_enabled: bool | None = None, + decode_tuples: bool | None = False, *args: Any, **kwargs: Any, ) -> Any: @@ -112,10 +112,10 @@ def call_contract_function( # pylint: disable=keyword-arg-before-vararg class ContractFunction(_ContractFunction): def call( self, - transaction: Optional[TxParams] = None, + transaction: TxParams | None = None, block_identifier: BlockIdentifier = "latest", - state_override: Optional[CallOverride] = None, - ccip_read_enabled: Optional[bool] = None, + state_override: CallOverride | None = None, + ccip_read_enabled: bool | None = None, ) -> Any: call_transaction = self._get_call_txparams(transaction) @@ -141,8 +141,8 @@ def __init__( self, abi: ABI, w3: Web3, - address: Optional[ChecksumAddress] = None, - decode_tuples: Optional[bool] = False, + address: ChecksumAddress | None = None, + decode_tuples: bool | None = False, ) -> None: # skip init for class _ContractFunctions super(_ContractFunctions, self).__init__(abi, w3, ContractFunction, address, decode_tuples) diff --git a/src/web3py/extensions/__init__.py b/src/web3py/extensions/__init__.py index 30382e166..806e86131 100644 --- a/src/web3py/extensions/__init__.py +++ b/src/web3py/extensions/__init__.py @@ -4,3 +4,4 @@ from src.web3py.extensions.contracts import LidoContracts from src.web3py.extensions.lido_validators import LidoValidatorsProvider from src.web3py.extensions.fallback import FallbackProviderModule +from src.web3py.extensions.csm import CSM, LazyCSM diff --git a/src/web3py/extensions/contracts.py b/src/web3py/extensions/contracts.py index b386e14bc..931fce5ca 100644 --- a/src/web3py/extensions/contracts.py +++ b/src/web3py/extensions/contracts.py @@ -1,6 +1,6 @@ -import json import logging from time import sleep +from typing import cast from web3 import Web3 from web3.contract import Contract @@ -10,22 +10,34 @@ from src import variables from src.metrics.prometheus.business import FRAME_PREV_REPORT_REF_SLOT -from src.typings import BlockStamp, SlotNumber +from src.providers.execution.contracts.accounting_oracle import AccountingOracleContract +from src.providers.execution.contracts.burner import BurnerContract +from src.providers.execution.contracts.exit_bus_oracle import ExitBusOracleContract +from src.providers.execution.contracts.lido import LidoContract +from src.providers.execution.contracts.lido_locator import LidoLocatorContract +from src.providers.execution.contracts.oracle_daemon_config import OracleDaemonConfigContract +from src.providers.execution.contracts.oracle_report_sanity_checker import OracleReportSanityCheckerContract +from src.providers.execution.contracts.staking_router import StakingRouterContract, StakingRouterContractV2 +from src.providers.execution.contracts.withdrawal_queue_nft import WithdrawalQueueNftContract +from src.types import BlockStamp, SlotNumber from src.utils.cache import global_lru_cache as lru_cache + logger = logging.getLogger() class LidoContracts(Module): - lido_locator: Contract - lido: Contract - accounting_oracle: Contract - staking_router: Contract - validators_exit_bus_oracle: Contract - withdrawal_queue_nft: Contract - oracle_report_sanity_checker: Contract - oracle_daemon_config: Contract - burner: Contract + w3: Web3 + + lido_locator: LidoLocatorContract + lido: LidoContract + accounting_oracle: AccountingOracleContract + staking_router: StakingRouterContract + validators_exit_bus_oracle: ExitBusOracleContract + withdrawal_queue_nft: WithdrawalQueueNftContract + oracle_report_sanity_checker: OracleReportSanityCheckerContract + oracle_daemon_config: OracleDaemonConfigContract + burner: BurnerContract def __init__(self, w3: Web3): super().__init__(w3) @@ -46,82 +58,95 @@ def has_contract_address_changed(self) -> bool: def _check_contracts(self): """This is startup check that checks that contract are deployed and has valid implementation""" + contract: AccountingOracleContract | ExitBusOracleContract = None # type: ignore try: - self.accounting_oracle.functions.getContractVersion().call() - self.validators_exit_bus_oracle.functions.getContractVersion().call() + # TODO: Do we really have to care about all the contracts if we just run one module at a time? + for contract in [self.accounting_oracle, self.validators_exit_bus_oracle]: + contract.get_contract_version() except BadFunctionCallOutput: logger.info({ - 'msg': 'getContractVersion method from accounting_oracle and validators_exit_bus_oracle ' + 'msg': f'getContractVersion method from one of the oracle contracts {contract.address=}' 'doesn\'t return any data. Probably addresses from Lido Locator refer to the wrong ' 'implementation or contracts don\'t exist. Sleep for 1 minute.' }) sleep(60) self._load_contracts() - else: - return def _load_contracts(self): # Contract that stores all lido contract addresses - self.lido_locator = self.w3.eth.contract( - address=variables.LIDO_LOCATOR_ADDRESS, - abi=self.load_abi('LidoLocator'), - decode_tuples=True, - ) - - self.lido = self.w3.eth.contract( - address=self.lido_locator.functions.lido().call(), - abi=self.load_abi('Lido'), + self.lido_locator: LidoLocatorContract = cast(LidoLocatorContract, self.w3.eth.contract( + address=variables.LIDO_LOCATOR_ADDRESS, # type: ignore + ContractFactoryClass=LidoLocatorContract, decode_tuples=True, - ) + )) - self.accounting_oracle = self.w3.eth.contract( - address=self.lido_locator.functions.accountingOracle().call(), - abi=self.load_abi('AccountingOracle'), + self.lido: LidoContract = cast(LidoContract, self.w3.eth.contract( + address=self.lido_locator.lido(), + ContractFactoryClass=LidoContract, decode_tuples=True, - ) + )) - self.staking_router = self.w3.eth.contract( - address=self.lido_locator.functions.stakingRouter().call(), - abi=self.load_abi('StakingRouter'), + self.accounting_oracle: AccountingOracleContract = cast(AccountingOracleContract, self.w3.eth.contract( + address=self.lido_locator.accounting_oracle(), + ContractFactoryClass=AccountingOracleContract, decode_tuples=True, - ) + )) - self.validators_exit_bus_oracle = self.w3.eth.contract( - address=self.lido_locator.functions.validatorsExitBusOracle().call(), - abi=self.load_abi('ValidatorsExitBusOracle'), + self.validators_exit_bus_oracle: ExitBusOracleContract = cast(ExitBusOracleContract, self.w3.eth.contract( + address=self.lido_locator.validator_exit_bus_oracle(), + ContractFactoryClass=ExitBusOracleContract, decode_tuples=True, - ) + )) - self.withdrawal_queue_nft = self.w3.eth.contract( - address=self.lido_locator.functions.withdrawalQueue().call(), - abi=self.load_abi('WithdrawalQueueERC721'), + self.withdrawal_queue_nft: WithdrawalQueueNftContract = cast(WithdrawalQueueNftContract, self.w3.eth.contract( + address=self.lido_locator.withdrawal_queue(), + ContractFactoryClass=WithdrawalQueueNftContract, decode_tuples=True, - ) + )) - self.oracle_report_sanity_checker = self.w3.eth.contract( - address=self.lido_locator.functions.oracleReportSanityChecker().call(), - abi=self.load_abi('OracleReportSanityChecker'), + self.oracle_report_sanity_checker: OracleReportSanityCheckerContract = cast(OracleReportSanityCheckerContract, self.w3.eth.contract( + address=self.lido_locator.oracle_report_sanity_checker(), + ContractFactoryClass=OracleReportSanityCheckerContract, decode_tuples=True, - ) + )) - self.oracle_daemon_config = self.w3.eth.contract( - address=self.lido_locator.functions.oracleDaemonConfig().call(), - abi=self.load_abi('OracleDaemonConfig'), + self.oracle_daemon_config: OracleDaemonConfigContract = cast(OracleDaemonConfigContract, self.w3.eth.contract( + address=self.lido_locator.oracle_daemon_config(), + ContractFactoryClass=OracleDaemonConfigContract, decode_tuples=True, - ) + )) - self.burner = self.w3.eth.contract( - address=self.lido_locator.functions.burner().call(), - abi=self.load_abi('Burner'), + self.burner: BurnerContract = cast(BurnerContract, self.w3.eth.contract( + address=self.lido_locator.burner(), + ContractFactoryClass=BurnerContract, decode_tuples=True, - ) + )) + self._load_staking_router(self.lido_locator) self._check_contracts() - @staticmethod - def load_abi(abi_name: str, abi_path: str = './assets/'): - with open(f'{abi_path}{abi_name}.json') as f: - return json.load(f) + def _load_staking_router(self, lido_locator: LidoLocatorContract): + staking_router_address = lido_locator.staking_router() + + self.staking_router = cast( + StakingRouterContractV2, + self.w3.eth.contract( + address=staking_router_address, + ContractFactoryClass=StakingRouterContractV2, + decode_tuples=True, + ), + ) + + if self.staking_router.get_contract_version() == 1: + logger.debug({'msg': 'Use staking router V1.'}) + self.staking_router = cast( + StakingRouterContract, + self.w3.eth.contract( + address=staking_router_address, + ContractFactoryClass=StakingRouterContract, + decode_tuples=True, + ), + ) # --- Contract methods --- @lru_cache(maxsize=1) @@ -130,32 +155,25 @@ def get_withdrawal_balance(self, blockstamp: BlockStamp) -> Wei: def get_withdrawal_balance_no_cache(self, blockstamp: BlockStamp) -> Wei: return Wei(self.w3.eth.get_balance( - self.lido_locator.functions.withdrawalVault().call( - block_identifier=blockstamp.block_hash - ), + self.lido_locator.withdrawal_vault(blockstamp.block_hash), block_identifier=blockstamp.block_hash, )) @lru_cache(maxsize=1) def get_el_vault_balance(self, blockstamp: BlockStamp) -> Wei: return Wei(self.w3.eth.get_balance( - self.lido_locator.functions.elRewardsVault().call( - block_identifier=blockstamp.block_hash - ), + self.lido_locator.el_rewards_vault(blockstamp.block_hash), block_identifier=blockstamp.block_hash, )) @lru_cache(maxsize=1) def get_accounting_last_processing_ref_slot(self, blockstamp: BlockStamp) -> SlotNumber: - result = self.accounting_oracle.functions.getLastProcessingRefSlot().call(block_identifier=blockstamp.block_hash) - logger.info({'msg': f'Accounting last processing ref slot {result}'}) - FRAME_PREV_REPORT_REF_SLOT.set(result) + result = self.accounting_oracle.get_last_processing_ref_slot(blockstamp.block_hash) + FRAME_PREV_REPORT_REF_SLOT.labels('accounting').set(result) return result + @lru_cache(maxsize=1) def get_ejector_last_processing_ref_slot(self, blockstamp: BlockStamp) -> SlotNumber: - result = self.validators_exit_bus_oracle.functions.getLastProcessingRefSlot().call( - block_identifier=blockstamp.block_hash - ) - logger.info({'msg': f'Ejector last processing ref slot {result}'}) - FRAME_PREV_REPORT_REF_SLOT.set(result) + result = self.validators_exit_bus_oracle.get_last_processing_ref_slot(blockstamp.block_hash) + FRAME_PREV_REPORT_REF_SLOT.labels('ejector').set(result) return result diff --git a/src/web3py/extensions/csm.py b/src/web3py/extensions/csm.py new file mode 100644 index 000000000..16a266ddd --- /dev/null +++ b/src/web3py/extensions/csm.py @@ -0,0 +1,141 @@ +import logging +from functools import partial +from itertools import groupby +from time import sleep +from typing import Callable, Iterable, cast + +from eth_typing import BlockNumber +from hexbytes import HexBytes +from lazy_object_proxy import Proxy +from web3 import Web3 +from web3.contract.contract import ContractEvent +from web3.exceptions import Web3Exception +from web3.module import Module +from web3.types import BlockIdentifier, EventData + +from src import variables +from src.metrics.prometheus.business import FRAME_PREV_REPORT_REF_SLOT +from src.providers.execution.contracts.cs_accounting import CSAccountingContract +from src.providers.execution.contracts.cs_fee_distributor import CSFeeDistributorContract +from src.providers.execution.contracts.cs_fee_oracle import CSFeeOracleContract +from src.providers.execution.contracts.cs_module import CSModuleContract +from src.providers.ipfs import CIDv0, CIDv1, is_cid_v0 +from src.types import BlockStamp, SlotNumber +from src.utils.events import get_events_in_range +from src.web3py.extensions.lido_validators import NodeOperatorId + +logger = logging.getLogger(__name__) + + +class CSM(Module): + w3: Web3 + + oracle: CSFeeOracleContract + fee_distributor: CSFeeDistributorContract + module: CSModuleContract + + def __init__(self, w3: Web3) -> None: + super().__init__(w3) + self._load_contracts() + + def get_csm_last_processing_ref_slot(self, blockstamp: BlockStamp) -> SlotNumber: + result = self.oracle.get_last_processing_ref_slot(blockstamp.block_hash) + FRAME_PREV_REPORT_REF_SLOT.labels("csm_oracle").set(result) + return result + + def get_csm_tree_root(self, blockstamp: BlockStamp) -> HexBytes: + return self.fee_distributor.tree_root(blockstamp.block_hash) + + def get_csm_tree_cid(self, blockstamp: BlockStamp) -> CIDv0 | CIDv1: + result = self.fee_distributor.tree_cid(blockstamp.block_hash) + return CIDv0(result) if is_cid_v0(result) else CIDv1(result) + + def get_csm_stuck_node_operators( + self, l_block: BlockIdentifier, r_block: BlockIdentifier + ) -> Iterable[NodeOperatorId]: + """Returns node operators assumed to be stuck for the given frame (defined by the blocks identifiers)""" + + stuck: set[NodeOperatorId] = set() + stuck.update(self.module.get_stuck_operators_ids(l_block)) + stuck.update( + self.get_operators_with_stucks_in_range( + l_block, + r_block, + ) + ) + + return stuck + + def get_operators_with_stucks_in_range( + self, + l_block: BlockIdentifier, + r_block: BlockIdentifier, + ) -> Iterable[NodeOperatorId]: + """Returns node operators assumed to be stuck for the given frame (defined by the block identifiers)""" + + l_block_number = self.w3.eth.get_block(l_block).get("number", BlockNumber(0)) + r_block_number = self.w3.eth.get_block(r_block).get("number", BlockNumber(0)) + + by_no_id: Callable[[EventData], int] = lambda e: e["args"]["nodeOperatorId"] + + events = sorted( + get_events_in_range( + cast(ContractEvent, self.module.events.StuckSigningKeysCountChanged), + l_block_number, + r_block_number, + ), + key=by_no_id, + ) + + for no_id, group in groupby(events, key=by_no_id): + if any(e["args"]["stuckKeysCount"] > 0 for e in group): + yield NodeOperatorId(no_id) + + def _load_contracts(self) -> None: + try: + self.module = cast( + CSModuleContract, + self.w3.eth.contract( + address=variables.CSM_MODULE_ADDRESS, # type: ignore + ContractFactoryClass=CSModuleContract, + decode_tuples=True, + ), + ) + + accounting = cast( + CSAccountingContract, + self.w3.eth.contract( + address=self.module.accounting(), + ContractFactoryClass=CSAccountingContract, + decode_tuples=True, + ), + ) + + self.fee_distributor = cast( + CSFeeDistributorContract, + self.w3.eth.contract( + address=accounting.fee_distributor(), + ContractFactoryClass=CSFeeDistributorContract, + decode_tuples=True, + ), + ) + + self.oracle = cast( + CSFeeOracleContract, + self.w3.eth.contract( + address=self.fee_distributor.oracle(), + ContractFactoryClass=CSFeeOracleContract, + decode_tuples=True, + ), + ) + except Web3Exception as ex: + logger.error({"msg": "Some of the contracts aren't healthy", "error": str(ex)}) + sleep(60) + self._load_contracts() + + +class LazyCSM(CSM): + """A wrapper around CSM module to achieve lazy-loading behaviour""" + + def __new__(cls, w3: Web3): + return Proxy(partial(CSM, w3)) # type: ignore diff --git a/src/web3py/extensions/lido_validators.py b/src/web3py/extensions/lido_validators.py index 24140e5a5..544ce6b0a 100644 --- a/src/web3py/extensions/lido_validators.py +++ b/src/web3py/extensions/lido_validators.py @@ -1,14 +1,15 @@ import logging from dataclasses import asdict, dataclass -from typing import TYPE_CHECKING, NewType, Tuple +from enum import Enum +from typing import TYPE_CHECKING from eth_typing import ChecksumAddress from web3.module import Module -from src.providers.consensus.typings import Validator -from src.providers.keys.typings import LidoKey -from src.typings import BlockStamp -from src.utils.dataclass import Nested, list_of_dataclasses +from src.providers.consensus.types import Validator +from src.providers.keys.types import LidoKey +from src.types import BlockStamp, StakingModuleId, NodeOperatorId, NodeOperatorGlobalIndex, StakingModuleAddress +from src.utils.dataclass import Nested from src.utils.cache import global_lru_cache as lru_cache @@ -16,12 +17,13 @@ if TYPE_CHECKING: - from src.web3py.typings import Web3 # pragma: no cover + from src.web3py.types import Web3 # pragma: no cover -StakingModuleId = NewType('StakingModuleId', int) -NodeOperatorId = NewType('NodeOperatorId', int) -NodeOperatorGlobalIndex = Tuple[StakingModuleId, NodeOperatorId] +class NodeOperatorLimitMode(Enum): + DISABLED = 0 + SOFT = 1 + FORCE = 2 @dataclass @@ -35,7 +37,7 @@ class StakingModule: # part of the fee taken from staking rewards that goes to the treasury treasury_fee: int # target percent of total validators in protocol, in BP - target_share: int + stake_share_limit: int # staking module status if staking module can not accept # the deposits or can participate in further reward distribution status: int @@ -47,13 +49,36 @@ class StakingModule: last_deposit_block: int # number of exited validators exited_validators_count: int + # --------------------- + # Available after SR2 + # --------------------- + # module's share threshold, upon crossing which, exits of validators from the module will be prioritized, in BP + priority_exit_share_threshold: int | None = None + # the maximum number of validators that can be deposited in a single block + max_deposits_per_block: int | None = None + # the minimum distance between deposits in blocks + min_deposit_block_distance: int | None = None + + @classmethod + def from_response(cls, **staking_module): + """ + To support both versions of StakingRouter, we map values by order instead of keys. + + Breaking changes are + target_share -> stake_share_limit + """ + # `target_share` renamed to `stake_share_limit` + return cls(*staking_module.values()) # pylint: disable=no-value-for-parameter + + def __hash__(self): + return hash(self.id) @dataclass class NodeOperator(Nested): id: NodeOperatorId is_active: bool - is_target_limit_active: bool + is_target_limit_active: NodeOperatorLimitMode target_validators_count: int stuck_validators_count: int refunded_validators_count: int @@ -76,6 +101,14 @@ def from_response(cls, data, staking_module): depositable_validators_count, ) = data + # Staking router v1 contract returns bool value in target limit mode + # Staking router v1.5 introduce new limit mode (force) and updates is_target_limit_active to uint type + # + # False == 0 == No priority ejections + # True == 1 == Soft priority ejections + # 2 == Force priority ejections + is_target_limit_active = NodeOperatorLimitMode(is_target_limit_active) + return cls( _id, is_active, @@ -172,26 +205,51 @@ def get_lido_validators_by_node_operators(self, blockstamp: BlockStamp) -> Valid return no_validators @lru_cache(maxsize=1) - def get_lido_node_operators(self, blockstamp: BlockStamp) -> list[NodeOperator]: - result = [] + def get_module_validators_by_node_operators(self, module_address: StakingModuleAddress, blockstamp: BlockStamp) -> ValidatorsByNodeOperator: + """Get module validators by querying the KeysAPI for the module keys""" + kapi = self.w3.kac.get_module_operators_keys(module_address, blockstamp) + if (kapi_module_address := kapi['module']['stakingModuleAddress']) != module_address: + raise ValueError(f"Module address mismatch: {kapi_module_address=} != {module_address=}") + operators = kapi['operators'] + keys = {k['key']: k for k in kapi['keys']} + validators = self.w3.cc.get_validators(blockstamp) + + module_id = StakingModuleId(int(kapi['module']['id'])) + + # Make sure even empty NO will be presented in dict + no_validators: ValidatorsByNodeOperator = { + (module_id, NodeOperatorId(int(operator['index']))): [] for operator in operators + } + + for validator in validators: + lido_key = keys.get(validator.validator.pubkey) + if not lido_key: + continue + global_id = (module_id, lido_key['operatorIndex']) + no_validators[global_id].append( + LidoValidator( + lido_id=LidoKey.from_response(**lido_key), + **asdict(validator), + ) + ) - for module in self.get_staking_modules(blockstamp): - operators = self.w3.lido_contracts.staking_router.functions.getAllNodeOperatorDigests( - module.id - ).call(block_identifier=blockstamp.block_hash) + return no_validators - for operator in operators: - result.append(NodeOperator.from_response(operator, module)) + @lru_cache(maxsize=1) + def get_lido_node_operators_by_modules(self, blockstamp: BlockStamp) -> dict[StakingModuleId, list[NodeOperator]]: + result = {} + + modules = self.w3.lido_contracts.staking_router.get_staking_modules(blockstamp.block_hash) + for module in modules: + result[module.id] = self.w3.lido_contracts.staking_router.get_all_node_operator_digests(module, blockstamp.block_hash) return result @lru_cache(maxsize=1) - @list_of_dataclasses(StakingModule) - def get_staking_modules(self, blockstamp: BlockStamp) -> list[StakingModule]: - modules = self.w3.lido_contracts.staking_router.functions.getStakingModules().call( - block_identifier=blockstamp.block_hash, - ) + def get_lido_node_operators(self, blockstamp: BlockStamp) -> list[NodeOperator]: + result = [] - logger.info({'msg': 'Fetch staking modules.', 'value': modules}) + for nos in self.get_lido_node_operators_by_modules(blockstamp).values(): + result.extend(nos) - return modules + return result diff --git a/src/web3py/extensions/tx_utils.py b/src/web3py/extensions/tx_utils.py index 22e290216..4b3b06d6f 100644 --- a/src/web3py/extensions/tx_utils.py +++ b/src/web3py/extensions/tx_utils.py @@ -1,9 +1,10 @@ import logging -from typing import Optional from eth_account.signers.local import LocalAccount +from web3 import Web3 +from hexbytes import HexBytes from web3.contract.contract import ContractFunction -from web3.exceptions import ContractLogicError +from web3.exceptions import ContractLogicError, TimeExhausted from web3.module import Module from web3.types import TxReceipt, Wei, TxParams, BlockData @@ -11,11 +12,14 @@ from src.metrics.prometheus.basic import TRANSACTIONS_COUNT, Status from src.utils.input import prompt + logger = logging.getLogger(__name__) class TransactionUtils(Module): - def check_and_send_transaction(self, transaction, account: Optional[LocalAccount] = None) -> Optional[TxReceipt]: + w3: Web3 + + def check_and_send_transaction(self, transaction, account: LocalAccount | None = None) -> TxReceipt | None: if not account: logger.info({'msg': 'No account provided to submit extra data. Dry mode'}) return None @@ -87,7 +91,7 @@ def _get_transaction_params(self, transaction: ContractFunction, account: LocalA return params @staticmethod - def _estimate_gas(transaction: ContractFunction, account: LocalAccount) -> Optional[int]: + def _estimate_gas(transaction: ContractFunction, account: LocalAccount) -> int | None: """If transaction throws exception return None""" try: gas = transaction.estimate_gas({'from': account.address}) @@ -106,18 +110,21 @@ def _estimate_gas(transaction: ContractFunction, account: LocalAccount) -> Optio def _sign_and_send_transaction( self, transaction: ContractFunction, - params: Optional[TxParams], + params: TxParams | None, account: LocalAccount, - ) -> Optional[TxReceipt]: + ) -> TxReceipt | None: tx = transaction.build_transaction(params) signed_tx = self.w3.eth.account.sign_transaction(tx, account.key) tx_hash = self.w3.eth.send_raw_transaction(signed_tx.rawTransaction) logger.info({"msg": "Transaction sent.", "value": tx_hash.hex()}) - tx_receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash) + return self._handle_sent_transaction(tx_hash) - if not tx_receipt: + def _handle_sent_transaction(self, transaction_hash: HexBytes) -> TxReceipt | None: + try: + tx_receipt = self.w3.eth.wait_for_transaction_receipt(transaction_hash) + except TimeExhausted: TRANSACTIONS_COUNT.labels(status=Status.FAILURE).inc() logger.warning({"msg": "Transaction was not found in blockchain after 120 seconds."}) return None diff --git a/src/web3py/typings.py b/src/web3py/types.py similarity index 81% rename from src/web3py/typings.py rename to src/web3py/types.py index 3bccee23d..c21e890eb 100644 --- a/src/web3py/typings.py +++ b/src/web3py/types.py @@ -1,12 +1,14 @@ from web3 import Web3 as _Web3 +from src.providers.ipfs import IPFSProvider from src.web3py.extensions import ( LidoContracts, TransactionUtils, ConsensusClientModule, KeysAPIClientModule, LidoValidatorsProvider, + CSM ) @@ -16,3 +18,5 @@ class Web3(_Web3): transaction: TransactionUtils cc: ConsensusClientModule kac: KeysAPIClientModule + csm: CSM + ipfs: IPFSProvider diff --git a/stubs/lazy_object_proxy/__init__.pyi b/stubs/lazy_object_proxy/__init__.pyi new file mode 100644 index 000000000..368ce6e3e --- /dev/null +++ b/stubs/lazy_object_proxy/__init__.pyi @@ -0,0 +1 @@ +from .lazy_object_proxy import Proxy as Proxy diff --git a/stubs/lazy_object_proxy/lazy_object_proxy.pyi b/stubs/lazy_object_proxy/lazy_object_proxy.pyi new file mode 100644 index 000000000..a4e54284c --- /dev/null +++ b/stubs/lazy_object_proxy/lazy_object_proxy.pyi @@ -0,0 +1,8 @@ +from typing import Generic, Type, TypeVar + + +T = TypeVar("T") + + +class Proxy(Generic[T]): + def __init__(self, factory: Type[T]) -> None: ... diff --git a/stubs/timeout_decorator/timeout_decorator.pyi b/stubs/timeout_decorator/timeout_decorator.pyi index b15b8e1df..e9a5f0bfa 100644 --- a/stubs/timeout_decorator/timeout_decorator.pyi +++ b/stubs/timeout_decorator/timeout_decorator.pyi @@ -5,7 +5,7 @@ class TimeoutError(AssertionError): def __init__(self, value: str = ...) -> None: ... def timeout( - seconds: int = ..., + seconds: int | None = ..., use_signals: bool = True, timeout_exception: type[TimeoutError] = TimeoutError, exception_message: str | None = ..., diff --git a/tests/README.md b/tests/README.md index 77f8de09f..5aab20c80 100644 --- a/tests/README.md +++ b/tests/README.md @@ -5,8 +5,8 @@ You can run it by running `pytest tests` in the root directory of the repository Most tests are unit tests and marked with the `@pytest.mark.unit` decorator. They use predefined rpc responses and do not require either consensus or beacon nodes. -Rpc and Http responses are stored in the `tests/responses` directory -and can be overriden using `--update-responses` flag while running tests (make sure that you set rpc node environment variables in this case). +Rpc and Http responses are stored in the `tests/responses` directory and can be overridden using `--update-responses` +flag while running tests (make sure that you set rpc node environment variables in this case). They are useful when you do not need to change response data for testing. In case if you need to test something with using specific responses, you can mock it directly using `add_mock` function from `MockProvider`. diff --git a/tests/conftest.py b/tests/conftest.py index 4e8359422..22d18471b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,25 +1,28 @@ +from dataclasses import dataclass from pathlib import Path +from typing import cast from unittest.mock import Mock import pytest from _pytest.fixtures import FixtureRequest +from eth_typing import ChecksumAddress +from hexbytes import HexBytes from web3.middleware import construct_simple_cache_middleware from web3.types import Timestamp import src.variables +from src.types import BlockNumber, EpochNumber, ReferenceBlockStamp, SlotNumber from src.variables import CONSENSUS_CLIENT_URI, EXECUTION_CLIENT_URI, KEYS_API_URI -from src.typings import BlockStamp, SlotNumber, BlockNumber, EpochNumber, ReferenceBlockStamp -from src.web3py.extensions import LidoContracts, TransactionUtils, LidoValidatorsProvider -from src.web3py.typings import Web3 - from src.web3py.contract_tweak import tweak_w3_contracts +from src.web3py.extensions import LidoContracts, LidoValidatorsProvider, TransactionUtils +from src.web3py.types import Web3 from tests.providers import ( ResponseFromFile, ResponseFromFileConsensusClientModule, ResponseFromFileKeysAPIClientModule, - UpdateResponsesProvider, UpdateResponsesConsensusClientModule, UpdateResponsesKeysAPIClientModule, + UpdateResponsesProvider, ) @@ -107,11 +110,34 @@ def keys_api_client(request, responses_path, web3): web3.attach_modules({"kac": lambda: client}) +@pytest.fixture() +def csm(web3): + mock = Mock() + web3.attach_modules({"csm": lambda: mock}) + return mock + + # ---- Lido contracts ---- @pytest.fixture() def contracts(web3, provider): src.variables.LIDO_LOCATOR_ADDRESS = "0x548C1ED5C83Bdf19e567F4cd7Dd9AC4097088589" LidoContracts._check_contracts = Mock() # pylint: disable=protected-access + + def _load_staking_router(self, lido_locator): + from src.providers.execution.contracts.staking_router import StakingRouterContract # pylint: disable=C0415 + + staking_router_address = lido_locator.staking_router() + self.staking_router = cast( + StakingRouterContract, + self.w3.eth.contract( + address=staking_router_address, + ContractFactoryClass=StakingRouterContract, + decode_tuples=True, + ), + ) + + LidoContracts._load_staking_router = _load_staking_router # pylint: disable=protected-access + with provider.use_mock(Path('common/contracts.json')): # First contracts deployment web3.attach_modules( @@ -141,16 +167,22 @@ def lido_validators(web3, consensus_client, keys_api_client): ) -def get_blockstamp_by_state(w3, state_id) -> BlockStamp: +def get_blockstamp_by_state(w3, state_id) -> ReferenceBlockStamp: root = w3.cc.get_block_root(state_id).root slot_details = w3.cc.get_block_details(root) return ReferenceBlockStamp( slot_number=SlotNumber(int(slot_details.message.slot)), state_root=slot_details.message.state_root, - block_number=BlockNumber(int(slot_details.message.body['execution_payload']['block_number'])), - block_hash=slot_details.message.body['execution_payload']['block_hash'], - block_timestamp=Timestamp(slot_details.message.body['execution_payload']['timestamp']), + block_number=BlockNumber(int(slot_details.message.body.execution_payload.block_number)), + block_hash=slot_details.message.body.execution_payload.block_hash, + block_timestamp=Timestamp(slot_details.message.body.execution_payload.timestamp), ref_slot=SlotNumber(int(slot_details.message.slot)), ref_epoch=EpochNumber(int(int(slot_details.message.slot) / 12)), ) + + +@dataclass +class Account: + address: ChecksumAddress + _private_key: HexBytes diff --git a/tests/factory/blockstamp.py b/tests/factory/blockstamp.py index 12501be09..c37d6b66b 100644 --- a/tests/factory/blockstamp.py +++ b/tests/factory/blockstamp.py @@ -2,7 +2,7 @@ from web3.types import Timestamp from tests.factory.web3_factory import Web3Factory -from src.typings import BlockStamp, StateRoot, SlotNumber, BlockHash, ReferenceBlockStamp, EpochNumber +from src.types import BlockStamp, StateRoot, SlotNumber, BlockHash, ReferenceBlockStamp, EpochNumber class BlockStampFactory(Web3Factory): diff --git a/tests/factory/configs.py b/tests/factory/configs.py index 3b120a387..ea89cf235 100644 --- a/tests/factory/configs.py +++ b/tests/factory/configs.py @@ -1,8 +1,14 @@ from typing import overload -from src.modules.accounting.typings import OracleReportLimits -from src.modules.submodules.typings import ChainConfig, FrameConfig -from src.providers.consensus.typings import BeaconSpecResponse -from src.services.bunker_cases.typings import BunkerConfig +from src.modules.accounting.types import OracleReportLimits +from src.modules.submodules.types import ChainConfig, FrameConfig +from src.providers.consensus.types import ( + BeaconSpecResponse, + SlotAttestationCommittee, + BlockAttestation, + AttestationData, + Checkpoint, +) +from src.services.bunker_cases.types import BunkerConfig from tests.factory.web3_factory import Web3Factory @@ -44,3 +50,25 @@ class BeaconSpecResponseFactory(Web3Factory): SECONDS_PER_SLOT = 12 SLOTS_PER_EPOCH = 32 + SLOTS_PER_HISTORICAL_ROOT = 8192 + + +class SlotAttestationCommitteeFactory(Web3Factory): + __model__ = SlotAttestationCommittee + + slot = 0 + index = 0 + validators = [] + + +class BlockAttestationFactory(Web3Factory): + __model__ = BlockAttestation + + aggregation_bits = "0x" + data = AttestationData( + slot="0", + index="0", + beacon_block_root="0x", + source=Checkpoint("0", "0x"), + target=Checkpoint("0", "0x"), + ) diff --git a/tests/factory/contract_responses.py b/tests/factory/contract_responses.py index 1fa93349e..250be7a2d 100644 --- a/tests/factory/contract_responses.py +++ b/tests/factory/contract_responses.py @@ -1,4 +1,4 @@ -from src.modules.accounting.typings import LidoReportRebase +from src.modules.accounting.types import LidoReportRebase from tests.factory.web3_factory import Web3Factory diff --git a/tests/factory/member_info.py b/tests/factory/member_info.py index be5a67c45..dcdc2a283 100644 --- a/tests/factory/member_info.py +++ b/tests/factory/member_info.py @@ -1,4 +1,4 @@ -from src.modules.submodules.typings import MemberInfo +from src.modules.submodules.types import MemberInfo from tests.factory.web3_factory import Web3Factory diff --git a/tests/factory/no_registry.py b/tests/factory/no_registry.py index 5450539f9..140fdf44b 100644 --- a/tests/factory/no_registry.py +++ b/tests/factory/no_registry.py @@ -4,8 +4,9 @@ from faker import Faker from pydantic_factories import Use -from src.providers.consensus.typings import Validator, ValidatorState -from src.providers.keys.typings import LidoKey +from src.constants import FAR_FUTURE_EPOCH +from src.providers.consensus.types import Validator, ValidatorState +from src.providers.keys.types import LidoKey from tests.factory.web3_factory import Web3Factory from src.web3py.extensions.lido_validators import StakingModule, LidoValidator, NodeOperator @@ -16,6 +17,8 @@ class ValidatorStateFactory(Web3Factory): __model__ = ValidatorState + exit_epoch = FAR_FUTURE_EPOCH + class ValidatorFactory(Web3Factory): __model__ = Validator diff --git a/tests/factory/web3_factory.py b/tests/factory/web3_factory.py index fc02916a1..11a76794a 100644 --- a/tests/factory/web3_factory.py +++ b/tests/factory/web3_factory.py @@ -3,7 +3,7 @@ from dataclasses import is_dataclass from enum import EnumMeta from inspect import isclass -from typing import Any, Optional, Union, cast, NewType +from typing import Any, cast, NewType from eth_typing import HexStr, HexAddress from eth_utils import to_checksum_address @@ -25,9 +25,7 @@ class Web3Factory(ModelFactory[Any]): __model__ = BaseModel @classmethod - def get_field_value( - cls, model_field: "ModelField", field_parameters: Optional[Union[dict[Any, Any], list[Any]]] = None - ) -> Any: + def get_field_value(cls, model_field: "ModelField", field_parameters: dict | list | None = None) -> Any: """Returns a field value on the subclass if existing, otherwise returns a mock value. Args: @@ -100,9 +98,11 @@ def get_web3_provider_map(cls): faker = cls.get_faker() return { + str: faker.pyint, HexAddress: lambda: to_checksum_address(HexBytes(faker.binary(length=20)).hex()), HexStr: lambda: HexBytes(faker.binary(length=20)).hex(), HexBytes: lambda: HexBytes(faker.binary(length=64)), + int | None: lambda: None, } @classmethod diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py new file mode 100644 index 000000000..13ccd13f8 --- /dev/null +++ b/tests/integration/conftest.py @@ -0,0 +1,119 @@ +from typing import cast + +import pytest +from web3 import Web3, HTTPProvider + +from src import variables +from src.providers.execution.contracts.accounting_oracle import AccountingOracleContract +from src.providers.execution.contracts.burner import BurnerContract +from src.providers.execution.contracts.exit_bus_oracle import ExitBusOracleContract +from src.providers.execution.contracts.lido import LidoContract +from src.providers.execution.contracts.lido_locator import LidoLocatorContract +from src.providers.execution.contracts.oracle_daemon_config import OracleDaemonConfigContract +from src.providers.execution.contracts.oracle_report_sanity_checker import OracleReportSanityCheckerContract +from src.providers.execution.contracts.staking_router import StakingRouterContract +from src.providers.execution.contracts.withdrawal_queue_nft import WithdrawalQueueNftContract + + +@pytest.fixture +def web3_provider_integration(request): + # Some tests can be executed only on mainnet, because of not trivial selected params + variables.LIDO_LOCATOR_ADDRESS = '0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb' + + w3 = Web3(HTTPProvider(variables.EXECUTION_CLIENT_URI[0], request_kwargs={'timeout': 3600})) + + assert w3.eth.chain_id == 1 + + return w3 + + +def get_contract(w3, contract_class, address): + return cast( + contract_class, + w3.eth.contract( + address=address, + ContractFactoryClass=contract_class, + decode_tuples=True, + ), + ) + + +@pytest.fixture +def lido_locator_contract(web3_provider_integration) -> LidoLocatorContract: + return get_contract( + web3_provider_integration, + LidoLocatorContract, + variables.LIDO_LOCATOR_ADDRESS, + ) + + +@pytest.fixture +def lido_contract(web3_provider_integration, lido_locator_contract) -> LidoContract: + return get_contract( + web3_provider_integration, + LidoContract, + lido_locator_contract.lido(), + ) + + +@pytest.fixture +def accounting_oracle_contract(web3_provider_integration, lido_locator_contract) -> AccountingOracleContract: + return get_contract( + web3_provider_integration, + AccountingOracleContract, + lido_locator_contract.accounting_oracle(), + ) + + +@pytest.fixture +def staking_router_contract(web3_provider_integration, lido_locator_contract) -> StakingRouterContract: + return get_contract( + web3_provider_integration, + StakingRouterContract, + lido_locator_contract.staking_router(), + ) + + +@pytest.fixture +def validators_exit_bus_oracle_contract(web3_provider_integration, lido_locator_contract) -> ExitBusOracleContract: + return get_contract( + web3_provider_integration, + ExitBusOracleContract, + lido_locator_contract.validator_exit_bus_oracle(), + ) + + +@pytest.fixture +def withdrawal_queue_nft_contract(web3_provider_integration, lido_locator_contract): + return get_contract( + web3_provider_integration, + WithdrawalQueueNftContract, + lido_locator_contract.withdrawal_queue(), + ) + + +@pytest.fixture +def oracle_report_sanity_checker_contract(web3_provider_integration, lido_locator_contract): + return get_contract( + web3_provider_integration, + OracleReportSanityCheckerContract, + lido_locator_contract.oracle_report_sanity_checker(), + ) + + +@pytest.fixture +def oracle_daemon_config_contract(web3_provider_integration, lido_locator_contract): + return get_contract( + web3_provider_integration, + OracleDaemonConfigContract, + lido_locator_contract.oracle_daemon_config(), + ) + + +@pytest.fixture +def burner_contract(web3_provider_integration, lido_locator_contract): + return get_contract( + web3_provider_integration, + BurnerContract, + lido_locator_contract.burner(), + ) diff --git a/tests/integration/contracts/__init__.py b/tests/integration/contracts/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/integration/contracts/contract_utils.py b/tests/integration/contracts/contract_utils.py new file mode 100644 index 000000000..d64c33f99 --- /dev/null +++ b/tests/integration/contracts/contract_utils.py @@ -0,0 +1,37 @@ +import logging +import re +from typing import Any, Callable + +from src.providers.execution.base_interface import ContractInterface + + +HASH_REGREX = re.compile(r'^0x[0-9,A-F]{64}$', flags=re.IGNORECASE) +ADDRESS_REGREX = re.compile('^0x[0-9,A-F]{40}$', flags=re.IGNORECASE) + + +def check_contract( + contract: ContractInterface, + functions_spec: list[tuple[str, tuple | None, Callable[[Any], None]]], + caplog, +): + caplog.set_level(logging.INFO) + + for function in functions_spec: + # get method + method = contract.__getattribute__(function[0]) # pylint: disable=unnecessary-dunder-call + # call method with args + response = method(*function[1]) if function[1] is not None else method() + # check response + function[2](response) + + log_with_call = list(filter(lambda log: 'Call ' in log or 'Build ' in log, caplog.messages)) + + assert len(functions_spec) == len(log_with_call) + + +def check_value_re(regrex, value) -> None: + assert regrex.findall(value) + + +def check_value_type(value, _type) -> None: + assert isinstance(value, _type) diff --git a/tests/integration/contracts/test_accounting_oracle.py b/tests/integration/contracts/test_accounting_oracle.py new file mode 100644 index 000000000..d1a354f53 --- /dev/null +++ b/tests/integration/contracts/test_accounting_oracle.py @@ -0,0 +1,18 @@ +import pytest +from web3.contract.contract import ContractFunction + +from src.modules.accounting.types import AccountingProcessingState +from tests.integration.contracts.contract_utils import check_contract, check_value_type + + +@pytest.mark.integration +def test_accounting_oracle_contract(accounting_oracle_contract, caplog): + check_contract( + accounting_oracle_contract, + [ + ('get_processing_state', None, lambda response: check_value_type(response, AccountingProcessingState)), + ('submit_report_extra_data_empty', None, lambda tx: check_value_type(tx, ContractFunction)), + ('submit_report_extra_data_list', (b'',), lambda tx: check_value_type(tx, ContractFunction)), + ], + caplog, + ) diff --git a/tests/integration/contracts/test_bunker.py b/tests/integration/contracts/test_bunker.py new file mode 100644 index 000000000..b8d4bef94 --- /dev/null +++ b/tests/integration/contracts/test_bunker.py @@ -0,0 +1,15 @@ +import pytest + +from src.modules.accounting.types import SharesRequestedToBurn +from tests.integration.contracts.contract_utils import check_contract, check_value_type + + +@pytest.mark.integration +def test_burner(burner_contract, caplog): + check_contract( + burner_contract, + [ + ('get_shares_requested_to_burn', None, lambda response: check_value_type(response, SharesRequestedToBurn)), + ], + caplog, + ) diff --git a/tests/integration/contracts/test_lido.py b/tests/integration/contracts/test_lido.py new file mode 100644 index 000000000..95333c276 --- /dev/null +++ b/tests/integration/contracts/test_lido.py @@ -0,0 +1,32 @@ +import pytest + +from tests.integration.contracts.contract_utils import check_contract, check_value_type + + +@pytest.mark.integration +def test_lido_contract_call(lido_contract, accounting_oracle_contract, burner_contract, caplog): + check_contract( + lido_contract, + [ + # Periodically fail with insufficient funds error. (-32000) + # ( + # 'handle_oracle_report', + # ( + # 1716724811, # timestamp + # 86400, + # 346727, + # 9290022163214746000000000, + # 898180576095000000000, + # 105274292338382770653, + # 0, + # accounting_oracle_contract.address, + # # Call depends on contract state + # '0xb35dd0cae381072a4856c08cf06013e56998d9152e970d89a1f38e92f133a8ea', + # ), + # lambda response: check_value_type(response, LidoReportRebase), + # ), + ('get_buffered_ether', None, lambda response: check_value_type(response, int)), + ('total_supply', None, lambda response: check_value_type(response, int)), + ], + caplog, + ) diff --git a/tests/integration/contracts/test_lido_locator.py b/tests/integration/contracts/test_lido_locator.py new file mode 100644 index 000000000..ef61a2728 --- /dev/null +++ b/tests/integration/contracts/test_lido_locator.py @@ -0,0 +1,74 @@ +import pytest +from eth_typing import ChecksumAddress + +from tests.integration.contracts.contract_utils import check_contract, check_value_type, check_value_re, ADDRESS_REGREX + + +@pytest.mark.integration +def test_lido_locator_contract(lido_locator_contract, caplog): + check_contract( + lido_locator_contract, + [ + ( + 'lido', + None, + lambda response: check_value_re(ADDRESS_REGREX, response) + and check_value_type(response, ChecksumAddress), + ), + ( + 'accounting_oracle', + None, + lambda response: check_value_re(ADDRESS_REGREX, response) + and check_value_type(response, ChecksumAddress), + ), + ( + 'staking_router', + None, + lambda response: check_value_re(ADDRESS_REGREX, response) + and check_value_type(response, ChecksumAddress), + ), + ( + 'validator_exit_bus_oracle', + None, + lambda response: check_value_re(ADDRESS_REGREX, response) + and check_value_type(response, ChecksumAddress), + ), + ( + 'withdrawal_queue', + None, + lambda response: check_value_re(ADDRESS_REGREX, response) + and check_value_type(response, ChecksumAddress), + ), + ( + 'oracle_report_sanity_checker', + None, + lambda response: check_value_re(ADDRESS_REGREX, response) + and check_value_type(response, ChecksumAddress), + ), + ( + 'oracle_daemon_config', + None, + lambda response: check_value_re(ADDRESS_REGREX, response) + and check_value_type(response, ChecksumAddress), + ), + ( + 'burner', + None, + lambda response: check_value_re(ADDRESS_REGREX, response) + and check_value_type(response, ChecksumAddress), + ), + ( + 'withdrawal_vault', + None, + lambda response: check_value_re(ADDRESS_REGREX, response) + and check_value_type(response, ChecksumAddress), + ), + ( + 'el_rewards_vault', + None, + lambda response: check_value_re(ADDRESS_REGREX, response) + and check_value_type(response, ChecksumAddress), + ), + ], + caplog, + ) diff --git a/tests/integration/contracts/test_oracle_daemon_config.py b/tests/integration/contracts/test_oracle_daemon_config.py new file mode 100644 index 000000000..34487602c --- /dev/null +++ b/tests/integration/contracts/test_oracle_daemon_config.py @@ -0,0 +1,55 @@ +import pytest + +from src.constants import TOTAL_BASIS_POINTS +from tests.integration.contracts.contract_utils import check_contract, check_value_type + + +@pytest.mark.integration +def test_oracle_daemon_config_contract(oracle_daemon_config_contract, caplog): + check_contract( + oracle_daemon_config_contract, + [ + ('normalized_cl_reward_per_epoch', None, lambda response: check_value_type(response, int)), + ( + 'normalized_cl_reward_mistake_rate_bp', + None, + lambda response: check_value_type(response, int) and response < TOTAL_BASIS_POINTS, + ), + ( + 'rebase_check_nearest_epoch_distance', + None, + lambda response: check_value_type(response, int), + ), + ( + 'rebase_check_distant_epoch_distance', + None, + lambda response: check_value_type(response, int), + ), + ( + 'node_operator_network_penetration_threshold_bp', + None, + lambda response: check_value_type(response, int) and response < TOTAL_BASIS_POINTS, + ), + ( + 'prediction_duration_in_slots', + None, + lambda response: check_value_type(response, int), + ), + ( + 'finalization_max_negative_rebase_epoch_shift', + None, + lambda response: check_value_type(response, int), + ), + ( + 'validator_delayed_timeout_in_slots', + None, + lambda response: check_value_type(response, int), + ), + ( + 'validator_delinquent_timeout_in_slots', + None, + lambda response: check_value_type(response, int), + ), + ], + caplog, + ) diff --git a/tests/integration/contracts/test_oracle_report_sanity_checker.py b/tests/integration/contracts/test_oracle_report_sanity_checker.py new file mode 100644 index 000000000..0b69b3fde --- /dev/null +++ b/tests/integration/contracts/test_oracle_report_sanity_checker.py @@ -0,0 +1,15 @@ +import pytest + +from src.modules.accounting.types import OracleReportLimits +from tests.integration.contracts.contract_utils import check_contract, check_value_type + + +@pytest.mark.integration +def test_oracle_report_sanity_checker(oracle_report_sanity_checker_contract, caplog): + check_contract( + oracle_report_sanity_checker_contract, + [ + ('get_oracle_report_limits', None, lambda response: check_value_type(response, OracleReportLimits)), + ], + caplog, + ) diff --git a/tests/integration/contracts/test_staking_router.py b/tests/integration/contracts/test_staking_router.py new file mode 100644 index 000000000..e55f653f9 --- /dev/null +++ b/tests/integration/contracts/test_staking_router.py @@ -0,0 +1,27 @@ +import pytest + +from src.web3py.extensions.lido_validators import StakingModule, NodeOperator +from tests.factory.no_registry import StakingModuleFactory +from tests.integration.contracts.contract_utils import check_contract, check_value_type + + +@pytest.mark.integration +def test_staking_router(staking_router_contract, caplog): + check_contract( + staking_router_contract, + [ + ( + 'get_staking_modules', + None, + lambda response: check_value_type(response, list) + and map(lambda sm: check_value_type(sm, StakingModule), response), + ), + ( + 'get_all_node_operator_digests', + (StakingModuleFactory.build(id=1),), + lambda response: check_value_type(response, list) + and map(lambda sm: check_value_type(sm, NodeOperator), response), + ), + ], + caplog, + ) diff --git a/tests/integration/contracts/test_validator_exit_bus_oracle.py b/tests/integration/contracts/test_validator_exit_bus_oracle.py new file mode 100644 index 000000000..d89bad8e1 --- /dev/null +++ b/tests/integration/contracts/test_validator_exit_bus_oracle.py @@ -0,0 +1,21 @@ +import pytest + +from src.modules.ejector.types import EjectorProcessingState +from tests.integration.contracts.contract_utils import check_contract, check_value_type + + +@pytest.mark.integration +def test_vebo(validators_exit_bus_oracle_contract, caplog): + check_contract( + validators_exit_bus_oracle_contract, + [ + ('is_paused', None, lambda response: check_value_type(response, bool)), + ('get_processing_state', None, lambda response: check_value_type(response, EjectorProcessingState)), + ( + 'get_last_requested_validator_indices', + (1, [1]), + lambda response: check_value_type(response, list) and map(lambda val: check_value_type(val, int)), + ), + ], + caplog, + ) diff --git a/tests/integration/contracts/test_withdrawal_queue_nft_contract.py b/tests/integration/contracts/test_withdrawal_queue_nft_contract.py new file mode 100644 index 000000000..cc30aa53f --- /dev/null +++ b/tests/integration/contracts/test_withdrawal_queue_nft_contract.py @@ -0,0 +1,74 @@ +import pytest + +from src.modules.accounting.types import WithdrawalRequestStatus, BatchState +from tests.integration.contracts.contract_utils import check_contract, check_value_type + + +@pytest.mark.integration +def test_withdrawal_queue(withdrawal_queue_nft_contract, caplog): + check_contract( + withdrawal_queue_nft_contract, + [ + ('unfinalized_steth', None, lambda response: check_value_type(response, int)), + ('bunker_mode_since_timestamp', None, lambda response: check_value_type(response, int)), + ('get_last_finalized_request_id', None, lambda response: check_value_type(response, int)), + ('get_withdrawal_status', (1,), lambda response: check_value_type(response, WithdrawalRequestStatus)), + ('get_last_request_id', None, lambda response: check_value_type(response, int)), + ('is_paused', None, lambda response: check_value_type(response, bool)), + ('max_batches_length', None, lambda response: check_value_type(response, int)), + ( + 'calculate_finalization_batches', + ( + 1167796098828864377325065539, + 1716716759, + 1000, + ( + 7937157558488263113651, + False, + ( + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ), + 0, + ), + "0xb35dd0cae381072a4856c08cf06013e56998d9152e970d89a1f38e92f133a8ea", + ), + lambda response: check_value_type(response, BatchState), + ), + ], + caplog, + ) diff --git a/tests/modules/accounting/bunker/conftest.py b/tests/modules/accounting/bunker/conftest.py index 2d7a3680c..68b01e80e 100644 --- a/tests/modules/accounting/bunker/conftest.py +++ b/tests/modules/accounting/bunker/conftest.py @@ -2,13 +2,13 @@ import pytest -from src.modules.submodules.typings import ChainConfig -from src.providers.consensus.typings import Validator, ValidatorStatus, ValidatorState +from src.modules.submodules.types import ChainConfig +from src.providers.consensus.types import Validator, ValidatorStatus, ValidatorState from src.services.bunker import BunkerService -from src.providers.keys.typings import LidoKey +from src.providers.keys.types import LidoKey from src.services.bunker_cases.abnormal_cl_rebase import AbnormalClRebase -from src.services.bunker_cases.typings import BunkerConfig -from src.typings import BlockNumber, BlockStamp, ReferenceBlockStamp +from src.services.bunker_cases.types import BunkerConfig +from src.types import BlockNumber, BlockStamp, ReferenceBlockStamp def simple_ref_blockstamp(block_number: int) -> ReferenceBlockStamp: @@ -123,18 +123,6 @@ def _get_eth_distributed_events(from_block: BlockNumber, to_block: BlockNumber): abnormal_case._get_eth_distributed_events = Mock(side_effect=_get_eth_distributed_events) -@pytest.fixture -def mock_get_total_supply(bunker): - def _get_total_supply(block: BlockStamp): - supplies = { - 0: 15 * 10**18, - } - - return supplies[block.block_number] - - bunker._get_total_supply = Mock(side_effect=_get_total_supply) - - @pytest.fixture def mock_get_withdrawal_vault_balance(abnormal_case, contracts): def _get_withdrawal_vault_balance(blockstamp: BlockStamp): diff --git a/tests/modules/accounting/bunker/test_bunker.py b/tests/modules/accounting/bunker/test_bunker.py index 4a71538be..a3340d1c2 100644 --- a/tests/modules/accounting/bunker/test_bunker.py +++ b/tests/modules/accounting/bunker/test_bunker.py @@ -3,9 +3,9 @@ import pytest -from src.modules.accounting.typings import LidoReportRebase +from src.modules.accounting.types import LidoReportRebase from src.services.bunker import BunkerService -from src.typings import ReferenceBlockStamp +from src.types import ReferenceBlockStamp from src.web3py.extensions.lido_validators import LidoValidator from tests.factory.blockstamp import ReferenceBlockStampFactory from tests.factory.configs import BunkerConfigFactory, ChainConfigFactory, FrameConfigFactory @@ -199,10 +199,12 @@ def is_abnormal_cl_rebase(self, monkeypatch: pytest.MonkeyPatch) -> Iterable[Moc ) def test_get_cl_rebase_for_frame( bunker, - mock_get_total_supply, + contracts, simulated_post_total_pooled_ether, expected_rebase, ): + bunker.w3.lido_contracts.lido.total_supply = Mock(return_value=15 * 10**18) + blockstamp = simple_ref_blockstamp(0) simulated_cl_rebase = LidoReportRebase( post_total_pooled_ether=simulated_post_total_pooled_ether, diff --git a/tests/modules/accounting/bunker/test_bunker_abnormal_cl_rebase.py b/tests/modules/accounting/bunker/test_bunker_abnormal_cl_rebase.py index d061c6b72..a85c46288 100644 --- a/tests/modules/accounting/bunker/test_bunker_abnormal_cl_rebase.py +++ b/tests/modules/accounting/bunker/test_bunker_abnormal_cl_rebase.py @@ -1,9 +1,9 @@ import pytest from src.constants import FAR_FUTURE_EPOCH -from src.providers.consensus.typings import Validator, ValidatorStatus, ValidatorState +from src.providers.consensus.types import Validator, ValidatorStatus, ValidatorState from src.services.bunker_cases.abnormal_cl_rebase import AbnormalClRebase -from src.services.bunker_cases.typings import BunkerConfig +from src.services.bunker_cases.types import BunkerConfig from tests.modules.accounting.bunker.conftest import simple_ref_blockstamp, simple_key, simple_blockstamp @@ -36,15 +36,23 @@ def simple_validators( @pytest.mark.unit @pytest.mark.parametrize( - ("blockstamp", "frame_cl_rebase", "nearest_epoch_distance", "far_epoch_distance", "expected_is_abnormal"), + ( + "blockstamp", + "frame_cl_rebase", + "nearest_epoch_distance", + "far_epoch_distance", + "expected_is_abnormal", + "lido_validators_exist", + ), [ - (simple_ref_blockstamp(40), 378585832, 0, 0, False), # < mistake rate - (simple_ref_blockstamp(40), 378585831.6, 0, 0, False), # == mistake rate and no check specific rebase - (simple_ref_blockstamp(40), 378585830, 10, 20, False), # > mistake rate but specific rebase is positive - (simple_ref_blockstamp(40), 378585830, 10, 10, False), # > mistake rate but specific rebase is positive - (simple_ref_blockstamp(40), 378585830, 0, 0, True), # > mistake rate and no check specific rebase - (simple_ref_blockstamp(20), 126195276, 10, 20, True), # > mistake rate and specific rebase is negative - (simple_ref_blockstamp(20), 126195276, 10, 10, True), # > mistake rate and specific rebase is negative + (simple_ref_blockstamp(40), 378585832, 0, 0, False, True), # < mistake rate + (simple_ref_blockstamp(40), 378585831.6, 0, 0, False, True), # == mistake rate and no check specific rebase + (simple_ref_blockstamp(40), 378585830, 10, 20, False, True), # > mistake rate but specific rebase is positive + (simple_ref_blockstamp(40), 378585830, 10, 10, False, True), # > mistake rate but specific rebase is positive + (simple_ref_blockstamp(40), 378585830, 0, 0, True, True), # > mistake rate and no check specific rebase + (simple_ref_blockstamp(20), 126195276, 10, 20, True, True), # > mistake rate and specific rebase is negative + (simple_ref_blockstamp(20), 126195276, 10, 10, True, True), # > mistake rate and specific rebase is negative + (simple_ref_blockstamp(20), 126195276, 10, 10, False, False), # > mistake rate and specific rebase is negative ], ) def test_is_abnormal_cl_rebase( @@ -59,9 +67,14 @@ def test_is_abnormal_cl_rebase( nearest_epoch_distance, far_epoch_distance, expected_is_abnormal, + lido_validators_exist, ): all_validators = abnormal_case.w3.cc.get_validators(blockstamp) - lido_validators = abnormal_case.w3.cc.get_validators(blockstamp)[3:6] + + lido_validators = [] + if lido_validators_exist: + lido_validators = abnormal_case.w3.cc.get_validators(blockstamp)[3:6] + abnormal_case.b_conf = BunkerConfig( normalized_cl_reward_per_epoch=64, normalized_cl_reward_mistake_rate=0.1, diff --git a/tests/modules/accounting/bunker/test_bunker_medterm_penalty.py b/tests/modules/accounting/bunker/test_bunker_medterm_penalty.py index 88a498ff7..a7fc0a4c4 100644 --- a/tests/modules/accounting/bunker/test_bunker_medterm_penalty.py +++ b/tests/modules/accounting/bunker/test_bunker_medterm_penalty.py @@ -1,10 +1,10 @@ import pytest from src.modules.submodules.consensus import FrameConfig -from src.modules.submodules.typings import ChainConfig -from src.providers.consensus.typings import Validator, ValidatorStatus, ValidatorState +from src.modules.submodules.types import ChainConfig +from src.providers.consensus.types import Validator, ValidatorStatus, ValidatorState from src.services.bunker_cases.midterm_slashing_penalty import MidtermSlashingPenalty -from src.typings import EpochNumber, ReferenceBlockStamp +from src.types import EpochNumber, ReferenceBlockStamp def simple_blockstamp( diff --git a/tests/modules/accounting/test_accounting_module.py b/tests/modules/accounting/test_accounting_module.py index 572c81b2f..c6832ce00 100644 --- a/tests/modules/accounting/test_accounting_module.py +++ b/tests/modules/accounting/test_accounting_module.py @@ -1,4 +1,3 @@ -from dataclasses import asdict from typing import Any, Iterable, cast from unittest.mock import Mock, patch @@ -9,11 +8,12 @@ from src.modules.accounting import accounting as accounting_module from src.modules.accounting.accounting import Accounting from src.modules.accounting.accounting import logger as accounting_logger -from src.modules.accounting.typings import LidoReportRebase +from src.modules.accounting.third_phase.types import FormatList +from src.modules.accounting.types import LidoReportRebase from src.modules.submodules.oracle_module import ModuleExecuteDelay -from src.modules.submodules.typings import ChainConfig, FrameConfig +from src.modules.submodules.types import ChainConfig, FrameConfig from src.services.withdrawal import Withdrawal -from src.typings import BlockStamp, ReferenceBlockStamp +from src.types import BlockStamp, ReferenceBlockStamp from src.web3py.extensions.lido_validators import NodeOperatorId, StakingModule from tests.factory.blockstamp import BlockStampFactory, ReferenceBlockStampFactory from tests.factory.configs import ChainConfigFactory, FrameConfigFactory @@ -202,7 +202,7 @@ def _no_sleep_before_report(self, accounting: Accounting): @pytest.mark.unit @pytest.mark.usefixtures('_no_sleep_before_report') - def test_no_sumbit_if_can_submit_is_false( + def test_no_submit_if_can_submit_is_false( self, accounting: Accounting, submit_extra_data_mock: Mock, @@ -219,7 +219,7 @@ def test_no_sumbit_if_can_submit_is_false( @pytest.mark.unit @pytest.mark.usefixtures('_no_sleep_before_report') - def test_sumbit_if_can_submit_is_true( + def test_submit_if_can_submit_is_true( self, accounting: Accounting, submit_extra_data_mock: Mock, @@ -245,48 +245,33 @@ def test_submit_extra_data_non_empty( ): extra_data = bytes(32) - accounting.get_chain_config = Mock(return_value=chain_config) - accounting.lido_validator_state_service.get_extra_data = Mock(return_value=Mock(extra_data=extra_data)) - accounting.report_contract.functions.submitReportExtraDataList = Mock() # type: ignore + accounting.w3.lido_contracts.accounting_oracle.get_consensus_version = Mock(return_value=1) + accounting.get_extra_data = Mock(return_value=Mock(extra_data_list=[extra_data])) + accounting.report_contract.submit_report_extra_data_list = Mock() # type: ignore accounting.w3.transaction = Mock() accounting._submit_extra_data(ref_bs) - accounting.report_contract.functions.submitReportExtraDataList.assert_called_once_with(extra_data) - accounting.lido_validator_state_service.get_extra_data.assert_called_once_with(ref_bs, chain_config) - accounting.get_chain_config.assert_called_once_with(ref_bs) + accounting.report_contract.submit_report_extra_data_list.assert_called_once_with(extra_data) + accounting.get_extra_data.assert_called_once_with(ref_bs) @pytest.mark.unit - @pytest.mark.parametrize( - ("extra_data",), - [ - (None,), - (bytes(0),), - ([],), - (b'',), - ('',), - (False,), - ], - ) def test_submit_extra_data_empty( self, accounting: Accounting, ref_bs: ReferenceBlockStamp, chain_config: ChainConfig, - extra_data: Any, ): - accounting.get_chain_config = Mock(return_value=chain_config) - accounting.lido_validator_state_service.get_extra_data = Mock(return_value=Mock(extra_data=extra_data)) - accounting.report_contract.functions.submitReportExtraDataList = Mock() # type: ignore - accounting.report_contract.functions.submitReportExtraDataEmpty = Mock() # type: ignore + accounting.get_extra_data = Mock(return_value=Mock(format=FormatList.EXTRA_DATA_FORMAT_LIST_EMPTY.value)) + accounting.report_contract.submit_report_extra_data_list = Mock() # type: ignore + accounting.report_contract.submit_report_extra_data_empty = Mock() # type: ignore accounting.w3.transaction = Mock() accounting._submit_extra_data(ref_bs) - accounting.report_contract.functions.submitReportExtraDataEmpty.assert_called_once() - accounting.report_contract.functions.submitReportExtraDataList.assert_not_called() - accounting.lido_validator_state_service.get_extra_data.assert_called_once_with(ref_bs, chain_config) - accounting.get_chain_config.assert_called_once_with(ref_bs) + accounting.report_contract.submit_report_extra_data_empty.assert_called_once() + accounting.report_contract.submit_report_extra_data_list.assert_not_called() + accounting.get_extra_data.assert_called_once_with(ref_bs) @pytest.mark.unit @@ -299,14 +284,14 @@ def test_submit_extra_data_empty( (True, True, False), ], ) -def test_can_sumbit_extra_data( +def test_can_submit_extra_data( accounting: Accounting, extra_data_submitted: bool, main_data_submitted: bool, expected: bool, bs: BlockStamp, ): - accounting._get_processing_state = Mock( + accounting.w3.lido_contracts.accounting_oracle.get_processing_state = Mock( return_value=Mock( extra_data_submitted=extra_data_submitted, main_data_submitted=main_data_submitted, @@ -316,7 +301,7 @@ def test_can_sumbit_extra_data( out = accounting.can_submit_extra_data(bs) assert out == expected, "can_submit_extra_data returned unexpected value" - accounting._get_processing_state.assert_called_once_with(bs) + accounting.w3.lido_contracts.accounting_oracle.get_processing_state.assert_called_once_with(bs.block_hash) @pytest.mark.unit @@ -349,15 +334,19 @@ def test_is_main_data_submitted( accounting: Accounting, bs: BlockStamp, ): - accounting._get_processing_state = Mock(return_value=Mock(main_data_submitted=False)) + accounting.w3.lido_contracts.accounting_oracle.get_processing_state = Mock( + return_value=Mock(main_data_submitted=False) + ) assert accounting.is_main_data_submitted(bs) is False, "is_main_data_submitted returned unexpected value" - accounting._get_processing_state.assert_called_once_with(bs) + accounting.w3.lido_contracts.accounting_oracle.get_processing_state.assert_called_once_with(bs.block_hash) - accounting._get_processing_state.reset_mock() + accounting.w3.lido_contracts.accounting_oracle.get_processing_state.reset_mock() - accounting._get_processing_state = Mock(return_value=Mock(main_data_submitted=True)) + accounting.w3.lido_contracts.accounting_oracle.get_processing_state = Mock( + return_value=Mock(main_data_submitted=True) + ) assert accounting.is_main_data_submitted(bs) is True, "is_main_data_submitted returned unexpected value" - accounting._get_processing_state.assert_called_once_with(bs) + accounting.w3.lido_contracts.accounting_oracle.get_processing_state.assert_called_once_with(bs.block_hash) @pytest.mark.unit @@ -386,23 +375,15 @@ def test_get_shares_to_burn( bs: BlockStamp, monkeypatch: pytest.MonkeyPatch, ): - call_mock = accounting.w3.lido_contracts.burner.functions.getSharesRequestedToBurn = Mock() # type: ignore + shares_data = Mock(cover_shares=42, non_cover_shares=17) + call_mock = accounting.w3.lido_contracts.burner.get_shares_requested_to_burn = Mock(return_value=shares_data) - with monkeypatch.context() as m: - shares_data = Mock(cover_shares=42, non_cover_shares=17) - m.setattr(accounting_module, 'named_tuple_to_dataclass', Mock(return_value=shares_data)) + out = accounting.get_shares_to_burn(bs) - out = accounting.get_shares_to_burn(bs) - - assert ( - out == shares_data.cover_shares + shares_data.non_cover_shares - ), "get_shares_to_burn returned unexpected value" - call_mock.assert_called_once() - - # @lru_cache - call_mock.reset_mock() - accounting.get_shares_to_burn(bs) - call_mock.assert_not_called() + assert ( + out == shares_data.cover_shares + shares_data.non_cover_shares + ), "get_shares_to_burn returned unexpected value" + call_mock.assert_called_once() @pytest.mark.unit @@ -435,7 +416,6 @@ def test_simulate_rebase_after_report( chain_config: ChainConfig, ): # NOTE: we don't test the actual rebase calculation here, just the logic of the method - accounting.get_chain_config = Mock(return_value=chain_config) accounting.w3.lido_contracts.get_withdrawal_balance = Mock(return_value=17) accounting.get_shares_to_burn = Mock(return_value=13) @@ -443,14 +423,7 @@ def test_simulate_rebase_after_report( accounting._get_consensus_lido_state = Mock(return_value=(0, 0)) accounting._get_slots_elapsed_from_last_report = Mock(return_value=42) - simulation_tx = Mock( - call=Mock( - return_value=asdict( - LidoReportRebaseFactory.build(), - ).values(), - ) - ) - accounting.w3.lido_contracts.lido.functions.handleOracleReport = Mock(return_value=simulation_tx) # type: ignore + accounting.w3.lido_contracts.lido.handle_oracle_report = Mock(return_value=LidoReportRebaseFactory.build()) # type: ignore out = accounting.simulate_rebase_after_report(ref_bs, Wei(0)) assert isinstance(out, LidoReportRebase), "simulate_rebase_after_report returned unexpected value" @@ -459,7 +432,7 @@ def test_simulate_rebase_after_report( @pytest.mark.unit @pytest.mark.usefixtures('lido_validators') def test_get_newly_exited_validators_by_modules(accounting: Accounting, ref_bs: ReferenceBlockStamp): - accounting.w3.lido_validators.get_staking_modules = Mock(return_value=[Mock(), Mock()]) + accounting.w3.lido_contracts.staking_router.get_staking_modules = Mock(return_value=[Mock(), Mock()]) accounting.lido_validator_state_service.get_exited_lido_validators = Mock(return_value=[]) RESULT = object() @@ -468,35 +441,10 @@ def test_get_newly_exited_validators_by_modules(accounting: Accounting, ref_bs: out = accounting._get_newly_exited_validators_by_modules(ref_bs) assert out is RESULT - accounting.w3.lido_validators.get_staking_modules.assert_called_once_with(ref_bs) + accounting.w3.lido_contracts.staking_router.get_staking_modules.assert_called_once_with(ref_bs.block_hash) accounting.lido_validator_state_service.get_exited_lido_validators.assert_called_once_with(ref_bs) -@pytest.mark.unit -def test_get_processing_state( - accounting: Accounting, - bs: BlockStamp, - monkeypatch: pytest.MonkeyPatch, -): - processing_state = Mock() - RESULT = object() - - call_mock = accounting.report_contract.functions.getProcessingState = Mock(return_value=processing_state) # type: ignore - - with monkeypatch.context() as m: - m.setattr(accounting_module, 'named_tuple_to_dataclass', Mock(return_value=RESULT)) - - out = accounting._get_processing_state(bs) - - assert out is RESULT, "_get_processing_state returned unexpected value" - call_mock.assert_called_once() - - # @lru_cache - call_mock.reset_mock() - accounting._get_processing_state(bs) - call_mock.assert_not_called() - - @pytest.mark.unit def test_is_bunker( accounting: Accounting, diff --git a/tests/modules/accounting/test_extra_data.py b/tests/modules/accounting/test_extra_data.py index 2d14120eb..f1dc784d9 100644 --- a/tests/modules/accounting/test_extra_data.py +++ b/tests/modules/accounting/test_extra_data.py @@ -1,8 +1,9 @@ import pytest from hexbytes import HexBytes -from src.modules.accounting.extra_data import ExtraDataService, ExtraData, FormatList -from src.web3py.extensions.lido_validators import NodeOperatorGlobalIndex, LidoValidator +from src.modules.accounting.third_phase.extra_data import ExtraDataService +from src.modules.accounting.third_phase.types import FormatList, ExtraData +from src.web3py.extensions.lido_validators import NodeOperatorGlobalIndex pytestmark = pytest.mark.unit @@ -22,7 +23,7 @@ def test_collect_zero(self, extra_data_service, contracts): extra_data = extra_data_service.collect({}, {}, 10, 10) assert isinstance(extra_data, ExtraData) assert extra_data.format == FormatList.EXTRA_DATA_FORMAT_LIST_EMPTY.value - assert extra_data.extra_data == b'' + assert not extra_data.extra_data_list assert extra_data.data_hash == HexBytes('0x0000000000000000000000000000000000000000000000000000000000000000') def test_collect_non_zero(self, extra_data_service): @@ -35,8 +36,9 @@ def test_collect_non_zero(self, extra_data_service): extra_data = extra_data_service.collect(vals_stuck_non_zero, vals_exited_non_zero, 10, 10) assert isinstance(extra_data, ExtraData) assert extra_data.format == FormatList.EXTRA_DATA_FORMAT_LIST_NON_EMPTY.value + assert len(extra_data.extra_data_list) == 1 assert ( - extra_data.extra_data + extra_data.extra_data_list[0] == b'\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x02\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02' ) assert extra_data.data_hash == HexBytes( @@ -68,8 +70,9 @@ def test_collect_stuck_vals_in_cap(self, extra_data_service): extra_data = extra_data_service.collect(vals_stuck_non_zero, vals_exited_non_zero, 1, 2) assert isinstance(extra_data, ExtraData) assert extra_data.format == FormatList.EXTRA_DATA_FORMAT_LIST_NON_EMPTY.value + assert len(extra_data.extra_data_list) == 1 assert ( - extra_data.extra_data + extra_data.extra_data_list[0] == b'\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' ) assert extra_data.data_hash == HexBytes( @@ -82,10 +85,12 @@ def test_collect_stuck_vals_in_cap(self, extra_data_service): item_length = 3 + 2 + 3 + 8 no_payload_length = 8 + 16 # Expecting one module - assert len(extra_data.extra_data) == item_length + no_payload_length * 2 + assert len(extra_data.extra_data_list[0]) == item_length + no_payload_length * 2 # Expecting two modules extra_data = extra_data_service.collect(vals_stuck_non_zero, vals_exited_non_zero, 2, 2) - assert len(extra_data.extra_data) == item_length + no_payload_length * 2 + item_length + no_payload_length + assert ( + len(extra_data.extra_data_list[0]) == item_length + no_payload_length * 2 + item_length + no_payload_length + ) def test_order(self, extra_data_service, monkeypatch): vals_order = { diff --git a/tests/modules/accounting/test_extra_data_v2.py b/tests/modules/accounting/test_extra_data_v2.py new file mode 100644 index 000000000..37cd46f01 --- /dev/null +++ b/tests/modules/accounting/test_extra_data_v2.py @@ -0,0 +1,129 @@ +import pytest +from web3 import Web3 + +from src.modules.accounting.third_phase.extra_data_v2 import ExtraDataServiceV2, ItemPayload +from src.modules.accounting.third_phase.types import FormatList +from src.modules.submodules.types import ZERO_HASH + + +@pytest.mark.unit +def test_collect(): + extra_data = ExtraDataServiceV2.collect( + { + (1, 1): 10, + (2, 1): 5, + }, + { + (1, 2): 16, + (2, 1): 12, + (2, 2): 14, + (2, 3): 18, + (2, 5): 18, + (2, 6): 18, + (2, 7): 18, + (2, 8): 18, + (3, 1): 18, + }, + 2, + 3, + ) + + assert extra_data.format == FormatList.EXTRA_DATA_FORMAT_LIST_NON_EMPTY.value + assert len(extra_data.extra_data_list) == 4 + assert extra_data.data_hash == Web3.keccak(extra_data.extra_data_list[0]) + assert extra_data.extra_data_list[0][:32] == Web3.keccak(extra_data.extra_data_list[1]) + assert ( + extra_data.extra_data_list[0] + == b'\xaf\x92O*Z\xc3#|`\xf2\xbc\xc3\xbd\xf2\xee\x92\xd1\xb6\xcbk\x86\xe8d\xd9\xf3\xbc\xc7,\x1c7\x8c4\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x01\x00\x01\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05' + ) + + extra_data = ExtraDataServiceV2.collect({}, {}, 2, 4) + assert extra_data.format == FormatList.EXTRA_DATA_FORMAT_LIST_EMPTY.value + + +@pytest.mark.unit +def test_build_validators_payloads(): + vals_payloads = { + (1, 1): 1, + (1, 2): 2, + (1, 3): 3, + (1, 4): 4, + (1, 5): 5, + (2, 1): 6, + (2, 2): 7, + } + + result = ExtraDataServiceV2.build_validators_payloads( + vals_payloads, + 2, + ) + + assert len(result) == 4 + + assert result[0].module_id == 1 + assert result[1].module_id == 1 + assert result[1].node_operator_ids == [3, 4] + assert result[1].vals_counts == [3, 4] + assert result[2].module_id == 1 + assert result[2].node_operator_ids == [5] + assert result[2].vals_counts == [5] + assert result[3].module_id == 2 + + assert not ExtraDataServiceV2.build_validators_payloads({}, 2) + + +@pytest.mark.unit +def test_build_extra_transactions_data(): + exit_items = [ + ItemPayload( + 1, + [1, 2, 3], + [11, 22, 33], + ), + ItemPayload( + 2, + [1, 2, 3], + [11, 22, 33], + ), + ] + stuck_items = [ + ItemPayload( + 1, + [3], + [11], + ) + ] + + items_count, txs = ExtraDataServiceV2.build_extra_transactions_data( + stuck_items, + exit_items, + 2, + ) + + assert items_count == 3 + assert len(txs[0]) == 128 + assert len(txs[1]) == 128 - 16 - 8 - 8 - 8 + assert ( + txs[0] + == b'\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x01\x00\x02\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!' + ) + + +@pytest.mark.unit +def test_add_hashes_to_transactions(): + next_hash, txs = ExtraDataServiceV2.add_hashes_to_transactions([]) + + assert next_hash == ZERO_HASH + assert txs == [] + + transactions = [b'a' * 32, b'b' * 32, b'c' * 32] + next_hash, txs = ExtraDataServiceV2.add_hashes_to_transactions(transactions) + + assert txs[0][32:] == b'a' * 32 + assert txs[1][32:] == b'b' * 32 + assert txs[2][32:] == b'c' * 32 + + assert next_hash == Web3.keccak(Web3.keccak(Web3.keccak(ZERO_HASH + b'c' * 32) + b'b' * 32) + b'a' * 32) + assert txs[0][:32] == Web3.keccak(Web3.keccak(ZERO_HASH + b'c' * 32) + b'b' * 32) + assert txs[1][:32] == Web3.keccak(ZERO_HASH + b'c' * 32) + assert txs[2][:32] == ZERO_HASH diff --git a/tests/modules/accounting/test_safe_border_integration.py b/tests/modules/accounting/test_safe_border_integration.py index b7bb18621..d50145e23 100644 --- a/tests/modules/accounting/test_safe_border_integration.py +++ b/tests/modules/accounting/test_safe_border_integration.py @@ -1,8 +1,8 @@ -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock, patch, Mock import pytest -from src.typings import ReferenceBlockStamp +from src.types import ReferenceBlockStamp from src.services.safe_border import SafeBorder from tests.factory.blockstamp import ReferenceBlockStampFactory from tests.factory.configs import ChainConfigFactory, FrameConfigFactory, OracleReportLimitsFactory @@ -31,21 +31,18 @@ def subject( lido_validators, finalization_max_negative_rebase_epoch_shift, ): - with patch.object( - SafeBorder, - '_fetch_oracle_report_limits_list', - return_value=OracleReportLimitsFactory.build(request_timestamp_margin=8 * 12 * 32), - ), patch.object( - SafeBorder, - '_fetch_finalization_max_negative_rebase_epoch_shift', - return_value=finalization_max_negative_rebase_epoch_shift, - ): - safe_border = SafeBorder(web3, past_blockstamp, ChainConfigFactory.build(), FrameConfigFactory.build()) + web3.lido_contracts.oracle_report_sanity_checker.get_oracle_report_limits = Mock( + return_value=OracleReportLimitsFactory.build(request_timestamp_margin=8 * 12 * 32) + ) + + web3.lido_contracts.oracle_daemon_config.finalization_max_negative_rebase_epoch_shift = Mock( + return_value=finalization_max_negative_rebase_epoch_shift + ) - return safe_border + return SafeBorder(web3, past_blockstamp, ChainConfigFactory.build(), FrameConfigFactory.build()) -@pytest.mark.integration +@pytest.mark.possible_integration def test_happy_path(subject, past_blockstamp: ReferenceBlockStamp): is_bunker_mode = False @@ -54,7 +51,7 @@ def test_happy_path(subject, past_blockstamp: ReferenceBlockStamp): ) -@pytest.mark.integration +@pytest.mark.possible_integration def test_bunker_mode_negative_rebase(subject, past_blockstamp: ReferenceBlockStamp): is_bunker_mode = True @@ -66,7 +63,7 @@ def test_bunker_mode_negative_rebase(subject, past_blockstamp: ReferenceBlockSta ) -@pytest.mark.integration +@pytest.mark.possible_integration def test_bunker_mode_associated_slashing_predicted( subject: SafeBorder, past_blockstamp: ReferenceBlockStamp, finalization_max_negative_rebase_epoch_shift: int ): @@ -93,7 +90,7 @@ def test_bunker_mode_associated_slashing_predicted( ) -@pytest.mark.integration +@pytest.mark.possible_integration def test_bunker_mode_associated_slashing_unpredicted( subject: SafeBorder, past_blockstamp: ReferenceBlockStamp, finalization_max_negative_rebase_epoch_shift: int ): diff --git a/tests/modules/accounting/test_safe_border_unit.py b/tests/modules/accounting/test_safe_border_unit.py index dfd64c85c..76400f31f 100644 --- a/tests/modules/accounting/test_safe_border_unit.py +++ b/tests/modules/accounting/test_safe_border_unit.py @@ -4,9 +4,10 @@ from unittest.mock import Mock from src.services.safe_border import SafeBorder from src.web3py.extensions.lido_validators import Validator -from src.providers.consensus.typings import ValidatorState +from src.providers.consensus.types import ValidatorState from src.modules.submodules.consensus import ChainConfig, FrameConfig from tests.factory.blockstamp import ReferenceBlockStampFactory +from tests.factory.configs import OracleReportLimitsFactory FAR_FUTURE_EPOCH = 2**64 - 1 MIN_VALIDATOR_WITHDRAWABILITY_DELAY = 2**8 @@ -22,12 +23,12 @@ class WithdrawalStatus: @pytest.fixture() def chain_config(): - return ChainConfig(slots_per_epoch=32, seconds_per_slot=12, genesis_time=0) + yield ChainConfig(slots_per_epoch=32, seconds_per_slot=12, genesis_time=0) @pytest.fixture() def frame_config(): - return FrameConfig(initial_epoch=0, epochs_per_frame=10, fast_lane_length_slots=0) + yield FrameConfig(initial_epoch=0, epochs_per_frame=10, fast_lane_length_slots=0) @pytest.fixture() @@ -36,88 +37,102 @@ def past_blockstamp(): @pytest.fixture() -def subject( - chain_config, frame_config, past_blockstamp, web3, contracts, keys_api_client, consensus_client, lido_validators +def safe_border( + chain_config, + frame_config, + past_blockstamp, + web3, + contracts, + keys_api_client, + consensus_client, + lido_validators, ): + web3.lido_contracts.oracle_report_sanity_checker.get_oracle_report_limits = Mock( + return_value=OracleReportLimitsFactory.build() + ) + web3.lido_contracts.oracle_daemon_config.finalization_max_negative_rebase_epoch_shift = Mock(return_value=100) return SafeBorder(web3, past_blockstamp, chain_config, frame_config) -def test_get_new_requests_border_epoch(subject, past_blockstamp): - border = subject._get_default_requests_border_epoch() +def test_get_new_requests_border_epoch(safe_border, past_blockstamp): + border = safe_border._get_default_requests_border_epoch() - assert border == past_blockstamp.ref_slot // SLOTS_PER_EPOCH - subject.finalization_default_shift + assert border == past_blockstamp.ref_slot // SLOTS_PER_EPOCH - safe_border.finalization_default_shift -def test_calc_validator_slashed_epoch_from_state(subject): +def test_calc_validator_slashed_epoch_from_state(safe_border): exit_epoch = 504800 withdrawable_epoch = exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY + 1 validator = create_validator_stub(exit_epoch, withdrawable_epoch) - assert subject._predict_earliest_slashed_epoch(validator) == withdrawable_epoch - EPOCHS_PER_SLASHINGS_VECTOR + assert safe_border._predict_earliest_slashed_epoch(validator) == withdrawable_epoch - EPOCHS_PER_SLASHINGS_VECTOR -def test_calc_validator_slashed_epoch_from_state_undetectable(subject): +def test_calc_validator_slashed_epoch_from_state_undetectable(safe_border): exit_epoch = 504800 withdrawable_epoch = exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY validator = create_validator_stub(exit_epoch, withdrawable_epoch) - assert subject._predict_earliest_slashed_epoch(validator) is None + assert safe_border._predict_earliest_slashed_epoch(validator) is None -def test_filter_validators_with_earliest_exit_epoch(subject): +def test_filter_validators_with_earliest_exit_epoch(safe_border): validators = [ create_validator_stub(100, 105), create_validator_stub(102, 107), create_validator_stub(103, 108), ] - assert subject._filter_validators_with_earliest_exit_epoch(validators) == [validators[0]] + assert safe_border._filter_validators_with_earliest_exit_epoch(validators) == [validators[0]] -def test_get_negative_rebase_border_epoch(subject, past_blockstamp): +def test_get_negative_rebase_border_epoch(safe_border, past_blockstamp): ref_epoch = past_blockstamp.ref_slot // SLOTS_PER_EPOCH - subject._get_bunker_start_or_last_successful_report_epoch = Mock(return_value=ref_epoch) + safe_border._get_bunker_start_or_last_successful_report_epoch = Mock(return_value=ref_epoch) - assert subject._get_negative_rebase_border_epoch() == ref_epoch - subject.finalization_default_shift + assert safe_border._get_negative_rebase_border_epoch() == ref_epoch - safe_border.finalization_default_shift -def test_get_negative_rebase_border_epoch_bunker_not_started_yet(subject, past_blockstamp): +def test_get_negative_rebase_border_epoch_bunker_not_started_yet(safe_border, past_blockstamp): ref_epoch = past_blockstamp.ref_slot // SLOTS_PER_EPOCH - subject._get_bunker_start_or_last_successful_report_epoch = Mock(return_value=ref_epoch) + safe_border._get_bunker_start_or_last_successful_report_epoch = Mock(return_value=ref_epoch) - assert subject._get_negative_rebase_border_epoch() == ref_epoch - subject.finalization_default_shift + assert safe_border._get_negative_rebase_border_epoch() == ref_epoch - safe_border.finalization_default_shift -def test_get_negative_rebase_border_epoch_max(subject, past_blockstamp): +def test_get_negative_rebase_border_epoch_max(safe_border, past_blockstamp): ref_epoch = past_blockstamp.ref_slot // SLOTS_PER_EPOCH - test_epoch = ref_epoch - subject.finalization_max_negative_rebase_shift - 1 - subject._get_bunker_mode_start_timestamp = Mock(return_value=test_epoch * SLOTS_PER_EPOCH * SLOT_TIME) + max_negative_rebase_shift = ( + safe_border.w3.lido_contracts.oracle_daemon_config.finalization_max_negative_rebase_epoch_shift() + ) + test_epoch = ref_epoch - max_negative_rebase_shift - 1 + safe_border._get_bunker_mode_start_timestamp = Mock(return_value=test_epoch * SLOTS_PER_EPOCH * SLOT_TIME) - assert subject._get_negative_rebase_border_epoch() == ref_epoch - subject.finalization_max_negative_rebase_shift + assert safe_border._get_negative_rebase_border_epoch() == ref_epoch - max_negative_rebase_shift -def test_get_associated_slashings_border_epoch(subject, past_blockstamp): +def test_get_associated_slashings_border_epoch(safe_border, past_blockstamp): ref_epoch = past_blockstamp.ref_slot // SLOTS_PER_EPOCH - subject._get_earliest_slashed_epoch_among_incomplete_slashings = Mock(return_value=None) - assert subject._get_associated_slashings_border_epoch() == ref_epoch - subject.finalization_default_shift + safe_border._get_earliest_slashed_epoch_among_incomplete_slashings = Mock(return_value=None) + assert safe_border._get_associated_slashings_border_epoch() == ref_epoch - safe_border.finalization_default_shift test_epoch = ref_epoch - 100 - subject._get_earliest_slashed_epoch_among_incomplete_slashings = Mock(return_value=test_epoch) + safe_border._get_earliest_slashed_epoch_among_incomplete_slashings = Mock(return_value=test_epoch) assert ( - subject._get_associated_slashings_border_epoch() - == subject.round_epoch_by_frame(test_epoch) - subject.finalization_default_shift + safe_border._get_associated_slashings_border_epoch() + == safe_border.round_epoch_by_frame(test_epoch) - safe_border.finalization_default_shift ) -def test_get_earliest_slashed_epoch_among_incomplete_slashings_no_validators(subject, past_blockstamp): - subject.w3.lido_validators.get_lido_validators = Mock(return_value=[]) +def test_get_earliest_slashed_epoch_among_incomplete_slashings_no_validators(safe_border, past_blockstamp): + safe_border.w3.lido_validators.get_lido_validators = Mock(return_value=[]) - assert subject._get_earliest_slashed_epoch_among_incomplete_slashings() is None + assert safe_border._get_earliest_slashed_epoch_among_incomplete_slashings() is None -def test_get_earliest_slashed_epoch_among_incomplete_slashings_no_slashed_validators(subject, past_blockstamp): - subject.w3.lido_validators.get_lido_validators = Mock( +def test_get_earliest_slashed_epoch_among_incomplete_slashings_no_slashed_validators(safe_border, past_blockstamp): + safe_border.w3.lido_validators.get_lido_validators = Mock( return_value=[ create_validator_stub(100, 105), create_validator_stub(102, 107), @@ -125,21 +140,21 @@ def test_get_earliest_slashed_epoch_among_incomplete_slashings_no_slashed_valida ] ) - assert subject._get_earliest_slashed_epoch_among_incomplete_slashings() is None + assert safe_border._get_earliest_slashed_epoch_among_incomplete_slashings() is None def test_get_earliest_slashed_epoch_among_incomplete_slashings_withdrawable_validators( - subject, past_blockstamp, lido_validators + safe_border, past_blockstamp, lido_validators ): withdrawable_epoch = past_blockstamp.ref_epoch - 10 validators = [create_validator_stub(100, withdrawable_epoch, True)] - subject.w3.lido_validators.get_lido_validators = Mock(return_value=validators) + safe_border.w3.lido_validators.get_lido_validators = Mock(return_value=validators) - assert subject._get_earliest_slashed_epoch_among_incomplete_slashings() is None + assert safe_border._get_earliest_slashed_epoch_among_incomplete_slashings() is None def test_get_earliest_slashed_epoch_among_incomplete_slashings_unable_to_predict( - subject, past_blockstamp, lido_validators + safe_border, past_blockstamp, lido_validators ): non_withdrawable_epoch = past_blockstamp.ref_epoch + 10 validators = [ @@ -147,14 +162,14 @@ def test_get_earliest_slashed_epoch_among_incomplete_slashings_unable_to_predict non_withdrawable_epoch - MIN_VALIDATOR_WITHDRAWABILITY_DELAY, non_withdrawable_epoch, True ) ] - subject.w3.lido_validators.get_lido_validators = Mock(return_value=validators) - subject._find_earliest_slashed_epoch_rounded_to_frame = Mock(return_value=1331) + safe_border.w3.lido_validators.get_lido_validators = Mock(return_value=validators) + safe_border._find_earliest_slashed_epoch_rounded_to_frame = Mock(return_value=1331) - assert subject._get_earliest_slashed_epoch_among_incomplete_slashings() == 1331 + assert safe_border._get_earliest_slashed_epoch_among_incomplete_slashings() == 1331 def test_get_earliest_slashed_epoch_among_incomplete_slashings_all_withdrawable( - subject, past_blockstamp, lido_validators + safe_border, past_blockstamp, lido_validators ): validators = [ create_validator_stub( @@ -164,12 +179,12 @@ def test_get_earliest_slashed_epoch_among_incomplete_slashings_all_withdrawable( past_blockstamp.ref_epoch - MIN_VALIDATOR_WITHDRAWABILITY_DELAY, past_blockstamp.ref_epoch - 2, True ), ] - subject.w3.lido_validators.get_lido_validators = Mock(return_value=validators) + safe_border.w3.lido_validators.get_lido_validators = Mock(return_value=validators) - assert subject._get_earliest_slashed_epoch_among_incomplete_slashings() is None + assert safe_border._get_earliest_slashed_epoch_among_incomplete_slashings() is None -def test_get_earliest_slashed_epoch_among_incomplete_slashings_predicted(subject, past_blockstamp, lido_validators): +def test_get_earliest_slashed_epoch_among_incomplete_slashings_predicted(safe_border, past_blockstamp, lido_validators): non_withdrawable_epoch = past_blockstamp.ref_epoch + 10 validators = [ create_validator_stub( @@ -179,15 +194,15 @@ def test_get_earliest_slashed_epoch_among_incomplete_slashings_predicted(subject non_withdrawable_epoch - MIN_VALIDATOR_WITHDRAWABILITY_DELAY - 2, non_withdrawable_epoch, True ), ] - subject.w3.lido_validators.get_lido_validators = Mock(return_value=validators) + safe_border.w3.lido_validators.get_lido_validators = Mock(return_value=validators) - assert subject._get_earliest_slashed_epoch_among_incomplete_slashings() == ( + assert safe_border._get_earliest_slashed_epoch_among_incomplete_slashings() == ( non_withdrawable_epoch - EPOCHS_PER_SLASHINGS_VECTOR ) def test_get_earliest_slashed_epoch_among_incomplete_slashings_at_least_one_unpredictable_epoch( - subject, + safe_border, past_blockstamp, lido_validators, ): @@ -200,41 +215,44 @@ def test_get_earliest_slashed_epoch_among_incomplete_slashings_at_least_one_unpr non_withdrawable_epoch - MIN_VALIDATOR_WITHDRAWABILITY_DELAY, non_withdrawable_epoch, True ), ] - subject.w3.lido_validators.get_lido_validators = Mock(return_value=validators) - subject._find_earliest_slashed_epoch_rounded_to_frame = Mock(return_value=1331) + safe_border.w3.lido_validators.get_lido_validators = Mock(return_value=validators) + safe_border._find_earliest_slashed_epoch_rounded_to_frame = Mock(return_value=1331) - assert subject._get_earliest_slashed_epoch_among_incomplete_slashings() == 1331 + assert safe_border._get_earliest_slashed_epoch_among_incomplete_slashings() == 1331 -def test_get_bunker_start_or_last_successful_report_epoch_no_bunker_start(subject, past_blockstamp): - subject._get_bunker_mode_start_timestamp = Mock(return_value=None) - subject.w3.lido_contracts.get_accounting_last_processing_ref_slot = Mock(return_value=past_blockstamp.ref_slot) +def test_get_bunker_start_or_last_successful_report_epoch_no_bunker_start(safe_border, past_blockstamp): + safe_border._get_bunker_mode_start_timestamp = Mock(return_value=None) + safe_border.w3.lido_contracts.get_accounting_last_processing_ref_slot = Mock(return_value=past_blockstamp.ref_slot) - assert subject._get_bunker_start_or_last_successful_report_epoch() == past_blockstamp.ref_slot // 32 + assert safe_border._get_bunker_start_or_last_successful_report_epoch() == past_blockstamp.ref_slot // 32 -def test_get_bunker_start_or_last_successful_report_epoch(subject, past_blockstamp): - subject._get_bunker_mode_start_timestamp = Mock(return_value=past_blockstamp.ref_slot * 12) +def test_get_bunker_start_or_last_successful_report_epoch(safe_border, past_blockstamp): + safe_border._get_bunker_mode_start_timestamp = Mock(return_value=past_blockstamp.ref_slot * 12) - assert subject._get_bunker_start_or_last_successful_report_epoch() == past_blockstamp.ref_slot // 32 + assert safe_border._get_bunker_start_or_last_successful_report_epoch() == past_blockstamp.ref_slot // 32 -def test_get_last_finalized_withdrawal_request_slot(subject): +def test_get_last_finalized_withdrawal_request_slot(safe_border): timestamp = 1677230000 - subject._get_last_finalized_request_id = Mock(return_value=3) - subject._get_withdrawal_request_status = Mock(return_value=WithdrawalStatus(timestamp=timestamp)) - slot = (timestamp - subject.chain_config.genesis_time) // subject.chain_config.seconds_per_slot - epoch = slot // subject.chain_config.slots_per_epoch - first_slot = epoch * subject.chain_config.slots_per_epoch + safe_border.w3.lido_contracts.withdrawal_queue_nft.get_last_finalized_request_id = Mock(return_value=3) + safe_border.w3.lido_contracts.withdrawal_queue_nft.get_withdrawal_status = Mock( + return_value=WithdrawalStatus(timestamp=timestamp) + ) + + slot = (timestamp - safe_border.chain_config.genesis_time) // safe_border.chain_config.seconds_per_slot + epoch = slot // safe_border.chain_config.slots_per_epoch + first_slot = epoch * safe_border.chain_config.slots_per_epoch - assert subject._get_last_finalized_withdrawal_request_slot() == first_slot + assert safe_border._get_last_finalized_withdrawal_request_slot() == first_slot -def test_get_last_finalized_withdrawal_request_slot_no_requests(subject): - subject._get_last_finalized_request_id = Mock(return_value=0) +def test_get_last_finalized_withdrawal_request_slot_no_requests(safe_border): + safe_border.w3.lido_contracts.withdrawal_queue_nft.get_last_finalized_request_id = Mock(return_value=0) - assert subject._get_last_finalized_withdrawal_request_slot() == 0 + assert safe_border._get_last_finalized_withdrawal_request_slot() == 0 def create_validator_stub(exit_epoch, withdrawable_epoch, slashed=False): diff --git a/tests/modules/accounting/test_validator_state.py b/tests/modules/accounting/test_validator_state.py index c3d5d0686..5fe11fb59 100644 --- a/tests/modules/accounting/test_validator_state.py +++ b/tests/modules/accounting/test_validator_state.py @@ -6,22 +6,18 @@ from src.constants import FAR_FUTURE_EPOCH from src.services.validator_state import LidoValidatorStateService -from src.modules.submodules.typings import ChainConfig -from src.providers.consensus.typings import Validator, ValidatorState -from src.providers.keys.typings import LidoKey -from src.typings import BlockStamp +from src.modules.submodules.types import ChainConfig +from src.providers.consensus.types import Validator, ValidatorState +from src.providers.keys.types import LidoKey +from src.types import StakingModuleId, NodeOperatorId from src.web3py.extensions.lido_validators import ( NodeOperator, StakingModule, LidoValidatorsProvider, LidoValidator, - ValidatorsByNodeOperator, - StakingModuleId, - NodeOperatorId, ) from tests.factory.blockstamp import ReferenceBlockStampFactory - TESTING_REF_EPOCH = 100 @@ -31,40 +27,90 @@ ) -class MockValidatorsProvider(LidoValidatorsProvider): - def get_lido_validators(self, blockstamp: BlockStamp) -> list[LidoValidator]: - raise NotImplementedError - - def get_lido_validators_by_node_operators(self, blockstamp: BlockStamp) -> ValidatorsByNodeOperator: - def validator(index: int, exit_epoch: int, pubkey: HexStr, activation_epoch: int = 0): - return LidoValidator( - lido_id=LidoKey( - key=pubkey, - depositSignature="", - operatorIndex=-1, - used=True, - moduleAddress="", - ), - **asdict( - Validator( - index=str(index), - balance="0", - status="", - validator=ValidatorState( - pubkey=pubkey, - withdrawal_credentials="0x1", - effective_balance="0", - slashed=False, - activation_eligibility_epoch="0", - activation_epoch=str(activation_epoch), - exit_epoch=str(exit_epoch), - withdrawable_epoch="0", - ), - ) - ), - ) - - return { +@pytest.fixture +def lido_validators(web3): + web3.attach_modules( + { + 'lido_validators': LidoValidatorsProvider, + } + ) + + sm = StakingModule( + id=1, + staking_module_address='0x8a1E2986E52b441058325c315f83C9D4129bDF72', + staking_module_fee=500, + treasury_fee=500, + stake_share_limit=10000, + status=0, + name='NodeOperatorsRegistry', + last_deposit_at=1676386968, + last_deposit_block=89677, + exited_validators_count=0, + ) + + web3.lido_contracts.staking_router.get_staking_modules = Mock(return_value=[sm]) + + web3.lido_contracts.staking_router.get_all_node_operator_digests = Mock( + return_value=[ + NodeOperator( + id=0, + is_active=True, + is_target_limit_active=False, + target_validators_count=0, + stuck_validators_count=0, + refunded_validators_count=0, + stuck_penalty_end_timestamp=0, + total_exited_validators=0, + total_deposited_validators=5, + depositable_validators_count=0, + staking_module=sm, + ), + NodeOperator( + id=1, + is_active=True, + is_target_limit_active=False, + target_validators_count=0, + stuck_validators_count=0, + refunded_validators_count=0, + stuck_penalty_end_timestamp=0, + total_exited_validators=1, + total_deposited_validators=5, + depositable_validators_count=0, + staking_module=sm, + ), + ] + ) + + def validator(index: int, exit_epoch: int, pubkey: HexStr, activation_epoch: int = 0): + return LidoValidator( + lido_id=LidoKey( + key=pubkey, + depositSignature="", + operatorIndex=-1, + used=True, + moduleAddress="", + ), + **asdict( + Validator( + index=str(index), + balance="0", + status="", + validator=ValidatorState( + pubkey=pubkey, + withdrawal_credentials="0x1", + effective_balance="0", + slashed=False, + activation_eligibility_epoch="0", + activation_epoch=str(activation_epoch), + exit_epoch=str(exit_epoch), + withdrawable_epoch="0", + ), + ) + ), + ) + + web3.lido_validators.get_lido_validators_by_node_operators = Mock( + return_value={ (StakingModuleId(1), NodeOperatorId(0)): [ validator(index=1, exit_epoch=FAR_FUTURE_EPOCH, pubkey='0x1'), # Stuck validator(index=2, exit_epoch=30, pubkey='0x2'), @@ -80,57 +126,15 @@ def validator(index: int, exit_epoch: int, pubkey: HexStr, activation_epoch: int validator(index=8, exit_epoch=FAR_FUTURE_EPOCH, pubkey='0x8'), ], } - - def get_staking_modules(self, blockstamp: BlockStamp) -> list[StakingModule]: - return [ - StakingModule( - id=1, - staking_module_address='0x8a1E2986E52b441058325c315f83C9D4129bDF72', - staking_module_fee=500, - treasury_fee=500, - target_share=10000, - status=0, - name='NodeOperatorsRegistry', - last_deposit_at=1676386968, - last_deposit_block=89677, - exited_validators_count=0, - ) - ] - - def get_lido_node_operators(self, blockstamp: BlockStamp) -> list[NodeOperator]: - def operator(id: int, total_exited_validators: int): - return NodeOperator( - id=id, - is_active=True, - is_target_limit_active=False, - target_validators_count=0, - stuck_validators_count=0, - refunded_validators_count=0, - stuck_penalty_end_timestamp=0, - total_exited_validators=total_exited_validators, - total_deposited_validators=5, - depositable_validators_count=0, - staking_module=module, - ) - - module = self.get_staking_modules(blockstamp)[0] - return [operator(id=0, total_exited_validators=0), operator(id=1, total_exited_validators=1)] - - -@pytest.fixture -def lido_validators(web3): - web3.attach_modules( - { - 'lido_validators': MockValidatorsProvider, - } ) @pytest.fixture def validator_state(web3, contracts, consensus_client, lido_validators): service = LidoValidatorStateService(web3) - requested_indexes = [3, 8] - service._get_last_requested_validator_indices = Mock(return_value=requested_indexes) + service.w3.lido_contracts.validators_exit_bus_oracle.get_last_requested_validator_indices = Mock( + return_value=[3, 8] + ) return service @@ -139,9 +143,10 @@ def chain_config(): return ChainConfig(slots_per_epoch=32, seconds_per_slot=12, genesis_time=0) +@pytest.mark.unit def test_get_lido_new_stuck_validators(web3, validator_state, chain_config): validator_state.get_last_requested_to_exit_pubkeys = Mock(return_value={"0x8"}) - validator_state.get_validator_delinquent_timeout_in_slot = Mock(return_value=0) + validator_state.w3.lido_contracts.oracle_daemon_config.validator_delinquent_timeout_in_slots = Mock(return_value=0) stuck_validators = validator_state.get_lido_newly_stuck_validators(blockstamp, chain_config) assert stuck_validators == {(1, 0): 1} diff --git a/tests/modules/accounting/test_withdrawal_integration.py b/tests/modules/accounting/test_withdrawal_integration.py index b6e619c6b..8c31233db 100644 --- a/tests/modules/accounting/test_withdrawal_integration.py +++ b/tests/modules/accounting/test_withdrawal_integration.py @@ -1,27 +1,27 @@ import pytest -from src.modules.submodules.typings import FrameConfig, ChainConfig +from src.modules.submodules.types import FrameConfig, ChainConfig from src.services.withdrawal import Withdrawal from src.constants import SHARE_RATE_PRECISION_E27 from tests.conftest import get_blockstamp_by_state -@pytest.fixture() +@pytest.fixture def chain_config(): return ChainConfig(slots_per_epoch=32, seconds_per_slot=12, genesis_time=1675263480) -@pytest.fixture() +@pytest.fixture def frame_config(): return FrameConfig(initial_epoch=0, epochs_per_frame=10, fast_lane_length_slots=0) -@pytest.fixture() +@pytest.fixture def past_blockstamp(web3, consensus_client): return get_blockstamp_by_state(web3, 'finalized') -@pytest.fixture() +@pytest.fixture def subject(web3, past_blockstamp, chain_config, frame_config, contracts, keys_api_client, consensus_client): return Withdrawal(web3, past_blockstamp, chain_config, frame_config) @@ -30,13 +30,11 @@ def test_happy_path(subject, past_blockstamp): withdrawal_vault_balance = subject.w3.lido_contracts.get_withdrawal_balance(past_blockstamp) el_rewards_vault_balance = subject.w3.lido_contracts.get_el_vault_balance(past_blockstamp) - expected_min_withdrawal_id = ( - subject.w3.lido_contracts.withdrawal_queue_nft.functions.getLastFinalizedRequestId().call( - block_identifier=past_blockstamp.block_hash - ) + expected_min_withdrawal_id = subject.w3.lido_contracts.withdrawal_queue_nft.get_last_finalized_request_id( + past_blockstamp.block_hash ) - expected_max_withdrawal_id = subject.w3.lido_contracts.withdrawal_queue_nft.functions.getLastRequestId().call( - block_identifier=past_blockstamp.block_hash + expected_max_withdrawal_id = subject.w3.lido_contracts.withdrawal_queue_nft.get_last_request_id( + past_blockstamp.block_hash ) results = subject.get_finalization_batches( diff --git a/tests/modules/accounting/test_withdrawal_unit.py b/tests/modules/accounting/test_withdrawal_unit.py index a4c62aa9c..0b88ab79e 100644 --- a/tests/modules/accounting/test_withdrawal_unit.py +++ b/tests/modules/accounting/test_withdrawal_unit.py @@ -5,7 +5,8 @@ from src.modules.submodules.consensus import ChainConfig, FrameConfig from tests.conftest import get_blockstamp_by_state from src.constants import SHARE_RATE_PRECISION_E27 -from src.modules.accounting.typings import BatchState +from src.modules.accounting.types import BatchState +from tests.factory.configs import OracleReportLimitsFactory @pytest.fixture() @@ -25,7 +26,9 @@ def past_blockstamp(web3, consensus_client): @pytest.fixture() def subject(web3, past_blockstamp, chain_config, frame_config, contracts, keys_api_client, consensus_client): - # web3.lido_contracts.oracle_report_sanity_checker.functions.getOracleReportLimits().call = Mock(return_value=0) + web3.lido_contracts.oracle_report_sanity_checker.get_oracle_report_limits = Mock( + return_value=OracleReportLimitsFactory.build() + ) return Withdrawal(web3, past_blockstamp, chain_config, frame_config) @@ -39,7 +42,7 @@ def test_returns_empty_batch_if_there_is_no_requests(subject: Withdrawal): @pytest.mark.unit def test_returns_empty_batch_if_paused(subject: Withdrawal): - subject._is_requests_finalization_paused = Mock(return_value=True) + subject.w3.lido_contracts.withdrawal_queue_nft.is_paused = Mock(return_value=True) result = subject.get_finalization_batches(True, 100, 0, 0) assert result == [] @@ -60,8 +63,10 @@ def test_returns_batch_if_there_are_finalizable_requests(subject: Withdrawal): def test_calculate_finalization_batches(subject: Withdrawal, past_blockstamp): state_initial = BatchState(remaining_eth_budget=100, finished=False, batches=[1] + [0] * 35, batches_length=1) state_final = BatchState(remaining_eth_budget=100, finished=True, batches=[2] + [0] * 35, batches_length=2) - subject._fetch_finalization_batches = Mock(side_effect=[state_initial, state_final]) - subject._fetch_max_batches_length = Mock(return_value=36) + subject.w3.lido_contracts.withdrawal_queue_nft.calculate_finalization_batches = Mock( + side_effect=[state_initial, state_final] + ) + subject.w3.lido_contracts.withdrawal_queue_nft.max_batches_length = Mock(return_value=36) result = subject._calculate_finalization_batches(1, SHARE_RATE_PRECISION_E27, past_blockstamp.block_timestamp) diff --git a/tests/modules/csm/test_checkpoint.py b/tests/modules/csm/test_checkpoint.py new file mode 100644 index 000000000..4470d4403 --- /dev/null +++ b/tests/modules/csm/test_checkpoint.py @@ -0,0 +1,379 @@ +from copy import deepcopy +from typing import cast, Iterator +from unittest.mock import Mock + +import pytest + +from src.modules.csm.checkpoint import ( + CheckpointsIterator, + Checkpoint, + CheckpointProcessor, + process_attestations, + MinStepIsNotReached, +) +from src.modules.csm.state import State +from src.modules.submodules.types import ChainConfig, FrameConfig +from src.providers.consensus.client import ConsensusClient +from src.providers.consensus.types import BeaconSpecResponse, SlotAttestationCommittee, BlockAttestation +from src.utils.web3converter import Web3Converter +from tests.factory.configs import ( + FrameConfigFactory, + ChainConfigFactory, + BeaconSpecResponseFactory, + SlotAttestationCommitteeFactory, + BlockAttestationFactory, +) + + +@pytest.fixture +def frame_config() -> FrameConfig: + return FrameConfigFactory.build( + epochs_per_frame=225, + ) + + +@pytest.fixture +def chain_config() -> ChainConfig: + return ChainConfigFactory.build( + slots_per_epoch=32, + seconds_per_slot=12, + genesis_time=0, + ) + + +@pytest.fixture +def converter(frame_config: FrameConfig, chain_config: ChainConfig) -> Web3Converter: + return Web3Converter(chain_config, frame_config) + + +def test_checkpoints_iterator_min_epoch_is_not_reached(converter): + with pytest.raises(MinStepIsNotReached): + CheckpointsIterator(converter, 100, 600, 109) + + +@pytest.mark.parametrize( + "l_epoch,r_epoch,finalized_epoch,expected_checkpoints", + [ + (0, 254, 253, [Checkpoint(253 * 32, tuple(range(0, 252)))]), + (0, 254, 254, [Checkpoint(254 * 32, tuple(range(0, 253)))]), + (0, 254, 255, [Checkpoint(255 * 32, tuple(range(0, 254)))]), + ( + # fit to max checkpoint step, can generate full checkpoint (with 255 epochs) + 0, + 254, + 256, + [Checkpoint(256 * 32, tuple(range(0, 255)))], + ), + ( + # fit to max checkpoint step, and first 15 epochs is processed + 15, + 254, + 256, + [Checkpoint(256 * 32, tuple(range(15, 255)))], + ), + ( + # fit to min checkpoint step, and first 15 epochs is processed + 15, + 255, + 27, + [Checkpoint(27 * 32, tuple(range(15, 26)))], + ), + ( + 0, + 255 * 2, + 255 * 2 + 2, + [ + Checkpoint(8192, tuple(range(0, 255))), + Checkpoint(16352, tuple(range(255, 510))), + Checkpoint(16384, tuple(range(510, 511))), + ], + ), + ( + 0, + 225 * 3, + 225 * 3 + 2, + [ + Checkpoint(8192, tuple(range(0, 255))), + Checkpoint(16352, tuple(range(255, 510))), + Checkpoint(21664, tuple(range(510, 676))), + ], + ), + ], +) +def test_checkpoints_iterator_given_checkpoints(converter, l_epoch, r_epoch, finalized_epoch, expected_checkpoints): + iterator = CheckpointsIterator(converter, l_epoch, r_epoch, finalized_epoch) + assert list(iter(iterator)) == expected_checkpoints + + +@pytest.fixture +def consensus_client(): + return ConsensusClient('http://localhost', 5 * 60, 5, 5) + + +@pytest.fixture +def mock_get_state_block_roots(consensus_client): + def _get_state_block_roots(state_id): + return [f'0x{r}' for r in range(state_id, state_id + 8192)] + + consensus_client.get_state_block_roots = Mock(side_effect=_get_state_block_roots) + + +@pytest.fixture +def mock_get_state_block_roots_with_duplicates(consensus_client): + def _get_state_block_roots(state_id): + br = [f'0x{r}' for r in range(0, 8192)] + return [br[i - 1] if i % 2 == 0 else br[i] for i in range(len(br))] + + consensus_client.get_state_block_roots = Mock(side_effect=_get_state_block_roots) + + +def test_checkpoints_processor_get_block_roots(consensus_client, mock_get_state_block_roots, converter: Web3Converter): + state = ... + finalized_blockstamp = ... + processor = CheckpointProcessor( + consensus_client, + converter, + state, + finalized_blockstamp, + ) + roots = processor._get_block_roots(0) + assert len([r for r in roots if r is not None]) == 8192 + + +def test_checkpoints_processor_get_block_roots_with_duplicates( + consensus_client, mock_get_state_block_roots_with_duplicates, converter: Web3Converter +): + state = ... + finalized_blockstamp = ... + processor = CheckpointProcessor( + consensus_client, + converter, + state, + finalized_blockstamp, + ) + roots = processor._get_block_roots(1) + assert len([r for r in roots if r is not None]) == 4096 + + +@pytest.fixture +def mock_get_config_spec(consensus_client): + bc_spec = cast(BeaconSpecResponse, BeaconSpecResponseFactory.build()) + bc_spec.SLOTS_PER_HISTORICAL_ROOT = 8192 + consensus_client.get_config_spec = Mock(return_value=bc_spec) + + +def test_checkpoints_processor_select_block_roots( + consensus_client, mock_get_state_block_roots, mock_get_config_spec, converter: Web3Converter +): + state = ... + finalized_blockstamp = ... + processor = CheckpointProcessor( + consensus_client, + state, + converter, + finalized_blockstamp, + ) + roots = processor._get_block_roots(0) + selected = processor._select_block_roots(10, roots, 8192) + assert len(selected) == 64 + assert selected == [f'0x{r}' for r in range(320, 384)] + + +def test_checkpoints_processor_select_block_roots_out_of_range( + consensus_client, mock_get_state_block_roots, mock_get_config_spec, converter: Web3Converter +): + state = ... + finalized_blockstamp = ... + processor = CheckpointProcessor( + consensus_client, + state, + converter, + finalized_blockstamp, + ) + roots = processor._get_block_roots(0) + with pytest.raises(ValueError, match="Slot is out of the state block roots range"): + processor._select_block_roots(255, roots, 8192) + + +@pytest.fixture() +def mock_get_attestation_committees(consensus_client): + def _get_attestation_committees(finalized_slot, epoch): + committees = [] + validators = [v for v in range(0, 2048 * 32)] + for i in range(epoch * 32, epoch * 32 + 32): # 1 epoch = 32 slots. + for j in range(0, 64): # 64 committees per slot + committee = deepcopy(cast(SlotAttestationCommittee, SlotAttestationCommitteeFactory.build())) + committee.slot = i + committee.index = j + # 32 validators per committee + committee.validators = [validators.pop() for _ in range(32)] + committees.append(committee) + return committees + + consensus_client.get_attestation_committees = Mock(side_effect=_get_attestation_committees) + + +def test_checkpoints_processor_prepare_committees(mock_get_attestation_committees, consensus_client, converter): + state = ... + finalized_blockstamp = ... + processor = CheckpointProcessor( + consensus_client, + state, + converter, + finalized_blockstamp, + ) + raw = consensus_client.get_attestation_committees(0, 0) + committees = processor._prepare_committees(0) + assert len(committees) == 2048 + for index, (committee_id, validators) in enumerate(committees.items()): + slot, committee_index = committee_id + committee_from_raw = raw[index] + assert int(slot) == committee_from_raw.slot + assert int(committee_index) == committee_from_raw.index + assert len(validators) == 32 + for validator in validators: + assert validator.included is False + + +def test_checkpoints_processor_process_attestations(mock_get_attestation_committees, consensus_client, converter): + state = ... + finalized_blockstamp = ... + processor = CheckpointProcessor( + consensus_client, + state, + converter, + finalized_blockstamp, + ) + committees = processor._prepare_committees(0) + # normal attestation + attestation = cast(BlockAttestation, BlockAttestationFactory.build()) + attestation.data.slot = 0 + attestation.data.index = 0 + attestation.aggregation_bits = '0x' + 'f' * 32 + # the same but with no included attestations in bits + attestation2 = cast(BlockAttestation, BlockAttestationFactory.build()) + attestation2.data.slot = 0 + attestation2.data.index = 0 + attestation2.aggregation_bits = '0x' + '0' * 32 + process_attestations([attestation, attestation2], committees) + for index, validators in enumerate(committees.values()): + for validator in validators: + # only the first attestation is accounted + if index == 0: + assert validator.included is True + else: + assert validator.included is False + + +def test_checkpoints_processor_process_attestations_undefined_committee( + mock_get_attestation_committees, consensus_client, converter +): + state = ... + finalized_blockstamp = ... + processor = CheckpointProcessor( + consensus_client, + state, + converter, + finalized_blockstamp, + ) + committees = processor._prepare_committees(0) + # undefined committee + attestation = cast(BlockAttestation, BlockAttestationFactory.build()) + attestation.data.slot = 100500 + attestation.data.index = 100500 + attestation.aggregation_bits = '0x' + 'f' * 32 + process_attestations([attestation], committees) + for validators in committees.values(): + for v in validators: + assert v.included is False + + +@pytest.fixture() +def mock_get_block_attestations(consensus_client): + def _get_block_attestations(root): + attestations = [] + for i in range(0, 64): + attestation = deepcopy(cast(BlockAttestation, BlockAttestationFactory.build())) + attestation.data.slot = root[2:] + attestation.data.index = str(i) + attestation.aggregation_bits = '0x' + 'f' * 32 + attestations.append(attestation) + return attestations + + consensus_client.get_block_attestations = Mock(side_effect=_get_block_attestations) + + +def test_checkpoints_processor_check_duty( + mock_get_state_block_roots, + mock_get_attestation_committees, + mock_get_block_attestations, + mock_get_config_spec, + consensus_client, + converter, +): + state = State() + state.validate_for_collect(0, 255) + finalized_blockstamp = ... + processor = CheckpointProcessor( + consensus_client, + state, + converter, + finalized_blockstamp, + ) + roots = processor._get_block_roots(0) + processor._check_duty(0, roots[:64]) + assert len(state._processed_epochs) == 1 + assert len(state._epochs_to_process) == 256 + assert len(state.unprocessed_epochs) == 255 + assert len(state.data) == 2048 * 32 + + +def test_checkpoints_processor_process( + mock_get_state_block_roots, + mock_get_attestation_committees, + mock_get_block_attestations, + mock_get_config_spec, + consensus_client, + converter, +): + state = State() + state.validate_for_collect(0, 255) + finalized_blockstamp = ... + processor = CheckpointProcessor( + consensus_client, + state, + converter, + finalized_blockstamp, + ) + roots = processor._get_block_roots(0) + processor._process([0, 1], {0: roots[:64], 1: roots[32:96]}) + assert len(state._processed_epochs) == 2 + assert len(state._epochs_to_process) == 256 + assert len(state.unprocessed_epochs) == 254 + assert len(state.data) == 2048 * 32 + + +def test_checkpoints_processor_exec( + mock_get_state_block_roots, + mock_get_attestation_committees, + mock_get_block_attestations, + mock_get_config_spec, + consensus_client, + converter, +): + state = State() + state.validate_for_collect(0, 255) + finalized_blockstamp = ... + processor = CheckpointProcessor( + consensus_client, + state, + converter, + finalized_blockstamp, + ) + iterator = CheckpointsIterator(converter, 0, 1, 255) + for checkpoint in iterator: + processor.exec(checkpoint) + assert len(state._processed_epochs) == 2 + assert len(state._epochs_to_process) == 256 + assert len(state.unprocessed_epochs) == 254 + assert len(state.data) == 2048 * 32 diff --git a/tests/modules/csm/test_csm_module.py b/tests/modules/csm/test_csm_module.py new file mode 100644 index 000000000..35c92375a --- /dev/null +++ b/tests/modules/csm/test_csm_module.py @@ -0,0 +1,65 @@ +from unittest.mock import Mock + +import pytest + +from src.modules.csm.csm import CSOracle +from src.modules.csm.state import AttestationsAggregate, State +from src.types import NodeOperatorId, ValidatorIndex +from src.web3py.extensions.csm import CSM + + +@pytest.fixture() +def module(web3, csm: CSM): + yield CSOracle(web3) + + +def test_init(module: CSOracle): + assert module + + +def test_calculate_distribution(module: CSOracle, csm: CSM): + csm.fee_distributor.shares_to_distribute = Mock(return_value=10_000) + csm.oracle.perf_leeway_bp = Mock(return_value=500) + + module.module_validators_by_node_operators = Mock( + return_value={ + (None, NodeOperatorId(0)): [Mock(index=0)], + (None, NodeOperatorId(1)): [Mock(index=1)], + (None, NodeOperatorId(2)): [Mock(index=2)], # stuck + (None, NodeOperatorId(3)): [Mock(index=3)], + (None, NodeOperatorId(4)): [Mock(index=4)], # stuck + (None, NodeOperatorId(5)): [Mock(index=5), Mock(index=6)], + (None, NodeOperatorId(6)): [Mock(index=7), Mock(index=8)], + (None, NodeOperatorId(7)): [Mock(index=9)], + } + ) + module.stuck_operators = Mock( + return_value=[ + NodeOperatorId(2), + NodeOperatorId(4), + ] + ) + + module.state = State( + { + ValidatorIndex(0): AttestationsAggregate(included=200, assigned=200), # short on frame + ValidatorIndex(1): AttestationsAggregate(included=1000, assigned=1000), + ValidatorIndex(2): AttestationsAggregate(included=1000, assigned=1000), + ValidatorIndex(3): AttestationsAggregate(included=999, assigned=1000), + ValidatorIndex(4): AttestationsAggregate(included=900, assigned=1000), + ValidatorIndex(5): AttestationsAggregate(included=500, assigned=1000), # underperforming + ValidatorIndex(5): AttestationsAggregate(included=500, assigned=1000), # underperforming + ValidatorIndex(6): AttestationsAggregate(included=0, assigned=0), # underperforming + ValidatorIndex(7): AttestationsAggregate(included=900, assigned=1000), + ValidatorIndex(8): AttestationsAggregate(included=500, assigned=1000), # underperforming + # ValidatorIndex(9): AttestationsAggregate(included=0, assigned=0), # missing in state + } + ) + _, shares = module.calculate_distribution(blockstamp=Mock()) + + assert tuple(shares.items()) == ( + (NodeOperatorId(0), 625), + (NodeOperatorId(1), 3125), + (NodeOperatorId(3), 3125), + (NodeOperatorId(6), 3125), + ) diff --git a/tests/modules/csm/test_state.py b/tests/modules/csm/test_state.py new file mode 100644 index 000000000..f6a519f29 --- /dev/null +++ b/tests/modules/csm/test_state.py @@ -0,0 +1,126 @@ +from pathlib import Path +from unittest.mock import Mock + +import pytest + +from src.modules.csm.state import AttestationsAggregate, State +from src.types import EpochNumber, ValidatorIndex +from src.utils.range import sequence + + +@pytest.fixture() +def state_file_path(tmp_path: Path) -> Path: + return (tmp_path / "mock").with_suffix(State.EXTENSION) + + +@pytest.fixture(autouse=True) +def mock_state_file(state_file_path: Path): + State.file = Mock(return_value=state_file_path) + + +def test_attestation_aggregate_perf(): + aggr = AttestationsAggregate(included=333, assigned=777) + assert aggr.perf == pytest.approx(0.4285, abs=1e-4) + + +def test_state_avg_perf(): + state = State() + + assert state.avg_perf == 0 + + state = State( + { + ValidatorIndex(0): AttestationsAggregate(included=0, assigned=0), + ValidatorIndex(1): AttestationsAggregate(included=0, assigned=0), + } + ) + + assert state.avg_perf == 0 + + state = State( + { + ValidatorIndex(0): AttestationsAggregate(included=333, assigned=777), + ValidatorIndex(1): AttestationsAggregate(included=167, assigned=223), + } + ) + + assert state.avg_perf == 0.5 + + +def test_state_attestations(): + state = State( + { + ValidatorIndex(0): AttestationsAggregate(included=333, assigned=777), + ValidatorIndex(1): AttestationsAggregate(included=167, assigned=223), + } + ) + + network_aggr = state.network_aggr + + assert network_aggr.assigned == 1000 + assert network_aggr.included == 500 + + +def test_state_load(): + orig = State( + { + ValidatorIndex(0): AttestationsAggregate(included=333, assigned=777), + ValidatorIndex(1): AttestationsAggregate(included=167, assigned=223), + } + ) + + orig.commit() + copy = State.load() + assert copy == orig + + +def test_state_clear(): + state = State( + { + ValidatorIndex(0): AttestationsAggregate(included=333, assigned=777), + ValidatorIndex(1): AttestationsAggregate(included=167, assigned=223), + } + ) + + state._epochs_to_process = {EpochNumber(1), EpochNumber(33)} + state._processed_epochs = {EpochNumber(42), EpochNumber(17)} + + state.clear() + assert state.is_empty + assert state == State() + + +def test_state_add_processed_epoch(): + state = State() + state.add_processed_epoch(EpochNumber(42)) + state.add_processed_epoch(EpochNumber(17)) + assert state._processed_epochs == {EpochNumber(42), EpochNumber(17)} + + +def test_state_inc(): + state = State( + { + ValidatorIndex(0): AttestationsAggregate(included=0, assigned=0), + ValidatorIndex(1): AttestationsAggregate(included=1, assigned=2), + } + ) + + state.inc(ValidatorIndex(0), True) + state.inc(ValidatorIndex(0), False) + + state.inc(ValidatorIndex(1), True) + state.inc(ValidatorIndex(1), True) + state.inc(ValidatorIndex(1), False) + + state.inc(ValidatorIndex(2), True) + state.inc(ValidatorIndex(2), False) + + assert tuple(state.data.values()) == ( + AttestationsAggregate(included=1, assigned=2), + AttestationsAggregate(included=3, assigned=5), + AttestationsAggregate(included=1, assigned=2), + ) + + +def test_state_file_is_path(): + assert isinstance(State.file(), Path) diff --git a/tests/modules/ejector/test_data_encode.py b/tests/modules/ejector/test_data_encode.py index 5e7ff1731..4d03a64a8 100644 --- a/tests/modules/ejector/test_data_encode.py +++ b/tests/modules/ejector/test_data_encode.py @@ -12,11 +12,8 @@ encode_data, sort_validators_to_eject, ) -from src.web3py.extensions.lido_validators import ( - LidoValidator, - NodeOperatorId, - StakingModuleId, -) +from src.types import StakingModuleId, NodeOperatorId +from src.web3py.extensions.lido_validators import LidoValidator from tests.factory.no_registry import LidoValidatorFactory diff --git a/tests/modules/ejector/test_ejector.py b/tests/modules/ejector/test_ejector.py index 42d1a123f..bf9adae2b 100644 --- a/tests/modules/ejector/test_ejector.py +++ b/tests/modules/ejector/test_ejector.py @@ -3,16 +3,19 @@ import pytest +from src import constants from src.constants import MAX_EFFECTIVE_BALANCE from src.modules.ejector import ejector as ejector_module -from src.modules.ejector.ejector import Ejector, EjectorProcessingState +from src.modules.ejector.ejector import Ejector from src.modules.ejector.ejector import logger as ejector_logger +from src.modules.ejector.types import EjectorProcessingState from src.modules.submodules.oracle_module import ModuleExecuteDelay -from src.modules.submodules.typings import ChainConfig -from src.typings import BlockStamp, ReferenceBlockStamp +from src.modules.submodules.types import ChainConfig +from src.types import BlockStamp, ReferenceBlockStamp +from src.utils import validator_state from src.web3py.extensions.contracts import LidoContracts from src.web3py.extensions.lido_validators import NodeOperatorId, StakingModuleId -from src.web3py.typings import Web3 +from src.web3py.types import Web3 from tests.factory.blockstamp import BlockStampFactory, ReferenceBlockStampFactory from tests.factory.configs import ChainConfigFactory from tests.factory.no_registry import LidoValidatorFactory @@ -41,6 +44,7 @@ def ref_blockstamp() -> ReferenceBlockStamp: @pytest.fixture() def ejector(web3: Web3, contracts: LidoContracts) -> Ejector: + web3.lido_contracts.validators_exit_bus_oracle.get_consensus_version = Mock(return_value=1) return Ejector(web3) @@ -65,7 +69,7 @@ def test_ejector_execute_module(ejector: Ejector, blockstamp: BlockStamp) -> Non def test_ejector_execute_module_on_pause(ejector: Ejector, blockstamp: BlockStamp) -> None: ejector.get_blockstamp_for_report = Mock(return_value=blockstamp) ejector.build_report = Mock(return_value=(1, 294271, 0, 1, b'')) - ejector._is_paused = Mock(return_value=True) + ejector.w3.lido_contracts.validators_exit_bus_oracle.is_paused = Mock(return_value=True) assert ( ejector.execute_module(last_finalized_blockstamp=blockstamp) is ModuleExecuteDelay.NEXT_SLOT ), "execute_module should wait for the next slot" @@ -73,6 +77,8 @@ def test_ejector_execute_module_on_pause(ejector: Ejector, blockstamp: BlockStam @pytest.mark.unit def test_ejector_build_report(ejector: Ejector, ref_blockstamp: ReferenceBlockStamp) -> None: + ejector.w3.lido_contracts.validators_exit_bus_oracle.get_contract_version = Mock(return_value=1) + ejector.w3.lido_contracts.validators_exit_bus_oracle.get_consensus_version = Mock(return_value=1) ejector.get_validators_to_eject = Mock(return_value=[]) result = ejector.build_report(ref_blockstamp) _, ref_slot, _, _, data = result @@ -83,17 +89,22 @@ def test_ejector_build_report(ejector: Ejector, ref_blockstamp: ReferenceBlockSt ejector.get_validators_to_eject.assert_called_once_with(ref_blockstamp) -class TestGetValidatorsToEject: - @pytest.mark.unit - def test_should_not_report_on_no_withdraw_requests( - self, - ejector: Ejector, - ref_blockstamp: ReferenceBlockStamp, - ) -> None: - ejector.get_total_unfinalized_withdrawal_requests_amount = Mock(return_value=0) - result = ejector.get_validators_to_eject(ref_blockstamp) - assert result == [], "Should not report on no withdraw requests" +class SimpleIterator: + def __init__(self, lst): + self.lst = lst + def __iter__(self): + self.iter = iter(self.lst) + return self + + def __next__(self): + return next(self.iter) + + def get_remaining_forced_validators(self): + pass + + +class TestGetValidatorsToEject: @pytest.mark.unit @pytest.mark.usefixtures("consensus_client") def test_no_validators_to_eject( @@ -104,12 +115,15 @@ def test_no_validators_to_eject( monkeypatch: pytest.MonkeyPatch, ): ejector.get_chain_config = Mock(return_value=chain_config) - ejector.get_total_unfinalized_withdrawal_requests_amount = Mock(return_value=100) + ejector.w3.lido_contracts.withdrawal_queue_nft.unfinalized_steth = Mock(return_value=100) + ejector.w3.lido_contracts.validators_exit_bus_oracle.get_contract_version = Mock(return_value=1) ejector.prediction_service.get_rewards_per_epoch = Mock(return_value=1) ejector._get_sweep_delay_in_epochs = Mock(return_value=1) ejector._get_total_el_balance = Mock(return_value=50) ejector.validators_state_service.get_recently_requested_but_not_exited_validators = Mock(return_value=[]) + ejector._get_predicted_withdrawable_epoch = Mock(return_value=ref_blockstamp.ref_epoch + 1) + ejector._get_withdrawable_lido_validators_balance = Mock(return_value=10) with monkeypatch.context() as m: m.setattr( @@ -120,6 +134,19 @@ def test_no_validators_to_eject( result = ejector.get_validators_to_eject(ref_blockstamp) assert result == [], "Unexpected validators to eject" + ejector.w3.lido_contracts.validators_exit_bus_oracle.get_consensus_version = Mock(return_value=2) + + with monkeypatch.context() as m: + val_iter = iter(SimpleIterator([])) + val_iter.get_remaining_forced_validators = Mock(return_value=[]) + m.setattr( + ejector_module.ValidatorExitIteratorV2, + "__iter__", + Mock(return_value=val_iter), + ) + result = ejector.get_validators_to_eject(ref_blockstamp) + assert result == [], "Unexpected validators to eject" + @pytest.mark.unit @pytest.mark.usefixtures("consensus_client") def test_simple( @@ -130,7 +157,8 @@ def test_simple( monkeypatch: pytest.MonkeyPatch, ): ejector.get_chain_config = Mock(return_value=chain_config) - ejector.get_total_unfinalized_withdrawal_requests_amount = Mock(return_value=200) + ejector.w3.lido_contracts.withdrawal_queue_nft.unfinalized_steth = Mock(return_value=200) + ejector.w3.lido_contracts.validators_exit_bus_oracle.get_contract_version = Mock(return_value=1) ejector.prediction_service.get_rewards_per_epoch = Mock(return_value=1) ejector._get_sweep_delay_in_epochs = Mock(return_value=ref_blockstamp.ref_epoch) ejector._get_total_el_balance = Mock(return_value=100) @@ -155,31 +183,36 @@ def test_simple( result = ejector.get_validators_to_eject(ref_blockstamp) assert result == [validators[0]], "Unexpected validators to eject" + ejector.w3.lido_contracts.validators_exit_bus_oracle.get_consensus_version = Mock(return_value=2) + + with monkeypatch.context() as m: + val_iter = iter(SimpleIterator(validators[:2])) + val_iter.get_remaining_forced_validators = Mock(return_value=validators[2:]) + m.setattr( + ejector_module.ValidatorExitIteratorV2, + "__iter__", + Mock(return_value=val_iter), + ) + result = ejector.get_validators_to_eject(ref_blockstamp) + assert result == [validators[0], *validators[2:]], "Unexpected validators to eject" + @pytest.mark.unit @pytest.mark.usefixtures("contracts") def test_get_unfinalized_steth(ejector: Ejector, blockstamp: BlockStamp) -> None: - result = ejector.get_total_unfinalized_withdrawal_requests_amount(blockstamp) + result = ejector.w3.lido_contracts.withdrawal_queue_nft.unfinalized_steth(blockstamp.block_hash) assert result == 8362187000000000000, "Unexpected unfinalized stETH" -@pytest.mark.unit -def test_compute_activation_exit_epoch( - ejector: Ejector, - monkeypatch: pytest.MonkeyPatch, -) -> None: - with monkeypatch.context() as m: - m.setattr(ejector_module, "MAX_SEED_LOOKAHEAD", 17) - ref_blockstamp = ReferenceBlockStampFactory.build(ref_epoch=3546) - result = ejector.compute_activation_exit_epoch(ref_blockstamp) - assert result == 3546 + 17 + 1, "Unexpected activation exit epoch" - - @pytest.mark.unit def test_is_main_data_submitted(ejector: Ejector, blockstamp: BlockStamp) -> None: - ejector._get_processing_state = Mock(return_value=Mock(data_submitted=True)) + ejector.w3.lido_contracts.validators_exit_bus_oracle.get_processing_state = Mock( + return_value=Mock(data_submitted=True) + ) assert ejector.is_main_data_submitted(blockstamp) is True, "Unexpected is_main_data_submitted result" - ejector._get_processing_state.assert_called_once_with(blockstamp) + ejector.w3.lido_contracts.validators_exit_bus_oracle.get_processing_state.assert_called_once_with( + blockstamp.block_hash + ) @pytest.mark.unit @@ -224,10 +257,10 @@ def test_get_withdrawable_lido_validators( Mock(side_effect=lambda v, _: int(v.balance) > 32), ) - result = ejector._get_withdrawable_lido_validators_balance(ref_blockstamp, 42) + result = ejector._get_withdrawable_lido_validators_balance(42, ref_blockstamp) assert result == 42 * 10**9, "Unexpected withdrawable amount" - ejector._get_withdrawable_lido_validators_balance(ref_blockstamp, 42) + ejector._get_withdrawable_lido_validators_balance(42, ref_blockstamp) ejector.w3.lido_validators.get_lido_validators.assert_called_once() @@ -286,29 +319,22 @@ def test_get_sweep_delay_in_epochs( ) # all 1024 validators - result = ejector._get_sweep_delay_in_epochs(ref_blockstamp) + result = ejector._get_sweep_delay_in_epochs(ReferenceBlockStampFactory.build(slot_number=1)) assert result == 1, "Unexpected sweep delay in epochs" -@pytest.mark.unit -@pytest.mark.usefixtures("contracts") -def test_get_reserved_buffer(ejector: Ejector, blockstamp: BlockStamp) -> None: - result = ejector._get_buffer_ether(blockstamp) - assert result == 2991010000000000000010, "Unexpected reserved buffer" - - @pytest.mark.usefixtures("contracts") def test_get_total_balance(ejector: Ejector, blockstamp: BlockStamp) -> None: ejector.w3.lido_contracts.get_withdrawal_balance = Mock(return_value=3) ejector.w3.lido_contracts.get_el_vault_balance = Mock(return_value=17) - ejector._get_buffer_ether = Mock(return_value=1) + ejector.w3.lido_contracts.lido.get_buffered_ether = Mock(return_value=1) result = ejector._get_total_el_balance(blockstamp) assert result == 21, "Unexpected total balance" ejector.w3.lido_contracts.get_withdrawal_balance.assert_called_once_with(blockstamp) ejector.w3.lido_contracts.get_el_vault_balance.assert_called_once_with(blockstamp) - ejector._get_buffer_ether.assert_called_once_with(blockstamp) + ejector.w3.lido_contracts.lido.get_buffered_ether.assert_called_once_with(blockstamp.block_hash) class TestChurnLimit: @@ -329,7 +355,7 @@ def mock_is_active_validator(self, monkeypatch: pytest.MonkeyPatch) -> Iterable: def test_get_churn_limit_no_validators(self, ejector: Ejector, ref_blockstamp: ReferenceBlockStamp) -> None: ejector.w3.cc.get_validators = Mock(return_value=[]) result = ejector._get_churn_limit(ref_blockstamp) - assert result == ejector_module.MIN_PER_EPOCH_CHURN_LIMIT, "Unexpected churn limit" + assert result == constants.MIN_PER_EPOCH_CHURN_LIMIT, "Unexpected churn limit" ejector.w3.cc.get_validators.assert_called_once_with(ref_blockstamp) @pytest.mark.unit @@ -342,8 +368,6 @@ def test_get_churn_limit_validators_less_than_min_churn( ) -> None: with monkeypatch.context() as m: ejector.w3.cc.get_validators = Mock(return_value=[1, 1, 0]) - m.setattr(ejector_module, "MIN_PER_EPOCH_CHURN_LIMIT", 4) - m.setattr(ejector_module, "CHURN_LIMIT_QUOTIENT", 1) result = ejector._get_churn_limit(ref_blockstamp) assert result == 4, "Unexpected churn limit" ejector.w3.cc.get_validators.assert_called_once_with(ref_blockstamp) @@ -358,8 +382,8 @@ def test_get_churn_limit_basic( ) -> None: with monkeypatch.context() as m: ejector.w3.cc.get_validators = Mock(return_value=[1] * 99) - m.setattr(ejector_module, "MIN_PER_EPOCH_CHURN_LIMIT", 0) - m.setattr(ejector_module, "CHURN_LIMIT_QUOTIENT", 2) + m.setattr(validator_state, "MIN_PER_EPOCH_CHURN_LIMIT", 0) + m.setattr(validator_state, "CHURN_LIMIT_QUOTIENT", 2) result = ejector._get_churn_limit(ref_blockstamp) assert result == 49, "Unexpected churn limit" ejector._get_churn_limit(ref_blockstamp) @@ -368,7 +392,7 @@ def test_get_churn_limit_basic( @pytest.mark.unit def test_get_processing_state(ejector: Ejector, blockstamp: BlockStamp) -> None: - result = ejector._get_processing_state(blockstamp) + result = ejector.w3.lido_contracts.validators_exit_bus_oracle.get_processing_state(blockstamp.block_hash) assert isinstance(result, EjectorProcessingState), "Unexpected processing state response" @@ -387,6 +411,3 @@ def test_get_latest_exit_epoch(ejector: Ejector, blockstamp: BlockStamp) -> None (max_epoch, count) = ejector._get_latest_exit_epoch(blockstamp) assert count == 2, "Unexpected count of exiting validators" assert max_epoch == 42, "Unexpected max epoch" - - ejector._get_latest_exit_epoch(blockstamp) - ejector.w3.cc.get_validators.assert_called_once_with(blockstamp) diff --git a/tests/modules/ejector/test_exit_order_iterator.py b/tests/modules/ejector/test_exit_order_iterator.py index 77bb8703c..41aa37224 100644 --- a/tests/modules/ejector/test_exit_order_iterator.py +++ b/tests/modules/ejector/test_exit_order_iterator.py @@ -1,12 +1,14 @@ +from unittest.mock import Mock + import pytest -from src.providers.consensus.typings import ValidatorState -from src.providers.keys.typings import LidoKey -from src.services.exit_order_iterator import ExitOrderIterator -from src.services.exit_order_iterator_state import NodeOperatorPredictableState, ExitOrderIteratorStateService +from src.providers.consensus.types import ValidatorState +from src.providers.keys.types import LidoKey +from src.services.exit_order.iterator import ExitOrderIterator +from src.services.exit_order.iterator_state import NodeOperatorPredictableState, ExitOrderIteratorStateService from src.web3py.extensions.lido_validators import LidoValidator, StakingModuleId, NodeOperatorId from tests.factory.blockstamp import ReferenceBlockStampFactory -from tests.factory.configs import ChainConfigFactory +from tests.factory.configs import ChainConfigFactory, OracleReportLimitsFactory from tests.factory.no_registry import LidoValidatorFactory @@ -137,9 +139,6 @@ def mock_exit_order_iterator_state_service(monkeypatch): class MockedExitOrderIteratorStateService(ExitOrderIteratorStateService): pass - inner_ = lambda _: None - inner_.max_validator_exit_requests_per_report = 100 - MockedExitOrderIteratorStateService.get_oracle_report_limits = lambda *_: inner_ MockedExitOrderIteratorStateService.get_operator_network_penetration_threshold = lambda *_: 0.05 MockedExitOrderIteratorStateService.get_operators_with_last_exited_validator_indexes = lambda *_: {} MockedExitOrderIteratorStateService.get_exitable_lido_validators = lambda *_: [] @@ -147,12 +146,16 @@ class MockedExitOrderIteratorStateService(ExitOrderIteratorStateService): MockedExitOrderIteratorStateService.get_total_predictable_validators_count = lambda *_: 0 monkeypatch.setattr( - 'src.services.exit_order_iterator.ExitOrderIteratorStateService', MockedExitOrderIteratorStateService + 'src.services.exit_order.iterator.ExitOrderIteratorStateService', MockedExitOrderIteratorStateService ) @pytest.mark.unit def test_exit_order_iterator_iter(web3, lido_validators, contracts, mock_exit_order_iterator_state_service): + web3.lido_contracts.oracle_report_sanity_checker.get_oracle_report_limits = Mock( + return_value=OracleReportLimitsFactory.build(max_validator_exit_requests_per_report=100) + ) + iterator = ExitOrderIterator(web3, ReferenceBlockStampFactory.build(), ChainConfigFactory.build()) web3.lido_validators.get_lido_node_operators = lambda _: [] web3.lido_validators.get_lido_validators_by_node_operators = lambda _: [] @@ -170,6 +173,10 @@ def test_exit_order_iterator_iter(web3, lido_validators, contracts, mock_exit_or @pytest.mark.unit def test_exit_order_iterator_next(web3, lido_validators, contracts, mock_exit_order_iterator_state_service): + web3.lido_contracts.oracle_report_sanity_checker.get_oracle_report_limits = Mock( + return_value=OracleReportLimitsFactory.build(max_validator_exit_requests_per_report=100) + ) + iterator = ExitOrderIterator(web3, ReferenceBlockStampFactory.build(), ChainConfigFactory.build()) web3.lido_validators.get_lido_node_operators = lambda _: [] web3.lido_validators.get_lido_validators_by_node_operators = lambda _: [] diff --git a/tests/modules/ejector/test_exit_order_state_service.py b/tests/modules/ejector/test_exit_order_state_service.py index ba16b9150..6a6e8bab0 100644 --- a/tests/modules/ejector/test_exit_order_state_service.py +++ b/tests/modules/ejector/test_exit_order_state_service.py @@ -2,10 +2,10 @@ import pytest -from src.modules.submodules.typings import ChainConfig -from src.providers.consensus.typings import ValidatorState, Validator, ValidatorStatus -from src.services.exit_order_iterator import NodeOperatorPredictableState -from src.services.exit_order_iterator_state import ExitOrderIteratorStateService +from src.modules.submodules.types import ChainConfig +from src.providers.consensus.types import ValidatorState, Validator, ValidatorStatus +from src.services.exit_order.iterator import NodeOperatorPredictableState +from src.services.exit_order.iterator_state import ExitOrderIteratorStateService from src.web3py.extensions.lido_validators import ( NodeOperator, StakingModule, @@ -99,7 +99,7 @@ def _get_lido_validators(blockstamp): @pytest.fixture def mock_get_recently_requests_to_exit_indexes(exit_order_state): - def _get_recently_requests_to_exit_indexes(blockstamp, *_): + def _get_recently_requests_to_exit_indexes(_, blockstamp): responses = { 100: { (0, 0): [8, 9], @@ -117,7 +117,7 @@ def _get_recently_requests_to_exit_indexes(blockstamp, *_): return responses[blockstamp.slot_number] - exit_order_state.get_recently_requests_to_exit_indexes_by_operators = Mock( + exit_order_state.get_recently_requested_validators_by_operator = Mock( side_effect=_get_recently_requests_to_exit_indexes ) diff --git a/tests/modules/ejector/test_iterator_v2.py b/tests/modules/ejector/test_iterator_v2.py new file mode 100644 index 000000000..3044aaee8 --- /dev/null +++ b/tests/modules/ejector/test_iterator_v2.py @@ -0,0 +1,349 @@ +from types import MethodType +from unittest.mock import Mock + +import pytest + +from src.services.exit_order_v2.iterator import ValidatorExitIteratorV2, NodeOperatorStats, StakingModuleStats +from src.web3py.extensions.lido_validators import NodeOperatorLimitMode +from tests.factory.blockstamp import ReferenceBlockStampFactory +from tests.factory.no_registry import NodeOperatorFactory, StakingModuleFactory, LidoValidatorFactory +from tests.factory.web3_factory import Web3Factory + + +class ModuleStatsFactory(Web3Factory): + __model__ = StakingModuleStats + + +class NodeOperatorStatsFactory(Web3Factory): + __model__ = NodeOperatorStats + + node_operator = NodeOperatorFactory + module_stats = ModuleStatsFactory + + +@pytest.fixture +def iterator(web3, contracts, lido_validators): + return ValidatorExitIteratorV2( + web3, + ReferenceBlockStampFactory.build(), + 12, + ) + + +@pytest.mark.unit +def test_get_filter_non_exitable_validators(iterator): + iterator.lvs.get_operators_with_last_exited_validator_indexes = Mock( + return_value={ + (1, 1): 1, + (1, 2): -1, + } + ) + + filt = iterator.get_filter_non_exitable_validators((1, 1)) + assert not filt(LidoValidatorFactory.build(index="1")) + + filt = iterator.get_filter_non_exitable_validators((1, 2)) + assert filt(LidoValidatorFactory.build(index="1")) + + +def test_get_delayed_validators(iterator): + iterator.lvs.get_operators_with_last_exited_validator_indexes = Mock( + return_value={ + (1, 1): 2, + (1, 2): 3, + } + ) + + iterator.lvs.get_recently_requested_validators_by_operator = Mock( + return_value={ + (1, 1): [2], + (1, 2): [3], + } + ) + + iterator.exitable_validators = { + (1, 1): [LidoValidatorFactory.build(index="1"), LidoValidatorFactory.build(index="2")], + (1, 2): [LidoValidatorFactory.build(index="3"), LidoValidatorFactory.build(index="4")], + } + + assert iterator._get_delayed_validators() == {(1, 1): 1, (1, 2): 0} + + +def test_calculate_validators_age(iterator, monkeypatch): + monkeypatch.setattr('src.services.exit_order_v2.iterator.get_validator_age', lambda x, _: 1) + iterator.blockstamp = ReferenceBlockStampFactory.build() + age = iterator.calculate_validators_age(list(range(20))) + assert age == 20 + + +def test_eject_validator(iterator): + sk_1 = StakingModuleFactory.build( + id=1, + priority_exit_share_threshold=1 * 10000, + ) + sk_2 = StakingModuleFactory.build( + id=2, + priority_exit_share_threshold=1 * 10000, + ) + iterator.w3.lido_contracts.staking_router.get_staking_modules = Mock( + return_value=[ + sk_1, + sk_2, + ] + ) + + no_1 = NodeOperatorFactory.build( + staking_module=sk_1, + total_deposited_validators=3, + target_validators_count=1, + is_target_limit_active=NodeOperatorLimitMode.FORCE, + ) + no_2 = NodeOperatorFactory.build( + staking_module=sk_1, + total_deposited_validators=2, + is_target_limit_active=NodeOperatorLimitMode.SOFT, + ) + no_3 = NodeOperatorFactory.build( + staking_module=sk_2, + id=1, + total_deposited_validators=3, + is_target_limit_active=NodeOperatorLimitMode.FORCE, + ) + + iterator.w3.lido_validators.get_lido_node_operators = Mock( + return_value=[ + no_1, + no_2, + no_3, + ] + ) + + iterator.w3.lido_validators.get_lido_validators_by_node_operators = Mock( + return_value={ + (1, 1): [LidoValidatorFactory.build(), LidoValidatorFactory.build(), LidoValidatorFactory.build()], + (1, 2): [LidoValidatorFactory.build(), LidoValidatorFactory.build()], + (2, 1): [ + LidoValidatorFactory.build(index='8'), + LidoValidatorFactory.build(index='7'), + LidoValidatorFactory.build(index='6'), + ], + } + ) + + iterator.lvs.get_operators_with_last_exited_validator_indexes = Mock( + return_value={ + (1, 1): -1, + (1, 2): -1, + (2, 1): 6, + } + ) + + iterator._get_delayed_validators = Mock(return_value={(1, 1): 1, (1, 2): -1, (2, 1): -1}) + + iterator._prepare_data_structure() + iterator._calculate_lido_stats() + + assert iterator.module_stats[1].exitable_validators == 5 + assert iterator.module_stats[2].exitable_validators == 2 + assert iterator.node_operators_stats[(1, 1)].exitable_validators == 3 + assert iterator.node_operators_stats[(1, 1)].delayed_validators == 1 + assert iterator.node_operators_stats[(1, 1)].delayed_validators == 1 + assert iterator.node_operators_stats[(1, 2)].soft_exit_to is not None + assert iterator.node_operators_stats[(2, 1)].force_exit_to is not None + assert iterator.exitable_validators[(2, 1)][0].index == '7' + assert iterator.total_lido_exitable_validators == 7 + + prev_total_age = iterator.node_operators_stats[(1, 1)].total_age + + iterator._eject_validator((1, 1)) + + assert iterator.total_lido_exitable_validators == 6 + assert iterator.module_stats[1].exitable_validators == 4 + assert iterator.node_operators_stats[(1, 1)].exitable_validators == 2 + assert iterator.node_operators_stats[(1, 1)].total_age < prev_total_age + + iterator.max_validators_to_exit = 3 + iterator.no_penetration_threshold = 0.1 + iterator.eth_validators_count = 1000 + iterator._load_constants = Mock() + + validators_to_eject = list(iterator) + assert len(validators_to_eject) == 3 + + ejector = iter(iterator) + val = next(ejector) + assert validators_to_eject[0] == val + + force_list = ejector.get_remaining_forced_validators() + + assert len(force_list) == 2 + assert force_list[0][0] == (1, 1) + assert force_list[1][0] == (1, 1) + + +@pytest.mark.unit +def test_no_predicate(iterator): + iterator.total_lido_exitable_validators = 1000 + iterator.no_penetration_threshold = 0.1 + iterator.eth_validators_count = 10000 + + result = iterator._no_predicate( + NodeOperatorStatsFactory.build( + exitable_validators=100, + delayed_validators=1, + total_age=1000, + force_exit_to=50, + soft_exit_to=25, + node_operator=NodeOperatorFactory.build(), + module_stats=ModuleStatsFactory.build( + exitable_validators=200, + staking_module=StakingModuleFactory.build(priority_exit_share_threshold=0.15 * 1000), + ), + ) + ) + assert result == (1, -50, -75, -185, 0, -100) + + result = iterator._no_predicate( + NodeOperatorStatsFactory.build( + exitable_validators=2000, + delayed_validators=0, + total_age=1000, + force_exit_to=50, + soft_exit_to=25, + node_operator=NodeOperatorFactory.build(), + module_stats=ModuleStatsFactory.build( + exitable_validators=200, + staking_module=StakingModuleFactory.build(priority_exit_share_threshold=0.15 * 1000), + ), + ) + ) + assert result == (0, -1950, -1975, -185, -1000, -2000) + + +@pytest.mark.unit +def test_no_force_and_soft_predicate(iterator): + nos = [ + NodeOperatorStatsFactory.build(force_exit_to=10, exitable_validators=20, soft_exit_to=20), + NodeOperatorStatsFactory.build(force_exit_to=5, exitable_validators=5, soft_exit_to=0), + NodeOperatorStatsFactory.build(force_exit_to=None, exitable_validators=100, soft_exit_to=20), + NodeOperatorStatsFactory.build(force_exit_to=0, exitable_validators=4, soft_exit_to=None), + ] + + # Priority to bigger diff exitable - forced_to + sorted_nos = sorted(nos, key=lambda x: -iterator._no_force_predicate(x)) + + assert [nos[0], nos[3], nos[1], nos[2]] == sorted_nos + + # Last two elements have same weight + assert [ + nos[0].node_operator.id, + nos[3].node_operator.id, + ] == [ + no.node_operator.id for no in sorted_nos + ][:2] + + sorted_nos = sorted(nos, key=lambda x: -iterator._no_soft_predicate(x)) + assert [ + nos[2].node_operator.id, + nos[1].node_operator.id, + ] == [ + no.node_operator.id for no in sorted_nos + ][:2] + + +@pytest.mark.unit +def test_max_share_rate_coefficient_predicate(iterator): + iterator.total_lido_exitable_validators = 10000 + + nos = [ + NodeOperatorStatsFactory.build( + module_stats=ModuleStatsFactory.build( + exitable_validators=1010, + staking_module=StakingModuleFactory.build(priority_exit_share_threshold=0.2 * 10000), + ), + ), + NodeOperatorStatsFactory.build( + module_stats=ModuleStatsFactory.build( + exitable_validators=3000, + staking_module=StakingModuleFactory.build(priority_exit_share_threshold=0.2 * 10000), + ), + ), + NodeOperatorStatsFactory.build( + module_stats=ModuleStatsFactory.build( + exitable_validators=3000, + staking_module=StakingModuleFactory.build(priority_exit_share_threshold=1 * 10000), + ), + ), + NodeOperatorStatsFactory.build( + module_stats=ModuleStatsFactory.build( + exitable_validators=5000, + staking_module=StakingModuleFactory.build(priority_exit_share_threshold=1 * 10000), + ), + ), + ] + + sorted_nos = sorted(nos, key=lambda x: -iterator._max_share_rate_coefficient_predicate(x)) + + assert sorted_nos[0] == nos[1] + assert sorted_nos[1] in [nos[2], nos[0]] + assert sorted_nos[2] in [nos[2], nos[0]] + assert sorted_nos[3] == nos[3] + + +@pytest.mark.unit +def test_stake_weight_coefficient_predicate(iterator): + nos = [ + NodeOperatorStatsFactory.build( + exitable_validators=900, + total_age=3000, + ), + NodeOperatorStatsFactory.build( + exitable_validators=1010, + total_age=2000, + ), + NodeOperatorStatsFactory.build( + exitable_validators=2010, + total_age=1000, + ), + ] + + sorted_nos = sorted( + nos, + key=lambda x: -iterator._stake_weight_coefficient_predicate( + x, + 10000, + 0.1, + ), + ) + + assert [nos[1], nos[2], nos[0]] == sorted_nos + + +@pytest.mark.unit +def test_get_remaining_forced_validators(iterator): + iterator.max_validators_to_exit = 10 + iterator.index = 5 + + iterator.node_operators_stats = { + (1, 1): NodeOperatorStatsFactory.build(exitable_validators=10, force_exit_to=None), + (1, 2): NodeOperatorStatsFactory.build(exitable_validators=10, force_exit_to=9), + } + iterator.node_operators_stats[(1, 1)].module_stats.staking_module.id = 1 + iterator.node_operators_stats[(1, 2)].module_stats.staking_module.id = 1 + iterator.node_operators_stats[(1, 1)].node_operator.id = 1 + iterator.node_operators_stats[(1, 2)].node_operator.id = 2 + + def _eject(self, gid): + self.node_operators_stats[gid].exitable_validators -= 1 + + iterator._eject_validator = MethodType(_eject, iterator) + + vals = iterator.get_remaining_forced_validators() + + assert len(vals) == 1 + + iterator.max_validators_to_exit = 10 + iterator.index = 10 + + vals = iterator.get_remaining_forced_validators() + assert len(vals) == 0 diff --git a/tests/modules/ejector/test_prediction.py b/tests/modules/ejector/test_prediction.py index 969c6419c..9c96b99ce 100644 --- a/tests/modules/ejector/test_prediction.py +++ b/tests/modules/ejector/test_prediction.py @@ -1,13 +1,13 @@ -from unittest.mock import MagicMock +from unittest.mock import MagicMock, Mock import pytest from hexbytes import HexBytes from web3.types import Wei import src.services.prediction as prediction_module -from src.modules.submodules.typings import ChainConfig +from src.modules.submodules.types import ChainConfig from src.services.prediction import RewardsPredictionService -from src.typings import BlockNumber, SlotNumber +from src.types import BlockNumber, SlotNumber from tests.factory.blockstamp import ReferenceBlockStampFactory @@ -280,13 +280,11 @@ def test_get_rewards_prediction(web3, contracts, monkeypatch: pytest.MonkeyPatch genesis_time=0, ) + web3.lido_contracts.oracle_daemon_config.prediction_duration_in_slots = Mock(return_value=12) + SOME_EVENTS = object() + with monkeypatch.context() as m: - m.setattr( - RewardsPredictionService, - "_get_prediction_duration_in_slots", - MagicMock(return_value=12), - ) m.setattr( prediction_module, "get_events_in_past", @@ -381,7 +379,7 @@ def test_get_rewards_prediction(web3, contracts, monkeypatch: pytest.MonkeyPatch ), ], ) -def test_group_events_incosistent(events_1, events_2): +def test_group_events_inconsistent(events_1, events_2): with pytest.raises(prediction_module.InconsistentEvents, match="Events are inconsistent"): RewardsPredictionService._group_events_by_transaction_hash(events_1, events_2) diff --git a/tests/modules/submodules/consensus/conftest.py b/tests/modules/submodules/consensus/conftest.py index efc263350..4de4c7bcb 100644 --- a/tests/modules/submodules/consensus/conftest.py +++ b/tests/modules/submodules/consensus/conftest.py @@ -1,12 +1,12 @@ import pytest from src.modules.submodules.consensus import ConsensusModule -from src.typings import BlockStamp, ReferenceBlockStamp +from src.types import BlockStamp, ReferenceBlockStamp class SimpleConsensusModule(ConsensusModule): - CONSENSUS_VERSION = 1 - CONTRACT_VERSION = 1 + COMPATIBLE_CONSENSUS_VERSIONS = [1] + COMPATIBLE_CONTRACT_VERSIONS = [1] def __init__(self, w3): self.report_contract = w3.lido_contracts.accounting_oracle diff --git a/tests/modules/submodules/consensus/test_consensus.py b/tests/modules/submodules/consensus/test_consensus.py index aa6b07fb4..8c236c990 100644 --- a/tests/modules/submodules/consensus/test_consensus.py +++ b/tests/modules/submodules/consensus/test_consensus.py @@ -4,13 +4,13 @@ import pytest from src import variables -from src.modules.accounting.typings import Account from src.modules.submodules import consensus as consensus_module from src.modules.submodules.consensus import ZERO_HASH, ConsensusModule, IsNotMemberException, MemberInfo -from src.modules.submodules.typings import ChainConfig -from src.providers.consensus.typings import BeaconSpecResponse -from src.typings import BlockStamp, ReferenceBlockStamp -from tests.conftest import get_blockstamp_by_state +from src.modules.submodules.exceptions import IncompatibleOracleVersion +from src.modules.submodules.types import ChainConfig +from src.providers.consensus.types import BeaconSpecResponse +from src.types import BlockStamp, ReferenceBlockStamp +from tests.conftest import get_blockstamp_by_state, Account from tests.factory.blockstamp import ReferenceBlockStampFactory from tests.factory.configs import BeaconSpecResponseFactory, ChainConfigFactory @@ -65,7 +65,7 @@ def set_report_account(monkeypatch): @pytest.mark.unit -def test_get_latest_blockstamp(consensus): +def test_get_latest_blockstamp(consensus, set_no_account): bs = consensus._get_latest_blockstamp() assert isinstance(bs, BlockStamp) @@ -120,7 +120,7 @@ def test_get_member_info_submit_only_account(consensus, set_submit_account): # ------ Get block for report tests ---------- @pytest.mark.unit @pytest.mark.possible_integration -def test_get_blockstamp_for_report_slot_not_finalized(web3, consensus, caplog): +def test_get_blockstamp_for_report_slot_not_finalized(web3, consensus, caplog, set_no_account): bs = ReferenceBlockStampFactory.build() current_frame = consensus.get_current_frame(bs) previous_blockstamp = get_blockstamp_by_state(web3, current_frame.ref_slot - 1) @@ -132,7 +132,7 @@ def test_get_blockstamp_for_report_slot_not_finalized(web3, consensus, caplog): @pytest.mark.unit @pytest.mark.possible_integration -def test_get_blockstamp_for_report_slot_deadline_missed(web3, consensus, caplog): +def test_get_blockstamp_for_report_slot_deadline_missed(web3, consensus, caplog, set_no_account): bs = ReferenceBlockStampFactory.build() member_info = consensus.get_member_info(bs) member_info.deadline_slot = bs.slot_number - 1 @@ -143,13 +143,14 @@ def test_get_blockstamp_for_report_slot_deadline_missed(web3, consensus, caplog) @pytest.mark.unit -def test_get_blockstamp_for_report_version_mismatch(consensus: ConsensusModule, caplog): +def test_incompatible_contract_version(consensus): bs = ReferenceBlockStampFactory.build() - consensus._get_latest_blockstamp = Mock(return_value=bs) - consensus._check_contract_versions = Mock(return_value=False) - consensus.get_blockstamp_for_report(bs) - assert "Waiting for Contracts to be updated" in caplog.messages[-1] + consensus.report_contract.get_contract_version = Mock(return_value=2) + consensus.report_contract.get_consensus_version = Mock(return_value=1) + + with pytest.raises(IncompatibleOracleVersion): + consensus._check_contract_versions(bs) @pytest.mark.unit @@ -165,7 +166,7 @@ def test_get_blockstamp_for_report_contract_is_not_reportable(consensus: Consens @pytest.mark.unit @pytest.mark.possible_integration -def test_get_blockstamp_for_report_slot_member_is_not_in_fast_line_ready(web3, consensus, caplog): +def test_get_blockstamp_for_report_slot_member_is_not_in_fast_line_ready(web3, consensus, caplog, set_no_account): latest_blockstamp = get_blockstamp_by_state(web3, 'head') member_info = consensus.get_member_info(latest_blockstamp) member_info.is_fast_lane = False @@ -178,7 +179,7 @@ def test_get_blockstamp_for_report_slot_member_is_not_in_fast_line_ready(web3, c @pytest.mark.unit @pytest.mark.possible_integration -def test_get_blockstamp_for_report_slot_member_ready_to_report(web3, consensus, caplog): +def test_get_blockstamp_for_report_slot_member_ready_to_report(web3, consensus, caplog, set_no_account): latest_blockstamp = get_blockstamp_by_state(web3, 'head') blockstamp = consensus.get_blockstamp_for_report(latest_blockstamp) assert isinstance(blockstamp, BlockStamp) diff --git a/tests/modules/submodules/consensus/test_reports.py b/tests/modules/submodules/consensus/test_reports.py index bff035970..4e0e428da 100644 --- a/tests/modules/submodules/consensus/test_reports.py +++ b/tests/modules/submodules/consensus/test_reports.py @@ -3,8 +3,9 @@ import pytest from hexbytes import HexBytes from src import variables -from src.modules.accounting.typings import Account, ReportData -from src.modules.submodules.typings import ChainConfig, FrameConfig, ZERO_HASH +from src.modules.accounting.types import ReportData +from src.modules.submodules.types import ChainConfig, FrameConfig, ZERO_HASH +from tests.conftest import Account from tests.factory.blockstamp import ReferenceBlockStampFactory from tests.factory.member_info import MemberInfoFactory @@ -33,7 +34,9 @@ def mock_latest_data(consensus): # ----- Process report main ---------- +@pytest.mark.unit def test_process_report_main(consensus, tx_utils, caplog): + consensus.w3.lido_contracts.accounting_oracle.get_consensus_version = Mock(return_value=1) blockstamp = ReferenceBlockStampFactory.build() consensus._get_latest_blockstamp = Mock(return_value=blockstamp) member_info = MemberInfoFactory.build(is_report_member=True, current_frame_consensus_report=ZERO_HASH) @@ -52,6 +55,7 @@ def test_process_report_main(consensus, tx_utils, caplog): # ----- Hash calculations ---------- +@pytest.mark.unit def test_hash_calculations(consensus): rd = ReportData(1, 2, 3, 4, [5, 6], [7, 8], 9, 10, 11, [12], 13, True, 13, HexBytes(int.to_bytes(14, 32)), 15) report_hash = consensus._encode_data_hash(rd.as_tuple()) @@ -60,7 +64,9 @@ def test_hash_calculations(consensus): # ------ Process report hash ----------- +@pytest.mark.unit def test_report_hash(web3, consensus, tx_utils, set_report_account): + consensus.w3.lido_contracts.accounting_oracle.get_consensus_version = Mock(return_value=1) blockstamp = ReferenceBlockStampFactory.build() consensus._get_latest_blockstamp = Mock(return_value=blockstamp) member_info = MemberInfoFactory.build(is_report_member=True) @@ -70,6 +76,7 @@ def test_report_hash(web3, consensus, tx_utils, set_report_account): consensus._send_report_hash.assert_called_once() +@pytest.mark.unit def test_report_hash_member_not_in_fast_lane(web3, consensus, caplog): blockstamp = ReferenceBlockStampFactory.build() consensus._get_latest_blockstamp = Mock(return_value=blockstamp) @@ -84,6 +91,7 @@ def test_report_hash_member_not_in_fast_lane(web3, consensus, caplog): assert "report will be postponed" in caplog.messages[-1] +@pytest.mark.unit def test_report_hash_member_is_not_report_member(consensus, caplog): blockstamp = ReferenceBlockStampFactory.build() consensus._get_latest_blockstamp = Mock(return_value=blockstamp) @@ -96,6 +104,7 @@ def test_report_hash_member_is_not_report_member(consensus, caplog): assert "Account can`t submit report hash" in caplog.messages[-1] +@pytest.mark.unit def test_do_not_report_same_hash(consensus, caplog, mock_latest_data): blockstamp = ReferenceBlockStampFactory.build() consensus._get_latest_blockstamp = Mock(return_value=blockstamp) @@ -110,6 +119,7 @@ def test_do_not_report_same_hash(consensus, caplog, mock_latest_data): # -------- Process report data --------- +@pytest.mark.unit def test_quorum_is_no_ready(consensus, caplog): blockstamp = ReferenceBlockStampFactory.build() consensus._get_latest_blockstamp = Mock(return_value=blockstamp) @@ -122,6 +132,7 @@ def test_quorum_is_no_ready(consensus, caplog): assert "Quorum is not ready." in caplog.messages[-1] +@pytest.mark.unit def test_process_report_data_hash_differs_from_quorums(consensus, caplog, mock_latest_data): blockstamp = ReferenceBlockStampFactory.build() report_data = tuple() @@ -131,6 +142,7 @@ def test_process_report_data_hash_differs_from_quorums(consensus, caplog, mock_l assert "Oracle`s hash differs from consensus report hash." in caplog.messages[-1] +@pytest.mark.unit def test_process_report_data_already_submitted(consensus, caplog, mock_latest_data): blockstamp = ReferenceBlockStampFactory.build() report_data = tuple() @@ -140,6 +152,7 @@ def test_process_report_data_already_submitted(consensus, caplog, mock_latest_da assert "Main data already submitted." in caplog.messages[-1] +@pytest.mark.unit def test_process_report_data_main_data_submitted(consensus, caplog, mock_latest_data): blockstamp = ReferenceBlockStampFactory.build() report_data = tuple() @@ -153,7 +166,10 @@ def test_process_report_data_main_data_submitted(consensus, caplog, mock_latest_ assert "Sleep for" not in caplog.text +@pytest.mark.unit def test_process_report_data_main_sleep_until_data_submitted(consensus, caplog, tx_utils, mock_latest_data): + consensus.w3.lido_contracts.accounting_oracle.get_consensus_version = Mock(return_value=1) + consensus.w3.lido_contracts.accounting_oracle.get_contract_version = Mock(return_value=1) consensus.get_chain_config = Mock( return_value=ChainConfig( slots_per_epoch=32, @@ -176,6 +192,7 @@ def test_process_report_data_main_sleep_until_data_submitted(consensus, caplog, assert "Send report data. Contract version: [1]" in caplog.text +@pytest.mark.unit def test_process_report_data_sleep_ends(consensus, caplog, mock_latest_data): consensus.get_chain_config = Mock( return_value=ChainConfig( @@ -198,7 +215,10 @@ def test_process_report_data_sleep_ends(consensus, caplog, mock_latest_data): assert "Main data already submitted." in caplog.text +@pytest.mark.unit def test_process_report_submit_report(consensus, tx_utils, caplog, mock_latest_data): + consensus.w3.lido_contracts.accounting_oracle.get_consensus_version = Mock(return_value=1) + consensus.w3.lido_contracts.accounting_oracle.get_contract_version = Mock(return_value=1) blockstamp = ReferenceBlockStampFactory.build() report_data = ReportData( 1, 2, 3, 4, [5, 6], [7, 8], 9, 10, 11, [12], 13, True, 13, HexBytes(int.to_bytes(14, 32)), 15 @@ -216,8 +236,6 @@ def test_process_report_submit_report(consensus, tx_utils, caplog, mock_latest_d # ----- Test sleep calculations - - @pytest.fixture def mock_configs(consensus): consensus.get_chain_config = Mock( @@ -237,6 +255,7 @@ def mock_configs(consensus): consensus.get_member_info = Mock(return_value=MemberInfoFactory.build(is_submit_member=False)) +@pytest.mark.unit def test_get_slot_delay_before_data_submit(consensus, caplog, set_report_account, mock_configs): consensus._get_consensus_contract_members = Mock(return_value=([variables.ACCOUNT.address], None)) delay = consensus._get_slot_delay_before_data_submit(ReferenceBlockStampFactory.build()) @@ -244,6 +263,7 @@ def test_get_slot_delay_before_data_submit(consensus, caplog, set_report_account assert "Calculate slots delay." in caplog.messages[-1] +@pytest.mark.unit def test_get_slot_delay_before_data_submit_three_members(consensus, caplog, set_report_account, mock_configs): blockstamp = ReferenceBlockStampFactory.build() consensus._get_consensus_contract_members = Mock(return_value=[[variables.ACCOUNT.address, '0x1', '0x2'], None]) diff --git a/tests/modules/submodules/test_oracle_module.py b/tests/modules/submodules/test_oracle_module.py index e266ccc8a..cb302bb81 100644 --- a/tests/modules/submodules/test_oracle_module.py +++ b/tests/modules/submodules/test_oracle_module.py @@ -7,11 +7,11 @@ from web3_multi_provider.multi_http_provider import NoActiveProviderError -from src.modules.submodules.exceptions import IsNotMemberException, IncompatibleContractVersion +from src.modules.submodules.exceptions import IsNotMemberException, IncompatibleOracleVersion from src.modules.submodules.oracle_module import BaseModule, ModuleExecuteDelay from src.providers.http_provider import NotOkResponse from src.providers.keys.client import KeysOutdatedException -from src.typings import BlockStamp +from src.types import BlockStamp from src.utils.slot import InconsistentData, NoSlotsAvailable, SlotNotFinalized from src import variables from tests.factory.blockstamp import ReferenceBlockStampFactory @@ -119,7 +119,7 @@ def _throw_with(*args): "ex", [ IsNotMemberException, - IncompatibleContractVersion, + IncompatibleOracleVersion, ], ) def test_run_cycle_fails_on_critical_exceptions(oracle: BaseModule, ex: Type[Exception]): diff --git a/tests/providers.py b/tests/providers.py index c7ca7773e..1cc1ded80 100644 --- a/tests/providers.py +++ b/tests/providers.py @@ -2,7 +2,7 @@ import os from contextlib import contextmanager from pathlib import Path -from typing import Any, Optional, Sequence, Callable +from typing import Any, Sequence, Callable from web3 import Web3 from web3.module import Module @@ -119,9 +119,10 @@ def __init__(self, mock_path: Path, w3: Web3): def _get( self, endpoint: str, - path_params: Optional[Sequence[str | int]] = None, - query_params: Optional[dict] = None, + path_params: Sequence[str | int] | None = None, + query_params: dict | None = None, force_raise: Callable[..., Exception | None] = lambda _: None, + stream: bool = False, ) -> dict | list: for response in self.responses: url = endpoint.format(*path_params) if path_params else endpoint @@ -153,9 +154,10 @@ def __init__(self, mock_path: Path, host: str, w3: Web3): def _get( self, endpoint: str, - path_params: Optional[Sequence[str | int]] = None, - query_params: Optional[dict] = None, + path_params: Sequence[str | int] | None = None, + query_params: dict | None = None, force_raise: Callable[..., Exception | None] = lambda _: None, + stream: bool = False, ) -> dict | list: url = endpoint.format(*path_params) if path_params else endpoint try: diff --git a/tests/providers_clients/test_consensus_client.py b/tests/providers_clients/test_consensus_client.py index 7423246e7..ca2cdb9f0 100644 --- a/tests/providers_clients/test_consensus_client.py +++ b/tests/providers_clients/test_consensus_client.py @@ -4,8 +4,8 @@ import pytest from src.providers.consensus.client import ConsensusClient -from src.providers.consensus.typings import Validator -from src.typings import SlotNumber +from src.providers.consensus.types import Validator +from src.types import SlotNumber from src.utils.blockstamp import build_blockstamp from src.variables import CONSENSUS_CLIENT_URI from tests.factory.blockstamp import BlockStampFactory @@ -29,6 +29,32 @@ def test_get_block_details(consensus_client: ConsensusClient, web3): assert block_details +@pytest.mark.integration +def test_get_block_attestations(consensus_client: ConsensusClient): + root = consensus_client.get_block_root('finalized').root + + attestations = list(consensus_client.get_block_attestations(root)) + assert attestations + + +@pytest.mark.integration +def test_get_attestation_committees(consensus_client: ConsensusClient): + root = consensus_client.get_block_root('finalized').root + block_details = consensus_client.get_block_details(root) + blockstamp = build_blockstamp(block_details) + + attestation_committees = list(consensus_client.get_attestation_committees(blockstamp)) + assert attestation_committees + + attestation_committee = attestation_committees[0] + attestation_committee_by_slot = list( + consensus_client.get_attestation_committees(blockstamp, slot=SlotNumber(int(attestation_committee.slot))) + ) + assert attestation_committee_by_slot[0].slot == attestation_committee.slot + assert attestation_committee_by_slot[0].index == attestation_committee.index + assert str(attestation_committee_by_slot[0].validators) == str(attestation_committee.validators) + + @pytest.mark.integration def test_get_validators(consensus_client: ConsensusClient): root = consensus_client.get_block_root('finalized').root diff --git a/tests/providers_clients/test_http_provider.py b/tests/providers_clients/test_http_provider.py index 2789cdeaf..e9f13009d 100644 --- a/tests/providers_clients/test_http_provider.py +++ b/tests/providers_clients/test_http_provider.py @@ -25,7 +25,7 @@ def test_no_providers(): def test_all_fallbacks_ok(): provider = HTTPProvider(['http://localhost:1', 'http://localhost:2'], 5 * 60, 1, 1) - provider._get_without_fallbacks = lambda host, endpoint, path_params, query_params: (host, endpoint) + provider._get_without_fallbacks = lambda host, endpoint, path_params, query_params, stream: (host, endpoint) assert provider._get('test') == ('http://localhost:1', 'test') assert len(provider.get_all_providers()) == 2 @@ -60,4 +60,4 @@ def _simple_get(host, endpoint, *_): provider._get_without_fallbacks = Mock(side_effect=_simple_get) with pytest.raises(CustomError): provider._get('test', force_raise=lambda _: CustomError()) - provider._get_without_fallbacks.assert_called_once_with('http://localhost:1', 'test', None, None) + provider._get_without_fallbacks.assert_called_once_with('http://localhost:1', 'test', None, None, False) diff --git a/tests/services/test_safe_border.py b/tests/services/test_safe_border.py index 9f5719d41..5d8dce52c 100644 --- a/tests/services/test_safe_border.py +++ b/tests/services/test_safe_border.py @@ -1,12 +1,12 @@ import pytest -from unittest.mock import MagicMock +from unittest.mock import Mock from src.services.safe_border import SafeBorder from tests.factory.no_registry import ValidatorFactory @pytest.mark.unit @pytest.mark.parametrize( - "is_bunker, negative_rebase_border_epoch, associated_slashings_border_epoch, default_requests_border_epoch, expected", + "is_bunker,negative_rebase_border_epoch,associated_slashings_border_epoch,default_requests_border_epoch,expected", [ (True, 1, 2, 7, 1), (True, 20, 5, 7, 5), @@ -20,15 +20,17 @@ def test_get_safe_border_epoch( default_requests_border_epoch, expected, ): - SafeBorder._retrieve_constants = MagicMock - SafeBorder._get_negative_rebase_border_epoch = MagicMock(return_value=negative_rebase_border_epoch) - SafeBorder._get_associated_slashings_border_epoch = MagicMock(return_value=associated_slashings_border_epoch) - SafeBorder._get_default_requests_border_epoch = MagicMock(return_value=default_requests_border_epoch) - - web3Mock = MagicMock - web3Mock.lido_contracts = MagicMock + SafeBorder._retrieve_constants = Mock() + sb = SafeBorder( + w3=Mock(), + blockstamp=Mock(), + chain_config=Mock(), + frame_config=Mock(), + ) - sb = SafeBorder(w3=web3Mock, blockstamp=MagicMock, chain_config=MagicMock, frame_config=MagicMock) + sb._get_negative_rebase_border_epoch = Mock(return_value=negative_rebase_border_epoch) + sb._get_associated_slashings_border_epoch = Mock(return_value=associated_slashings_border_epoch) + sb._get_default_requests_border_epoch = Mock(return_value=default_requests_border_epoch) actual = sb.get_safe_border_epoch(is_bunker=is_bunker) assert actual == expected @@ -45,19 +47,19 @@ def test_get_safe_border_epoch( def test_get_bunker_start_or_last_successful_report_epoch( get_bunker_timestamp, slots_per_epoch, last_processing_ref_slot, initial_epoch, expected ): - SafeBorder._retrieve_constants = MagicMock - SafeBorder._get_negative_rebase_border_epoch = MagicMock() - SafeBorder._get_associated_slashings_border_epoch = MagicMock() - SafeBorder._get_default_requests_border_epoch = MagicMock() - SafeBorder._get_bunker_mode_start_timestamp = MagicMock(return_value=get_bunker_timestamp) - web3Mock = MagicMock() - web3Mock.lido_contracts.get_accounting_last_processing_ref_slot = MagicMock(return_value=last_processing_ref_slot) - - chain_config = MagicMock + SafeBorder._retrieve_constants = Mock + SafeBorder._get_negative_rebase_border_epoch = Mock() + SafeBorder._get_associated_slashings_border_epoch = Mock() + SafeBorder._get_default_requests_border_epoch = Mock() + SafeBorder._get_bunker_mode_start_timestamp = Mock(return_value=get_bunker_timestamp) + web3Mock = Mock() + web3Mock.lido_contracts.get_accounting_last_processing_ref_slot = Mock(return_value=last_processing_ref_slot) + + chain_config = Mock chain_config.slots_per_epoch = slots_per_epoch chain_config.initial_epoch = initial_epoch - sb = SafeBorder(w3=web3Mock, blockstamp=MagicMock, chain_config=chain_config, frame_config=MagicMock) + sb = SafeBorder(w3=web3Mock, blockstamp=Mock, chain_config=chain_config, frame_config=Mock) actual = sb._get_bunker_start_or_last_successful_report_epoch() @@ -83,7 +85,7 @@ def validators(): @pytest.fixture def frame_config(): - frame_config = MagicMock + frame_config = Mock frame_config.initial_epoch = 50 frame_config.epochs_per_frame = 2 @@ -92,7 +94,7 @@ def frame_config(): @pytest.fixture def chain_config(): - chain_config = MagicMock + chain_config = Mock chain_config.slots_per_epoch = 12 return chain_config @@ -100,7 +102,7 @@ def chain_config(): @pytest.fixture def blockstamp(): - blockstamp = MagicMock + blockstamp = Mock blockstamp.ref_epoch = 99 return blockstamp @@ -123,16 +125,14 @@ def test_find_earliest_slashed_epoch_rounded_to_frame( last_finalized_withdrawal_request_slot, expected, ): - SafeBorder._retrieve_constants = MagicMock() - SafeBorder._get_negative_rebase_border_epoch = MagicMock() - SafeBorder._get_associated_slashings_border_epoch = MagicMock() - SafeBorder._get_last_finalized_withdrawal_request_slot = MagicMock( - return_value=last_finalized_withdrawal_request_slot - ) - SafeBorder._slashings_in_frame = MagicMock(return_value=slashings_in_frame) - - web3Mock = MagicMock() - web3Mock.lido_contracts = MagicMock() + SafeBorder._retrieve_constants = Mock() + SafeBorder._get_negative_rebase_border_epoch = Mock() + SafeBorder._get_associated_slashings_border_epoch = Mock() + SafeBorder._get_last_finalized_withdrawal_request_slot = Mock(return_value=last_finalized_withdrawal_request_slot) + SafeBorder._slashings_in_frame = Mock(return_value=slashings_in_frame) + + web3Mock = Mock() + web3Mock.lido_contracts = Mock() sb = SafeBorder(w3=web3Mock, blockstamp=blockstamp, chain_config=chain_config, frame_config=frame_config) diff --git a/tests/utils/test_cache.py b/tests/utils/test_cache.py index e97e7461f..0e7b177fe 100644 --- a/tests/utils/test_cache.py +++ b/tests/utils/test_cache.py @@ -1,8 +1,14 @@ +import random + +from hexbytes import HexBytes +from web3.types import BlockIdentifier + +from src.providers.execution.base_interface import ContractInterface from src.utils.cache import clear_global_cache, global_lru_cache class Calc: - @global_lru_cache(maxsize=1) + @global_lru_cache(maxsize=2) def get(self, a, b): return a + b @@ -12,6 +18,49 @@ def test_clear_global_cache(): calc.get(1, 2) assert calc.get.cache_info().currsize == 1 + calc.get(2, 1) + assert calc.get.cache_info().currsize == 2 + clear_global_cache() assert calc.get.cache_info().currsize == 0 + + +class Contract(ContractInterface): + def __init__(self): + pass + + @global_lru_cache(maxsize=5) + def func(self, block_identifier: BlockIdentifier = 'latest'): + pass + + @global_lru_cache(maxsize=1) + def func_1(self, module_id: int, block_identifier: BlockIdentifier = 'latest'): + return random.random() + + +def test_cache_do_not_cache_contract_with_relative_blocks(): + c = Contract() + + c.func() + assert c.func.cache_info().currsize == 0 + c.func(block_identifier=HexBytes('11')) + c.func(block_identifier=HexBytes('11')) + c.func(block_identifier=HexBytes('22')) + c.func(block_identifier='latest') + c.func(block_identifier='finalized') + c.func('finalized') + assert c.func.cache_info().currsize == 2 + + c.func(HexBytes('22')) + c.func(HexBytes('11')) + c.func(HexBytes('33')) + c.func('finalized') + assert c.func.cache_info().currsize == 3 + + result_1 = c.func_1(1, 1) + result_2 = c.func_1(1) + result_3 = c.func_1(1, 1) + + assert result_1 != result_2 + assert result_1 == result_3 diff --git a/tests/utils/test_dataclass.py b/tests/utils/test_dataclass.py index d1140c502..b6397a964 100644 --- a/tests/utils/test_dataclass.py +++ b/tests/utils/test_dataclass.py @@ -1,5 +1,5 @@ from dataclasses import dataclass, is_dataclass -from typing import Any +from typing import Any, Iterable import pytest @@ -83,6 +83,23 @@ def get_cars_with_already_as_cars() -> list[Car]: get_cars_with_already_as_cars() +def test_list_of_dataclasses_empty(): + @list_of_dataclasses(Car) + def get_no_cars() -> list[Car]: + return [] + + assert get_no_cars() == [] + + +def test_list_of_dataclasses_generator(): + @list_of_dataclasses(Car) + def get_iterable_cars() -> Iterable: + return range(10) + + with pytest.raises(DecodeToDataclassException): + get_iterable_cars() + + def test_list_of_dataclasses_with_mixed_types(): @list_of_dataclasses(Car) def get_cars_inconsistent() -> list[Any]: @@ -133,6 +150,12 @@ def test_dataclass_ignore_extra_fields(): assert pet == Pet(name="Bob", age=5) +def test_dataclass_raises_missing_field(): + response = {"name": "Bob"} + with pytest.raises(TypeError, match="age"): + pet = Pet.from_response(**response) + + @dataclass class Hooman(Nested, FromResponse): favourite_pet: Pet @@ -145,3 +168,9 @@ def test_dataclass_nested_with_extra_fields(): ) hooman = Hooman.from_response(**hooman_response) assert hooman == Hooman(favourite_pet=Pet(name="Bob", age=5), pets=[Pet(name="Bob", age=5)]) + + +def test_dataclass_nested_raises_missing_field(): + response = dict(pets=[{"name": "Bob", "age": 5, "extra": "field"}]) + with pytest.raises(TypeError, match="favourite_pet"): + Hooman.from_response(**response) diff --git a/tests/utils/test_events.py b/tests/utils/test_events.py index 3ab056a47..a0de891d6 100644 --- a/tests/utils/test_events.py +++ b/tests/utils/test_events.py @@ -1,27 +1,38 @@ +# pyright: reportArgumentType=false + +from unittest.mock import Mock + import pytest -from src.typings import ReferenceBlockStamp -from src.utils.events import get_events_in_past +from src import variables +from src.providers.execution.exceptions import InconsistentEvents +from src.utils.events import get_events_in_past, get_events_in_range from tests.factory.blockstamp import ReferenceBlockStampFactory -class ContractEvent: - def get_logs(self, fromBlock, toBlock): - events = [ - {'blockNumber': 10, 'args': {'timestamp': 10 * 10}}, - {'blockNumber': 15, 'args': {'timestamp': 15 * 10}}, - # 5 missed blocks - {'blockNumber': 20, 'args': {'timestamp': 25 * 10}}, - {'blockNumber': 25, 'args': {'timestamp': 30 * 10}}, - {'blockNumber': 30, 'args': {'timestamp': 35 * 10}}, - ] +@pytest.fixture() +def events(): + return [ + {'blockNumber': 10, 'args': {'timestamp': 10 * 10}}, + {'blockNumber': 15, 'args': {'timestamp': 15 * 10}}, + # 5 missed blocks + {'blockNumber': 20, 'args': {'timestamp': 25 * 10}}, + {'blockNumber': 25, 'args': {'timestamp': 30 * 10}}, + {'blockNumber': 30, 'args': {'timestamp': 35 * 10}}, + ] + - return list(filter(lambda e: fromBlock < e['blockNumber'] < toBlock, events)) +@pytest.fixture() +def contract_event(events): + def get_logs(fromBlock, toBlock): + return [e for e in events if fromBlock <= e['blockNumber'] <= toBlock] + + return Mock(get_logs=Mock(side_effect=get_logs)) @pytest.mark.unit @pytest.mark.possible_integration -def test_get_contract_events_in_past(): +def test_get_contract_events_in_past(contract_event): seconds_per_slot = 10 bs = ReferenceBlockStampFactory.build( slot_number=36, @@ -31,14 +42,56 @@ def test_get_contract_events_in_past(): ref_epoch=0, ) - events = get_events_in_past(ContractEvent(), bs, 10, seconds_per_slot) + events = get_events_in_past(contract_event, bs, 10, seconds_per_slot) assert len(events) == 2 - events = get_events_in_past(ContractEvent(), bs, 15, seconds_per_slot) + events = get_events_in_past(contract_event, bs, 15, seconds_per_slot) assert len(events) == 3 # 1 block should be filtered by ts - events = get_events_in_past(ContractEvent(), bs, 20, seconds_per_slot) + events = get_events_in_past(contract_event, bs, 20, seconds_per_slot) assert len(events) == 3 - events = get_events_in_past(ContractEvent(), bs, 25, seconds_per_slot) + events = get_events_in_past(contract_event, bs, 25, seconds_per_slot) assert len(events) == 4 - events = get_events_in_past(ContractEvent(), bs, 31, seconds_per_slot) + events = get_events_in_past(contract_event, bs, 31, seconds_per_slot) assert len(events) == 5 + + +@pytest.mark.unit +def test_get_events_in_range(contract_event): + variables.EVENTS_SEARCH_STEP = 2 + events = list(get_events_in_range(contract_event, 10, 28)) + assert len(events) == 4 + assert contract_event.get_logs.call_args_list == [ + ({'fromBlock': 10, 'toBlock': 12},), + ({'fromBlock': 13, 'toBlock': 15},), + ({'fromBlock': 16, 'toBlock': 18},), + ({'fromBlock': 19, 'toBlock': 21},), + ({'fromBlock': 22, 'toBlock': 24},), + ({'fromBlock': 25, 'toBlock': 27},), + ({'fromBlock': 28, 'toBlock': 28},), + ] + + +@pytest.mark.unit +def test_get_events_in_range_single_block(contract_event): + events = list(get_events_in_range(contract_event, 25, 25)) + assert len(events) == 1 + assert contract_event.get_logs.call_args == ({'fromBlock': 25, 'toBlock': 25},) + + +@pytest.mark.unit +def test_get_events_in_range_invalid_range(): + with pytest.raises(ValueError, match="l_block=30 > r_block=10"): + list(get_events_in_range(Mock(), 30, 10)) + + +@pytest.mark.unit +def test_get_events_in_range_inconsistent_events(): + event = Mock() + + event.get_logs = Mock(return_value=[{"blockNumber": 100500}]) + with pytest.raises(InconsistentEvents): + list(get_events_in_range(event, 10, 20)) + + event.get_logs = Mock(return_value=[{"blockNumber": 1}]) + with pytest.raises(InconsistentEvents): + list(get_events_in_range(event, 10, 20)) diff --git a/tests/utils/test_range.py b/tests/utils/test_range.py new file mode 100644 index 000000000..fe2463673 --- /dev/null +++ b/tests/utils/test_range.py @@ -0,0 +1,18 @@ +import pytest + +from src.utils.range import sequence + + +def test_sequence(): + assert list(sequence(0, 3)) == [0, 1, 2, 3] + assert list(sequence(1, 3)) == [1, 2, 3] + assert list(sequence(3, 3)) == [3] + + assert list(sequence(-3, -3)) == [-3] + assert list(sequence(-3, -1)) == [-3, -2, -1] + assert list(sequence(-3, 0)) == [-3, -2, -1, 0] + + +def test_sequence_raises(): + with pytest.raises(ValueError, match="start=3 > stop=1"): + sequence(3, 1) diff --git a/tests/utils/test_slot.py b/tests/utils/test_slot.py index 70d93f3ab..546c430b0 100644 --- a/tests/utils/test_slot.py +++ b/tests/utils/test_slot.py @@ -5,15 +5,16 @@ import pytest from src.providers.http_provider import NotOkResponse +from src.types import SlotNumber from src.utils.slot import NoSlotsAvailable, get_first_non_missed_slot from tests.conftest import get_blockstamp_by_state -@pytest.mark.unit @pytest.mark.possible_integration -def test_get_first_non_missed_slot(web3, consensus_client): +@pytest.mark.usefixtures("consensus_client") +def test_get_first_non_missed_slot(web3): finalized_blockstamp = get_blockstamp_by_state(web3, 'finalized') - ref_slot = finalized_blockstamp.slot_number - 225 + ref_slot = SlotNumber(finalized_blockstamp.slot_number - 225) slot_details = get_first_non_missed_slot( web3.cc, @@ -25,7 +26,8 @@ def test_get_first_non_missed_slot(web3, consensus_client): @pytest.mark.unit -def test_get_third_non_missed_slot(web3, consensus_client): +@pytest.mark.usefixtures("consensus_client") +def test_get_third_non_missed_slot_backward(web3): def get_block_header(_): setattr(get_block_header, "call_count", getattr(get_block_header, "call_count", 0) + 1) if getattr(get_block_header, "call_count") == 3: @@ -38,21 +40,45 @@ def get_block_header(_): web3.cc.get_block_header = Mock(side_effect=get_block_header) slot_details = get_first_non_missed_slot( web3.cc, - slot=139456, + slot=SlotNumber(139456), last_finalized_slot_number=finalized_blockstamp.slot_number, ) assert int(slot_details.message.slot) < finalized_blockstamp.slot_number assert int(slot_details.message.slot) == 139455 +@pytest.mark.unit +@pytest.mark.usefixtures("consensus_client") +def test_get_third_non_missed_slot_forward(web3): + def get_block_header(_): + setattr(get_block_header, "call_count", getattr(get_block_header, "call_count", 0) + 1) + if getattr(get_block_header, "call_count") == 3: + web3.cc.get_block_header = original + raise NotOkResponse("No slots", status=HTTPStatus.NOT_FOUND, text="text") + + finalized_blockstamp = get_blockstamp_by_state(web3, 'finalized') + + original = web3.cc.get_block_header + web3.cc.get_block_header = Mock(side_effect=get_block_header) + slot_details = get_first_non_missed_slot( + web3.cc, + slot=SlotNumber(1541622), + last_finalized_slot_number=finalized_blockstamp.slot_number, + direction="forward", + ) + assert int(slot_details.message.slot) < finalized_blockstamp.slot_number + assert int(slot_details.message.slot) == 1541625 + + @pytest.mark.unit @pytest.mark.possible_integration -def test_all_slots_are_missed(web3, consensus_client): +@pytest.mark.usefixtures("consensus_client") +def test_all_slots_are_missed(web3): finalized_blockstamp = get_blockstamp_by_state(web3, 'finalized') web3.cc.get_block_header = Mock(side_effect=NotOkResponse("No slots", status=HTTPStatus.NOT_FOUND, text="text")) with pytest.raises(NoSlotsAvailable): get_first_non_missed_slot( cc=web3.cc, slot=finalized_blockstamp.ref_slot, - last_finalized_slot_number=finalized_blockstamp.ref_slot + 50, + last_finalized_slot_number=SlotNumber(finalized_blockstamp.ref_slot + 50), ) diff --git a/tests/utils/test_validator_state_utils.py b/tests/utils/test_validator_state_utils.py index 9fdbe8e5a..677763b3c 100644 --- a/tests/utils/test_validator_state_utils.py +++ b/tests/utils/test_validator_state_utils.py @@ -2,8 +2,8 @@ import pytest from src.constants import FAR_FUTURE_EPOCH, EFFECTIVE_BALANCE_INCREMENT -from src.providers.consensus.typings import Validator, ValidatorStatus, ValidatorState -from src.typings import EpochNumber, Gwei +from src.providers.consensus.types import Validator, ValidatorStatus, ValidatorState +from src.types import EpochNumber, Gwei from src.utils.validator_state import ( calculate_total_active_effective_balance, is_on_exit, @@ -15,6 +15,7 @@ has_eth1_withdrawal_credential, is_exited_validator, is_active_validator, + compute_activation_exit_epoch, ) from tests.factory.no_registry import ValidatorFactory from tests.modules.accounting.bunker.test_bunker_abnormal_cl_rebase import simple_validators @@ -289,3 +290,9 @@ def test_skip_ongoing(self, validators: list[Validator]): actual = calculate_total_active_effective_balance(validators, EpochNumber(170256)) assert actual == Gwei(2000000000) + + +@pytest.mark.unit +def test_compute_activation_exit_epoch(): + ref_epoch = 3455 + assert 3460 == compute_activation_exit_epoch(ref_epoch) diff --git a/tests/utils/test_web3_converter.py b/tests/utils/test_web3_converter.py index 026f86329..b091dfae3 100644 --- a/tests/utils/test_web3_converter.py +++ b/tests/utils/test_web3_converter.py @@ -1,7 +1,7 @@ import pytest -from src.modules.submodules.typings import ChainConfig, FrameConfig -from src.typings import EpochNumber, FrameNumber, SlotNumber +from src.modules.submodules.types import ChainConfig, FrameConfig +from src.types import EpochNumber, FrameNumber, SlotNumber from src.utils.web3converter import Web3Converter from tests.factory.configs import ChainConfigFactory, FrameConfigFactory diff --git a/tests/web3_extentions/test_lido_validators.py b/tests/web3_extentions/test_lido_validators.py index be3523683..5af2efa75 100644 --- a/tests/web3_extentions/test_lido_validators.py +++ b/tests/web3_extentions/test_lido_validators.py @@ -2,7 +2,7 @@ import pytest -from src.web3py.extensions.lido_validators import CountOfKeysDiffersException, LidoValidatorsProvider +from src.web3py.extensions.lido_validators import CountOfKeysDiffersException from tests.factory.blockstamp import ReferenceBlockStampFactory from tests.factory.no_registry import ( LidoKeyFactory, @@ -12,6 +12,7 @@ ValidatorFactory, ) + blockstamp = ReferenceBlockStampFactory.build() diff --git a/tests/web3_extentions/test_middleware.py b/tests/web3_extentions/test_middleware.py index 6c4fb0d54..183269121 100644 --- a/tests/web3_extentions/test_middleware.py +++ b/tests/web3_extentions/test_middleware.py @@ -1,6 +1,7 @@ import pytest from requests import HTTPError from web3 import Web3, HTTPProvider +from web3.exceptions import MethodUnavailable from src.metrics.prometheus.basic import EL_REQUESTS_DURATION from src.variables import EXECUTION_CLIENT_URI @@ -42,7 +43,7 @@ def test_success(provider, web3): 'call_to': '', 'code': '0', 'endpoint': 'eth_blockNumber', - 'le': '0.005', + 'le': '0.01', } @@ -56,12 +57,15 @@ def test_fail_with_status_code(provider, web3): 'call_to': '', 'code': '404', 'endpoint': 'eth_blockNumber', - 'le': '0.005', + 'le': '0.01', } def test_fail_with_body_error(provider, web3): - with pytest.raises(ValueError): + with pytest.raises((MethodUnavailable, ValueError)): web3.eth.coinbase labels = _get_requests_labels() - assert labels == {'call_method': '', 'call_to': '', 'code': '-32000', 'endpoint': 'eth_coinbase', 'le': '0.005'} + assert labels in [ + {'call_method': '', 'call_to': '', 'code': '-32601', 'endpoint': 'eth_coinbase', 'le': '0.01'}, + {'call_method': '', 'call_to': '', 'code': '-32000', 'endpoint': 'eth_coinbase', 'le': '0.01'}, + ] diff --git a/tests/web3_extentions/test_tx_utils.py b/tests/web3_extentions/test_tx_utils.py index 670f83d73..70329ade9 100644 --- a/tests/web3_extentions/test_tx_utils.py +++ b/tests/web3_extentions/test_tx_utils.py @@ -1,12 +1,13 @@ +from collections import defaultdict from unittest.mock import Mock import pytest -from web3.exceptions import ContractLogicError +from web3.exceptions import ContractLogicError, TimeExhausted from src import variables from src.constants import MAX_BLOCK_GAS_LIMIT -from src.modules.accounting.typings import Account from src.utils import input +from tests.conftest import Account class Transaction: @@ -100,3 +101,23 @@ def test_daemon_check_and_send_transaction(web3, tx_utils, tx, account, monkeypa web3.transaction._check_transaction = Mock(return_value=True) web3.transaction.check_and_send_transaction(tx, account) web3.transaction._sign_and_send_transaction.assert_not_called() + + +def test_find_transaction_timeout(web3, tx_utils, tx, account, monkeypatch): + web3.eth.wait_for_transaction_receipt = Mock(side_effect=TimeExhausted()) + + assert not web3.transaction._handle_sent_transaction('0x000001') + + web3.eth.wait_for_transaction_receipt = Mock( + return_value={ + 'blockHash': b'', + 'blockNumber': '', + 'gasUsed': '', + 'effectiveGasPrice': '', + 'status': '', + 'transactionHash': b'', + 'transactionIndex': '', + } + ) + + assert web3.transaction._handle_sent_transaction('0x000001')